Scan your dependencies. Know your risks. Ship with confidence.
license-checkr is a blazing-fast CLI tool written in Rust that scans your project's dependency manifests, resolves license information, evaluates it against a policy you define, and outputs a clear report — in your terminal, as JSON, as a PDF, or as a standards-compliant SBOM (CycloneDX or SPDX).
- 🌍 Multi-ecosystem — Rust, Python, Java, Node.js, and .NET in a single run
- 🔎 Auto-detection — no configuration required; detects your stack automatically
- 📡 Online enrichment — fetch missing license data from crates.io, PyPI, Maven Central, and npm
- ⚖️ Policy engine — define per-license rules (
pass/warn/error) in a simple TOML file - 🏷️ SPDX-aware — normalizes 20+ non-standard license strings to SPDX identifiers
- 🧮 Expression support — parses full SPDX compound expressions including
(Apache-2.0 OR MIT) AND BSD-3-Clausewith proper operator precedence (ANDbinds tighter thanOR, parentheses override) - 📊 Multiple outputs — colored terminal table, machine-readable JSON, or a shareable PDF report
- 🚦 CI-friendly — exits with code
1when a policy error is found;0otherwise - 🦊 GitLab integration —
--report gitlaboutputs a Code Quality JSON artifact that renders inline on Merge Requests - 🗂️ Workspace scanning — use
--recursiveto scan all sub-projects in a monorepo in a single run - 📦 SBOM generation — export a Software Bill of Materials in CycloneDX JSON/XML (v1.5) or SPDX JSON (v2.3) via
sbom generate - 🤖 MCP server — expose
license-checkras an MCP tool so AI agents (Claude Desktop, Cursor, etc.) can scan projects and look up licenses directly
Download the latest release for your platform:
Extract and place the binary somewhere on your PATH:
# Linux / macOS
tar -xzf license-checkr-*.tar.gz
sudo mv license-checkr /usr/local/bin/
# Windows — extract the .zip and move license-checkr.exe to a folder in your PATHcargo install --git https://github.com/QuentinRob/license-checkrgit clone https://github.com/QuentinRob/license-checkr
cd license-checkr
cargo build --release
# binary at ./target/release/license-checkrlicense-checkr [OPTIONS] [PATH]
| Argument | Description |
|---|---|
[PATH] |
Project root to scan (default: current directory) |
--online |
Fetch license data from package registries |
--config <FILE> |
Override policy config file path |
--report <FORMAT> |
Output format: terminal (default), json, pdf, gitlab |
--pdf [FILE] |
Write PDF report (default: license-report.pdf) |
--exclude-lang <LANG> |
Skip an ecosystem: rust python java node dotnet (repeatable) |
-r, --recursive |
Recursively scan sub-projects (workspace mode) |
-v, --verbose |
Show all dependencies, not just warnings and errors |
-q, --quiet |
Print summary line only |
# Scan the current directory
license-checkr
# Scan a specific project with online registry lookup
license-checkr ~/my-project --online
# Export a PDF report
license-checkr --pdf report.pdf
# Output machine-readable JSON for CI pipelines
license-checkr --report json | jq '.[] | select(.verdict == "error")'
# Scan only Rust and Node, skip Python and Java
license-checkr --exclude-lang python --exclude-lang java
# Quiet mode — perfect for CI scripts
license-checkr -q && echo "✅ All licenses OK"When your repository contains multiple sub-projects (a monorepo), use --recursive to discover and scan every sub-project in a single pass:
# Scan all sub-projects under the current directory
license-checkr --recursive
# Workspace scan with online enrichment and a unified PDF report
license-checkr --recursive --online --pdf workspace-report.pdf
# JSON output: array of { project, path, dependencies }
license-checkr --recursive --report json | jq '.[].project'
# Quiet workspace summary — great for CI
license-checkr --recursive -q && echo "✅ All workspace licenses OK"Each sub-project is scanned independently with its own policy config (if present). The PDF report includes a workspace cover page with an aggregated summary, followed by per-project Risk Summary and Dependency Table sections.
license-checkr can produce a GitLab Code Quality artifact so that license violations appear inline on every Merge Request.
license-checkr --report gitlabThe output is a JSON array where every dependency with a warn or error verdict becomes a Code Quality issue. pass verdicts are omitted.
| Policy verdict | GitLab severity |
|---|---|
error |
blocker |
warn |
minor |
pass |
(omitted) |
[
{
"description": "Dependency 'some-gpl-lib@2.1.0' uses license 'GPL-3.0' — policy verdict: error",
"check_name": "license-checkr/license-error",
"fingerprint": "a3f1c2d4e5b6a7f8",
"severity": "blocker",
"location": {
"path": "Cargo.lock",
"lines": { "begin": 1 }
}
}
]license-check:
stage: test
image: rust:latest
script:
- cargo install --git https://github.com/QuentinRob/license-checkr
- license-checkr --report gitlab > gl-code-quality-report.json
artifacts:
reports:
codequality: gl-code-quality-report.json
allow_failure: true # remove this line to block MRs on license errorsFor workspace (monorepo) scanning, add --recursive:
- license-checkr --recursive --report gitlab > gl-code-quality-report.jsonlicense-checkr can act as an MCP (Model Context Protocol) server, letting AI agents like Claude Desktop or Cursor query it as a tool.
license-checkr mcp serveThis starts a JSON-RPC server over stdio. The server exposes two tools:
| Tool | Description |
|---|---|
scan_licenses |
Scan a project directory — accepts path, online, config, exclude_lang, recursive |
get_package_license |
Look up a single package — accepts name, version, ecosystem (rust/python/java/node) |
Add to your claude_desktop_config.json:
{
"mcpServers": {
"license-checkr": {
"command": "license-checkr",
"args": ["mcp", "serve"]
}
}
}Config file locations:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Once configured, Claude can answer questions like:
- "Scan my project at ~/my-app and show any license errors"
- "What license does serde 1.0 use? Is it compatible with my policy?"
Generate a standards-compliant Software Bill of Materials from your dependencies:
license-checkr sbom generate [OPTIONS] [PATH]| Option | Description |
|---|---|
[PATH] |
Project root to scan (default: current directory) |
--format <FORMAT> |
cyclonedx-json (default), cyclonedx-xml, spdx-json |
--output, -o <FILE> |
Output file path (default: sbom.json or sbom.xml) |
--pdf [FILE] |
Also generate an SBOM PDF report (default: sbom-report.pdf) |
--online |
Enrich with license data from package registries |
-r, --recursive |
Workspace mode — merge all sub-projects into a single SBOM |
--config <FILE> |
Policy config override |
--exclude-lang <LANG> |
Skip an ecosystem (repeatable) |
# Generate a CycloneDX JSON SBOM for the current project
license-checkr sbom generate
# CycloneDX XML format
license-checkr sbom generate --format cyclonedx-xml --output sbom.xml
# SPDX JSON format with online enrichment
license-checkr sbom generate --format spdx-json --online
# Custom output path
license-checkr sbom generate --output /tmp/my-project-sbom.json
# Also produce a PDF summary alongside the SBOM
license-checkr sbom generate --pdf
# Workspace mode — single SBOM covering all sub-projects
license-checkr sbom generate --recursive --output workspace-sbom.json| Format | Standard | Extension |
|---|---|---|
cyclonedx-json |
CycloneDX v1.5 JSON | .json |
cyclonedx-xml |
CycloneDX v1.5 XML | .xml |
spdx-json |
SPDX v2.3 JSON | .json |
| Ecosystem | Manifest files parsed | Unit tested | Offline validated | Online validated |
|---|---|---|---|---|
| 🦀 Rust | Cargo.lock |
✅ | ✅ | ✅ crates.io |
| 🐍 Python | Pipfile.lock, requirements.txt, pyproject.toml |
✅ | ||
| ☕ Java | pom.xml, build.gradle, build.gradle.kts, gradle.lockfile |
✅ | ||
| 🟢 Node.js | package-lock.json, yarn.lock, package.json |
✅ | ||
| 🔷 .NET | *.csproj, *.fsproj, packages.config, paket.lock |
✅ | ❌ no NuGet client yet |
Multiple ecosystems are detected automatically in a single pass. Use --exclude-lang to opt out of any you don't need.
Create a .license-checkr/config.toml file in your project root (or at ~/.config/license-checkr/config.toml for a global policy). If no config is found, a sensible default policy is applied.
[policy]
# Default verdict for any license not listed below
default = "warn" # pass | warn | error
[policy.licenses]
# Permissive — always allowed
"MIT" = "pass"
"Apache-2.0" = "pass"
"BSD-2-Clause" = "pass"
"BSD-3-Clause" = "pass"
"ISC" = "pass"
"0BSD" = "pass"
"Unlicense" = "pass"
"CC0-1.0" = "pass"
# Weak copyleft — review required
"LGPL-2.1" = "warn"
"MPL-2.0" = "warn"
"LGPL-3.0" = "warn"
# Strong copyleft — blocked
"GPL-2.0" = "error"
"GPL-3.0" = "error"
"AGPL-3.0" = "error"
# Unknown licenses — warn but don't block
"unknown" = "warn"--config <FILE>argument./.license-checkr/config.toml(project-level)~/.config/license-checkr/config.toml(global)- Built-in default policy
→ Rust 42 dependencies
→ Node 87 dependencies
┌──────────────────────────────────────────────────────┐
│ SUMMARY │
│ Scanned path : /home/user/my-project │
│ Total : 129 │
│ ✓ Pass : 114 MIT (68), Apache-2.0 (32) │
│ ⚠ Warn : 12 unknown (12) │
│ ✗ Error : 3 GPL-3.0 (3) │
└──────────────────────────────────────────────────────┘
Errors
┌───────────────────┬─────────┬───────────┬─────────┬───────────────┬────────┐
│ Name │ Version │ Ecosystem │ License │ Risk │Verdict │
╞═══════════════════╪═════════╪═══════════╪═════════╪═══════════════╪════════╡
│ some-gpl-package │ 2.1.0 │ Node │ GPL-3.0 │ StrongCopyleft│ error │
└───────────────────┴─────────┴───────────┴─────────┴───────────────┴────────┘
license-checkr --report json[
{
"name": "serde",
"version": "1.0.136",
"ecosystem": "Rust",
"license_raw": "MIT OR Apache-2.0",
"license_spdx": "MIT OR Apache-2.0",
"risk": "Permissive",
"verdict": "pass",
"source": "registry"
}
]license-checkr --report gitlab > gl-code-quality-report.jsonOutputs a JSON array of Code Quality issues (warn/error verdicts only) consumable by GitLab CI as a codequality artifact.
license-checkr --pdf report.pdfGenerates a multi-page PDF with:
- Cover page with scan summary and verdict statistics
- Risk summary table with per-verdict counts and ecosystem breakdown
- Full dependency table (paginated)
| Risk | Description | Examples |
|---|---|---|
| ✅ Permissive | Minimal restrictions; use freely | MIT, Apache-2.0, BSD, ISC, Unlicense |
| Share-alike applies only to the library | LGPL, MPL-2.0, EPL | |
| 🔴 Strong Copyleft | May require your project to be open-sourced | GPL-2.0, GPL-3.0, AGPL-3.0 |
| 🔒 Proprietary | Commercial; requires explicit agreement | commercial, proprietary |
| ❓ Unknown | Could not be determined | missing or unrecognized license |
Contributions are welcome! Here's how to get started:
- Fork the repository
- Clone your fork:
git clone https://github.com/YOUR_USERNAME/license-checkr - Create a branch:
git checkout -b feat/my-improvement - Make your changes and add tests
- Run the test suite:
cargo test - Open a pull request — describe what you changed and why
- 🆕 New ecosystem analyzer (Go modules, Ruby gems, PHP Composer, Swift SPM…)
- 📡 NuGet registry client for
--online.NET support - 🌐 Additional SPDX identifiers in the classifier
- 🧪 More unit tests and edge-case coverage
Please open an issue before starting work on a large change so we can discuss the approach.
This project is licensed under the MIT License — see the LICENSE file for details.
If license-checkr saved you time, a coffee is always appreciated — but never required!
Made with ❤️ and 🦀 Rust