Skip to main content
Glama
OSV Dependency Vulnerability Check MCP Server

OSV Dependency Vulnerability Check MCP Server

Check dependencies for known vulnerabilities (OSV.dev)

check_dependency_vulnerabilities
Read-onlyIdempotent

Checks pinned package versions or manifests against OSV.dev to find known vulnerabilities and recommend fixing versions.

Instructions

WHAT: Check exact package versions, or a pasted manifest (package.json, package-lock.json v1-v3, requirements.txt with == pins, go.mod), against the OSV.dev vulnerability database (GHSA, PYSEC, GO, RUSTSEC, CVE aliases). WHEN TO USE: auditing a project or a list of dependencies before upgrading or shipping, or answering "is lodash 4.17.20 vulnerable and what should I upgrade to?". WHEN NOT TO USE: for the full record of an advisory ID you already have use get_vulnerability_details (free); to browse all advisories of a package without a version use list_package_vulnerabilities (free). Does not scan source code, containers or unpinned ranges (ranges produce VERSION_NOT_PINNED warnings). BEHAVIOR: runs the Fairquery Apify Actor fairquery/osv-dependency-vulnerability-check through the Apify API, which queries api.osv.dev. Requires APIFY_TOKEN. Typical run 5-60 s depending on package count. COST: paid (billed to your Apify account, pay-per-event): $0.00005 per run + $0.0005 per package row + $0.0015 per emitted vulnerability row; error/warning rows are free. Example: lodash + django (2 packages, 41 vulns) ~ $0.06. RETURNS: one type="package" row per unique package (recommended_version = smallest version fixing every emitted vuln, or null) plus one type="vulnerability" row per advisory; type="error" rows carry code (INPUT_EMPTY, INVALID_PACKAGE, MANIFEST_UNDETECTED, MANIFEST_PARSE_FAILED, MAX_PACKAGES_EXCEEDED, OSV_QUERYBATCH_FAILED, OSV_VULN_FETCH_FAILED, or the warnings VERSION_NOT_PINNED / VERSION_NOT_PINNABLE / RANGE_APPROXIMATED) and retryable. EXAMPLE: {"packages":[{"ecosystem":"npm","name":"lodash","version":"4.17.20"}],"minSeverity":"HIGH"} -> 1 package row (vulnerable, recommended_version) + HIGH/CRITICAL vulnerability rows. PARAMETERS: packages and/or manifestText: at least one is required although the schema marks both optional (neither -> INPUT_EMPTY, not billed); both may be combined and packages parsed from the manifest are merged with packages, deduped by ecosystem+name+version. Every unique package is one billed row, so maxPackages (default 1000) is also your spend cap; extras produce a free MAX_PACKAGES_EXCEEDED row. Versions must be pinned: requirements.txt needs "==" pins, package.json ranges such as "^4.17.0" are approximated (RANGE_APPROXIMATED warning) - paste package-lock.json for exact results. manifestType: leave "auto" unless detection fails (MANIFEST_UNDETECTED). minSeverity uses the CVSS v3 base score, else the advisory label; package rows are always emitted, but their vulnerable, vuln_count, max_severity and recommended_version then cover only the vulns that passed the filter (vuln_count_total keeps the unfiltered count); includeUnknownSeverity decides whether vulns without any severity pass that filter, and has no effect when minSeverity is "ALL". dedupeAliases=false emits one row per OSV ID (GHSA and PYSEC copies of the same issue), which raises cost. includeDevDependencies only affects package.json / package-lock.json.

Tool call template

This tool declares no required parameters. Add optional parameters from the input schema as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {},
    "name": "check_dependency_vulnerabilities"
  }
}

Input Schema

NameRequiredDescriptionDefault
packagesNoOptional if manifestText is given (at least one is required). 0-1000 {ecosystem, name, version} objects; one billed row per unique package. Example: [{"ecosystem":"npm","name":"lodash","version":"4.17.20"}]
maxPackagesNoOptional integer 1-10000, default 1000. Safety/spend cap on unique packages checked per run; extra packages are skipped with one free MAX_PACKAGES_EXCEEDED error row. Example: 200
minSeverityNoOptional, one of "ALL" | "LOW" | "MEDIUM" | "HIGH" | "CRITICAL", default "ALL". Only emit (and bill) vulnerability rows at or above this severity (CVSS v3 base score, else advisory label); package rows are always emitted. Example: "HIGH"
manifestTextNoOptional if packages is given. Raw file content (<= 2,000,000 chars) of package.json, package-lock.json (v1-v3), requirements.txt (== pins) or go.mod; packages found are merged into `packages`. Example: "django==3.2.0\nrequests==2.19.0"
manifestTypeNoOptional, one of "auto" | "package.json" | "package-lock.json" | "requirements.txt" | "go.mod", default "auto" (detect from content). Only used with manifestText. Example: "requirements.txt"
dedupeAliasesNoOptional boolean, default true = one row per real vulnerability when OSV lists it under several IDs (GHSA record preferred); false = one billed row per OSV ID
includeDevDependenciesNoOptional boolean, default true. false skips devDependencies (package.json) and dev packages (package-lock.json); no effect on requirements.txt / go.mod / packages
includeUnknownSeverityNoOptional boolean, default true. With minSeverity above ALL, true still emits vulnerabilities that have no severity data; false drops them

