osv-advisory-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@osv-advisory-mcp-serverCheck if express 4.18.2 in npm has vulnerabilities"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Public Hosted Server: https://osv-advisory.caseyjhand.com/mcp
Overview
Vulnerability data from OSV.dev, the open-source vulnerability database. Query a single package version, batch-audit a full dependency list or SBOM, and fetch complete advisory records with CVSS severity, CVE aliases, and affected version ranges. Runs as a stdio process, a local Streamable HTTP server, or the public hosted endpoint above.
Tools
Tool | Description |
| Query known vulnerabilities for a single package version by name, ecosystem, and version |
| Batch vulnerability query for an array of package tuples — one call for a full dependency list or SBOM audit |
| Fetch the full advisory record for a single OSV vulnerability ID |
| Return the list of supported ecosystem identifier strings |
Related MCP server: dep-guard-mcp
Capability reference
osv_query_package tool
Accepts
name,ecosystem(case-sensitive exact match), andversion— an exact version string, not a rangeSurrounding whitespace is trimmed from all three before the request, and
queryMetaechoes the trimmed values; interior whitespace (Rocky Linux) is kept. Blank or whitespace-only values are rejected before any upstream callReturns matching advisories with OSV IDs, CVE
aliases, severity entries (CVSS vectors, Ubuntu priorities),severityLabelwith itsseveritySource,fixedVersions,affectedRanges(SEMVER/ECOSYSTEM/GIT), andcweIdsfixedVersionslists every fix the advisory records for the queried package (one per affected interval), matched the way OSV matches the query — release-suffixed ecosystems (Debian→Debian:12,Ubuntu:22.04→Ubuntu:22.04:LTS) and PEP 503 names on PyPI. Other packages' fixes and GIT commits stay out of it;affectedRangeskeeps every rangetruncated: truemeans OSV paginated beyondOSV_QUERY_MAX_PAGES(default 10) — an emptyvulnsarray withtruncated: trueis NOT a confirmed clean resultTyped
invalid_ecosystemerror when the ecosystem string isn't recognized by OSV — callosv_list_ecosystemsfor valid values, then retryaliaseson each vuln chain tonist-nvd-mcp-serverfor CVSS base scores, EPSS exploitation probability, and CISA KEV status
osv_query_batch tool
Accepts an array of
{name, ecosystem, version}tuples, 1–1000 per call;results[i]corresponds positionally topackages[i]Each row's fields are trimmed of surrounding whitespace the same way as
osv_query_package, andresults[i]echoes the trimmed values; a blank field in any row rejects the callPer-package
vulnerable,vulnCount,vulns(withaliases,severityLabel, and the row package'sfixedVersions), and a nullableerror— one bad ecosystem or upstream failure fails only that row, not the whole batchAggregate
summary:totalPackages,vulnerableCount,cleanCount,truncatedCount,errorCount,totalVulns,worstSeveritycleanCountexcludes truncated rows — a per-packagetruncated: trueresult is never counted clean even with zero findingsPer-package requests run in parallel, capped by
OSV_BATCH_CONCURRENCY(default 10)
osv_get_vulnerability tool
Accepts one exact, complete advisory ID from any OSV source database, matched case-sensitively —
GHSA-(GitHub),PYSEC-(PyPI),RUSTSEC-(Rust),GO-(Go),DSA-/DLA-(Debian),USN-(Ubuntu),RHSA-(Red Hat),CVE-, and the rest. IDs come fromosv_query_package/osv_query_batchresultsSurrounding whitespace is trimmed before the request (
" GHSA-29mw-wpgm-hmr9 "resolves); input that can't be an OSV ID (wildcards, a bare package name, a prefix with no ID) is rejected before any upstream call, with a message naming the expected formReturns the full record —
detailstext, all CVEaliases, every affected package with its version ranges, orderedfixedevents, and any package-level severity, severity entries withseverityLabelandseveritySource,cweIds, andreferences(ADVISORY, FIX, REPORT, etc.)Typed
vulnerability_not_founderror when the ID doesn't exist in OSV — the recovery covers case and the Debian/Ubuntu/SUSE revision suffix (DSA-5678-1, notDSA-5678); a CVE-style alias may still resolve vianist-nvd-mcp-serverwithdrawnis present only on retracted advisories — treat as no longer active, not as an error
osv_list_ecosystems tool
No input; returns the static list of valid
ecosystemidentifier strings plus an advisorynoteon currencyEcosystem strings are case-sensitive exact matches —
"pypi"fails where"PyPI"succeedsEvery ecosystem in the OSV schema's
ecosystemNameenum that OSV.dev accepts at query time, plusGIT(accepted via theecosystemWithSuffixpattern); a schema ecosystem OSV.dev still rejects is left out. Thenotecarries the verification date; the list may lag later additions
Features
Built on @cyanheads/mcp-ts-core: stdio and Streamable HTTP transports, pluggable auth (none / jwt / oauth), swappable storage (in-memory, filesystem, Supabase, Cloudflare KV/R2/D1), structured logging with optional OpenTelemetry tracing.
OSV-specific:
No API key required — OSV.dev is fully public, keyless, and has no published rate limit
osv_query_batchissues parallel per-package requests (capped byOSV_BATCH_CONCURRENCY) and returns full records, includingaliases, that the upstream OSV batch endpoint omitsPer-package failures are isolated in
osv_query_batch— one invalid ecosystem or upstream error surfaces as that row'serrorwithout failing the whole batchEcosystem discovery via
osv_list_ecosystems— the OSV schema's ecosystems that OSV.dev accepts, checked against both withbun run check:ecosystems
Agent-friendly output:
aliases(CVE IDs) surfaced on every vuln entry — the composition point for chaining tonist-nvd-mcp-serverfor CVSS base scores, EPSS, and CISA KEV statusseverityLabelfrom the first source that yields one:database_specific.severity(GHSA, openEuler, and others;Mediumreads asMODERATE), an Ubuntu priority, then the highest CVSS v3/v4 score computed from the vector as published (every metric group of a CVSS 4.0 vector; base and temporal for CVSS 3.x). Package-level severity counts when the record has none.severitySourcenames the entry used, with the computed score for CVSS; both arenullrather than fabricated when no source yields a labelTruncation is never silently treated as clean —
truncated(single query) and per-packagetruncatedplustruncatedCount(batch) flag incomplete OSV pagination, and truncated rows are excluded fromcleanCountQuery echo (
queryMeta/effectiveQuery) and aggregate batchsummary(worstSeverity,vulnerableCount,cleanCount) let agents verify requests and triage without reading every rowAdvisory text is framed as untrusted data in
content[]and escaped at the render boundary: tag-shaped text (<template>,<script), autolinks, reference definitions, non-http(s)link destinations (javascript:), and forged frame tags can't turn into live HTML or links in a Markdown client.structuredContentkeeps every OSV string verbatim
Getting started
Public Hosted Instance
A public instance is available at https://osv-advisory.caseyjhand.com/mcp — no installation required. Point any MCP client at it via Streamable HTTP:
{
"mcpServers": {
"osv-advisory-mcp-server": {
"type": "streamable-http",
"url": "https://osv-advisory.caseyjhand.com/mcp"
}
}
}Self-Hosted / Local
Add the following to your MCP client configuration file. No API key is required — OSV.dev is fully public.
{
"mcpServers": {
"osv-advisory-mcp-server": {
"type": "stdio",
"command": "bunx",
"args": ["@cyanheads/osv-advisory-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with npx (no Bun required):
{
"mcpServers": {
"osv-advisory-mcp-server": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@cyanheads/osv-advisory-mcp-server@latest"],
"env": {
"MCP_TRANSPORT_TYPE": "stdio",
"MCP_LOG_LEVEL": "info"
}
}
}
}Or with Docker:
{
"mcpServers": {
"osv-advisory-mcp-server": {
"type": "stdio",
"command": "docker",
"args": [
"run", "-i", "--rm",
"-e", "MCP_TRANSPORT_TYPE=stdio",
"ghcr.io/cyanheads/osv-advisory-mcp-server:latest"
]
}
}
}For Streamable HTTP, set the transport and start the server:
MCP_TRANSPORT_TYPE=http MCP_HTTP_PORT=3010 bun run start:http
# Server listens at http://localhost:3010/mcpPrerequisites
Bun v1.4.0 or higher (or Node.js v24+).
No API key required — OSV.dev is fully public.
Installation
Clone the repository:
git clone https://github.com/cyanheads/osv-advisory-mcp-server.gitNavigate into the directory:
cd osv-advisory-mcp-serverInstall dependencies:
bun installConfigure environment:
cp .env.example .env
# edit .env if needed (no required vars)Configuration
All configuration is validated at startup. No server-specific env vars are required — OSV.dev is keyless and fully public.
Variable | Description | Default |
| HTTP request timeout for OSV.dev API calls, in milliseconds. |
|
| Maximum concurrent OSV.dev requests issued by |
|
| Maximum OSV.dev result pages |
|
| Transport: |
|
| Port for HTTP server. |
|
| HTTP endpoint path. |
|
| Public origin override for TLS-terminating reverse-proxy deployments. | none |
| HTTP session mode: |
|
| Auth mode: |
|
| Log level (RFC 5424). |
|
| Directory for log files (Node.js only). |
|
| Storage backend. |
|
| Enable OpenTelemetry instrumentation (spans, metrics, completion logs). |
|
See .env.example for the full list of optional overrides.
Running the server
Local development
Build and run:
# One-time build bun run rebuild # Run the built server bun run start:stdio # or bun run start:httpRun checks and tests:
bun run devcheck # Lint, format, typecheck, security bun run test # Vitest test suite bun run lint:mcp # Validate MCP definitions against spec bun run check:ecosystems # Compare osv_list_ecosystems with the live OSV schema and API
Docker
docker build -t osv-advisory-mcp-server .
docker run --rm -p 3010:3010 osv-advisory-mcp-serverThe Dockerfile defaults to HTTP transport, stateless session mode, and logs to /var/log/osv-advisory-mcp-server. OpenTelemetry peer dependencies are installed by default — build with --build-arg OTEL_ENABLED=false to omit them.
Project structure
Directory | Purpose |
|
|
| Server-specific environment variable parsing and validation with Zod. |
| Tool definitions ( |
| OSV.dev REST API service — fetch, retry, response normalization. |
| Unit and integration tests mirroring |
Development guide
See CLAUDE.md/AGENTS.md for development guidelines and architectural rules. The short version:
Handlers throw, framework catches — no
try/catchin tool logicUse
ctx.logfor request-scoped logging,ctx.enrichfor response context, andctx.signalfor cancellable OSV requestsRegister new tools via the barrel in
src/mcp-server/tools/definitions/index.tsWrap external API calls: validate raw → normalize to domain type → return output schema; never fabricate missing fields
Contributing
Issues are welcome. Run checks and tests before submitting:
bun run devcheck
bun run testLicense
Apache-2.0 — see LICENSE for details.
This server cannot be deployed
Maintenance
Related MCP Connectors
Detect malicious or vulnerable npm packages: registry search, OSV.dev and GitHub advisory lookups
Check a dependency list against CISA's live Known Exploited Vulnerabilities catalog.
Known vulnerabilities for exact package versions from OSV, with fixes. Paid per call, x402.
Related MCP Servers
- AlicenseBqualityDmaintenanceAudits package lockfiles for vulnerabilities, supporting npm, yarn, and pnpm. Runs via CLI or as an MCP server over stdio.112 npm83MIT
- FlicenseNot gradedqualityCmaintenanceScans Python, Node.js, Java/Spring, and PHP dependency manifests for known vulnerabilities using OSV and GitHub Advisory APIs.-
- AlicenseAqualityBmaintenanceMCP server for checking packages against an AI-aware vulnerability database, including CVEs, slopsquatting, CISA KEV, and MCP-server trust profiles.1054 PyPIElastic 2.0
- AlicenseAqualityBmaintenanceMCP server for querying CVE and package vulnerability data from NVD and OSV.dev, allowing CVE lookups and dependency scanning.41MIT