CleanLibrary MCP Server
cleanlib-mcp-server is a Python implementation of the Model Context Protocol that exposes CleanLibrary's verdict-aware supply-chain risk surface as a set of tools an AI coding agent can call directly. Agents such as Claude Code, Claude Desktop, and Cursor connect to the server over stdio and can answer questions like "is lodash@4.17.21 safe to install?" or "what's the upgrade path to a fix for CVE-2021-44228?" without leaving the chat surface.
1. What it does
When an agent calls a CleanLibrary MCP tool, the server fetches a structured response from the CleanLibrary backend — typically a verdict envelope or a CVE enrichment row — and returns it as JSON the agent can reason about. Each tool maps to one endpoint on the CleanLibrary enrichment surface; one tool fans out the full vulnerability profile for a single CVE.
The transport is stdio. The bearer token and endpoint configuration come from environment variables the agent process inherits. No daemon, no socket, no separate authentication round-trip beyond what each tool call already carries.
2. Install
pip install cleanlib-mcp-server
uv users:
uv pip install cleanlib-mcp-server
Virtualenv:
python -m venv .venv && source .venv/bin/activate
pip install cleanlib-mcp-server
The package ships as a console script — cleanlib-mcp-server resolves to the installed entry point.
3. Configure your agent
Add the server entry to the agent's MCP configuration. For Claude Code:
{
"mcpServers": {
"cleanlib": {
"command": "cleanlib-mcp-server",
"env": {
"CLEANLIB_ENRICH_BEARER": "<your-api-key>"
}
}
}
}
For Cursor and Claude Desktop, the same shape applies — the configuration UI may differ, but the keys (command, env) are identical.
Environment variables
| Variable | Purpose | Default |
|---|---|---|
CLEANLIB_ENRICH_BEARER | Bearer token for the CleanLibrary enrichment surface (required for advisory / KEV / EPSS / exploitability / remediation tools). | — |
CLEANLIB_ENRICH_BASE_URL | Override the enrichment endpoint. Useful for staging environments. | https://cleanlib-enrich.clnstrt.dev |
CLEANLIB_API_KEY | Bearer token for the verdict / health-check tools (CleanLibrary App). CLEANLIB_ENRICH_BEARER is also accepted as an alias since v0.4.2. | — |
CLEANLIB_ENDPOINT | App endpoint for the verdict / health-check tools. | — |
CLEANLIB_REMEDIATION_BASE_URL | Override the remediation endpoint if it diverges from the enrichment base. | (matches CLEANLIB_ENRICH_BASE_URL) |
CLEANLIB_REMEDIATION_BEARER | Bearer for the remediation surface if it diverges from the enrichment bearer. | (matches CLEANLIB_ENRICH_BEARER) |
CLEANLIB_CVE_ENRICH_ENABLED | Feature flag for the cleanlib_cve_enrich tool. Defaults off until the upstream profile pipeline is ready. | false |
If CLEANLIB_API_KEY and CLEANLIB_ENDPOINT are not set, the verdict tool falls back to bundled demo fixtures so the tool always responds — useful while wiring up your first agent.
4. Tools exposed
cleanlib-mcp-server registers eight tools. Names are stable across 0.4.x.
cleanlib_fetch_verdict
Returns the CleanLibrary verdict for a (ecosystem, package, version) tuple. Decision is one of ALLOW, DENY, WARN, with severity (NONE / LOW / MEDIUM / HIGH / CRITICAL), composite score, reasoning, and source label.
// Agent invocation
{
"ecosystem": "npm",
"package": "lodash",
"version": "4.17.21"
}
The tool returns a human-readable summary that AI agents can both render in chat and parse for downstream decisions:
✓ npm/lodash@4.17.21 → ALLOW (confidence 97%)
Severity: NONE
Composite score: 12.0
Source: ALLOWED_NO_FINDINGS
Reasoning: No findings; widely used
verdict_id: 01KDVDNA0000000000000000Z9
The icon at the start of the first line reflects the decision and the confidence the server has in it:
| Icon | Meaning |
|---|---|
✓ | ALLOW with real evidence (clean catalog match) |
✗ | DENY (known-malicious / policy-blocked) |
⚠ | WARN (vulnerability finding or policy review needed) |
❓ | INSUFFICIENT_DATA (catalog has no opinion yet — fail-closed default; treat as "needs investigation", not "safe") |
The verdict_id is the stable identifier for the response and can be passed to a future risk-accept flow. Supported ecosystems: npm, pypi, go, maven, crates, nuget, rubygems.
cleanlib_health_check
Verifies that the MCP server can reach the CleanLibrary App /health endpoint. No API key required — useful as a connectivity smoke test before invoking any verdict.
cleanlib_advisories
Returns deduped advisory rows for a library. Each row carries cve_id, summary, severity, ghsa_id, epss_score, kev_flag. Dedup is by cve_id.
{
"ecosystem": "npm",
"library": "log4js"
}
cleanlib_exploitability
Returns the fused exploitability block for a single CVE — KEV flag, EPSS percentile, an exploit_risk_score between 0 and 100, and an exploitation_likelihood bucket (CRITICAL / HIGH / MEDIUM / LOW). This is the canonical "is this CVE actually being exploited" surface.
{ "cve": "CVE-2021-44228" }
cleanlib_epss
Raw EPSS row for a CVE: score, percentile, as_of, availability. Reserve this for detail panes — cleanlib_exploitability covers the common case in one round trip.
cleanlib_kev
Raw KEV row for a CVE: in_kev, date_added, due_date, availability. Same rule — cleanlib_exploitability is the everyday surface.
cleanlib_remediation
Returns the sparse seven-block remediation composite for a library: fix, upstream_lag, blast_radius, fix_trust, deadline, reachability, recommended_version. Each block carries availability — empty blocks indicate the corresponding signal is not present, not an error.
{
"ecosystem": "npm",
"library": "log4js",
"version": "6.4.0"
}
cleanlib_cve_enrich
Single-call CVE profile: fuses advisories, KEV, EPSS, and exploitability into one response. Currently feature-gated (CLEANLIB_CVE_ENRICH_ENABLED=true) — raises a clear "not yet available" error until the upstream profile pipeline lands. Use the per-signal tools (cleanlib_advisories / cleanlib_kev / cleanlib_epss / cleanlib_exploitability) until then.
5. Error handling
Every tool returns a structured error envelope rather than throwing. Common shapes:
EnvelopeError— the CleanLibrary backend returned a non-2xx response. The error payload includes the upstream status and a short reason.UnauthorizedError— bearer missing, expired, or scope-insufficient. Refresh the bearer in your agent config.EndpointNotConfigured—CLEANLIB_ENRICH_BASE_URLresolves to an unreachable host. Check network reachability from the agent process.CveEnrichNotAvailable— only raised bycleanlib_cve_enrich; the gated tool is not yet enabled in your environment.
Agents that surface tool errors back to the user will get an actionable message — no opaque stack traces.
6. Security model
- Bearer scope. The enrichment bearer is read-only and scoped to your customer surface. It cannot mutate verdicts or policy.
- What leaves your machine. Tool calls send the
(ecosystem, package, version)or(cve)you asked about. Nothing else. The server does not exfiltrate file contents, environment, or process state. - Canonical surface.
https://cleanlib-enrich.clnstrt.devis the only endpoint the server contacts (the App endpoint for verdict / health-check is configured separately). Override only viaCLEANLIB_ENRICH_BASE_URLfor staging. - Local fallback (fail-closed since v0.4.2). If the verdict endpoint is unreachable or the catalog has no entry for the requested package, the server returns a
WARNverdict (notALLOW) with a❓icon and reasoning text that explains the degraded state. Absence of a positive finding is not the same as a positive verification — the server defaults conservative so AI agents and customers see the uncertainty signal rather than a silent green check.
7. Troubleshooting
Agent doesn't see the tools. Confirm the agent picked up the MCP config — most agents log MCP tool discovery on startup. If your agent supports a "list tools" surface, cleanlib_fetch_verdict should appear.
All tools return UnauthorizedError. Bearer not set or expired. Set CLEANLIB_ENRICH_BEARER in the agent's env block (not your shell — the agent process needs it).
cleanlib_health_check returns connection error. The CleanLibrary App endpoint is unreachable from your machine. Network policy or VPN may be blocking; confirm curl $CLEANLIB_ENDPOINT/health works from the same shell the agent runs in.
cleanlib_cve_enrich raises CveEnrichNotAvailable. Expected until the upstream profile pipeline lands. Use the per-signal tools as the workaround.
Tool returns demo fixtures instead of live data. CLEANLIB_API_KEY + CLEANLIB_ENDPOINT aren't configured. Add them to the agent's env block.
See also
- Getting Started — provision the bearer this server consumes.
- CLI — the same enrichment surface from a terminal.
- Integrations — how to combine the MCP server, CLI, and the VS Code extension across one developer workflow.
- Vulnerability Intelligence — what's inside the verdict envelope.