About
Dependency license + SBOM gate, developer-CLI first
README
LICENSELENS
Dependency license + SBOM gate, developer-CLI first
PyPI CI License: COCL 1.0 Suite
Developer Tools — fast, single-purpose, CI- and agent-friendly.
pip install cognis-licenselens
licenselens scan requirements.txt # license gate — prioritized findings in seconds
licenselens vulncheck requirements.txt # + offline CVE enrichment vs 262k bundled OSV vulns
What it does, concretely: point it at a requirements.txt, and licenselens
(1) resolves every dependency's license to a canonical SPDX id, (2) gates the
build on an allow/warn/forbid policy, (3) emits a CycloneDX 1.5 SBOM and
SARIF 2.1.0 for code-scanning, and (4) cross-references each package against
a bundled, offline, ~262,000-record OSV vulnerability database — no API key,
no network, works air-gapped.
🔎 Example output
Real, reproducible output from the tool — runs offline:
$ licenselens-emit --version
licenselens 0.4.0
$ licenselens-emit --help
usage: licenselens [-h] [--version] [--format {table,json,sarif}]
{scan,sbom,vulncheck,cve} ...
Dependency license + SBOM gate for CI (stdlib only, zero install).
positional arguments:
{scan,sbom,vulncheck,cve}
scan audit licenses and gate the build
sbom emit a CycloneDX-style SBOM
vulncheck enrich the dependency set with known vulnerabilities
(offline)
cve resolve a CVE / GHSA / OSV id from the bundled DB
(offline)
options:
-h, --help show this help message and exit
--version show program's version number and exit
--format {table,json,sarif}
output format (default: table). 'sarif' applies to
scan and emits a SARIF 2.1.0 log for code-scanning
UIs.
Blocks above are real
licenselensoutput — reproduce them from a clone.
Sample result format (illustrative values — run on your own data for real findings):
{
"timestamp": "2023-02-16T14:30:00Z",
"platform": "stix",
"data": {
"indicators": [
{
"id": "indicator-12345",
"type": "ip-dns",
"value": "1.2.3.4"
}
],
"observables": [
{
"id": "observable-67890",
"type": "file-hash",
"value": "abc123"
}
]
},
"report": {
"id": "report-1234567890",
"name": "Example Report",
"description": "This is an example report."
}
}
Usage — step by step
- Install (Python 3.8+, stdlib only):
pip install licenselens - Scan a requirements file against the built-in license policy and gate the build:
Exitslicenselens scan requirements.txt0when the gate passes,1on forbidden/unknown licenses,2on IO errors. - Read the output as JSON for dashboards or policy reporting:
licenselens --format json scan requirements.txt | jq '.counts, .findings[]' - Emit a CycloneDX-style SBOM for the same dependency set:
licenselens --format json sbom requirements.txt > sbom.json - Gate CI — fail the pipeline on a license violation, attach the SBOM as an artifact:
licenselens scan requirements.txt && licenselens --format json sbom requirements.txt > sbom.json - Upload findings to code-scanning — emit a SARIF 2.1.0 log for the GitHub
Security tab / PR annotations:
licenselens --format sarif scan requirements.txt > licenselens.sarif - Check for known vulnerabilities — cross-reference every dependency against
the bundled offline OSV database (no network, no key):
licenselens vulncheck requirements.txt # report licenselens vulncheck requirements.txt --fail-on high # gate CI on high/critical licenselens --format json vulncheck requirements.txt | jq '.severity_counts' - Resolve a single CVE / GHSA / OSV id straight from the offline DB:
licenselens cve CVE-2021-44228
Demos
Runnable, real-use-case scenarios live in demos/. Each folder has a
requirements.txt in the tool's real input format plus a SCENARIO.md that
explains where the data came from, the exact command, and how to act on the
result.
| Demo | Scenario | Outcome |
|---|---|---|
| 01-basic | Mixed requirements with one GPL + one unknown | gate FAIL (exit 1) |
| 04-fastapi-service | Production FastAPI stack, one LGPL driver | gate PASS, 1 warn |
| 05-data-science | NumPy/pandas/sklearn permissive stack | gate PASS, clean |
| 06-agpl-violation | AGPL + proprietary deps in a SaaS backend | gate FAIL (exit 1) |
| 07-sbom-export | Publish a CycloneDX 1.5 SBOM | exit 0 |
| 08-sarif-codescan | SARIF 2.1.0 for GitHub code-scanning | warn+error results |
| 09-unpinned-unknowns | No overrides, no metadata → all UNKNOWN | gate FAIL (exit 1) |
| 10-policy-clean-release | Resolve licenses from installed .dist-info metadata |
gate PASS, source=metadata |
python -m licenselens scan demos/04-fastapi-service/requirements.txt
python -m licenselens --format sarif scan demos/08-sarif-codescan/requirements.txt
Contents
- Why licenselens? · Features · Quick start · Example · Architecture · Vulnerability enrichment · Edge / air-gap · AI stack · How it compares · Integrations · Install anywhere · Related · Contributing
Why licenselens?
license risk in CI
licenselens is single-purpose, scriptable, and self-hostable: point it at a target, get prioritized results in the format your workflow already speaks (table · JSON · SARIF), gate CI on it, and let agents drive it over MCP.
Features
- ✅ Normalize messy license strings → canonical SPDX ids
- ✅ Classify against an allow / warn / forbid policy (UNKNOWN = risk)
- ✅ Parse
requirements.txtwith inline# license:overrides - ✅ Resolve licenses from installed
*.dist-info/METADATA(PEP 566) - ✅ Gate CI with exit codes (0 pass · 1 violation · 2 IO error)
- ✅ Export CycloneDX 1.5 SBOM and SARIF 2.1.0 for code-scanning
- ✅ Offline vulnerability enrichment — match deps against a bundled ~262k-record OSV DB (
vulncheck/cve), no network, no key - ✅ Edge / air-gap ready — refresh the corpus from NVD/OSV/GHSA when online, then sneakernet the cache to a disconnected enclave
- ✅ Runs on Linux/macOS/Windows · Docker · devcontainer
- ✅ Ports in Python, JavaScript, Go, and Rust (
ports/), each CI-built
Quick start
pip install cognis-licenselens
licenselens --version
licenselens scan requirements.txt # license gate (table)
licenselens --format json scan requirements.txt # machine-readable
licenselens --format sarif scan requirements.txt # SARIF for code-scanning
licenselens vulncheck requirements.txt # offline CVE enrichment
Example — worked output
License gate
$ licenselens scan requirements.txt
RISK NAME VERSION LICENSE SOURCE
----------------------------------------------------
FAIL pycopyleft 3.1.0 GPL-3.0 override
???? mysterylib 1.0.0 UNKNOWN unresolved
OK requests 2.31.0 COCL (Cognis Open Collaboration License) metadata
OK click 8.1.7 BSD-3-Clause metadata
summary: 2 allowed, 0 warn, 1 forbidden, 1 unknown
gate: FAIL
$ echo $?
1
Offline vulnerability enrichment
$ licenselens vulncheck requirements.txt --ecosystem PyPI
SEV NAME VULNS LICENSE TOP CVE / ADVISORY
-------------------------------------------------------
MOD requests 13 COCL (Cognis Open Collaboration License) CVE-2014-1830: Exposure of sensitive information ...
---- click 0 BSD-3-Clause
db: 262351 records (offline) · 1 vulnerable package(s) · 13 total vuln(s)
severity: 0 critical, 0 high, 1 moderate, 6 low, 6 unknown
Single CVE lookup (offline)
$ licenselens cve CVE-2021-44228
GHSA-jfh8-c2jp-5v3q [Maven] severity=critical
aliases: CVE-2021-44228
packages: org.apache.logging.log4j:log4j-core, ...
summary: Remote code injection in Log4j
published: 2021-12-10T00:40:56Z
Architecture
flowchart LR
REQ[requirements.txt<br/>+ # license overrides] --> PARSE[parse + resolve]
META[installed *.dist-info<br/>METADATA / PKG-INFO] --> PARSE
PARSE --> NORM[normalize → SPDX]
NORM --> POL[policy: allow / warn / forbid]
POL --> GATE[exit code gate]
POL --> SBOM[CycloneDX 1.5]
POL --> SARIF[SARIF 2.1.0]
PARSE --> VDB[(bundled OSV DB<br/>~262k vulns, offline)]
VDB --> VULN[vulncheck / cve]
Offline vulnerability enrichment
A license gate only answers half of a supply-chain review. licenselens ships
the other half in the box: cognis_vulndb.jsonl.gz, a consolidated, compact
OSV corpus of ~262,000 real vulnerabilities across PyPI, npm, Go, Maven,
RubyGems, crates.io and NuGet — each record carrying id, CVE/GHSA aliases,
ecosystem, summary, severity, affected packages, and publish/modify dates.
licenselens vulncheck requirements.txt # report
licenselens vulncheck requirements.txt --ecosystem Maven # match another ecosystem
licenselens vulncheck requirements.txt --fail-on critical # CI gate floor
licenselens cve CVE-2021-44228 # resolve one id
licenselens --format json vulncheck requirements.txt # machine-readable
- Fully offline / air-gapped — no API key, no network call, ever. The DB is the moment-of-clone baseline.
- Namespace-tolerant matching — a bare
log4j-coreresolves the Mavenorg.apache.logging.log4j:log4j-corerecord without inventing data. - No fabricated data — a package with no real record reports zero vulns.
- Severity-floor gate —
--fail-on {off,any,low,moderate,high,critical}(defaultoff= report-only).
Edge / air-gap refresh
The bundled DB is the offline baseline. When you do have connectivity, refresh
and extend it from upstream, then carry the cache to a disconnected enclave with
licenselens.datafeeds (licenselens-feeds):
# online side: pull from CISA-KEV / EPSS / OSV / NVD / GHSA (keyless, HTTPS)
licenselens-feeds list --domain vuln
licenselens-feeds update cisa-kev epss osv
licenselens-feeds snapshot-export feeds.tar.gz # tar the cache (sneakernet)
# air-gapped side: import the snapshot; everything then serves from disk
licenselens-feeds snapshot-import feeds.tar.gz
licenselens-feeds get cisa-kev --offline
The catalog (data_feeds_2026.json) is real, recent, mostly-keyless intelligence
feeds. offline=True serves cache only and never touches the network. Bulk CVE
harvest (licenselens-feeds bulk nvd-cve) paginates NVD 2.0 / GHSA to grow the
corpus well past the bundled baseline.
Use it from any AI stack
licenselens is interoperable with every popular way of using AI:
- MCP server —
licenselens mcp(Claude Desktop, Cursor, Cognis.Studio, uncensored-fleet) - OpenAI-compatible / JSON — pipe
licenselens scan . --format jsoninto any agent or LLM - LangChain · CrewAI · AutoGen · LlamaIndex — wrap the CLI/JSON as a tool in one line
- CI / scripts — exit codes + SARIF for non-AI pipelines
How it compares
| Cognis licenselens | FOSSA | |
|---|---|---|
| Self-hostable, no account | ✅ | varies |
| Single command, zero config | ✅ | ⚠️ |
| JSON + SARIF for CI | ✅ | varies |
| MCP-native (AI agents) | ✅ | ❌ |
| Polyglot ports (JS/Go/Rust) | ✅ | ❌ |
| Open license | ✅ COCL | varies |
Built in the spirit of FOSSA, re-framed the Cognis way. Missing a credit? Open a PR.
Integrations
Pipes into your stack: SARIF for code-scanning, JSON for anything, an MCP server (licenselens mcp) for AI agents, and a webhook forwarder for SIEM/Slack/Jira. See docs/INTEGRATIONS.md.
Install — every way, every platform
pip install "git+https://github.com/cognis-digital/licenselens.git" # pip (works today)
pipx install "git+https://github.com/cognis-digital/licenselens.git" # isolated CLI
uv tool install "git+https://github.com/cognis-digital/licenselens.git" # uv
pip install cognis-licenselens # PyPI (when published)
docker run --rm ghcr.io/cognis-digital/licenselens:latest --help # Docker
brew install cognis-digital/tap/licenselens # Homebrew tap
curl -fsSL https://raw.githubusercontent.com/cognis-digital/licenselens/main/install.sh | sh
| Linux | macOS | Windows | Docker | Cloud |
|---|---|---|---|---|
scripts/setup-linux.sh |
scripts/setup-macos.sh |
scripts/setup-windows.ps1 |
docker run ghcr.io/cognis-digital/licenselens |
DEPLOY.md (AWS/Azure/GCP/k8s) |
Related Cognis tools
- mcpforge — Scaffold, test, and publish MCP servers in minutes
- promptlint — Lint, version, and test prompts as code with a CI gate
- envdoctor — .env validator, secret-presence and config-drift checker
- apidiff — Breaking-change detector for OpenAPI / GraphQL across commits
- codeglance — Repo onboarding map — architecture + hotspots for humans and agents
- flakefinder — Flaky-test detector from CI history with quarantine suggestions
Explore the suite → 🗂️ all 170+ tools · ⭐ awesome-cognis · 🔗 cognis-sources · 🤖 uncensored-fleet · 🧠 engram
Contributing
PRs, new rules, and demo scenarios are welcome under the collaboration-pull model — see CONTRIBUTING.md and SECURITY.md.
⭐ If
licenselenssaved you time, star it — it genuinely helps others find it.
Interoperability
{} composes with the 300+ tool Cognis suite — JSON in/out and a shared
OpenAI-compatible /v1 backbone. See INTEROP.md for the
suite map, composition patterns, and reference stacks.
Scope, authorization & safety
licenselens is a passive, offline, defensive tool. It reads manifests and
package metadata on disk and matches them against a bundled vulnerability
database. It performs no active scanning, no network probing, and no exploit
behavior — scan, vulncheck and cve never touch the network. The optional
licenselens-feeds refresher only fetches public, authorized intelligence
feeds over HTTPS to update your local cache, and supports an explicit
--offline mode that serves the cache exclusively. No data is fabricated: every
vulnerability shown is a real OSV/CVE/GHSA record from the bundled corpus.
Use it on code and dependency manifests you own or are authorized to audit.
License
Source-available under the Cognis Open Collaboration License (COCL) v1.0 — free for personal, internal-evaluation, research, and educational use; commercial / production use requires a license ([email protected]). See LICENSE.
Install Licenselens in Claude Desktop, Claude Code & Cursor
unyly install licenselensInstalls into Claude Desktop, Claude Code, Cursor & VS Code — handles npx, uvx and build-from-source repos for you.
First time? Get the CLI: curl -fsSL https://unyly.org/install | sh
Or configure manually
Run in your terminal:
claude mcp add licenselens -- uvx --from git+https://github.com/cognis-digital/licenselens cognis-licenselensStep-by-step: how to install Licenselens
FAQ
Is Licenselens MCP free?
Yes, Licenselens MCP is free — one-click install via Unyly at no cost.
Does Licenselens need an API key?
No, Licenselens runs without API keys or environment variables.
Is Licenselens hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Licenselens in Claude Desktop, Claude Code or Cursor?
Open Licenselens on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
GitHub
PRs, issues, code search, CI status
by GitHubFilesystem
Secure file operations with configurable access controls.
Memory
Knowledge graph-based persistent memory system.
Template MCP Server
A CLI tool to create a new Model Context Protocol server project with TypeScript support, dual transport options, and an extensible structure
by mcpdotdirectAmap Maps Mcp Server
MCP server for using the AMap Maps API
by duxiaohuiSupabase
Database, auth and storage
by SupabaseEverything
Reference / test server with prompts, resources, and tools.
Git
Tools to read, search, and manipulate Git repositories.
Sequential Thinking
Dynamic and reflective problem-solving through thought sequences.
Time
Time and timezone conversion capabilities.
Compare Licenselens with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All development MCPs
