NPMScan
Server Details
Detect malicious or vulnerable npm packages: registry search, OSV.dev and GitHub advisory lookups
- Status
- Healthy
- Uptime
- 100.0% over 65 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 23 tools
Most tools have clearly distinct purposes and the descriptions explicitly cross-reference each other (e.g. 'use batch_query_vulnerabilities instead when you already have a flat list'). There are a few tightly related clusters — three maintainer tools (check_maintainer_changes/check_maintainer_blast_radius/get_maintainer_profile), three vulnerability-query tools (query_vulnerabilities/batch_query_vulnerabilities/analyze_transitive_dependencies), and get_package vs get_package_version — that require careful reading to pick correctly, but each boundary is documented.
Every tool follows a strict snake_case verb_noun pattern (analyze_install_script, check_license_compliance, get_package_version, query_vulnerabilities, prioritize_remediation). No camelCase or vague verbs appear anywhere in the set.
23 tools is on the heavier side but justified by a genuinely broad domain spanning vulnerability scanning, license compliance, maintainer/provenance analysis, SBOM generation, dependency diffing, and remediation. Nearly every tool earns its place with a distinct function, though the count is near the upper bound of comfortable.
The surface covers the full npm-supply-chain lifecycle: single/batch/transitive vulnerability queries, license compliance, install-script analysis, provenance, maintainer-change and blast-radius detection, SBOM export, remediation prioritization, upgrade simulation, dependency diffing, alternatives, and CVE/advisory lookups. As a read-only analysis server it has no obvious dead ends.
Available Tools
23 toolsanalyze_install_scriptAnalyze an npm package install scriptARead-onlyInspect
Statically scans a package's preinstall/install/postinstall/prepare lifecycle scripts AND the file(s) they reference — fetched directly from the published tarball, not just the command string in package.json — against npmscan's documented red-flags rubric (/docs/red-flags): child_process use, network calls, access to sensitive paths/env (.ssh, .aws, .npmrc, *TOKEN/*KEY), obfuscation, remote binaries hosted off trusted CDNs, writes to HOME, Discord/Telegram/Pastebin exfil endpoints, eval on decoded strings, chmod+exec of downloaded binaries, and CI-metadata telemetry — plus a possibleTyposquatOf name check. Returns a weighted totalScore and riskTier ('none'/'low'/'moderate'/'high'/'critical'). This is a heuristic static scan, not proof of malice or a guarantee of safety: it doesn't execute any code, can't see behavior gated on runtime conditions, and does NOT check maintainer/ownership history (a separate red-flags signal this tool doesn't cover). Use get_package/get_package_version first for the raw script listing; use this when you need to know what an install script actually does, not just that one exists.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name, e.g. "lodash" or "@scope/name" | |
| version | No | Exact version to analyze; omit to use the latest published version |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| version | Yes | |
| findings | Yes | |
| riskTier | Yes | |
| scanNote | Yes | |
| npmscanUrl | Yes | |
| totalScore | Yes | |
| filesScanned | Yes | |
| lifecycleScripts | Yes | |
| hasLifecycleScripts | Yes | |
| possibleTyposquatOf | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld annotations, the description reveals essential behavioral traits: it fetches directly from the published tarball, performs a heuristic static scan, does not execute code, cannot detect behavior gated on runtime conditions, and returns a weighted score and risk tier. This is substantial added context beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every element earns its place: scope, what it checks, return value, limitations, and usage guidance. The dense red-flag enumeration could be summarized more tightly, but it is informative rather than fluff. Overall, it is well structured and front-loaded with the core action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers what the tool does, how it operates, its limitations, its output, and how it relates to siblings. Given that an output schema exists, the description is more than complete for an agent to decide when and how to invoke it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% for both parameters (name and version), and the schema already explains their meaning and defaults. The description adds no additional parameter-level details, so the baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Statically scans a package's preinstall/install/postinstall/prepare lifecycle scripts AND the file(s) they reference'. It also clearly differentiates itself from sibling tools by stating it does NOT check the raw script listing and explicitly points to get_package/get_package_version for that purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives direct when-to-use guidance: 'use get_package/get_package_version first for the raw script listing; use this when you need to know what an install script actually does, not just that one exists.' It also states what the tool cannot do, such as not executing code and not seeing runtime-gated behavior, which helps agents decide if this is the right tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
analyze_transitive_dependenciesAnalyze transitive dependencies for vulnerabilitiesARead-onlyInspect
Walk one or more root packages' dependency trees (e.g. a package.json "dependencies" section) up to maxDepth levels (default 2, max 3) and check every resolved package@version against OSV.dev, so vulnerabilities several levels down still surface. Read summary first; vulnerablePaths answers "which of my dependencies pulled this in"; nodes has the full graph. npm aliases are followed (actualName).
Before calling a result clean:
A node with
resolutionError(unsatisfiable range, 404, or a git/file/workspace/URL specifier) hasisVulnerable: null— it was never scanned, not clean.Only "dependencies" are followed (not dev/peer/optional). Each range is resolved independently to its max-satisfying version, so this shows which vulnerable versions are reachable, not npm's exact hoisted install.
The walk has a node budget: check
truncated/truncationNote.
Use batch_query_vulnerabilities instead when you already have a flat list of exact versions (faster, no graph walk).
| Name | Required | Description | Default |
|---|---|---|---|
| maxDepth | No | How many levels of transitive dependencies to expand beyond the given root packages (0 = only check the roots themselves). Default 2, capped at 3 to bound registry calls and stay within the request timeout. | |
| packages | Yes | 1-15 direct/root packages to expand from, e.g. a package.json's "dependencies". version accepts an exact version or a semver range like "^4.17.21"; omitted = latest. |
Output Schema
| Name | Required | Description |
|---|---|---|
| nodes | Yes | |
| roots | Yes | |
| summary | Yes | |
| maxDepth | Yes | |
| truncated | Yes | |
| enrichmentNote | Yes | |
| truncationNote | Yes | |
| unresolvedCount | Yes | |
| vulnerablePaths | Yes | |
| totalPackagesScanned | Yes | |
| totalVulnerabilities | Yes | |
| vulnerablePackageCount | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, non-destructive, openWorld), and the description adds genuinely non-obvious behavior: resolutionError nodes are unscanned rather than clean, only 'dependencies' are followed, ranges resolve independently, and a node budget can truncate the walk. One small gap: it doesn't state auth or rate-limit expectations for OSV.dev calls.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and key caveats, and the bullet list is dense with operational warnings rather than filler. It is longer than average, but nearly every sentence carries a decision-relevant caveat, so little is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a graph-walking tool with an output schema, the description points directly at the meaningful output fields (summary, vulnerablePaths, nodes, truncated) and pre-empts the two highest-risk misinterpretations: unscanned nodes and truncation. Nothing needed to call or correctly read it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real interpretability: it clarifies that maxDepth bounds registry calls/timeout, that nodes resolve independently rather than mirroring npm's hoisting, and that version accepts ranges. It mostly reinforces rather than extends the schema's own parameter text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (walk dependency trees), resource (root packages), and external action (check against OSV.dev), plus the outcome (vulnerabilities several levels down surface). It explicitly contrasts with batch_query_vulnerabilities, so an agent can distinguish it from siblings without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit alternative with the selecting condition: 'Use batch_query_vulnerabilities instead when you already have a flat list of exact versions (faster, no graph walk).' It also directs how to consume results, telling the agent to read summary first and use vulnerablePaths for the 'which dependency pulled this in' question.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
audit_github_repositoryAudit a GitHub repository's npm dependenciesARead-onlyInspect
Audit a GitHub repository's npm dependencies from its URL — no pasted files needed. Fetches package.json plus the first lockfile found (pnpm-lock.yaml, then package-lock.json, then yarn.lock) from the default branch (or ref), and detects monorepos (package.json workspaces, pnpm-workspace.yaml), merging member dependencies (up to 50 members).
What it checks:
Every lockfile entry (up to 3,000; the repo's own workspace/link entries skipped) against OSV.dev, so
vulnerablePackageCountcovers the whole dependency set.Up to 100 packages, vulnerable ones first, also get a license verdict (same default policy as check_license_compliance, or pass
policy) and an install-script signal; up to 10 with lifecycle scripts get the deep tarball scan (installScriptScanScope).Up to 5 high-risk packages (critical/high vulnerability, possible typosquat, deprecated) get the maintainer-change and provenance checks; others are named in
ownershipCheckNote.
Read coverage and the summary before calling a repo clean: a summary starting PARTIAL AUDIT (coverage.complete: false) means not every package got every check. findings has full detail only for packages with something to report; the other detailed packages are listed compactly in cleanFindings. Vulnerable packages past the 100-package detail cap are in overflowVulnerablePackages. peerDependencies are skipped unless includePeerDependencies: true. This is the most expensive tool here — do not call it in a loop across many repos.
| Name | Required | Description | Default |
|---|---|---|---|
| ref | No | Branch, tag, or commit SHA to audit. Omit to use the repository's default branch. | |
| url | Yes | GitHub repository URL, e.g. "https://github.com/owner/repo". | |
| policy | No | License allow/deny policy, same shape as check_license_compliance. Omit for the default policy (only copyleft/network-copyleft/proprietary are violations). | |
| includeDevDependencies | No | Include package.json devDependencies in the audit. Default false. Ignored when a lockfile is used instead (its own format decides direct-dependency scope), and yarn.lock can never distinguish dev from production dependencies regardless of this flag. | |
| includePeerDependencies | No | Include package.json peerDependencies (root and, for a monorepo, each workspace member) in the audit. Default false — a peer is often intentionally left unresolved by the consumer. See warnings for which peers were excluded. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ref | Yes | |
| owner | Yes | |
| policy | Yes | |
| summary | Yes | |
| coverage | Yes | How much of the dependency set was actually checked — read this before calling a repo clean. |
| findings | Yes | Detailed packages with something to report (vulnerable, unchecked, license issue, install-script/ownership signal, typosquat, deprecated). |
| repoName | Yes | |
| warnings | Yes | |
| isMonorepo | Yes | |
| inputFormat | Yes | |
| deepScanNote | Yes | |
| lockfilePath | Yes | |
| manifestPath | Yes | |
| cleanFindings | Yes | Detailed packages with nothing flagged, listed compactly. Together with `findings` these are the `totalPackages` packages that got full detail. |
| totalPackages | Yes | |
| workspaceNote | Yes | |
| truncationNote | Yes | |
| deepScannedCount | Yes | |
| overflowPackages | Yes | |
| defaultBranchUsed | Yes | |
| workspacePatterns | Yes | |
| ownershipCheckNote | Yes | |
| overflowPackageCount | Yes | |
| licenseViolationCount | Yes | |
| ownershipCheckedCount | Yes | |
| workspacePackageCount | Yes | |
| vulnerablePackageCount | Yes | Vulnerable packages across every vulnerability-checked entry, not just `findings`. |
| installScriptFlaggedCount | Yes | |
| ownershipRiskFlaggedCount | Yes | |
| overflowVulnerablePackages | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly/openWorld/non-destructive), and the description adds substantial behavior beyond them: fetch order and lockfile fallback, monorepo merging (up to 50 members), concrete caps (3,000 entries, 100 detail packages, 10 tarball scans, 5 high-risk), how 'coverage.complete: false' / 'PARTIAL AUDIT' should be interpreted, and escalation/cost warnings.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is long, but the first sentence front-loads the purpose and the key architectural fact, and the remaining detail is organized under a 'What it checks' heading. The density is justified by the tool's complexity, though a few clauses about output fields could be trimmed since an output schema exists.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity, multi-parameter tool with a nested policy object and an output schema, the description is complete: it explains coverage semantics, cap behavior, overflow handling, and cost so an agent can call it and interpret results responsibly even though return structure itself is delegated to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the schema already documents ref, policy, includeDevDependencies and includePeerDependencies in detail. The description largely restates these (default branch vs ref, peer skip, default policy), adding only a small amount of meaning such as the pointer to warnings for excluded peers, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (audit) and resource (a GitHub repository's npm dependencies) with a defining constraint — it works from a URL with 'no pasted files needed'. This clearly distinguishes it from file-based and lower-level sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives strong usage context ('no pasted files needed', use a repo URL) and an explicit when-not ('the most expensive tool here — do not call it in a loop across many repos'). It references check_license_compliance for policy shape but never names an alternative tool for narrower single-concern queries, so routing guidance is clear but not exhaustive.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
batch_query_vulnerabilitiesBatch query known vulnerabilitiesARead-onlyInspect
Check a whole npm dependency inventory against OSV.dev in one call: pass packages: [{name, version?}], or raw package.json / package-lock / yarn.lock / pnpm-lock / CycloneDX / SPDX content via content. Large inventories are chunked automatically. Each finding has severity, summary, CVE aliases, fixedVersion and isMalware, so no per-package follow-up is needed.
Before calling anything clean, read:
unresolvedPackages/nonexistentVersions(and each result'sregistryStatus): a name or version not on npm shows vulnerabilityCount 0 just like a clean package. A version npm removed can still have real OSV findings (often malware).A
packagesentry with no version is checked against every historical version; confirm against the version actually in use before calling it vulnerable.signals(deprecated, hasInstallScripts, popularity/maintenance tiers, possibleTyposquatOf): 0 vulnerabilities can still be deprecated, abandoned or a typosquat.signalsis null for git/file/workspace/URL entries, which are not scanned.source(lockfile input):nonRegistryHostmeans the tarball comes from an unexpected host;identityMismatchmeans it is a different package/version than declared (resolvedName/resolvedVersion) and the counts describe the declared one. Treat both as lockfile tampering.Use
uniqueVulnerabilityCountfor distinct issues; raw counts can list one CVE twice.package.json input:
projectLifecycleScripts/projectLifecycleScriptRiskare the project's own install scripts; peerDependencies are skipped unlessincludePeerDependencies: true(seeignoredPeerDependencyNames);declaredSpecmarks a version resolved from a range, which can change on the next install.npm aliases are followed:
package.actualNameis the real package the data describes.
| Name | Required | Description | Default |
|---|---|---|---|
| content | No | Raw dependency inventory content: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, CycloneDX JSON, or SPDX JSON. Use this OR `packages`, not both. | |
| packages | No | Explicit package list (1-1000 items). Use this OR `content`, not both. | |
| includeDevDependencies | No | Ignored when using `packages`; only applies when `content` is a manifest/lockfile format that distinguishes dev dependencies. | |
| includePeerDependencies | No | Ignored when using `packages`; only applies when `content` is a package.json. peerDependencies are excluded from scanning by default (see ignoredPeerDependencyNames) since a peer is often intentionally left unresolved by the consumer — set this to also check them. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| warnings | No | |
| inputFormat | No | |
| ignoredCount | No | |
| enrichmentNote | No | |
| queryFailureCount | No | |
| existenceCheckNote | No | |
| parsedPackageCount | No | |
| unresolvedPackages | No | |
| nonexistentVersions | No | |
| totalVulnerabilities | Yes | |
| projectLifecycleScripts | No | |
| ignoredPeerDependencyNames | No | |
| projectLifecycleScriptRisk | No | |
| totalUniqueVulnerabilities | Yes | |
| packagesWithVulnerabilities | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld/non-destructive annotations: automatic chunking, deduplication via uniqueVulnerabilityCount, npm alias resolution, and explicit warnings that 0-counts can mask unresolved packages, nonexistent versions, deprecated/abandoned/typosquat packages, and lockfile tampering (nonRegistryHost, identityMismatch). This is exactly the extra context annotations cannot carry.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads purpose, then a tightly scoped bullet block; each caveat addresses a specific false-positive risk, so most sentences earn their place. Minor redundancy remains, e.g. enumerating finding fields (severity, summary, CVE aliases, fixedVersion, isMalware) that the output schema already documents.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a high-complexity batch tool with two mutually exclusive input modes and subtle failure modes, the description covers input selection, chunking behavior, and the interpretation pitfalls an agent would otherwise misread as clean results. An output schema exists, so its coverage of return values is a bonus rather than a necessity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning: an entry with no version is checked against every historical version, ranges/tags cost an extra lookup, and includePeerDependencies surfaces ignoredPeerDependencyNames. It enriches rather than merely restates the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb, resource and scope: 'Check a whole npm dependency inventory against OSV.dev in one call.' The batch framing plus 'no per-package follow-up is needed' implicitly distinguishes it from query_vulnerabilities, but the sibling is never named, so the routing contrast is left to inference.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear operational context: use `packages` OR `content` (not both), large inventories are chunked automatically, and peerDependencies are skipped unless opted in. However it never explicitly says when to prefer this over query_vulnerabilities for a single package, and the 'Before calling anything clean' block is output-interpretation guidance rather than selection guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_license_complianceCheck a dependency list against a license policyARead-onlyInspect
Given a list of packages (name + optional exact version or semver range — e.g. straight from a package.json "dependencies" object) and an optional allow/deny license policy, resolves each package's declared SPDX license and reports a compliance verdict per package. Classifies every license into one of permissive/weak-copyleft/copyleft/network-copyleft/proprietary/public-domain/unknown, and understands simple SPDX expressions: "(MIT OR GPL-3.0)" is compliant if EITHER side is permitted (a consumer may legally pick the clean alternative), "MIT AND Apache-2.0" requires both sides to pass, and "X WITH exception" is judged on X. A mixed/nested expression like "(MIT OR ISC) AND Apache-2.0" is reported as needsReview rather than guessed at. policy.deny entries always win over policy.allow (so a name can appear in both without a silent contradiction); with policy.allow set, anything not matching it is a violation (unproven is treated as non-compliant); with neither given, the default policy flags only copyleft/network-copyleft/proprietary (e.g. GPL/AGPL/UNLICENSED) — weak-copyleft (LGPL/MPL/EPL) and unrecognized license strings are surfaced but not auto-flagged. Policy entries accept an exact SPDX id, a family prefix ("GPL" catches GPL-2.0/GPL-3.0-only/etc.), or a category name. This reads only the registry-declared license field — it does not fetch or parse LICENSE file contents from the source repository.
| Name | Required | Description | Default |
|---|---|---|---|
| policy | No | Omit entirely to use the default policy: only copyleft/network-copyleft/proprietary are violations. | |
| packages | Yes | 1-100 packages to check. version accepts an exact version or a semver range like "^4.17.21"; omitted = latest. |
Output Schema
| Name | Required | Description |
|---|---|---|
| policy | Yes | |
| results | Yes | |
| summary | Yes | |
| totalPackages | Yes | |
| compliantCount | Yes | |
| violationCount | Yes | |
| unresolvedCount | Yes | |
| needsReviewCount | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld/non-destructive annotations, the description adds substantial behavioral detail: it defines license classification categories, explains how SPDX OR/AND/WITH expressions are evaluated, states that mixed nested expressions are reported as needsReview, and notes that policy.deny always overrides policy.allow. It also exposes the limitation that LICENSE file contents are not parsed. These disclosures meaningfully shape agent expectations and contradict nothing in the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The first sentence is a compact, front-loaded summary of the tool's core purpose, and each subsequent sentence adds a distinct non-obvious behavior: classification categories, SPDX expression interpretation, mixed-expression fallback, deny precedence, and the registry-field limitation. The length is proportionate to the tool's complexity, with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-parameter tool with nested schemas and an output schema, the description covers the input format, optional policy behavior, expression evaluation rules, precedence semantics, and a critical limitation. An agent has enough information to decide whether to invoke the tool and what kinds of results to expect, and the output schema handles return-value details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents both parameters and their fields at 100% coverage, providing a strong baseline. The description goes further by giving concrete semantics: packages can come 'straight from a package.json dependencies object', version accepts exact or semver ranges, omitted version means latest, deny always wins over allow, and omitted policy means the default policy applies. This adds practical invocation guidance beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action: resolving a list of packages' declared SPDX licenses and reporting a compliance verdict per package, with the title naming the resource and goal. The focus on licensing, policy handling, and per-package verdicts clearly distinguishes it from sibling vulnerability, provenance, and maintainer-focused tools without needing explicit cross-references.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly states when to use the tool: given a list of packages and an optional allow/deny license policy. It also clarifies that omitting the policy uses the default, and it emphasizes the limitation that only the registry-declared license field is read. It does not explicitly name alternative sibling tools or state 'when not to use', so it falls just short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_maintainer_blast_radiusCheck npm maintainer blast radiusARead-onlyInspect
Given an npm username, lists the packages npm's maintainer: search index returns for that account and looks for a tight cluster of packages whose latest version was published within a short rolling window of each other — the shape of a compromised-account supply-chain attack, where a stolen credential is used on every package the account can publish to within hours (e.g. the September 2025 chalk/debug compromise, ~18 packages in ~2 hours). A large total package count is not itself a red flag; only a tight publish-time cluster is scored, weighted by its package count and combined weekly downloads/dependentsCount. Clusters mostly within one npm scope (a monorepo release) are dampened, and multiple clusters combine with diminishing returns. isCurrentMaintainer shows whether the account still maintains each package. avatarUrl is a proxied Gravatar image (null if no email is on record). Natural follow-up to check_maintainer_changes: call this with a newly added maintainer's username to see whether the same account touched other packages around the same time. Limitations: npm's search index can lag or omit packages; results are capped at 250 packages ranked by relevance, not recency (see resultsTruncated/totalPackagesFound); lastPublished reflects only each package's latest version. npmscanUrl is the account's npmscan profile; npmProfileUrl is its npmjs.com page.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many packages to list (default 50, max 250), most-downloaded first. Totals still cover every package found. | |
| maintainerUsername | Yes | Exact npm username, e.g. "sindresorhus" — as shown at npmjs.com/~username. Not an email address, not a package name or scope. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | |
| clusters | Yes | |
| findings | Yes | |
| packages | Yes | |
| riskTier | Yes | |
| avatarUrl | Yes | |
| npmscanUrl | Yes | |
| totalScore | Yes | |
| npmProfileUrl | Yes | |
| packagesOmitted | Yes | Packages left out of `packages` by `limit`; totals and scoring still include them. |
| packagesReturned | Yes | |
| resultsTruncated | Yes | |
| clusterWindowHours | Yes | |
| maintainerUsername | Yes | |
| totalPackagesFound | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, openWorld, non-destructive), and the description goes well beyond them: it explains the scoring model (cluster weighted by count and downloads, dampened for single-scope monorepos, diminishing returns for multiple clusters), discloses hard limitations (index lag, 250-package relevance-ranked cap, resultsTruncated/totalPackagesFound, lastPublished only covers latest version), and interprets output fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core action and the attack pattern it detects, then limitations. Every sentence carries information, though the density is high and some field explanations (avatarUrl proxying) are marginal for tool selection.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex heuristic-scoring tool, the description is thorough: it defines the detection model, the caveats that affect interpretation, and the auxiliary output URLs. An output schema exists, yet the added interpretation of scores and truncation flags is exactly the context an agent needs to act on results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and both parameters are self-documenting, so baseline is 3. The description adds real value by clarifying that results are 'capped at 250 packages ranked by relevance, not recency' and that the limit is 'most-downloaded first' while totals still cover everything found — semantics the schema alone does not convey.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('lists the packages npm's maintainer:<username> search index returns') plus the analytical goal (detecting a tight publish-time cluster). It explicitly distinguishes itself from the sibling check_maintainer_changes by naming it as the natural predecessor, so an agent can route between them without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear context for use ('Natural follow-up to check_maintainer_changes: call this with a newly added maintainer's username') and names the alternative tool and trigger condition. It stops short of explicit when-not-to-use guidance, but the operational trigger is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_maintainer_changesCheck an npm package for maintainer/ownership red flagsARead-onlyInspect
Reconstruct who has controlled an npm package and when, straight from the packument (each version records the maintainer list at publish time and who ran npm publish). Use it for the 'who controls this package, and did that change recently' question; use get_package/check_package_provenance for general health and publish integrity.
Flags:
a maintainer added recently who then published soon after, on a package with real prior history — the takeover shape behind ua-parser-js, event-stream and the 2025 chalk/debug ('qix') compromise
the whole maintainer list replaced at once
a long-standing maintainer quietly dropped
a maintainer change on npm AFTER the latest release — more urgent: access changed hands but nothing has shipped yet
It also checks the declared GitHub repository: transferred or renamed (repository.ownerLogin/ownerAvatarUrl show the CURRENT owner), unreachable, or a latest release that landed long after any real push activity. If it flags a newly added or fully replaced maintainer, follow up with check_maintainer_blast_radius on that username to see whether the same account touched other packages at the same time. Findings are signals to verify, not proof of compromise.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name, e.g. "lodash" or "@scope/name" |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| history | Yes | |
| findings | Yes | |
| riskTier | Yes | |
| npmscanUrl | Yes | |
| repository | Yes | |
| totalScore | Yes | |
| lookbackDays | Yes | |
| currentMaintainers | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the read-only, non-destructive, open-world profile, but the description goes well beyond them: it enumerates the four specific red-flag patterns, explains why the post-release change case is more urgent, covers the GitHub repository checks, and honestly caveats that findings are 'signals to verify, not proof of compromise'.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose and routing in the first two sentences, then a numbered flag list that is genuinely informative rather than padding. It is on the long side for a single-parameter tool, but each section (flags, repo checks, follow-up, caveat) earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 needn't explain return values, and it doesn't try. Given the open-world security domain and the ambiguity of the findings, the description supplies exactly the framing an agent needs: what signals mean, how to chain tools, and the verification caveat.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter and schema coverage is 100%, so the schema already carries the name format and constraints. The description adds the data-source context (packument) but no additional syntax or edge-case meaning for the parameter itself; baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Reconstruct who has controlled an npm package and when') and the exact data source (the packument, per-version maintainer lists). It explicitly separates itself from siblings get_package and check_package_provenance by naming the question it answers ('who controls this package, and did that change recently').
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives an explicit when-to-use framing ('the who controls this package, and did that change recently question') and names the alternatives for the adjacent questions (get_package, check_package_provenance). It also prescribes a concrete follow-up workflow with check_maintainer_blast_radius when a maintainer flag fires.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_package_provenanceCheck an npm package version for publish-provenance red flagsARead-onlyInspect
Checks whether a package version was published with npm's own Sigstore-backed publish provenance (npm publish --provenance), and cross-checks that provenance against reality rather than just reporting its presence. Three checks: (1) parses the SLSA build attestation (declared source repo, commit, builder identity, GitHub Actions run URL) and flags a builder that isn't GitHub-hosted, or an attested source repo that doesn't match package.json's own repository field; (2) when this version LACKS provenance, checks whether most peer packages (same npm scope, or same maintainer for an unscoped name) DO have it — a package that's the odd one out in an org that otherwise always publishes from CI is a real anomaly, not proof of malice; (3) fetches package.json from the source repository at the exact attested commit (or a best-effort matching git tag when no provenance/commit is available) and diffs its install-lifecycle scripts (preinstall/install/postinstall/prepare) and dependency names against what's actually in the published tarball — this is the single highest-signal check here, since a script or dependency that exists on npm but was never committed is exactly the pattern of a stolen-npm-token publish that bypasses CI (the event-stream/ua-parser-js incident shape). This is a heuristic, structural check: it does NOT cryptographically re-verify the Sigstore bundle (Fulcio cert chain, Rekor inclusion proof) — it trusts that npm's registry already refused to accept a publish that failed that verification, and checks the CONTENT of what the registry reports instead. Most packages don't use --provenance yet, so its bare absence is never scored on its own — only an org-norm anomaly or an actual source mismatch is. Use get_package/get_package_version first for basic package info; use this specifically to assess publish-integrity risk.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name, e.g. "lodash" or "@scope/name" | |
| version | No | Exact version to check; omit to use the latest published version |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| peers | Yes | |
| version | Yes | |
| findings | Yes | |
| riskTier | Yes | |
| npmscanUrl | Yes | |
| provenance | Yes | |
| sourceDiff | Yes | |
| totalScore | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond readOnlyHint/destructiveHint, the description discloses the heuristic nature, the three check strategies, the exact limitation that Sigstore is not cryptographically re-verified, and the anomaly logic. There is no contradiction with the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded and every sentence contributes, but it is a dense, long paragraph that could be tightened or bulleted for quicker scanning. No filler, yet it is heavier than the minimum viable definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With annotated read-only behavior, an output schema, and fully described parameters, the description still adds the missing edge cases: no-provenance versions, best-effort tag matching, and what counts as an anomaly. Nothing needed for correct invocation is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the exact package name and the optional version with 'omit to use the latest published version'. The description adds context about source-repo fetching and tarball diffs but no additional parameter-level syntax or format details.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource ('Checks whether a package version was published with npm's own Sigstore-backed publish provenance') and enumerates three distinct checks, making the tool's job unmistakable. It also differentiates it from get_package/get_package_version by positioning those as basic-info prerequisites and this tool as the publish-integrity-risk assessment.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly instructs the agent to use get_package/get_package_version first and says to use this tool specifically for publish-integrity risk. It also states when a result should not be interpreted as malice ('bare absence is never scored on its own'), giving clear when-to-use and when-not-to-conclude guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_packagesCompare npm packages side-by-sideARead-onlyInspect
Compare 2-5 candidate packages for the same job (e.g. "axios vs got vs node-fetch") side by side and get a deterministic pick. More than 5 names is rejected, never truncated; duplicate names are rejected. Use search_packages first if you have no shortlist.
Per candidate: downloads and trend, popularity/maintenance tiers, GitHub stars, TypeScript support, license, deprecation, latest-version vulnerabilities, a tarball-free installScriptRisk (scores preinstall/install/postinstall; a prepare-only package scores 0 since prepare never runs on install — use analyze_install_script for the deep scan), and installSize (own size plus a transitive rollup up to depth 2 / 60 nodes; truncated/sizeUnknownCount mark a partial sum).
differentiators names who stands out on each dimension. recommendation.pick comes from a weighted score (popularity, maintenance, deprecation, vulnerabilities, typosquat flag, install-script risk, TypeScript, stars; size is reported, not scored) — never a deprecated or typosquat-flagged candidate — with a rationale and a confidence from how close the top two scored.
Before trusting the result: vulnerabilityCheckFailed: true means the safe/not-safe answer is unknown, not clean; a name that cannot be resolved stays in candidates with found: false and resolutionError.
| Name | Required | Description | Default |
|---|---|---|---|
| packages | Yes | 2-5 exact npm package names to compare, e.g. ["axios", "got", "node-fetch"]. More than 5 is rejected with an error, not truncated. |
Output Schema
| Name | Required | Description |
|---|---|---|
| candidates | Yes | |
| recommendation | Yes | |
| differentiators | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover safety (readOnly, non-destructive, open-world), and the description still adds substantial behavioral context: rejection semantics, the weighted scoring inputs, the rule that deprecated/typosquat-flagged candidates can never be picked, and confidence derived from score gap. The main caveat section on vulnerabilityCheckFailed and found:false further qualifies trust in results. It falls short of 5 only because failure/auth/rate-limit conditions beyond those two flags are not addressed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, constraints, and the sibling pointer in the first sentence, then organized by output concern. It is dense but each sentence carries information; the long per-candidate enumeration is the one place that could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists, yet the description still orients the agent on the shape and trustworthiness of results (differentiators, recommendation.pick, rationale, confidence, partial installSize sums). For a single-parameter comparison tool this is more than sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single parameter is fully documented in the schema, so baseline is 3. The description adds meaning the schema does not: duplicate names are rejected and names that cannot be resolved stay in candidates with found:false and resolutionError, which clarifies what values are acceptable and how they behave.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Compare 2-5 candidate packages ... side by side and get a deterministic pick') with scope (same job) and an example. It is clearly distinguishable from search_packages, which it explicitly routes to for shortlist building.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit preconditions and exclusions: 2-5 names, more than 5 rejected rather than truncated, duplicates rejected, and 'Use search_packages first if you have no shortlist.' It also names analyze_install_script as the deeper alternative for install scripts.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
diff_dependenciesDiff two package.json/lockfile snapshotsARead-onlyInspect
Compare two snapshots of a package.json, package-lock.json (v1-v3), yarn.lock (classic or Berry) or pnpm-lock.yaml (e.g. before/after a PR; formats can differ) and report added, removed and changed packages. Lockfiles cover the full resolved graph, so transitive-only changes are caught; npm aliases are followed (actualName). Up to 100 added/changed packages are checked in detail. Ideal for a CI gate.
Per added/changed package:
installScriptIntroduced: a preinstall/install/postinstall script the old version lacked — the shape of a compromised-maintainer release.preparenever runs on a registry install, so it is excluded;installScriptKeysIntroducedlists every new key, prepare included.sourceIntegrityChanged: the same version now resolves to a different tarball URL or hash, or a bump moved to another host (ordinary bumps are not flagged). A same-version swap ischangeType: "source-swap".identityMismatch: the tarball is a different package or version than declared;tarballName/tarballVersionsay what really installs, and the vulnerability fields describe that.vulnerabilityDelta(introduced/fixed/still-vulnerable/still-clean) plus the findings, each with isMalware.
Project-level: projectLifecycleChanges diffs the project's own root install scripts (package.json only; a PR that only adds a root postinstall changes no dependency), and overridesChanges diffs overrides/resolutions/pnpm.overrides, from package.json or between two pnpm-lock.yaml files (removing one can let a vulnerable version back in). Both count toward flaggedCount. Read comparisonNote when the two snapshots differ in format. Install-script checks are presence-only; use analyze_install_script to see what a script does.
| Name | Required | Description | Default |
|---|---|---|---|
| after | Yes | Raw file content of the "after" snapshot — a package.json, package-lock.json (npm v1-v3), yarn.lock (classic v1 or Berry), or pnpm-lock.yaml. Format is auto-detected; before/after may be different formats. | |
| before | Yes | Raw file content of the "before" snapshot — a package.json, package-lock.json (npm v1-v3), yarn.lock (classic v1 or Berry), or pnpm-lock.yaml. Format is auto-detected; before/after may be different formats. |
Output Schema
| Name | Required | Description |
|---|---|---|
| added | Yes | |
| changed | Yes | |
| removed | Yes | |
| summary | Yes | |
| truncated | Yes | |
| totalAdded | Yes | |
| afterFormat | Yes | |
| beforeFormat | Yes | |
| flaggedCount | Yes | |
| totalChanged | Yes | |
| totalRemoved | Yes | |
| comparisonNote | Yes | |
| enrichmentNote | Yes | |
| truncationNote | Yes | |
| overridesChanges | Yes | |
| projectLifecycleChanges | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/non-destructive, yet the description adds substantial behavioral depth: transitive-only changes are caught via full resolved graph, npm aliases are followed, only up to 100 added/changed packages are inspected in detail, and each flagged field (installScriptIntroduced, sourceIntegrityChanged, identityMismatch, vulnerabilityDelta) is explained with its semantics. This goes well beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded core purpose followed by clearly scoped bullet points for each reported field, each sentence carrying real semantic content. It is dense and re-explains some return fields despite an output schema existing, but the structure keeps it navigable.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a two-snapshot diff tool, the description covers formats, edge cases, per-field meaning, project-level checks, and the comparisonNote caveat, while the output schema handles return structure. An agent has everything needed to invoke and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the schema already documents both params; the description adds the practical framing that the two snapshots represent before/after (e.g. a PR) and that formats are auto-detected and may differ. This is modest added meaning over the schema's own text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: compare two snapshots, listing all supported formats (package.json, package-lock v1-v3, yarn.lock, pnpm-lock.yaml) and stating the output (added, removed, changed packages). This is unmistakable against siblings like analyze_transitive_dependencies or compare_packages.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Ideal for a CI gate' names a concrete usage context, and it routes the agent to analyze_install_script for script-body inspection, clarifying the boundary of this tool. It stops short of explicit when-not conditions, but the alternative reference is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
enrich_npm_auditRank raw `npm audit --json` output by what to fix firstARead-onlyInspect
Given the raw output of npm audit --json (npm 7+'s {vulnerabilities: {...}} format, or legacy npm 6's {advisories: {...}}), parses it directly — no need to re-paste package.json/lockfile content — and runs it through the same remove-now/patch-now/patch-soon/scheduled/monitor ranking prioritize_remediation exposes for hand-built finding lists (an advisory that is malware — a MAL-* id, or a GHSA whose OSV record carries CWE-506 / a MAL-* alias — is auto-detected and forces remove-now). npm audit's JSON almost never includes a CVE id (only a GHSA advisory URL), so this resolves each GHSA to its CVE alias via OSV.dev when one exists (ghsaResolvedToCveCount reports how many) before doing the same CISA KEV + FIRST.org EPSS + severity scoring — skipping this step would silently degrade most findings to severity-only ranking despite prioritize_remediation being built around CVE-keyed KEV/EPSS data. Also carries through npm-audit-specific context prioritize_remediation itself has no field for: isDirect (direct vs. transitive dependency) and fixAvailable/fixTarget (npm's own computed fix — note fixTarget can name a different package than the vulnerable one, e.g. bumping a parent to pull in a patched transitive dependency). A package with more than one distinct advisory in the source report only has its first advisory used for ranking; a warning names the package so query_vulnerabilities can be called on it directly for the rest. yarn audit --json and pnpm audit --json use different report shapes and are not supported — use batch_query_vulnerabilities with the project's manifest/lockfile for those instead.
| Name | Required | Description | Default |
|---|---|---|---|
| content | Yes | Raw stdout of `npm audit --json` — either npm 7+ format ({"auditReportVersion": 2, "vulnerabilities": {...}}) or legacy npm 6 format ({"advisories": {...}}). |
Output Schema
| Name | Required | Description |
|---|---|---|
| ranked | Yes | |
| summary | Yes | |
| warnings | Yes | |
| inputFormat | Yes | |
| skippedCount | Yes | |
| totalFindings | Yes | |
| uniqueCveCount | Yes | |
| ghsaResolvedToCveCount | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, non-destructive, openWorld), and the description adds substantial behavior beyond them: GHSA→CVE resolution via OSV.dev before KEV/EPSS scoring, automatic malware detection (MAL-* / CWE-506) forcing remove-now, carry-through of `isDirect`/`fixAvailable`/`fixTarget`, and the limitation that only the first advisory per package is ranked. It also explains the consequence of skipping resolution ('would silently degrade most findings to severity-only ranking'), which is exactly the kind of non-obvious trait an agent needs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose is front-loaded in the opening clause, and the dense parentheticals (malware detection rules, fixTarget semantics, unsupported package managers) each carry information an agent would otherwise lack. The cost is a single unbroken paragraph of run-on sentences, which hurts scanability even though little of the content is redundant.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one input, a full output schema, and rich annotations, the description covers everything material: supported and unsupported input formats, the enrichment pipeline, the ranking buckets, the multi-advisory caveat, and fallback tools. Output values (e.g. `ghsaResolvedToCveCount`) are appropriately left to the output schema.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Single required parameter with 100% schema description coverage, so the schema already documents the accepted JSON shapes and the description does not need to restate them. The description does add useful framing (the content is raw stdout, and no manifest/lockfile content is required), which is slightly more than the baseline for a fully-documented single-param tool.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (parse raw `npm audit --json` output and rank findings for remediation) and explicitly scopes the accepted input formats (npm 7+ `{vulnerabilities}` vs legacy npm 6 `{advisories}`). It draws a precise boundary against `prioritize_remediation` ('the same ranking prioritize_remediation exposes for hand-built finding lists') and against the yarn/pnpm case, so an agent can distinguish it from every relevant sibling.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit when-to-use (you have raw npm audit JSON and do not want to re-paste package.json/lockfile) and when-not-to-use with the named alternative ('`yarn audit --json` and `pnpm audit --json` ... are not supported — use batch_query_vulnerabilities'). It also routes the multi-advisory-per-package case to `query_vulnerabilities`. Nothing about tool selection is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
generate_sbomGenerate a CycloneDX or SPDX SBOMARead-onlyInspect
Given the same inputs batch_query_vulnerabilities accepts — either a flat {packages:[...]} list, or raw package.json / lockfile / CycloneDX JSON / SPDX JSON content via content — emits a spec-valid CycloneDX 1.6 or SPDX 2.3 JSON document (pick with format, default 'cyclonedx') with npmscan's own OSV.dev vulnerability findings and registry license data embedded in each spec's native fields: CycloneDX gets a top-level vulnerabilities[] array (VEX analysis.state: 'in_triage' — an unreviewed automated finding, not a claim of exploitability) and per-component licenses[]; SPDX (which has no vulnerabilities array in 2.3) gets one externalRefs SECURITY/advisory entry per finding and licenseDeclared/licenseConcluded. Only a flat package inventory is known here, so the CycloneDX dependencies[] transitive graph and any SPDX package hierarchy are intentionally omitted rather than fabricated. Set includeVulnerabilities/includeLicenses to false to skip either enrichment pass (faster, no registry/OSV calls for that pass); pass policy (same shape as check_license_compliance) to also get per-package compliance context; componentName/componentVersion name the SBOM's own root component/document if known. When content is a package.json, peerDependencies are excluded by default (a peer is often intentionally left unresolved by the consumer) — pass includePeerDependencies: true to include them as SBOM components too, since an SBOM meant to be complete shouldn't silently omit a whole dependency category.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | SBOM format to emit. Default 'cyclonedx'. | |
| policy | No | License allow/deny policy, same shape as check_license_compliance. Omit for the default policy. | |
| content | No | Raw dependency inventory content: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, CycloneDX JSON, or SPDX JSON. Use this OR `packages`, not both. | |
| packages | No | Explicit package list (1-1000 items, capped to 100 when includeLicenses is on). Use this OR `content`, not both. | |
| componentName | No | Name of the SBOM's own root component/document, if known. | |
| includeLicenses | No | Resolve registry license data and embed it natively. Default true. | |
| componentVersion | No | ||
| includeDevDependencies | No | Ignored when using `packages`; only applies when `content` is a manifest/lockfile format that distinguishes dev dependencies. | |
| includeVulnerabilities | No | Query OSV.dev and embed findings natively. Default true. | |
| includePeerDependencies | No | Ignored when using `packages`; only applies when `content` is a package.json. peerDependencies are excluded by default — set this to also include them as SBOM components. |
Output Schema
| Name | Required | Description |
|---|---|---|
| sbom | Yes | |
| format | Yes | |
| policy | No | |
| warnings | No | |
| inputFormat | No | |
| ignoredCount | No | |
| enrichmentNote | No | |
| parsedPackageCount | Yes | |
| totalVulnerabilities | Yes | |
| licenseViolationCount | No | |
| packagesWithVulnerabilities | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the readOnlyHint/openWorldHint/destructiveHint annotations: discloses that OSV.dev and registry calls occur, clarifies VEX analysis.state 'in_triage' is an unreviewed automated finding (not an exploitability claim), explains SPDX 2.3 has no vulnerabilities array so externalRefs are used, and states the transitive dependencies[] graph is intentionally omitted rather than fabricated. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and format details in the first sentence, and every subsequent sentence carries behaviorally meaningful information. However, it is a dense wall of text across four long paragraphs that could benefit from structural separation; the density is justified by tool complexity but the length is at the upper edge.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Highly complete for a complex 10-parameter tool with nested objects and an output schema: it explains output-format differences (CycloneDX vulnerabilities[]/licenses vs SPDX externalRefs/licenseDeclared), enrichment and policy options, intentional omissions, and cross-tool parameter reuse. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is high (90%), but the description still adds value: enumerates the content formats (package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, CycloneDX/SPDX JSON) beyond the schema, documents the 100-item cap on packages when includeLicenses is on, cross-references the policy param shape to check_license_compliance, and explains peerDependencies exclusion default and includeDevDependencies ignoring behavior — details the schema omits.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'emits a spec-valid CycloneDX 1.6 or SPDX 2.3 JSON document' with an explicit format choice and default. No sibling tool generates SBOMs (siblings cover vulnerability queries, license checks, remediation), so it is cleanly distinguished from all alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear contextual guidance: references the shared input shape with batch_query_vulnerabilities, explains when to skip enrichment passes (includeVulnerabilities/includeLicenses=false for speed), when to set includePeerDependencies (when an SBOM must be complete), and the content-vs-packages exclusivity. It lacks an explicit 'don't use when' exclusion, but for a generation tool the usage contexts are well covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_cveLook up a CVE in the NIST NVDARead-onlyInspect
Look up authoritative NIST NVD data for one exact CVE ID (e.g. "CVE-2026-2950"), or browse/search NVD by keyword, CVSS severity, CWE, or a publication-date range. Every result is enriched with CISA KEV status (kev, non-null only if this CVE is a confirmed, actively-exploited-in-the-wild vulnerability — treat that as an urgent-patch signal regardless of CVSS score) and FIRST.org EPSS (epss, the probability of exploitation in the next 30 days — a better prioritization signal than CVSS severity alone, which measures impact, not likelihood). If the KEV or EPSS lookup itself fails (network/timeout/upstream outage), kev/epss come back null only because those fields have to be nullable — kevCheckFailed/epssCheckFailed (true in that case) is the real signal, and means "unknown", not "confirmed absent/unscored". For a search, a failed EPSS batch call sets epssCheckFailed on every result in that response, since one call scores every id together; kevCheckFailed is tracked per-CVE since each is looked up independently. For a single cveId lookup, if NVD has no record yet or hasn't scored it, this falls back to the raw MITRE CVE record automatically (source: "mitre" on the result) rather than returning nothing. NVD is NOT npm-scoped — unlike query_vulnerabilities/get_latest_advisories, search results can include CVEs for any ecosystem, so pass keywordSearch (e.g. the package name) to narrow it. Prefer this for the authoritative CVSS score/vector/KEV/EPSS data on a CVE already found via another tool, or when a user pastes a CVE ID/link directly; prefer get_latest_advisories for npm-specific browsing. NVD enforces a strict shared rate limit, so this tool may occasionally ask you to retry in a few seconds — do so rather than assuming failure.
| Name | Required | Description | Default |
|---|---|---|---|
| cveId | No | Exact CVE ID for a single lookup, e.g. "CVE-2026-2950". When given, search filters below are ignored and should be omitted. | |
| cweId | No | Filter by weakness type, e.g. "CWE-79" | |
| severity | No | Filter by CVSS v3 base severity | |
| startIndex | No | Pagination offset for a search | |
| keywordSearch | No | Free-text search, e.g. a package or product name | |
| publishedSince | No | Publication date range start (YYYY-MM-DD). Must be given together with publishedUntil. | |
| publishedUntil | No | Publication date range end (YYYY-MM-DD). Must be given together with publishedSince; range is capped at 120 days. | |
| resultsPerPage | No | Max results for a search (default 10, capped at 50) |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | No | |
| kev | No | |
| cves | No | |
| cvss | No | |
| cwes | No | |
| epss | No | |
| note | No | |
| cveId | No | |
| found | No | |
| source | No | |
| published | No | |
| npmscanUrl | No | |
| references | No | |
| startIndex | No | |
| vulnStatus | No | |
| description | No | |
| lastModified | No | |
| totalResults | No | |
| kevCheckFailed | No | |
| resultsPerPage | No | |
| epssCheckFailed | No | |
| dateRangeClamped | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations (readOnlyHint=true, openWorldHint=true, destructiveHint=false) already covering the read-only profile, the description adds substantial behavioral disclosure: the automatic MITRE fallback for unscored CVEs (`source: "mitre"`), the precise nullable-field semantics (`kev`/`epss` null means 'unknown' via `kevCheckFailed`/`epssCheckFailed`, not 'confirmed absent'), the distinction between batch EPSS failure vs per-CVE KEV failure, and the shared NVD rate limit prompting retries. This goes well beyond what annotations convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The core purpose is front-loaded in the first sentence, and the dense follow-on sentences earn their place given the tool's complexity: dual lookup/search modes, nullable-field error semantics, fallback routing, and rate limiting all need explanation. It is verbose, and the educational aside about CVSS measuring impact vs likelihood is slightly extraneous to tool invocation, preventing a 5, but nothing is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 8 parameters, 0 required, an output schema, and annotations, the description covers every operational concern an agent needs: mode selection, sibling routing, fallback behavior, null/error-flag interpretation, rate-limit handling, and ecosystem scope. With the output schema present, the description rightly does not need to explain return values. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds value beyond the schema by explaining parameter interplay: that cveId supersedes search filters, that keywordSearch (e.g. a package name) should be used to narrow broad ecosystem-wide search results, and that severity filtering alone is a weaker prioritization signal than the returned EPSS score. This crosses the baseline into genuinely helpful parameter guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb+resource pairing: 'Look up authoritative NIST NVD data for one exact CVE ID... or browse/search NVD by keyword, CVSS severity, CWE, or a publication-date range.' It explicitly distinguishes itself from siblings: 'NVD is NOT npm-scoped — unlike query_vulnerabilities/get_latest_advisories' and 'prefer get_latest_advisories for npm-specific browsing.' An agent can tell exactly what this tool does and how it differs from its siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use and when-not-to-use guidance: 'Prefer this for the authoritative CVSS score/vector/KEV/EPSS data on a CVE already found via another tool, or when a user pastes a CVE ID/link directly; prefer get_latest_advisories for npm-specific browsing.' It also names the alternative (query_vulnerabilities/get_latest_advisories) and explains the ecosystem-scope reason for choosing the sibling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_latest_advisoriesGet latest npm security advisoriesARead-onlyInspect
Browse recently published npm security advisories and known-malicious-package findings. Three disjoint sources, selected via type: "reviewed" (default) is GitHub's curated, mostly CVE-backed advisories; "malware" is GitHub's own known-malicious-package advisories; "osv" is OSV.dev's OpenSSF malicious-packages feed, a separate dataset whose entries use MAL-/OSV ids rather than GHSA ids. None of "malware"/"osv" carry a CVE or meaningful CWE beyond "embedded malicious code". Filter by severity, vulnerability category (XSS, SQL/NoSQL Injection, SSRF, Access Control, Code Injection, etc. — reviewed only), an affected package name, or (reviewed/malware only) look up one exact advisory by GHSA or CVE ID. Advisories GitHub has withdrawn (most often "Duplicate Advisory: ..." records merged into a canonical GHSA) are excluded from browse results, so a page can hold fewer than 30 entries; an exact ghsaId/cveId lookup still returns a withdrawn advisory, with withdrawnAt set — treat it as retracted, not as a live finding. Paginated with an opaque cursor: pass a previous response's nextCursor back in as cursor to fetch the next page.
| Name | Required | Description | Default |
|---|---|---|---|
| type | No | Advisory source: "reviewed" (curated CVE-style, default), "malware" (GitHub-curated known-malicious packages), or "osv" (OSV.dev/OpenSSF malicious-packages feed) | |
| cveId | No | Look up one exact advisory by its CVE ID (e.g. "CVE-2024-12345") — reviewed/malware only | |
| cursor | No | Opaque pagination cursor from a previous response's nextCursor, to fetch the next page | |
| ghsaId | No | Look up one exact advisory by its GHSA ID (e.g. "GHSA-xxxx-xxxx-xxxx") — reviewed/malware only | |
| affects | No | Filter to advisories affecting this npm package name | |
| category | No | Filter by vulnerability category (reviewed only). One of: access-control, dos, xss, ssrf, auth, code-injection, info-exposure, path-traversal, input-validation, prototype-pollution, command-injection, sqli, crypto, race-condition, open-redirect, csrf, crlf-injection, xml-injection, malicious-code, deserialization | |
| severity | No | Filter by severity (default all; not applicable to "malware"/"osv") | |
| direction | No | Sort by published date, newest or oldest first (default desc) |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | What this feed covers (set for type "osv": its snapshot date, that malware with a GitHub advisory is listed under "malware"/"reviewed" instead, and how many entries came back id-only because their OSV detail fetch failed). |
| type | Yes | |
| category | Yes | |
| severity | Yes | |
| direction | Yes | |
| advisories | Yes | |
| nextCursor | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Adds substantial behavior beyond the annotations: withdrawn 'Duplicate Advisory' records are excluded from browse results so a page may hold fewer than 30 entries, yet an exact GHSA/CVE lookup still returns them with withdrawnAt set and they should be treated as retracted. It also discloses the ID-scheme split (MAL-/OSV vs GHSA) and the opaque-cursor pagination contract.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the browse summary before the source breakdown, and nearly every sentence carries new information (source distinctions, returned-flag behavior, pagination). It is a single dense paragraph with some run-on phrasing, keeping it from a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present, return values needn't be described, and the description still covers source selection, filter applicability, withdrawn-record handling, and pagination. An agent has everything needed to invoke this 8-parameter tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3, but the description adds real meaning: which sources each filter applies to (category and severity reviewed-only, malware/osv carry no CVE or meaningful CWE), and that ghsaId/cveId perform an exact single-advisory lookup. This goes beyond the per-field schema text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Browse recently published npm security advisories and known-malicious-package findings,' and breaks that down into three named source types. It is very clear on scope, but never explicitly contrasts itself with overlapping siblings such as get_cve or query_vulnerabilities, so an agent must infer the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives strong selection guidance for the type parameter and the reviewed/malware-only constraints on category, severity, and ID lookup, plus when a result may be withdrawn. It stops short of explicit when-to-use-this-vs-alternative routing against siblings like get_cve, which also does advisory lookup.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_maintainer_profileGet basic profile info for an npm maintainerARead-onlyInspect
Given an npm username, returns every package npm's own maintainer: search index currently returns for that account (registry.npmjs.org's /-/v1/search — the public registry API has no dedicated 'list packages by maintainer' endpoint otherwise), plus precomputed aggregates: currentlyMaintainsCount (still listed as maintainer right now vs. already-revoked), totalWeeklyDownloads and totalDependents summed across every returned package, and avatarUrl — a proxied Gravatar image (null if no email is on record). This is a plain info lookup — it does NOT run the publish-cluster / compromised-account detection that check_maintainer_blast_radius does; use that tool instead when the goal is a security read on whether this account's recent activity looks like a takeover, not just a profile summary. Natural pairing with check_maintainer_changes: once that tool names a maintainer on a package, call this with that maintainer's username to see the rest of what they touch. npmscanUrl is this account's profile page on npmscan itself; npmProfileUrl is the account's actual page on npmjs.com, included for verification since that's the authoritative record of the account.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | How many packages to list (default 50, max 250), most-downloaded first. Totals still cover every package found. | |
| maintainerUsername | Yes | Exact npm username, e.g. "sindresorhus" — as shown at npmjs.com/~username. Not an email address, not a package name or scope. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | Yes | |
| packages | Yes | |
| avatarUrl | Yes | |
| npmscanUrl | Yes | |
| npmProfileUrl | Yes | |
| packagesOmitted | Yes | Packages left out of `packages` by `limit`; totals and scoring still include them. |
| totalDependents | Yes | |
| packagesReturned | Yes | |
| resultsTruncated | Yes | |
| maintainerUsername | Yes | |
| totalPackagesFound | Yes | |
| totalWeeklyDownloads | Yes | |
| currentlyMaintainsCount | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only/open-world safety, but the description adds substantive behavior: the reliance on an undocumented search index endpoint, that counts distinguish currently-maintained vs. revoked packages, that avatarUrl is a proxied Gravatar and can be null, and that npmProfileUrl is the authoritative record. This is context an agent could not get from annotations or schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Dense but front-loaded, leading with the core behavior before the sibling disambiguation. Some clauses (e.g., the parenthetical about the missing registry endpoint) are lengthy, but each sentence carries distinct information rather than restating structured fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Even though an output schema exists, the description proactively explains the aggregate fields and null behavior, and it covers scope, source, and sibling routing. Nothing needed to call the tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value by explaining that limit affects only the returned list ('totals still cover every package found'), clarifying the interaction between the limit parameter and the reported aggregates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('given an npm username, returns every package...') plus the exact data source (the maintainer:<username> search index) and what aggregates come back. It explicitly differentiates itself from check_maintainer_blast_radius, so an agent can route correctly without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit when/when-not: it states it does NOT run the publish-cluster/compromised-account detection and names check_maintainer_blast_radius for security reads. It also describes a concrete workflow pairing with check_maintainer_changes, covering the main alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_packageGet npm package detailsARead-onlyInspect
Fetch npm registry metadata for a package: latest version, install scripts (preinstall/postinstall are a key risk signal), maintainers, license, recent version history, weekly downloads, GitHub stars, TypeScript support, days since last publish, a topPackagesRank (position among npm's ~100k most-downloaded packages, from npmscan's own periodically-refreshed snapshot — not live), and a downloadTrend (growing/stable/declining vs. ~3 months ago). Also checks the LATEST version against OSV.dev for known vulnerabilities — isLatestVersionVulnerable/highestSeverity give a direct safe/not-safe answer, and each finding includes severity, a summary, and the fixedVersion to upgrade to (use get_package_version or query_vulnerabilities to check a specific older version instead). If the OSV.dev query itself fails (network/timeout/upstream outage), isLatestVersionVulnerable comes back false only because the field has to be a boolean — vulnerabilityCheckFailed:true is the real signal there, and means the safe/not-safe answer is unknown, not confirmed clean. Also returns popularityTier/maintenanceTier (deterministic rule-based labels, not model-generated) and a plain-language maintenanceSummary, plus a possibleTyposquatOf flag if the name is one typo away from a top-5,000 package while itself being obscure — read deprecated and maintenanceSummary before recommending a package, since a long gap since the last release can mean either a stable/finished package or a slowing one. Includes a link to the full npmscan.com analysis page.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name, e.g. "lodash" or "@scope/name" |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| license | Yes | |
| distTags | Yes | |
| homepage | Yes | |
| keywords | Yes | |
| createdAt | Yes | |
| modifiedAt | Yes | |
| npmscanUrl | Yes | |
| repository | Yes | |
| description | Yes | |
| githubStars | Yes | |
| maintainers | Yes | |
| downloadTrend | Yes | |
| latestVersion | Yes | |
| popularityTier | Yes | |
| recentVersions | Yes | |
| hasBuiltInTypes | Yes | |
| highestSeverity | Yes | |
| maintenanceTier | Yes | |
| topPackagesRank | Yes | |
| vulnerabilities | Yes | |
| weeklyDownloads | Yes | |
| latestVersionInfo | Yes | |
| maintenanceSummary | Yes | |
| possibleTyposquatOf | Yes | |
| daysSinceLastPublish | Yes | |
| vulnerabilityCheckFailed | Yes | |
| isLatestVersionVulnerable | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the readOnly/openWorld annotations: it discloses the vulnerabilityCheckFailed failure-mode trap (false boolean is not confirmation), that topPackagesRank is a periodic snapshot not live data, that tiers are deterministic rule-based labels, and that typosquat flagging only applies when the name is obscure. These are non-obvious behavioral traits an agent could not infer from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the core purpose and field list before caveats, and every clause ties to a real output signal. It is a single dense block that is somewhat hard to scan, but given the breadth of return fields the length largely earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still adds interpretive context (vulnerability failure semantics, snapshot staleness, maintenance interpretation). Combined with annotations covering the safety profile, nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only one parameter (name) at 100% schema description coverage, so the schema already documents that it must be an exact package name including scoped names. The description adds no format or syntax detail beyond the schema, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (Fetch) and resource (npm registry metadata for a package) and enumerates the returned signals. An agent can clearly distinguish this broad package-profile tool from narrower siblings like get_package_version without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit routing: 'use get_package_version or query_vulnerabilities to check a specific older version instead.' It also advises reading deprecated/maintenanceSummary before recommending, and notes the vuln check targets only the latest version. It does not cover when to prefer siblings like compare_packages or search_packages, so it falls short of full when/when-not coverage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_package_versionGet a specific npm package versionARead-onlyInspect
Fetch registry metadata for one exact version of a package (dependencies, install scripts, tarball) AND check that exact version against OSV.dev for known vulnerabilities — isVulnerable/highestSeverity give a direct answer, and each finding includes severity, a summary, and the fixedVersion to upgrade to. Use this to check a version pinned in a lockfile rather than the latest release. If the OSV.dev query itself fails (network/timeout/upstream outage), isVulnerable comes back false only because the field has to be a boolean — vulnerabilityCheckFailed:true is the real signal there, and means the answer is unknown, not confirmed clean.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name | |
| version | Yes | Exact version string, e.g. "4.17.21", or a dist-tag such as "latest" (resolved to its exact version before the vulnerability check). Semver ranges like "^4.17.0" are not supported. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | Yes | |
| shasum | Yes | |
| license | Yes | |
| scripts | Yes | |
| tarball | Yes | |
| version | Yes | |
| deprecated | Yes | |
| npmscanUrl | Yes | |
| description | Yes | |
| dependencies | Yes | |
| isVulnerable | Yes | |
| existenceNote | Yes | |
| versionExists | Yes | false = the registry no longer lists this version but OSV still has advisories for it (e.g. unpublished for malware); registry metadata is empty then — see existenceNote. |
| highestSeverity | Yes | |
| vulnerabilities | Yes | |
| vulnerabilityCheckFailed | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare the safe read-only, open-world profile, yet the description goes further: it explains the meaning of isVulnerable, highestSeverity, severity, summary, and fixedVersion, and critically discloses a failure mode most tools hide — that vulnerabilityCheckFailed:true means the OSV query failed and the answer is unknown, not confirmed clean. That is exactly the kind of nuance structured fields cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with what the tool returns, then the when-to-use guidance, then the failure-mode caveat. It is dense but every sentence carries information an agent needs; the only slight redundancy is restating field names already visible in the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
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 need not explain return values, yet it crisply maps the key fields and closes the loop on the ambiguous failure case. For a read-only, open-world lookup tool, nothing an agent needs to call it correctly or interpret its output is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both name (exact npm package name) and version (exact version or dist-tag, semver ranges unsupported) are fully documented in the schema. The description reinforces 'exact version' but adds no syntax or format detail beyond what the schema already provides, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and two distinct resources: fetches registry metadata for one exact version AND checks that version against OSV.dev for vulnerabilities. It explicitly scopes the tool to 'one exact version' and contrasts it with 'the latest release', which separates it from get_package and the bulk query siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
'Use this to check a version pinned in a lockfile rather than the latest release' gives a clear when-to-use condition and implies the alternative to get_package. It stops short of naming a sibling tool explicitly or stating when NOT to use it (e.g. for ranges), though the schema note about unsupported semver ranges partially covers that.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_remediation_playbookGet the concrete remediation playbook for a flagged findingARead-onlyInspect
Maps a finding's rule value from analyze_install_script, check_maintainer_changes, or check_package_provenance to the matching human-authored incident-response playbook (the same content published at /docs/playbooks) and returns its concrete, ordered steps, severity tier, real-incident references, and prevention tips — not just a link. Pass the exact rule string(s) a prior finding already returned (batch up to 10 in one call to cover a whole findings array; duplicates resolving to the same playbook are deduplicated) or an id to look up a specific playbook by slug directly. Each matched rule also gets its own short situationNote explaining specifically what that rule caught — so a batch of several different rules landing on the same playbook does not read as identical, repeated boilerplate. An unrecognized rule or id is not an error — it comes back with matched:false and a note, since a low-severity or baseline-only finding (e.g. analyze_install_script's lifecycle-present) legitimately has no dedicated playbook.
| Name | Required | Description | Default |
|---|---|---|---|
| id | No | A playbook slug to look up directly, e.g. "postinstall-binary" — see /docs/playbooks | |
| rules | No | 1-10 exact `rule` values copied from findings already returned by analyze_install_script/check_maintainer_changes/check_package_provenance |
Output Schema
| Name | Required | Description |
|---|---|---|
| matches | Yes | |
| playbooks | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is clear. The description adds valuable behavioral context: batching with deduplication, situationNote per rule to avoid repeated boilerplate, and the matched:false behavior for unrecognized inputs. It also discloses that the content matches /docs/playbooks, giving the agent a confidence anchor.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place: it explains the mapping, the return payload, batching, deduplication, situationNote behavior, and error semantics. It is front-loaded with the core purpose and then layers in usage details. No filler or repetition of schema fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with 2 optional params and no required params, the description is remarkably complete. It covers input source, batching limits, deduplication, per-rule output nuance, unmatched behavior, and references the published playbook location. The output schema exists, so return values don't need to be spelled out.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema descriptions already explain both id and rules well. The description adds meaning by explaining how the two parameters relate (id for direct slug lookup, rules for batch lookup from findings), and clarifies that duplicates resolving to the same playbook are deduplicated. This goes beyond the schema's basic field descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description precisely identifies the tool's function: it maps rule values from specific sibling analysis tools to human-authored playbooks and returns ordered steps, severity tier, references, and prevention tips. It clearly distinguishes itself from siblings like prioritize_remediation and query_vulnerabilities by saying it returns actual playbook content, not just a link.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says when to use this tool: after a finding from analyze_install_script, check_maintainer_changes, or check_package_provenance, and how to batch up to 10 rules. It also explains what is not an error (unrecognized rule/id returns matched:false) and gives a concrete example of an id lookup. Alternatives are implicitly covered by naming the exact source tools, and the description clarifies the 'not just a link' distinction.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
prioritize_remediationRank a batch of flagged vulnerabilities by what to fix firstARead-onlyInspect
Rank vulnerability findings other tools already returned (batch_query_vulnerabilities, query_vulnerabilities, analyze_transitive_dependencies, diff_dependencies...) by what to fix first. Pass up to 200 {packageName, cveId?, severity?, advisoryId?, currentVersion?, fixedVersion?, findingType?}. Each gets a tier: remove-now / patch-now / patch-soon / scheduled / monitor.
How the tier is decided:
remove-now: confirmed malware —
findingType: "malware", a MAL-* advisoryId, or an advisoryId whose OSV record is a malware advisory (CWE-506 or a MAL-* alias, looked up automatically). Malware is removed, not patched. Advisories that could not be looked up are listed inmalwareCheckFailedAdvisoryIds.patch-now: on the CISA KEV list (actively exploited), whatever the severity.
otherwise a score led by FIRST.org EPSS (30-day exploitation probability), with severity as a secondary signal — or the only signal when there is no EPSS data (no CVE id). An EPSS of 10% or more always ranks at least patch-soon.
The tier is a fix-ORDER across a backlog, not a severity verdict or a merge gate: a CRITICAL CVE with low EPSS can rank monitor. Never describe a monitor/scheduled finding as "low severity", and judge whether a change that INTRODUCES a vulnerability is acceptable by its severity, not this tier.
| Name | Required | Description | Default |
|---|---|---|---|
| findings | Yes | 1-200 previously-flagged vulnerability findings to rank |
Output Schema
| Name | Required | Description |
|---|---|---|
| ranked | Yes | |
| summary | Yes | |
| totalFindings | Yes | |
| uniqueCveCount | Yes | |
| malwareCheckFailedAdvisoryIds | Yes | advisoryIds whose OSV record could not be fetched, so whether they are malware is unknown — not confirmed safe. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover the safety profile (readOnly, non-destructive), and the description adds substantial behavior the annotations cannot: the full tier taxonomy (remove-now/patch-now/patch-soon/scheduled/monitor), the inputs that drive each tier (KEV, EPSS ≥10%, malware detection via MAL-*/CWE-506), and a failure-mode output (malwareCheckFailedAdvisoryIds). This is unusually rich behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with purpose, then a clearly labeled 'How the tier is decided' block, then caveats. Structure is excellent. It is somewhat long and the malware/remove-now rule is restated in both the tier bullets and the schema, but no sentence is wasted relative to the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with an output schema (so return shape needn't be explained) and full schema coverage, the description supplies everything an agent needs: what it consumes, how each tier is derived, the meaning of the output tiers, and explicit guidance on how NOT to interpret them. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the per-field baseline would be 3. The description goes beyond the schema by explaining how fields interact with outcomes — findingType/advisorId triggering remove-now, EPSS being the primary signal and severity the fallback, and the 200-item cap. That cross-field semantic layer is real added value over the schema's per-property text.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (rank) and resource (vulnerability findings) with explicit scope: it consumes output other tools already returned, and it names those siblings (batch_query_vulnerabilities, query_vulnerabilities, etc.). An agent can tell it apart from the query tools it depends on without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says this operates on findings 'other tools already returned' and lists them, so the agent knows not to call it for fresh scanning. It also gives a strong when-NOT-to-use caveat: the tier is a fix-order across a backlog, not a severity verdict or merge gate, with concrete misuse warnings (don't call monitor findings 'low severity').
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
query_vulnerabilitiesQuery known vulnerabilities for a packageARead-onlyInspect
Query OSV.dev for known vulnerabilities affecting an npm package, optionally scoped to one exact version (e.g. to check whether a version pinned in a lockfile is safe). Returns isVulnerable and highestSeverity as a direct answer, plus each finding's severity, a plain-language summary, CVE aliases, and the fixedVersion to upgrade to — not a raw advisory dump. Also cross-checks the name/version against the npm registry: isVulnerable:false on a package that does not actually exist there (typo, wrong ecosystem) would otherwise look identical to a genuinely clean result — see packageExists/existenceCheckNote. A name or version not found on the registry does NOT discard already-fetched OSV data or short-circuit into an error: OSV/GHSA advisory data is independent of the package's current registry listing, and a package/version pulled from npm for being malicious (unpublished/yanked) is exactly the case where real vulnerability data must still be reported, not hidden behind a 404. Use before recommending, installing, or upgrading a package.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | npm package name (required; `packageName` is accepted as an alias) | |
| version | No | Optional exact version to narrow results, e.g. to check one version pinned in a lockfile. For the npm ecosystem a dist-tag such as "latest" is also accepted and resolved to its exact version first; semver ranges like "^4.17.0" are rejected. | |
| ecosystem | No | OSV ecosystem, default "npm" | |
| packageName | No | Alias for `name`, matching simulate_dependency_upgrade/prioritize_remediation |
Output Schema
| Name | Required | Description |
|---|---|---|
| package | Yes | |
| version | Yes | |
| npmscanUrl | Yes | npmscan package page; null for a non-npm ecosystem. |
| isVulnerable | Yes | |
| packageExists | Yes | |
| highestSeverity | Yes | |
| vulnerabilities | Yes | |
| existenceCheckNote | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With readOnlyHint/openWorldHint already declaring the safety profile, the description still adds real behavioral context: it enumerates the response fields (isVulnerable, highestSeverity, severity, summary, CVE aliases, fixedVersion), discloses the npm-registry cross-check and the packageExists/existenceCheckNote flag, and explicitly documents the non-obvious non-error behavior when a package is unpublished/yanked. This is richer than the annotations and prevents a plausible misreading of isVulnerable:false.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and return shape are front-loaded well, but the middle passage about registry misses is long and restates the same point twice ('does NOT discard already-fetched OSV data' vs. 'data must still be reported, not hidden behind a 404'). It reads as defensive prose rather than tight specification.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a four-parameter read tool with annotations and an output schema, nothing needed to call it correctly is missing: scope, version semantics, registry cross-check, and the not-found edge case are all covered. Return-value details are summarized rather than required, which is acceptable given the output schema exists.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents name/packageName aliasing, version format rules, and the ecosystem default. The description adds the motivating intent for the version parameter (lockfile safety check) but no format or behavioral detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (query OSV.dev for known vulnerabilities) and the exact scope (npm package, optionally one exact version), which cleanly separates it from siblings like batch_query_vulnerabilities and get_cve. The parenthetical about lockfile version checks makes the intended granularity unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says when to use it: 'Use before recommending, installing, or upgrading a package,' and gives a concrete scenario for the version parameter. It does not name the alternative sibling tools (e.g. batch_query_vulnerabilities for multi-package sweeps, get_cve for a direct CVE lookup), so routing is clear but not fully disambiguated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_packagesSearch npm packagesARead-onlyInspect
Search the npm registry by name or keywords. Each result includes its current weekly/monthly download counts, dependentsCount (how many other npm packages depend on it), topPackagesRank (position among npmscan's own top-100k-by-downloads snapshot — not live, but a second independent popularity signal), and deterministic (not model-generated) popularityTier/maintenanceTier labels — a package matching the query with a 'very-low' popularityTier, zero dependents, or a 'stale' maintenanceTier is very likely an abandoned, copy-paste, or squatted package, not a real contender, regardless of how relevant its name/description look. A result may also carry possibleTyposquatOf — set when its name is one typo away (e.g. 'raect' vs 'react') from a top-5,000 package while itself having very low popularity; treat that as a red flag to call out explicitly, not silently filter. Use these (not name recognition or the package's own README) to judge which candidates are actually established, and call get_package on your shortlist for install-script risk, TypeScript support, and GitHub stars before recommending one. Includes a link to each package's full npmscan.com risk/analysis page.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max results to return (default 20, max 50) | |
| query | Yes | Search text, e.g. a package name or keywords |
Output Schema
| Name | Required | Description |
|---|---|---|
| query | Yes | |
| total | Yes | |
| results | Yes | |
| queryNote | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only state readOnly/openWorld/non-destructive; the description adds substantial behavioral context beyond them — the exact result fields, that topPackagesRank is a non-live snapshot, that popularityTier/maintenanceTier are deterministic rather than model-generated, and how to interpret 'very-low'/'stale'/zero-dependents packages. It also flags the possibleTyposquatOf red flag and warns against silently filtering, which is genuinely operational guidance.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose is front-loaded in the first sentence and every subsequent clause carries interpretive value. It is dense and runs long as a single block, with the get_package follow-up advice buried mid-paragraph, so it loses a point on structure rather than on waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, yet the description still supplies the interpretation layer an agent actually needs (how to read tiers, dependents, typosquat flags). For a two-param search entrypoint, nothing required to call or use it is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so query and limit are already documented in the schema (including the default 20 / max 50 for limit). The description only paraphrases 'by name or keywords' and adds no extra syntax, format, or edge-case meaning, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a specific verb+resource: 'Search the npm registry by name or keywords.' It is clearly distinguishable from siblings like compare_packages or get_package, and it explicitly frames itself as the candidate-discovery step that feeds get_package.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives clear usage context: use the returned tiers/dependents/typosquat signals rather than name recognition to judge candidates, then 'call get_package on your shortlist for install-script risk, TypeScript support, and GitHub stars before recommending one.' It also advises calling out typosquat hits instead of filtering them. It stops short of naming an explicit alternative search tool or a when-not-to-use condition.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
simulate_dependency_upgradeSimulate an npm dependency upgradeARead-onlyInspect
Before running npm install, check whether upgrading a package from a current to a target version is safe. Pass packageName + currentVersion + targetVersion (omit target for "latest"), or packages: [...] (1-100) to check many in one call; a name that cannot be resolved comes back with fetchError instead of failing the batch. A natural follow-up to prioritize_remediation: pass its packageName/currentVersion/fixedVersion straight in.
What it checks:
semver jump (major/minor/patch/prerelease; a 0.x minor bump counts as breaking; skipped majors are flagged)
registry signals on the target: deprecated, a newly added preinstall/install/postinstall script (
installScriptIntroduced; a newprepareis listed ininstallScriptKeysIntroducedbut never runs on a registry install), a tightened engines.node, prereleaseOSV for both versions:
vulnerabilityDelta(introduced/fixed/still-vulnerable/still-clean) andtargetVulnerabilitieswith isMalware — catching a "fix" that does not clear every CVE
Result: one riskTier — safe / low-risk / review-recommended / breaking-change-likely / unknown / do-not-upgrade — with reasons. do-not-upgrade means the target is known malware, or npm no longer lists it while OSV still has advisories for it (how npm removes malicious releases). It does not read changelogs or diff source; it is a fast pre-check, not a substitute for release notes on a major bump.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Alias for `packageName`, matching the other tools | |
| packages | No | Batch of upgrades to simulate (1-100 items), each mirroring the single-item packageName/currentVersion/targetVersion fields. Use this OR packageName/currentVersion, not both. Natural pairing with prioritize_remediation: pass its ranked findings straight in as one call instead of one simulate_dependency_upgrade call per finding. | |
| packageName | No | Exact npm package name, e.g. "lodash" or "@scope/name". Use this (with currentVersion) OR `packages`, not both. | |
| targetVersion | No | Version to simulate upgrading to — exact version, range, or dist-tag (e.g. the fixedVersion a prioritize_remediation finding named). Omit to use the registry's "latest" dist-tag. Only applies to the single-item `packageName` form. | |
| currentVersion | No | Currently installed version — an exact version (e.g. "4.17.20"), a semver range (e.g. "^4.17.0"), or a dist-tag. Required when `packageName` is used. |
Output Schema
| Name | Required | Description |
|---|---|---|
| reasons | No | |
| results | No | |
| verdict | No | |
| riskTier | No | |
| direction | No | |
| npmscanUrl | No | |
| semverBump | No | |
| packageName | No | |
| batchSummary | No | |
| engineChange | No | |
| zeroMajorNote | No | |
| targetDeprecated | No | |
| targetVersionNote | No | |
| currentVersionNote | No | |
| isBreakingBySemver | No | |
| targetIsPrerelease | No | |
| targetIsVulnerable | No | |
| vulnerabilityDelta | No | |
| currentIsVulnerable | No | |
| majorVersionsSkipped | No | |
| resolvedTargetVersion | No | |
| targetVulnerabilities | No | |
| requestedTargetVersion | No | |
| resolvedCurrentVersion | No | |
| vulnerabilityCheckNote | No | Set when the OSV check was incomplete (query failed, or advisories came back id-only with no severity/malware flag) — treat the vulnerability fields as unverified. |
| installScriptIntroduced | No | |
| requestedCurrentVersion | No | |
| installScriptKeysIntroduced | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only declare readOnly/openWorld/non-destructive; the description adds substantial behavior beyond that: batch failure semantics (a name that can't resolve returns `fetchError` rather than failing the batch), the six-value riskTier vocabulary, what triggers `do-not-upgrade` (known malware or npm delisting a release OSV still flags), and nuances like a new `prepare` script never running on a registry install.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded call instructions in the first paragraph, then a clearly headed 'What it checks' list and a result summary — well organized and scannable. It is on the long side and some registry-signal detail borders on documentation rather than selection guidance, keeping it just short of a 5.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite a rich output schema, the description still names the single result field (riskTier), its enum values, and the accompanying `reasons`, so an agent knows what to expect. Combined with the check list and failure mode, nothing needed to invoke or interpret the tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents aliases, ranges, dist-tags and mutual exclusivity, so the baseline is 3. The description still adds value the schema lacks: the prioritize_remediation field mapping, the 1-100 batch size rationale, and 'omit target for latest' framing in the entry sentence.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: simulate whether upgrading a package from current to target version is safe before running npm install. It explicitly distinguishes itself from siblings by framing it as a fast pre-check ('not a substitute for release notes on a major bump') and naming prioritize_remediation as the upstream tool it complements.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit invocation conditions (before npm install), tells the agent how to feed prioritize_remediation output straight in (packageName/currentVersion/fixedVersion), and documents both the single-item and batch forms with their mutual exclusivity. It also states the boundary of applicability — no changelog or source diffing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
suggest_alternativeSuggest better-maintained npm alternativesARead-onlyInspect
Given a package that looks deprecated, vulnerable, abandoned, or suspicious, suggest better-maintained alternatives in the same category. This tool first checks the source package's own latest-version health (deprecation, latest-version OSV verdict, popularity/maintenance tiers, typosquat flag), then combines maintainer-provided deprecation hints with deterministic npm search-based category matching. It ranks candidates using category overlap plus search_packages-style popularity/maintenance signals, filters out typosquats and weak/stale contenders, and returns a short list with plain-language whySuggested notes. A candidate is also never suggested if it's deprecated, has a confirmed HIGH/CRITICAL OSV vulnerability, or its own OSV check itself failed (network/timeout/upstream outage) — an unverifiable candidate is excluded the same as a confirmed-bad one, not defaulted to 'looks fine', since this tool's entire purpose is not recommending something dangerous. Best for turning a 'don't use this package' warning into an actionable replacement shortlist. If the OSV.dev vulnerability check fails for the SOURCE package (as opposed to a candidate, which gets excluded per above), source.isLatestVersionVulnerable comes back false only because the field has to be a boolean — source.vulnerabilityCheckFailed:true is the real signal there, and means that safe/not-safe answer is unknown, not confirmed clean.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name, e.g. "request" or "node-sass" | |
| limit | No | Max suggestions to return (default 5, max 10) | |
| reason | No | Optional reason to bias filtering/ranking |
Output Schema
| Name | Required | Description |
|---|---|---|
| reason | Yes | |
| source | Yes | |
| confidence | Yes | |
| suggestions | Yes | |
| categoryTokens | Yes | |
| searchedQueries | Yes | |
| nonPackageAlternatives | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and non-destructiveness, but the description goes far beyond that. It discloses critical behavioral nuances: unverifiable candidates are excluded rather than defaulting to safe, the source's vulnerabilityCheckFailed flag is the real signal (since isLatestVersionVulnerable returns false as a placeholder), and the ranking/filtering criteria. This is essential for an agent to interpret results correctly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but every sentence earns its place. It opens with the core purpose, then explains the methodology, then the best-use case, and finally a crucial caveat about vulnerability-check failure. The structure is logical and front-loaded with the primary action, making it easy for an agent to parse and apply.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the tool being read-only and having an output schema, the description covers exceptional cases like OSV check failures and candidate exclusion. It explains what the output contains (short list with whySuggested notes) and why certain candidates are never suggested. For a tool with this complexity, the description is exceptionally complete and leaves no critical gaps for correct invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description does not add much parameter-specific detail beyond what the schema already provides. It references the 'name' parameter as the source package and mentions the 'limit' implicitly in 'Max suggestions,' but these are already in the schema. The description's value is in process explanation, not parameter meanings.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states the exact purpose: given a problematic package, suggest better-maintained alternatives in the same category. It clearly distinguishes this from sibling tools by highlighting the category-matching and safety-filtering behavior, and explicitly frames it as turning a 'don't use' warning into a replacement shortlist.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description includes 'Best for turning a ... warning into an actionable replacement shortlist,' which gives clear usage context. It also explains the internal decision logic but does not explicitly name alternative sibling tools or say when NOT to use it (e.g., when you just want to search packages). Still, it provides enough situational guidance for an agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
- Changed
get_latest_advisories1 field changed- changed
Output schema / properties / note / descriptionPrevious value: -"What this feed covers (set for type \"osv\": its snapshot date, and that malware with a GitHub advisory is listed under \"malware\"/\"reviewed\" instead)."New value: +"What this feed covers (set for type \"osv\": its snapshot date, that malware with a GitHub advisory is listed under \"malware\"/\"reviewed\" instead, and how many entries came back id-only because their OSV detail fetch failed)."
- Changed
simulate_dependency_upgrade4 fields changed- added
Output schema / properties / batchSummary / properties / advisoryDetailFailedCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / batchSummary / properties / vulnerabilityCheckNoteAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / batchSummary / requiredPrevious value: -[ - "totalRequested", - "fetchFailedCount", - "riskTierCounts", - "vulnQueryFailedCount" -]New value: +[ + "totalRequested", + "fetchFailedCount", + "riskTierCounts", + "vulnQueryFailedCount", + "advisoryDetailFailedCount", + "vulnerabilityCheckNote" +] - added
Output schema / properties / vulnerabilityCheckNoteAdded value: +{ + "description": "Set when the OSV check was incomplete (query failed, or advisories came back id-only with no severity/malware flag) — treat the vulnerability fields as unverified.", + "type": [ + "string", + "null" + ] +}
2 tool updates
- Changed
get_latest_advisories2 fields changed- added
Output schema / properties / noteAdded value: +{ + "description": "What this feed covers (set for type \"osv\": its snapshot date, and that malware with a GitHub advisory is listed under \"malware\"/\"reviewed\" instead).", + "type": [ + "string", + "null" + ] +} - changed
Output schema / requiredPrevious value: -[ - "type", - "severity", - "category", - "direction", - "nextCursor", - "advisories" -]New value: +[ + "type", + "severity", + "category", + "direction", + "nextCursor", + "note", + "advisories" +]
- Changed
search_packages2 fields changed- added
Output schema / properties / queryNoteAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / requiredPrevious value: -[ - "query", - "total", - "results" -]New value: +[ + "query", + "queryNote", + "total", + "results" +]
5 tool updates
- Changed
audit_github_repository3 fields changed- added
Output schema / properties / cleanFindingsAdded value: +{ + "description": "Detailed packages with nothing flagged, listed compactly. Together with `findings` these are the `totalPackages` packages that got full detail.", + "items": { + "additionalProperties": false, + "properties": { + "license": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": "string" + }, + "version": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "name", + "version", + "license" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / findings / descriptionAdded value: +"Detailed packages with something to report (vulnerable, unchecked, license issue, install-script/ownership signal, typosquat, deprecated)." - changed
Output schema / requiredPrevious value: -[ - "summary", - "owner", - "repoName", - "ref", - "defaultBranchUsed", - "manifestPath", - "lockfilePath", - "inputFormat", - "isMonorepo", - "workspacePatterns", - "workspacePackageCount", - "workspaceNote", - "policy", - "findings", - "coverage", - "overflowPackages", - "overflowPackageCount", - "overflowVulnerablePackages", - "totalPackages", - "vulnerablePackageCount", - "licenseViolationCount", - "installScriptFlaggedCount", - "deepScannedCount", - "ownershipCheckedCount", - "ownershipRiskFlaggedCount", - "warnings", - "truncationNote", - "deepScanNote", - "ownershipCheckNote" -]New value: +[ + "summary", + "owner", + "repoName", + "ref", + "defaultBranchUsed", + "manifestPath", + "lockfilePath", + "inputFormat", + "isMonorepo", + "workspacePatterns", + "workspacePackageCount", + "workspaceNote", + "policy", + "findings", + "cleanFindings", + "coverage", + "overflowPackages", + "overflowPackageCount", + "overflowVulnerablePackages", + "totalPackages", + "vulnerablePackageCount", + "licenseViolationCount", + "installScriptFlaggedCount", + "deepScannedCount", + "ownershipCheckedCount", + "ownershipRiskFlaggedCount", + "warnings", + "truncationNote", + "deepScanNote", + "ownershipCheckNote" +]
- Changed
check_maintainer_blast_radius3 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "How many packages to list (default 50, max 250), most-downloaded first. Totals still cover every package found.", + "maximum": 250, + "minimum": 1, + "type": "integer" +} - added
Output schema / properties / packagesOmittedAdded value: +{ + "description": "Packages left out of `packages` by `limit`; totals and scoring still include them.", + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "maintainerUsername", - "npmscanUrl", - "npmProfileUrl", - "avatarUrl", - "totalPackagesFound", - "packagesReturned", - "resultsTruncated", - "clusterWindowHours", - "packages", - "clusters", - "findings", - "totalScore", - "riskTier", - "note" -]New value: +[ + "maintainerUsername", + "npmscanUrl", + "npmProfileUrl", + "avatarUrl", + "totalPackagesFound", + "packagesReturned", + "resultsTruncated", + "packagesOmitted", + "clusterWindowHours", + "packages", + "clusters", + "findings", + "totalScore", + "riskTier", + "note" +]
- Changed
get_maintainer_profile3 fields changed- added
Input schema / properties / limitAdded value: +{ + "description": "How many packages to list (default 50, max 250), most-downloaded first. Totals still cover every package found.", + "maximum": 250, + "minimum": 1, + "type": "integer" +} - added
Output schema / properties / packagesOmittedAdded value: +{ + "description": "Packages left out of `packages` by `limit`; totals and scoring still include them.", + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "maintainerUsername", - "npmscanUrl", - "npmProfileUrl", - "avatarUrl", - "totalPackagesFound", - "packagesReturned", - "resultsTruncated", - "currentlyMaintainsCount", - "totalWeeklyDownloads", - "totalDependents", - "packages", - "note" -]New value: +[ + "maintainerUsername", + "npmscanUrl", + "npmProfileUrl", + "avatarUrl", + "totalPackagesFound", + "packagesReturned", + "resultsTruncated", + "packagesOmitted", + "currentlyMaintainsCount", + "totalWeeklyDownloads", + "totalDependents", + "packages", + "note" +]
- Changed
query_vulnerabilities5 fields changed- changed
Input schema / properties / name / descriptionPrevious value: -"npm package name"New value: +"npm package name (required; `packageName` is accepted as an alias)" - added
Input schema / properties / packageNameAdded value: +{ + "description": "Alias for `name`, matching simulate_dependency_upgrade/prioritize_remediation", + "maxLength": 214, + "minLength": 1, + "type": "string" +} - removed
Input schema / requiredRemoved value: -[ - "name" -] - added
Output schema / properties / npmscanUrl / descriptionAdded value: +"npmscan package page; null for a non-npm ecosystem." - changed
Output schema / properties / npmscanUrl / typePrevious value: -"string"New value: +[ + "string", + "null" +]
- Changed
simulate_dependency_upgrade1 field changed- added
Input schema / properties / nameAdded value: +{ + "description": "Alias for `packageName`, matching the other tools", + "maxLength": 214, + "minLength": 1, + "type": "string" +}
9 tool updates
- Changed
analyze_transitive_dependencies2 fields changed- added
Output schema / properties / nodes / items / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / nodes / items / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +]
- Changed
audit_github_repository7 fields changed- added
Output schema / properties / coverageAdded value: +{ + "additionalProperties": false, + "description": "How much of the dependency set was actually checked — read this before calling a repo clean.", + "properties": { + "complete": { + "type": "boolean" + }, + "detailedCount": { + "type": "number" + }, + "localPackagesSkipped": { + "type": "number" + }, + "totalPackages": { + "type": "number" + }, + "vulnerabilityCheckedCount": { + "type": "number" + } + }, + "required": [ + "totalPackages", + "detailedCount", + "vulnerabilityCheckedCount", + "localPackagesSkipped", + "complete" + ], + "type": "object" +} - added
Output schema / properties / findings / items / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / findings / items / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +] - added
Output schema / properties / overflowPackageCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / overflowVulnerablePackagesAdded value: +{ + "items": { + "additionalProperties": false, + "properties": { + "highestSeverity": { + "type": [ + "string", + "null" + ] + }, + "isMalware": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "version": { + "type": "string" + }, + "vulnerabilityIds": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "name", + "version", + "highestSeverity", + "isMalware", + "vulnerabilityIds" + ], + "type": "object" + }, + "type": "array" +} - added
Output schema / properties / vulnerablePackageCount / descriptionAdded value: +"Vulnerable packages across every vulnerability-checked entry, not just `findings`." - changed
Output schema / requiredPrevious value: -[ - "summary", - "owner", - "repoName", - "ref", - "defaultBranchUsed", - "manifestPath", - "lockfilePath", - "inputFormat", - "isMonorepo", - "workspacePatterns", - "workspacePackageCount", - "workspaceNote", - "policy", - "findings", - "overflowPackages", - "totalPackages", - "vulnerablePackageCount", - "licenseViolationCount", - "installScriptFlaggedCount", - "deepScannedCount", - "ownershipCheckedCount", - "ownershipRiskFlaggedCount", - "warnings", - "truncationNote", - "deepScanNote", - "ownershipCheckNote" -]New value: +[ + "summary", + "owner", + "repoName", + "ref", + "defaultBranchUsed", + "manifestPath", + "lockfilePath", + "inputFormat", + "isMonorepo", + "workspacePatterns", + "workspacePackageCount", + "workspaceNote", + "policy", + "findings", + "coverage", + "overflowPackages", + "overflowPackageCount", + "overflowVulnerablePackages", + "totalPackages", + "vulnerablePackageCount", + "licenseViolationCount", + "installScriptFlaggedCount", + "deepScannedCount", + "ownershipCheckedCount", + "ownershipRiskFlaggedCount", + "warnings", + "truncationNote", + "deepScanNote", + "ownershipCheckNote" +]
- Changed
batch_query_vulnerabilities2 fields changed- added
Output schema / properties / results / items / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / results / items / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +]
- Changed
diff_dependencies7 fields changed- changed
Output schema / properties / added / items / properties / changeType / anyOfPrevious value: -[ - { - "enum": [ - "upgrade", - "downgrade", - "unresolved" - ], - "type": "string" - }, - { - "type": "null" - } -]New value: +[ + { + "enum": [ + "upgrade", + "downgrade", + "unresolved", + "source-swap" + ], + "type": "string" + }, + { + "type": "null" + } +] - added
Output schema / properties / added / items / properties / identityMismatchAdded value: +{ + "description": "The lockfile tarball is a different package/version than declared; tarballName/tarballVersion say what is really installed, and the vulnerability fields describe that.", + "type": [ + "boolean", + "null" + ] +} - added
Output schema / properties / added / items / properties / tarballNameAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / added / items / properties / tarballVersionAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / added / items / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / added / items / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +] - changed
Output schema / properties / added / items / requiredPrevious value: -[ - "name", - "actualName", - "npmscanUrl", - "beforeVersion", - "afterVersion", - "coexistingVersions", - "changeType", - "hasInstallScript", - "installScriptIntroduced", - "installScriptKeys", - "installScriptKeysIntroduced", - "sourceIntegrityChanged", - "resolvedUrl", - "integrity", - "isVulnerable", - "highestSeverity", - "vulnerabilities", - "vulnerabilityDelta", - "resolutionNote" -]New value: +[ + "name", + "actualName", + "npmscanUrl", + "beforeVersion", + "afterVersion", + "coexistingVersions", + "changeType", + "hasInstallScript", + "installScriptIntroduced", + "installScriptKeys", + "installScriptKeysIntroduced", + "sourceIntegrityChanged", + "identityMismatch", + "tarballName", + "tarballVersion", + "resolvedUrl", + "integrity", + "isVulnerable", + "highestSeverity", + "vulnerabilities", + "vulnerabilityDelta", + "resolutionNote" +]
- Changed
get_package2 fields changed- added
Output schema / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +]
- Changed
get_package_version5 fields changed- added
Output schema / properties / existenceNoteAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / versionExistsAdded value: +{ + "description": "false = the registry no longer lists this version but OSV still has advisories for it (e.g. unpublished for malware); registry metadata is empty then — see existenceNote.", + "type": "boolean" +} - added
Output schema / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +] - changed
Output schema / requiredPrevious value: -[ - "name", - "version", - "description", - "license", - "dependencies", - "scripts", - "deprecated", - "tarball", - "shasum", - "npmscanUrl", - "isVulnerable", - "vulnerabilityCheckFailed", - "highestSeverity", - "vulnerabilities" -]New value: +[ + "name", + "version", + "description", + "license", + "dependencies", + "scripts", + "deprecated", + "tarball", + "shasum", + "npmscanUrl", + "versionExists", + "existenceNote", + "isVulnerable", + "vulnerabilityCheckFailed", + "highestSeverity", + "vulnerabilities" +]
- Changed
prioritize_remediation3 fields changed- changed
Input schema / properties / findings / items / properties / advisoryId / descriptionPrevious value: -"GHSA/OSV advisory id, passed through unchanged for reference — a MAL-* id is auto-detected as malware even without findingType set"New value: +"GHSA/OSV advisory id — looked up on OSV.dev: a MAL-* id, or a GHSA whose record is a malware advisory (CWE-506 / MAL-* alias), is auto-detected as malware even without findingType set" - added
Output schema / properties / malwareCheckFailedAdvisoryIdsAdded value: +{ + "description": "advisoryIds whose OSV record could not be fetched, so whether they are malware is unknown — not confirmed safe.", + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / requiredPrevious value: -[ - "totalFindings", - "uniqueCveCount", - "summary", - "ranked" -]New value: +[ + "totalFindings", + "uniqueCveCount", + "summary", + "ranked", + "malwareCheckFailedAdvisoryIds" +]
- Changed
query_vulnerabilities2 fields changed- added
Output schema / properties / vulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / vulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +]
- Changed
simulate_dependency_upgrade10 fields changed- added
Output schema / properties / batchSummary / properties / riskTierCounts / properties / doNotUpgradeAdded value: +{ + "type": "number" +} - changed
Output schema / properties / batchSummary / properties / riskTierCounts / requiredPrevious value: -[ - "safe", - "lowRisk", - "reviewRecommended", - "breakingChangeLikely", - "unknown" -]New value: +[ + "safe", + "lowRisk", + "reviewRecommended", + "breakingChangeLikely", + "unknown", + "doNotUpgrade" +] - added
Output schema / properties / installScriptKeysIntroducedAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / results / items / properties / installScriptIntroduced / descriptionAdded value: +"A preinstall/install/postinstall script is new in the target (prepare excluded: it never runs on a registry install)." - added
Output schema / properties / results / items / properties / installScriptKeysIntroducedAdded value: +{ + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "description": "Every lifecycle key new in the target, prepare included." +} - changed
Output schema / properties / results / items / properties / riskTier / enumPrevious value: -[ - "safe", - "low-risk", - "review-recommended", - "breaking-change-likely", - "unknown" -]New value: +[ + "safe", + "low-risk", + "review-recommended", + "breaking-change-likely", + "unknown", + "do-not-upgrade" +] - changed
Output schema / properties / results / items / requiredPrevious value: -[ - "packageName", - "npmscanUrl", - "requestedCurrentVersion", - "requestedTargetVersion", - "resolvedCurrentVersion", - "resolvedTargetVersion", - "currentVersionNote", - "targetVersionNote", - "direction", - "semverBump", - "isBreakingBySemver", - "majorVersionsSkipped", - "zeroMajorNote", - "targetIsPrerelease", - "targetDeprecated", - "installScriptIntroduced", - "engineChange", - "currentIsVulnerable", - "targetIsVulnerable", - "vulnerabilityDelta", - "targetVulnerabilities", - "riskTier", - "reasons", - "verdict", - "fetchError" -]New value: +[ + "packageName", + "npmscanUrl", + "requestedCurrentVersion", + "requestedTargetVersion", + "resolvedCurrentVersion", + "resolvedTargetVersion", + "currentVersionNote", + "targetVersionNote", + "direction", + "semverBump", + "isBreakingBySemver", + "majorVersionsSkipped", + "zeroMajorNote", + "targetIsPrerelease", + "targetDeprecated", + "installScriptIntroduced", + "installScriptKeysIntroduced", + "engineChange", + "currentIsVulnerable", + "targetIsVulnerable", + "vulnerabilityDelta", + "targetVulnerabilities", + "riskTier", + "reasons", + "verdict", + "fetchError" +] - changed
Output schema / properties / riskTier / enumPrevious value: -[ - "safe", - "low-risk", - "review-recommended", - "breaking-change-likely", - "unknown" -]New value: +[ + "safe", + "low-risk", + "review-recommended", + "breaking-change-likely", + "unknown", + "do-not-upgrade" +] - added
Output schema / properties / targetVulnerabilities / items / properties / isMalwareAdded value: +{ + "description": "Confirmed-malicious package (MAL-* id/alias or CWE-506), not an ordinary vulnerability: remove it, do not patch.", + "type": "boolean" +} - changed
Output schema / properties / targetVulnerabilities / items / requiredPrevious value: -[ - "id", - "summary", - "severity", - "aliases", - "publishedAt", - "fixedVersion", - "npmscanUrl" -]New value: +[ + "id", + "summary", + "severity", + "aliases", + "publishedAt", + "fixedVersion", + "isMalware", + "npmscanUrl" +]
1 tool update
- Changed
compare_packages1 field changed- changed
Input schema / properties / packages / descriptionPrevious value: -"2-5 exact npm package names to compare, e.g. [\"axios\", \"got\", \"node-fetch\"]."New value: +"2-5 exact npm package names to compare, e.g. [\"axios\", \"got\", \"node-fetch\"]. More than 5 is rejected with an error, not truncated."
2 tool updates
- Changed
get_package_version1 field changed- changed
Input schema / properties / version / descriptionPrevious value: -"Exact version string, e.g. \"4.17.21\""New value: +"Exact version string, e.g. \"4.17.21\", or a dist-tag such as \"latest\" (resolved to its exact version before the vulnerability check). Semver ranges like \"^4.17.0\" are not supported."
- Changed
query_vulnerabilities1 field changed- changed
Input schema / properties / version / descriptionPrevious value: -"Optional exact version to narrow results, e.g. to check one version pinned in a lockfile"New value: +"Optional exact version to narrow results, e.g. to check one version pinned in a lockfile. For the npm ecosystem a dist-tag such as \"latest\" is also accepted and resolved to its exact version first; semver ranges like \"^4.17.0\" are rejected."
2 tool updates
- Changed
batch_query_vulnerabilities2 fields changed- added
Output schema / properties / results / items / properties / registryStatusAdded value: +{ + "enum": [ + "found", + "package-not-found", + "version-not-found", + "unchecked" + ], + "type": "string" +} - changed
Output schema / properties / results / items / requiredPrevious value: -[ - "package", - "npmscanUrl", - "scanStatus", - "vulnerabilityCount", - "advisoryCount", - "uniqueVulnerabilityCount", - "vulnerabilities", - "signals", - "source" -]New value: +[ + "package", + "npmscanUrl", + "scanStatus", + "registryStatus", + "vulnerabilityCount", + "advisoryCount", + "uniqueVulnerabilityCount", + "vulnerabilities", + "signals", + "source" +]
- Changed
get_latest_advisories2 fields changed- added
Output schema / properties / advisories / items / properties / withdrawnAtAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / advisories / items / requiredPrevious value: -[ - "id", - "cve", - "summary", - "severity", - "publishedAt", - "ghsaUrl", - "npmscanUrl", - "cwes", - "categories", - "packages" -]New value: +[ + "id", + "cve", + "summary", + "severity", + "publishedAt", + "withdrawnAt", + "ghsaUrl", + "npmscanUrl", + "cwes", + "categories", + "packages" +]
1 tool update
- Changed
enrich_npm_audit5 fields changed- added
Output schema / properties / ranked / items / properties / findingTypeAdded value: +{ + "enum": [ + "malware", + "vulnerability", + "supply-chain", + "install-script" + ], + "type": "string" +} - changed
Output schema / properties / ranked / items / properties / tier / enumPrevious value: -[ - "patch-now", - "patch-soon", - "scheduled", - "monitor" -]New value: +[ + "remove-now", + "patch-now", + "patch-soon", + "scheduled", + "monitor" +] - changed
Output schema / properties / ranked / items / requiredPrevious value: -[ - "rank", - "packageName", - "cveId", - "advisoryId", - "advisoryTitle", - "currentVersion", - "fixedVersion", - "severity", - "kev", - "epss", - "score", - "tier", - "reason", - "npmscanUrl", - "cveNpmscanUrl", - "isDirect", - "fixAvailable", - "fixTarget" -]New value: +[ + "rank", + "packageName", + "cveId", + "advisoryId", + "currentVersion", + "fixedVersion", + "severity", + "kev", + "epss", + "score", + "tier", + "findingType", + "reason", + "npmscanUrl", + "cveNpmscanUrl", + "advisoryTitle", + "isDirect", + "fixAvailable", + "fixTarget" +] - added
Output schema / properties / summary / properties / removeNowAdded value: +{ + "type": "number" +} - changed
Output schema / properties / summary / requiredPrevious value: -[ - "patchNow", - "patchSoon", - "scheduled", - "monitor", - "kevListedCount" -]New value: +[ + "removeNow", + "patchNow", + "patchSoon", + "scheduled", + "monitor", + "kevListedCount" +]
1 tool update
- Changed
batch_query_vulnerabilities1 field changed- changed
Output schema / properties / results / items / properties / source / anyOfPrevious value: -[ - { - "additionalProperties": false, - "properties": { - "integrity": { - "type": [ - "string", - "null" - ] - }, - "nonRegistryHost": { - "type": [ - "boolean", - "null" - ] - }, - "resolvedUrl": { - "type": [ - "string", - "null" - ] - } - }, - "required": [ - "resolvedUrl", - "integrity", - "nonRegistryHost" - ], - "type": "object" - }, - { - "type": "null" - } -]New value: +[ + { + "additionalProperties": false, + "properties": { + "identityMismatch": { + "type": [ + "boolean", + "null" + ] + }, + "integrity": { + "type": [ + "string", + "null" + ] + }, + "nonRegistryHost": { + "type": [ + "boolean", + "null" + ] + }, + "resolvedName": { + "type": [ + "string", + "null" + ] + }, + "resolvedUrl": { + "type": [ + "string", + "null" + ] + }, + "resolvedVersion": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "resolvedUrl", + "integrity", + "nonRegistryHost", + "identityMismatch", + "resolvedName", + "resolvedVersion" + ], + "type": "object" + }, + { + "type": "null" + } +]
1 tool update
- Changed
batch_query_vulnerabilities2 fields changed- added
Output schema / properties / results / items / properties / sourceAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "integrity": { + "type": [ + "string", + "null" + ] + }, + "nonRegistryHost": { + "type": [ + "boolean", + "null" + ] + }, + "resolvedUrl": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "resolvedUrl", + "integrity", + "nonRegistryHost" + ], + "type": "object" + }, + { + "type": "null" + } + ] +} - changed
Output schema / properties / results / items / requiredPrevious value: -[ - "package", - "npmscanUrl", - "scanStatus", - "vulnerabilityCount", - "advisoryCount", - "uniqueVulnerabilityCount", - "vulnerabilities", - "signals" -]New value: +[ + "package", + "npmscanUrl", + "scanStatus", + "vulnerabilityCount", + "advisoryCount", + "uniqueVulnerabilityCount", + "vulnerabilities", + "signals", + "source" +]
1 tool update
- Changed
get_cve5 fields changed- added
Output schema / properties / cves / items / properties / epssCheckFailedAdded value: +{ + "$ref": "#/properties/epssCheckFailed" +} - added
Output schema / properties / cves / items / properties / kevCheckFailedAdded value: +{ + "$ref": "#/properties/kevCheckFailed" +} - changed
Output schema / properties / cves / items / requiredPrevious value: -[ - "id", - "npmscanUrl", - "vulnStatus", - "description", - "published", - "lastModified", - "cvss", - "cwes", - "references", - "source", - "kev", - "epss" -]New value: +[ + "id", + "npmscanUrl", + "vulnStatus", + "description", + "published", + "lastModified", + "cvss", + "cwes", + "references", + "source", + "kev", + "epss", + "kevCheckFailed", + "epssCheckFailed" +] - added
Output schema / properties / epssCheckFailedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / kevCheckFailedAdded value: +{ + "type": "boolean" +}
4 tool updates
- Changed
compare_packages2 fields changed- added
Output schema / properties / candidates / items / properties / vulnerabilityCheckFailedAdded value: +{ + "type": "boolean" +} - changed
Output schema / properties / candidates / items / requiredPrevious value: -[ - "name", - "found", - "resolutionError", - "npmscanUrl", - "description", - "license", - "latestVersion", - "deprecated", - "weeklyDownloads", - "downloadTrend", - "githubStars", - "hasBuiltInTypes", - "daysSinceLastPublish", - "popularityTier", - "maintenanceTier", - "maintenanceSummary", - "possibleTyposquatOf", - "isLatestVersionVulnerable", - "highestSeverity", - "vulnerabilityCount", - "installScriptRisk", - "installSize", - "score" -]New value: +[ + "name", + "found", + "resolutionError", + "npmscanUrl", + "description", + "license", + "latestVersion", + "deprecated", + "weeklyDownloads", + "downloadTrend", + "githubStars", + "hasBuiltInTypes", + "daysSinceLastPublish", + "popularityTier", + "maintenanceTier", + "maintenanceSummary", + "possibleTyposquatOf", + "isLatestVersionVulnerable", + "vulnerabilityCheckFailed", + "highestSeverity", + "vulnerabilityCount", + "installScriptRisk", + "installSize", + "score" +]
- Changed
get_package2 fields changed- added
Output schema / properties / vulnerabilityCheckFailedAdded value: +{ + "type": "boolean" +} - changed
Output schema / requiredPrevious value: -[ - "name", - "description", - "license", - "homepage", - "repository", - "keywords", - "maintainers", - "distTags", - "latestVersion", - "latestVersionInfo", - "recentVersions", - "createdAt", - "modifiedAt", - "npmscanUrl", - "weeklyDownloads", - "githubStars", - "hasBuiltInTypes", - "daysSinceLastPublish", - "popularityTier", - "maintenanceTier", - "maintenanceSummary", - "topPackagesRank", - "downloadTrend", - "possibleTyposquatOf", - "isLatestVersionVulnerable", - "highestSeverity", - "vulnerabilities" -]New value: +[ + "name", + "description", + "license", + "homepage", + "repository", + "keywords", + "maintainers", + "distTags", + "latestVersion", + "latestVersionInfo", + "recentVersions", + "createdAt", + "modifiedAt", + "npmscanUrl", + "weeklyDownloads", + "githubStars", + "hasBuiltInTypes", + "daysSinceLastPublish", + "popularityTier", + "maintenanceTier", + "maintenanceSummary", + "topPackagesRank", + "downloadTrend", + "possibleTyposquatOf", + "isLatestVersionVulnerable", + "vulnerabilityCheckFailed", + "highestSeverity", + "vulnerabilities" +]
- Changed
get_package_version2 fields changed- added
Output schema / properties / vulnerabilityCheckFailedAdded value: +{ + "type": "boolean" +} - changed
Output schema / requiredPrevious value: -[ - "name", - "version", - "description", - "license", - "dependencies", - "scripts", - "deprecated", - "tarball", - "shasum", - "npmscanUrl", - "isVulnerable", - "highestSeverity", - "vulnerabilities" -]New value: +[ + "name", + "version", + "description", + "license", + "dependencies", + "scripts", + "deprecated", + "tarball", + "shasum", + "npmscanUrl", + "isVulnerable", + "vulnerabilityCheckFailed", + "highestSeverity", + "vulnerabilities" +]
- Changed
suggest_alternative4 fields changed- added
Output schema / properties / source / properties / vulnerabilityCheckFailedAdded value: +{ + "type": "boolean" +} - changed
Output schema / properties / source / requiredPrevious value: -[ - "name", - "latestVersion", - "deprecated", - "isLatestVersionVulnerable", - "highestSeverity", - "popularityTier", - "maintenanceTier", - "possibleTyposquatOf", - "npmscanUrl" -]New value: +[ + "name", + "latestVersion", + "deprecated", + "isLatestVersionVulnerable", + "vulnerabilityCheckFailed", + "highestSeverity", + "popularityTier", + "maintenanceTier", + "possibleTyposquatOf", + "npmscanUrl" +] - added
Output schema / properties / suggestions / items / properties / vulnerabilityCheckFailedAdded value: +{ + "type": "boolean" +} - changed
Output schema / properties / suggestions / items / requiredPrevious value: -[ - "name", - "version", - "description", - "npmscanUrl", - "weeklyDownloads", - "dependentsCount", - "githubStars", - "hasBuiltInTypes", - "deprecated", - "isLatestVersionVulnerable", - "highestSeverity", - "popularityTier", - "maintenanceTier", - "topPackagesRank", - "categoryOverlap", - "matchedQueries", - "whySuggested" -]New value: +[ + "name", + "version", + "description", + "npmscanUrl", + "weeklyDownloads", + "dependentsCount", + "githubStars", + "hasBuiltInTypes", + "deprecated", + "isLatestVersionVulnerable", + "vulnerabilityCheckFailed", + "highestSeverity", + "popularityTier", + "maintenanceTier", + "topPackagesRank", + "categoryOverlap", + "matchedQueries", + "whySuggested" +]
6 tool updates
- Changed
analyze_transitive_dependencies3 fields changed- added
Output schema / properties / nodes / items / properties / actualNameAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / nodes / items / properties / isVulnerable / typePrevious value: -"boolean"New value: +[ + "boolean", + "null" +] - changed
Output schema / properties / nodes / items / requiredPrevious value: -[ - "name", - "version", - "depth", - "isRoot", - "rootPackages", - "parents", - "npmscanUrl", - "resolutionError", - "isVulnerable", - "highestSeverity", - "vulnerabilities" -]New value: +[ + "name", + "actualName", + "version", + "depth", + "isRoot", + "rootPackages", + "parents", + "npmscanUrl", + "resolutionError", + "isVulnerable", + "highestSeverity", + "vulnerabilities" +]
- Changed
audit_github_repository1 field changed- added
Input schema / properties / includePeerDependenciesAdded value: +{ + "description": "Include package.json peerDependencies (root and, for a monorepo, each workspace member) in the audit. Default false — a peer is often intentionally left unresolved by the consumer. See warnings for which peers were excluded.", + "type": "boolean" +}
- Changed
batch_query_vulnerabilities7 fields changed- added
Input schema / properties / includePeerDependenciesAdded value: +{ + "description": "Ignored when using `packages`; only applies when `content` is a package.json. peerDependencies are excluded from scanning by default (see ignoredPeerDependencyNames) since a peer is often intentionally left unresolved by the consumer — set this to also check them.", + "type": "boolean" +} - added
Output schema / properties / ignoredPeerDependencyNamesAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / projectLifecycleScriptRiskAdded value: +{ + "additionalProperties": false, + "properties": { + "hasLifecycleScripts": { + "type": "boolean" + }, + "riskTier": { + "enum": [ + "none", + "low", + "moderate", + "high", + "critical" + ], + "type": "string" + }, + "totalScore": { + "type": "number" + } + }, + "required": [ + "hasLifecycleScripts", + "riskTier", + "totalScore" + ], + "type": "object" +} - added
Output schema / properties / results / items / properties / package / properties / actualNameAdded value: +{ + "type": "string" +} - added
Output schema / properties / results / items / properties / package / properties / declaredSpecAdded value: +{ + "type": "string" +} - added
Output schema / properties / results / items / properties / scanStatusAdded value: +{ + "enum": [ + "scanned", + "not-scanned" + ], + "type": "string" +} - changed
Output schema / properties / results / items / requiredPrevious value: -[ - "package", - "npmscanUrl", - "vulnerabilityCount", - "advisoryCount", - "uniqueVulnerabilityCount", - "vulnerabilities", - "signals" -]New value: +[ + "package", + "npmscanUrl", + "scanStatus", + "vulnerabilityCount", + "advisoryCount", + "uniqueVulnerabilityCount", + "vulnerabilities", + "signals" +]
- Changed
diff_dependencies10 fields changed- added
Output schema / properties / added / items / properties / actualNameAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / added / items / properties / integrityAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / added / items / properties / resolvedUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / added / items / properties / sourceIntegrityChangedAdded value: +{ + "type": [ + "boolean", + "null" + ] +} - changed
Output schema / properties / added / items / requiredPrevious value: -[ - "name", - "npmscanUrl", - "beforeVersion", - "afterVersion", - "coexistingVersions", - "changeType", - "hasInstallScript", - "installScriptIntroduced", - "installScriptKeys", - "installScriptKeysIntroduced", - "isVulnerable", - "highestSeverity", - "vulnerabilities", - "vulnerabilityDelta", - "resolutionNote" -]New value: +[ + "name", + "actualName", + "npmscanUrl", + "beforeVersion", + "afterVersion", + "coexistingVersions", + "changeType", + "hasInstallScript", + "installScriptIntroduced", + "installScriptKeys", + "installScriptKeysIntroduced", + "sourceIntegrityChanged", + "resolvedUrl", + "integrity", + "isVulnerable", + "highestSeverity", + "vulnerabilities", + "vulnerabilityDelta", + "resolutionNote" +] - added
Output schema / properties / overridesChangesAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "changed": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "after": { + "type": "string" + }, + "before": { + "type": "string" + } + }, + "required": [ + "before", + "after" + ], + "type": "object" + }, + "type": "object" + }, + "introduced": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "removed": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "introduced", + "removed", + "changed" + ], + "type": "object" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / projectLifecycleChangesAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "changed": { + "additionalProperties": { + "additionalProperties": false, + "properties": { + "after": { + "type": "string" + }, + "before": { + "type": "string" + } + }, + "required": [ + "before", + "after" + ], + "type": "object" + }, + "type": "object" + }, + "introduced": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "removed": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + } + }, + "required": [ + "introduced", + "removed", + "changed" + ], + "type": "object" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / removed / items / properties / actualNameAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / removed / items / requiredPrevious value: -[ - "name", - "version", - "npmscanUrl" -]New value: +[ + "name", + "actualName", + "version", + "npmscanUrl" +] - changed
Output schema / requiredPrevious value: -[ - "summary", - "beforeFormat", - "afterFormat", - "comparisonNote", - "added", - "removed", - "changed", - "totalAdded", - "totalRemoved", - "totalChanged", - "flaggedCount", - "truncated", - "truncationNote", - "enrichmentNote" -]New value: +[ + "summary", + "beforeFormat", + "afterFormat", + "comparisonNote", + "added", + "removed", + "changed", + "totalAdded", + "totalRemoved", + "totalChanged", + "flaggedCount", + "truncated", + "truncationNote", + "enrichmentNote", + "projectLifecycleChanges", + "overridesChanges" +]
- Changed
generate_sbom1 field changed- added
Input schema / properties / includePeerDependenciesAdded value: +{ + "description": "Ignored when using `packages`; only applies when `content` is a package.json. peerDependencies are excluded by default — set this to also include them as SBOM components.", + "type": "boolean" +}
- Changed
prioritize_remediation7 fields changed- changed
Input schema / properties / findings / items / properties / advisoryId / descriptionPrevious value: -"GHSA/OSV advisory id, passed through unchanged for reference"New value: +"GHSA/OSV advisory id, passed through unchanged for reference — a MAL-* id is auto-detected as malware even without findingType set" - added
Input schema / properties / findings / items / properties / findingTypeAdded value: +{ + "description": "\"malware\" forces the remove-now tier regardless of score/CVE/severity — set this (or pass a MAL-* advisoryId) for a confirmed-malicious package. Omit for an ordinary vulnerability finding.", + "enum": [ + "malware", + "vulnerability", + "supply-chain", + "install-script" + ], + "type": "string" +} - added
Output schema / properties / ranked / items / properties / findingTypeAdded value: +{ + "enum": [ + "malware", + "vulnerability", + "supply-chain", + "install-script" + ], + "type": "string" +} - changed
Output schema / properties / ranked / items / properties / tier / enumPrevious value: -[ - "patch-now", - "patch-soon", - "scheduled", - "monitor" -]New value: +[ + "remove-now", + "patch-now", + "patch-soon", + "scheduled", + "monitor" +] - changed
Output schema / properties / ranked / items / requiredPrevious value: -[ - "rank", - "packageName", - "cveId", - "advisoryId", - "currentVersion", - "fixedVersion", - "severity", - "kev", - "epss", - "score", - "tier", - "reason", - "npmscanUrl", - "cveNpmscanUrl" -]New value: +[ + "rank", + "packageName", + "cveId", + "advisoryId", + "currentVersion", + "fixedVersion", + "severity", + "kev", + "epss", + "score", + "tier", + "findingType", + "reason", + "npmscanUrl", + "cveNpmscanUrl" +] - added
Output schema / properties / summary / properties / removeNowAdded value: +{ + "type": "number" +} - changed
Output schema / properties / summary / requiredPrevious value: -[ - "patchNow", - "patchSoon", - "scheduled", - "monitor", - "kevListedCount" -]New value: +[ + "removeNow", + "patchNow", + "patchSoon", + "scheduled", + "monitor", + "kevListedCount" +]
2 tool updates
- Changed
batch_query_vulnerabilities9 fields changed- added
Input schema / properties / packages / items / properties / version / descriptionAdded value: +"One exact published version, e.g. \"18.2.0\" (not a range/tag like \"^18.2.0\" or \"latest\" — those are resolved against the registry first, at the cost of an extra lookup, rather than rejected)" - added
Output schema / properties / nonexistentVersionsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - added
Output schema / properties / projectLifecycleScriptsAdded value: +{ + "anyOf": [ + { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / results / items / properties / advisoryCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / results / items / properties / signalsAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "deprecated": { + "type": [ + "string", + "null" + ] + }, + "hasInstallScripts": { + "type": [ + "boolean", + "null" + ] + }, + "maintenanceTier": { + "enum": [ + "active", + "aging", + "stale", + "unknown" + ], + "type": "string" + }, + "popularityTier": { + "enum": [ + "very-high", + "high", + "moderate", + "low", + "very-low", + "unknown" + ], + "type": "string" + }, + "possibleTyposquatOf": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "name": { + "type": "string" + }, + "rank": { + "type": "number" + } + }, + "required": [ + "name", + "rank" + ], + "type": "object" + }, + { + "type": "null" + } + ] + } + }, + "required": [ + "deprecated", + "hasInstallScripts", + "popularityTier", + "maintenanceTier", + "possibleTyposquatOf" + ], + "type": "object" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / results / items / properties / uniqueVulnerabilityCountAdded value: +{ + "type": "number" +} - changed
Output schema / properties / results / items / requiredPrevious value: -[ - "package", - "npmscanUrl", - "vulnerabilityCount", - "vulnerabilities" -]New value: +[ + "package", + "npmscanUrl", + "vulnerabilityCount", + "advisoryCount", + "uniqueVulnerabilityCount", + "vulnerabilities", + "signals" +] - added
Output schema / properties / totalUniqueVulnerabilitiesAdded value: +{ + "type": "number" +} - changed
Output schema / requiredPrevious value: -[ - "results", - "totalVulnerabilities", - "packagesWithVulnerabilities" -]New value: +[ + "results", + "totalVulnerabilities", + "totalUniqueVulnerabilities", + "packagesWithVulnerabilities" +]
- Changed
diff_dependencies3 fields changed- added
Output schema / properties / added / items / properties / installScriptKeysAdded value: +{ + "anyOf": [ + { + "items": { + "enum": [ + "preinstall", + "install", + "postinstall", + "prepare" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / added / items / properties / installScriptKeysIntroducedAdded value: +{ + "anyOf": [ + { + "items": { + "enum": [ + "preinstall", + "install", + "postinstall", + "prepare" + ], + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ] +} - changed
Output schema / properties / added / items / requiredPrevious value: -[ - "name", - "npmscanUrl", - "beforeVersion", - "afterVersion", - "coexistingVersions", - "changeType", - "hasInstallScript", - "installScriptIntroduced", - "isVulnerable", - "highestSeverity", - "vulnerabilities", - "vulnerabilityDelta", - "resolutionNote" -]New value: +[ + "name", + "npmscanUrl", + "beforeVersion", + "afterVersion", + "coexistingVersions", + "changeType", + "hasInstallScript", + "installScriptIntroduced", + "installScriptKeys", + "installScriptKeysIntroduced", + "isVulnerable", + "highestSeverity", + "vulnerabilities", + "vulnerabilityDelta", + "resolutionNote" +]
Related MCP Servers
- AlicenseNot gradedqualityBmaintenancePerplexity for social: ask what competitors are running across social and get answers grounded in real ad and creative data, not guesses.2Apache 2.0
- AlicenseCqualityBmaintenanceCompetitor Monitor AI - MCP server providing AI-powered tools and automation by MEOK AI Labs119 npmMIT
- AlicenseAqualityCmaintenanceEnables brand visibility monitoring across major AI platforms like ChatGPT, Claude, Gemini, and Perplexity. It allows users to track visibility scores, analyze competitor data, and receive actionable insights to improve AI-generated brand recommendations.164 npm1MIT

industrylens-mcpofficial
AlicenseNot gradedqualityBmaintenanceBrowse IndustryLens's published competitive-intelligence reports and head-to-head competitor comparisons from any AI agent — real, source-backed data.MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.