audit_dependencies
Audit npm and PyPI packages for known security vulnerabilities using the OSV database. Analyze package.json or requirements.txt files to identify CVEs and assess risk levels.
Instructions
Audit npm and PyPI packages for known CVEs using the OSV database (GitHub Dependabot's source). Pass packages directly or paste package.json / requirements.txt content.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| packages | No | Packages to audit | |
| manifest | No | Raw package.json or requirements.txt | |
| manifestType | No | auto | |
| includeDevDependencies | No | ||
| minSeverity | No | LOW |
Implementation Reference
- src/tools/dependency-auditor.ts:174-284 (handler)The handler function processes package information or manifest files, queries the OSV database, and returns vulnerability details.
async function handler(input: Input) { // Build package list let packages: PackageInput[] = input.packages || []; if (input.manifest) { const fromManifest = detectAndParse(input.manifest, input.manifestType, input.includeDevDependencies); packages = [...packages, ...fromManifest]; } if (packages.length === 0) { return { error: "No packages provided. Supply 'packages' array or 'manifest' content." }; } // Deduplicate const seen = new Set<string>(); packages = packages.filter((p) => { const key = `${p.ecosystem}:${p.name}:${p.version || "*"}`; if (seen.has(key)) return false; seen.add(key); return true; }); // Query OSV for each package (sequential to be polite to the API) const results = await Promise.all(packages.map(async (pkg) => { const vulns = await queryPackage(pkg); return { pkg, vulns }; })); const minSeverityRank = severityRank(input.minSeverity); const vulnerable: Array<{ package: string; version?: string; ecosystem: string; vulnerabilities: Array<{ id: string; cves: string[]; summary: string; severity: string; fixedIn: string[]; published?: string; url: string; cweIds?: string[]; }>; highestSeverity: string; }> = []; const clean: string[] = []; const bySeverity: Record<string, number> = {}; for (const { pkg, vulns } of results) { if (vulns.length === 0) { clean.push(`${pkg.name}${pkg.version ? `@${pkg.version}` : ""}`); continue; } const filtered = vulns .map((v) => ({ id: v.id, cves: (v.aliases || []).filter((a) => a.startsWith("CVE-")), summary: v.summary || "No summary available", severity: getSeverity(v), fixedIn: getFixedVersions(v, pkg.ecosystem), published: v.published, url: getAdvisoryUrl(v), cweIds: v.database_specific?.cwe_ids, })) .filter((v) => severityRank(v.severity) >= minSeverityRank); if (filtered.length === 0) { clean.push(`${pkg.name}${pkg.version ? `@${pkg.version}` : ""}`); continue; } // Count by severity for (const v of filtered) { bySeverity[v.severity] = (bySeverity[v.severity] || 0) + 1; } vulnerable.push({ package: pkg.name, version: pkg.version, ecosystem: pkg.ecosystem, vulnerabilities: filtered, highestSeverity: highestSeverity(filtered.map((v) => v.severity)), }); } // Sort vulnerable packages by highest severity desc vulnerable.sort((a, b) => severityRank(b.highestSeverity) - severityRank(a.highestSeverity)); const totalVulnerabilities = vulnerable.reduce((sum, p) => sum + p.vulnerabilities.length, 0); return { vulnerable, clean, summary: { totalPackages: packages.length, vulnerablePackages: vulnerable.length, cleanPackages: clean.length, totalVulnerabilities, bySeverity, riskLevel: vulnerable.some((p) => p.highestSeverity === "CRITICAL") ? "CRITICAL" : vulnerable.some((p) => p.highestSeverity === "HIGH") ? "HIGH" : vulnerable.length > 0 ? "MODERATE" : "NONE", }, }; } - Input schema definition using Zod for the dependency auditor tool.
const inputSchema = z.object({ packages: z .array(packageSchema) .min(1) .max(50) .optional() .describe("List of packages to audit"), manifest: z .string() .optional() .describe("Raw package.json or requirements.txt content. Parsed automatically."), manifestType: z .enum(["package.json", "requirements.txt", "auto"]) .default("auto") .describe("Manifest format. 'auto' detects from content."), includeDevDependencies: z .boolean() .default(true) .describe("Include devDependencies when parsing package.json"), minSeverity: z .enum(["LOW", "MODERATE", "HIGH", "CRITICAL"]) .default("LOW") .describe("Minimum severity to include in results"), }); - src/tools/dependency-auditor.ts:287-313 (registration)Tool registration for 'dependency-auditor'. Note: mcp-server/src/index.ts registers this tool as 'audit_dependencies'.
const dependencyAuditorTool: ToolDefinition<Input> = { name: "dependency-auditor", description: "Audit npm and PyPI packages for known security vulnerabilities using the OSV (Open Source Vulnerabilities) database. " + "Accepts a list of packages with versions, or paste raw package.json / requirements.txt content for automatic parsing. " + "Returns per-package vulnerability details: CVE IDs, severity (CRITICAL/HIGH/MODERATE/LOW), fixed versions, and advisory links. " + "Results are sorted by severity. Powered by osv.dev — the same database used by GitHub Dependabot.", version: "1.0.0", inputSchema, handler, metadata: { tags: ["security", "vulnerabilities", "npm", "pypi", "cve", "dependencies", "devtools"], pricing: "$0.005 per call", exampleInput: { packages: [ { name: "lodash", version: "4.17.11", ecosystem: "npm" }, { name: "axios", version: "0.21.0", ecosystem: "npm" }, { name: "express", version: "4.18.0", ecosystem: "npm" }, ], minSeverity: "MODERATE", manifestType: "auto", includeDevDependencies: true, }, }, }; registerTool(dependencyAuditorTool);