Output Schema

NameRequiredDescriptionDefault
countYesNumber of rows returned
itemsYesResult rows; each has a "type" field (data rows or machine-readable "error" rows)

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed11 schema fields changedv1.1.4
    • changedInput schema / properties / dedupeAliases / description
      Previous value: -"Emit one row per real vulnerability when OSV lists it under several IDs, preferring the GHSA record (default true)"New value: +"Optional boolean, default true = one row per real vulnerability when OSV lists it under several IDs (GHSA record preferred); false = one billed row per OSV ID"
    • changedInput schema / properties / includeDevDependencies / description
      Previous value: -"Include devDependencies from package.json / dev packages from package-lock.json (default true)"New value: +"Optional boolean, default true. false skips devDependencies (package.json) and dev packages (package-lock.json); no effect on requirements.txt / go.mod / packages"
    • changedInput schema / properties / includeUnknownSeverity / description
      Previous value: -"With minSeverity set, still emit vulnerabilities whose severity is unknown (default true)"New value: +"Optional boolean, default true. With minSeverity above ALL, true still emits vulnerabilities that have no severity data; false drops them"
    • changedInput schema / properties / manifestText / description
      Previous value: -"Optional; up to 2,000,000 chars of raw file content of package.json, package-lock.json, requirements.txt or go.mod. Packages found are added to `packages`."New value: +"Optional if packages is given. Raw file content (<= 2,000,000 chars) of package.json, package-lock.json (v1-v3), requirements.txt (== pins) or go.mod; packages found are merged into `packages`. Example: \"django==3.2.0\\nrequests==2.19.0\""
    • changedInput schema / properties / manifestType / description
      Previous value: -"Format of manifestText (default \"auto\" = detect from content)"New value: +"Optional, one of \"auto\" | \"package.json\" | \"package-lock.json\" | \"requirements.txt\" | \"go.mod\", default \"auto\" (detect from content). Only used with manifestText. Example: \"requirements.txt\""
    • changedInput schema / properties / maxPackages / description
      Previous value: -"Safety cap on unique packages checked per run (1-10000, default 1000); extra packages produce a MAX_PACKAGES_EXCEEDED error row"New value: +"Optional integer 1-10000, default 1000. Safety/spend cap on unique packages checked per run; extra packages are skipped with one free MAX_PACKAGES_EXCEEDED error row. Example: 200"
    • changedInput schema / properties / minSeverity / description
      Previous value: -"Only emit vulnerabilities at or above this severity (CVSS v3 base score, else advisory label). Default ALL. Package rows are always emitted."New value: +"Optional, one of \"ALL\" | \"LOW\" | \"MEDIUM\" | \"HIGH\" | \"CRITICAL\", default \"ALL\". Only emit (and bill) vulnerability rows at or above this severity (CVSS v3 base score, else advisory label); package rows are always emitted. Example: \"HIGH\""
    • changedInput schema / properties / packages / description
      Previous value: -"Up to 1000 exact package versions to check (optional if manifestText is given). Example: [{\"ecosystem\":\"npm\",\"name\":\"lodash\",\"version\":\"4.17.20\"}]"New value: +"Optional if manifestText is given (at least one is required). 0-1000 {ecosystem, name, version} objects; one billed row per unique package. Example: [{\"ecosystem\":\"npm\",\"name\":\"lodash\",\"version\":\"4.17.20\"}]"
    • changedInput schema / properties / packages / items / properties / ecosystem / description
      Previous value: -"OSV ecosystem name: npm, PyPI, Go, Maven, crates.io, RubyGems, NuGet, Packagist, Pub, Hex (aliases like pip/cargo/gem are accepted)"New value: +"Required. OSV ecosystem, case-insensitive: npm, PyPI, Go, Maven, crates.io, RubyGems, NuGet, Packagist, Pub, Hex (aliases like pip/cargo/gem are accepted). Example: \"PyPI\""
    • changedInput schema / properties / packages / items / properties / name / description
      Previous value: -"Package name as published, e.g. \"lodash\", \"django\", \"github.com/gin-gonic/gin\", \"org.apache.logging.log4j:log4j-core\""New value: +"Required. Package name exactly as published: npm \"lodash\" or \"@scope/pkg\", PyPI \"django\", Go module path \"github.com/gin-gonic/gin\", Maven \"groupId:artifactId\" e.g. \"org.apache.logging.log4j:log4j-core\""
    • changedInput schema / properties / packages / items / properties / version / description
      Previous value: -"Exact version, e.g. \"4.17.20\" (no ranges like ^4.0.0)"New value: +"Required. One exact version, e.g. \"4.17.20\" (no ranges like ^4.0.0 or >=2); Go versions keep the \"v\" prefix, e.g. \"v1.9.0\""
  2. Changed14 schema fields changedv1.1.1
    • addedInput schema / properties / dedupeAliases / description
      Added value: +"Emit one row per real vulnerability when OSV lists it under several IDs, preferring the GHSA record (default true)"
    • addedInput schema / properties / includeDevDependencies / description
      Added value: +"Include devDependencies from package.json / dev packages from package-lock.json (default true)"
    • addedInput schema / properties / includeUnknownSeverity / description
      Added value: +"With minSeverity set, still emit vulnerabilities whose severity is unknown (default true)"
    • changedInput schema / properties / manifestText / description
      Previous value: -"Raw package.json, package-lock.json, requirements.txt (== pins) or go.mod content"New value: +"Optional; up to 2,000,000 chars of raw file content of package.json, package-lock.json, requirements.txt or go.mod. Packages found are added to `packages`."
    • addedInput schema / properties / manifestText / maxLength
      Added value: +2000000
    • addedInput schema / properties / manifestType / description
      Added value: +"Format of manifestText (default \"auto\" = detect from content)"
    • addedInput schema / properties / maxPackages / description
      Added value: +"Safety cap on unique packages checked per run (1-10000, default 1000); extra packages produce a MAX_PACKAGES_EXCEEDED error row"
    • changedInput schema / properties / minSeverity / description
      Previous value: -"Only return vulnerabilities at or above this severity (default ALL)"New value: +"Only emit vulnerabilities at or above this severity (CVSS v3 base score, else advisory label). Default ALL. Package rows are always emitted."
    • changedInput schema / properties / packages / description
      Previous value: -"Exact package versions to check"New value: +"Up to 1000 exact package versions to check (optional if manifestText is given). Example: [{\"ecosystem\":\"npm\",\"name\":\"lodash\",\"version\":\"4.17.20\"}]"
    • changedInput schema / properties / packages / items / properties / ecosystem / description
      Previous value: -"OSV ecosystem, e.g. npm, PyPI, Go, Maven"New value: +"OSV ecosystem name: npm, PyPI, Go, Maven, crates.io, RubyGems, NuGet, Packagist, Pub, Hex (aliases like pip/cargo/gem are accepted)"
    • addedInput schema / properties / packages / items / properties / name / description
      Added value: +"Package name as published, e.g. \"lodash\", \"django\", \"github.com/gin-gonic/gin\", \"org.apache.logging.log4j:log4j-core\""
    • addedInput schema / properties / packages / items / properties / version / description
      Added value: +"Exact version, e.g. \"4.17.20\" (no ranges like ^4.0.0)"
    • addedInput schema / properties / packages / maxItems
      Added value: +1000
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "$schema": "http://json-schema.org/draft-07/schema#",
      +  "additionalProperties": false,
      +  "properties": {
      +    "count": {
      +      "description": "Number of rows returned",
      +      "type": "integer"
      +    },
      +    "items": {
      +      "description": "Result rows; each has a \"type\" field (data rows or machine-readable \"error\" rows)",
      +      "items": {
      +        "additionalProperties": {},
      +        "type": "object"
      +      },
      +      "type": "array"
      +    }
      +  },
      +  "required": [
      +    "count",
      +    "items"
      +  ],
      +  "type": "object"
      +}
  3. First observedv0.1.0

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations already supplying readOnlyHint/idempotentHint/openWorldHint, the description adds operational context annotations cannot: APIFY_TOKEN requirement, 5-60s runtime, a full pay-per-event cost model with a worked example, the concrete error/warning codes emitted, and which rows are free vs. billable. This is exactly the beyond-annotations context the dimension rewards.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Strongly front-loaded and header-labeled (WHAT/WHEN TO USE/WHEN NOT TO USE/BEHAVIOR/COST/RETURNS/EXAMPLE/PARAMETERS), and the length is justified by the tool's cost and error complexity. It loses a point for restating some schema content (the minSeverity scoring rule and enum values) that the schema already carries.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description still goes beyond it by enumerating emitted row types, recommended_version semantics, and error/warning codes. Combined with auth, cost, and param-interaction coverage, nothing an agent needs to call this correctly is missing; the required-params mismatch in the schema is even explicitly corrected.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (baseline 3), but the description adds meaning the schema omits: packages and manifestText are 'at least one required although the schema marks both optional' (neither -> INPUT_EMPTY, not billed), manifest-parsed packages are merged and deduped by ecosystem+name+version, maxPackages doubles as a spend cap, and minSeverity's interaction with package-row fields (vuln_count_total) and includeUnknownSeverity is spelled out.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Check exact package versions, or a pasted manifest ... against the OSV.dev vulnerability database') and enumerates the ecosystems and advisory sources covered. It also explicitly names the two sibling tools it is not, so an agent can differentiate without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Has explicit WHEN TO USE ('auditing a project or a list of dependencies before upgrading or shipping') and WHEN NOT TO USE sections that route to get_vulnerability_details and list_package_vulnerabilities by condition (existing advisory ID vs. versionless browsing). Also states exclusions (source code, containers, unpinned ranges).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.