NPMScan
Server Details
Detect malicious or vulnerable npm packages: registry search, OSV.dev and GitHub advisory lookups
- Status
- Healthy
- Last Tested
- Transport
- Streamable HTTP
- URL
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
Recursively resolves one or more direct/root packages' dependency graphs — e.g. the "dependencies" section of a package.json — up to maxDepth levels deep (default 2, max 3) and batch-checks every resolved package@version against OSV.dev, so vulnerabilities buried several levels down (which would never show up from checking direct dependencies alone) still surface. summary is a one-sentence, deterministic recap (packages scanned, unresolved count, vulnerable count and which roots pulled them in) — read it first. The vulnerablePaths field directly answers "which of my dependencies pulled this in" by naming the root package(s) responsible for each vulnerable transitive package; nodes has the full resolved graph (depth, parents, resolutionError) for deeper inspection. Scope/limits worth knowing before trusting a "clean" result: only the "dependencies" field is followed (not devDependencies/peerDependencies/optionalDependencies); each range is resolved independently per branch via semver max-satisfying against published versions — this does NOT emulate npm/yarn's actual node_modules hoisting/dedup, so read results as "which vulnerable versions are reachable in the graph," not the exact installed layout; git/file/workspace/URL/npm-alias dependencies aren't resolvable from the registry and show up with a resolutionError instead of being silently skipped; and the whole traversal is capped at a total node budget — check truncated/truncationNote rather than assuming a large graph was scanned exhaustively. Prefer batch_query_vulnerabilities instead when you only need to check exact packages you already have a flat list for (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?
The annotations already mark this as read-only, non-destructive, and open-world, and the description adds substantial behavioral detail beyond that: independent per-branch semver resolution, non-aborting resolution errors, skipped git/file: dependencies, deterministic summary output, and what vulnerablePaths/nodes contain. No contradiction with annotations exists.
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 front-loaded: the first sentence establishes the core operation, then output-field guidance, then critical scope limits, then the alternative tool. It is structured logically and nearly every sentence earns its place, though there is minor redundancy around file: dependencies being skipped and the paragraph is dense.
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?
Given the output schema exists and the annotations cover safety, the description is remarkably complete. It tells the agent how to read the summary first, what vulnerablePaths answers, what nodes offers for deep inspection, what the resolver does and does not follow, and when to choose a sibling tool instead. Nothing essential for correct invocation 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 and the schema already documents maxDepth defaults and packages ranges, so the baseline is 3. The description adds useful parameter behavior by explaining that each version range is resolved independently per branch via npm's resolver, which can yield multiple versions of the same package, and clarifies that packages are roots for expansion, not a flat list to check.
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 clearly states a specific verb (recursively resolves), a resource (dependency graphs of direct/root packages), and an action (batch-checks resolved packages against OSV.dev). It also distinguishes itself from the sibling batch_query_vulnerabilities by emphasizing the graph-walk approach and deep, buried vulnerabilities.
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 tells the agent when to prefer batch_query_vulnerabilities instead: when checking exact packages already available as a flat list, since that is faster and avoids graph walking. It also documents limitations that affect trust in a 'clean' result, such as only following 'dependencies' and not dev/peer/optional dependencies.
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
Given a GitHub repository URL, fetches its package.json (and, if present, a pnpm-lock.yaml/package-lock.json/yarn.lock — first one found wins, in that priority order) straight from the repo's default branch and runs the same vulnerability, license-compliance, install-script, and ownership-risk pipelines batch_query_vulnerabilities/check_license_compliance/analyze_install_script/check_maintainer_changes/check_package_provenance expose individually, in one call — no copy-pasting file contents required. A monorepo (package.json#workspaces, Yarn's {packages:[...]} form, or pnpm-workspace.yaml) is detected automatically: pnpm-lock.yaml and yarn.lock already record every workspace member's dependencies directly, and for package.json-only or package-lock.json repos this additionally lists the repo's file tree, resolves the declared glob patterns to member directories, and merges each member's dependencies into the audit (capped at 50 member packages) — see isMonorepo/workspacePatterns/workspacePackageCount/workspaceNote in the result. Every direct dependency (up to 100 per call, across the root and any merged workspace members) gets: an OSV.dev vulnerability check, a license-compliance verdict against the given policy (same default as check_license_compliance: only copyleft/network-copyleft/proprietary are violations unless you pass one), and a tarball-free install-script risk signal (installScriptScanScope: 'lifecycle-scripts-only'). Up to 10 of the packages that actually declare a lifecycle script — prioritized by already-vulnerable, then possible-typosquat, then whatever's left — additionally get the full tarball-fetching deep scan analyze_install_script itself runs (installScriptScanScope: 'deep-tarball-scan', with a populated installScriptFindings array); any remaining flagged packages past that cap keep the lighter signal only, noted in deepScanNote. Any package that comes back vulnerable at high/critical severity, a possible typosquat, or deprecated (ownershipRiskEligible) additionally gets check_maintainer_changes and check_package_provenance run against it — up to 5 such packages per call (ownershipRiskChecked), prioritized the same way as the deep install-script scan, populating maintainerRiskTier/maintainerFindings and provenanceRiskTier/provenanceFindings; remaining eligible packages past that cap are named in ownershipCheckNote. This is the most expensive tool in the suite (a repo lookup, a handful of file fetches, up to 100 registry doc fetches, one OSV batch call, up to 10 tarball fetches, up to 5 packages each getting a maintainer-history check plus a provenance check — the latter alone can fan out to ~8 more registry fetches on its own — and, for a monorepo needing enumeration, one file-tree listing plus up to 50 more manifest fetches) — don't 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| ref | Yes | |
| owner | Yes | |
| policy | Yes | |
| summary | Yes | |
| findings | Yes | |
| repoName | Yes | |
| warnings | Yes | |
| isMonorepo | Yes | |
| inputFormat | Yes | |
| deepScanNote | Yes | |
| lockfilePath | Yes | |
| manifestPath | Yes | |
| totalPackages | Yes | |
| workspaceNote | Yes | |
| truncationNote | Yes | |
| deepScannedCount | Yes | |
| overflowPackages | Yes | |
| defaultBranchUsed | Yes | |
| workspacePatterns | Yes | |
| ownershipCheckNote | Yes | |
| licenseViolationCount | Yes | |
| ownershipCheckedCount | Yes | |
| workspacePackageCount | Yes | |
| vulnerablePackageCount | Yes | |
| installScriptFlaggedCount | Yes | |
| ownershipRiskFlaggedCount | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description goes far beyond the readOnly/openWorld annotations by detailing lockfile priority, workspace detection, dependency caps, deep-scan prioritization, ownership-check limits, and the large number of downstream network fetches. This is exactly the behavioral context an agent needs before invoking an expensive open-world read tool.
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 the tool genuinely has many important caps, priority rules, and cost characteristics that would be dangerous to omit. It is front-loaded with the core action and resource cost, but the dense single-paragraph format with nested clauses could be significantly easier to scan.
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 the full runtime behavior: file-fetch strategy, monorepo handling, dependency caps, scan priorities, ownership-risk eligibility, and cost profile. Combined with an output schema, the agent has everything needed to invoke the tool correctly and set expectations about its price.
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?
All four parameters are already documented in the input schema with 100% coverage, so the description does not need to compensate. It adds general behavioral context around policy defaults and lockfile scope, but most of that is either already in the schema or is not parameter-specific.
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 concrete verb and resource: given a GitHub repository URL, fetch its dependency manifests and run a complete npm audit in one call. It explicitly names the sibling pipelines it aggregates, so an agent can distinguish this combined audit tool from the individual check 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?
It clearly states that this is the most expensive tool in the suite and warns not to call it in a loop across many repositories. It also names the individual sibling tools it composes, but it never explicitly tells the agent when to choose those cheaper alternatives instead of this aggregate.
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
Query OSV.dev for known vulnerabilities across a whole npm dependency inventory at once: either pass a flat {packages:[...]} list, or paste raw package.json / lockfile / CycloneDX JSON / SPDX JSON content via content. The tool normalizes npm dependencies first, then chunk-queries OSV behind the scenes so large SBOMs don't stop at the upstream 100-package batch limit. Each finding includes severity, a summary, CVE aliases, and the fixed version — not just a bare advisory ID — so a dependency audit answer doesn't need a follow-up call per flagged package.
| 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. |
Output Schema
| Name | Required | Description |
|---|---|---|
| results | Yes | |
| warnings | No | |
| inputFormat | No | |
| ignoredCount | No | |
| enrichmentNote | No | |
| queryFailureCount | No | |
| parsedPackageCount | No | |
| totalVulnerabilities | Yes | |
| packagesWithVulnerabilities | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this as a read-only, non-destructive operation. The description adds meaningful behavioral context beyond that: input normalization, chunked background queries, the 100-package upstream limit, and that each finding contains severity, summary, CVE aliases, and fixed version. No contradictions with the annotations exist.
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?
Three dense sentences with no wasted words: the first fronts the core purpose and input options, the second explains the batch behavior, and the third specifies return-value richness. Every sentence earns its place and there is no repetition of schema content.
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?
Given the annotations, full parameter descriptions, and presence of an output schema, the description is complete for an agent to select and invoke the tool correctly. It covers both input modes, clarifies the batch limit workaround, and describes what the results contain without needing to restate 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%, so the schema already documents all three parameters and their mutual exclusivity. The description reinforces the distinction between packages and content and adds useful output context, but it does not substantially extend parameter-level meaning beyond what the schema provides, making the baseline 3 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 states a specific verb and resource ('Query OSV.dev for known vulnerabilities across a whole npm dependency inventory at once') and clearly signals batch behavior, distinguishing it from the sibling query_vulnerabilities tool. It also enumerates the two input modes, leaving no ambiguity about what the tool operates on.
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 frames when to use the tool: when auditing a whole dependency inventory or a large SBOM, and it explains that chunking avoids the upstream 100-package limit. However, it does not explicitly name sibling tools like query_vulnerabilities or state when the non-batch variant would be preferable, so the guidance stops just short of full exclusion criteria.
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 annotations, the description discloses important behavior: license classification categories, SPDX expression handling, policy precedence, default policy behavior, family-prefix matching, and the registry-field limitation. This gives agents a realistic model of how the tool will behave without overpromising.
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 and dense, but every sentence adds operational detail that would otherwise need to be inferred from examples. It is front-loaded with the core purpose before diving into edge cases, though a bit more whitespace or bullet structure could aid quick scanning.
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?
Given the complexity of the tool (nested policy object, expression semantics, default policy, exclusion behavior) and the existing output schema, the description covers all necessary context. An agent can correctly construct inputs and anticipate verdict outcomes without additional external knowledge.
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?
Even though schema coverage is 100%, the description enriches parameter meaning substantially: it explains how semver ranges are interpreted, that deny always overrides allow, how family prefixes and categories match, and what happens when policy is omitted. These are not obvious from the schema alone and directly affect how an agent should build the parameters.
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 action: check a package list against a license policy and report per-package compliance. It clearly identifies the resource (dependency list with SPDX licenses) and the verdict output, and it is distinct from the sibling tools like analyze_transitive_dependencies or query_vulnerabilities.
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 a clear use case: resolve license compliance for packages with an optional allow/deny policy. It also provides a notable exclusion ('does not fetch or parse LICENSE file contents from the source repository'), which helps agents avoid misusing it. However, it does not explicitly name alternative sibling tools or state conditions for choosing them.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
check_maintainer_blast_radiusFind every package an npm maintainer account touches, and flag a tight publish clusterARead-onlyInspect
Given an npm username, finds every package npm's own maintainer: search index currently returns for that account (registry.npmjs.org's /-/v1/search — the same reverse lookup npmjs.com's own site search uses; the public registry API has no dedicated 'list packages by maintainer' endpoint otherwise) and looks for a tight cluster of packages whose LATEST version was published within a short rolling window of each other. That's the shape of a compromised-account supply-chain attack: a stolen or phished credential doesn't get used on one package, it gets used on every package that account can publish to, usually within hours — the exact pattern behind the September 2025 chalk/debug ('qix') compromise, which hit roughly 18 packages within about 2 hours. A large total package count is NOT itself a red flag — many legitimate maintainers publish hundreds of packages over a career — only a tight publish-time cluster is scored, weighted up by how many packages it includes and by their combined weekly downloads/dependentsCount, since a burst touching a handful of near-zero-download packages is a very different event than one touching something with billions of weekly downloads. A cluster where most of the packages share one npm scope (e.g. @docusaurus/*) is dampened, since that's the shape of a project's own monorepo doing one coordinated release, not a compromised account spread across unrelated packages — this is why a large official org account (e.g. facebook/fb) publishing several of its own monorepos still lands well below what a plain sum of its cluster count would suggest. Multiple distinct clusters on one account combine with diminishing returns (the single worst cluster counts in full; each additional one contributes half the previous one's weight), not a plain sum — an account that does many independent, legitimate coordinated releases over its lifetime should not accumulate an unbounded score purely from being prolific. avatarUrl is the same Gravatar image npmjs.com's own profile page shows for this account, derived from the email already public in the registry's own maintainer records but served from our own /api/avatar/:hash proxy rather than linking gravatar.com directly (null only if no returned package still lists an email for this exact username). Each returned package's CURRENT maintainer list is cross-checked against the queried username (isCurrentMaintainer), since access is often already revoked by the time this runs. Natural follow-up to check_maintainer_changes: when that tool flags a newly added or fully turned-over maintainer on one package, call this with that maintainer's username to see whether the same account touched other packages around the same time. Known limitations: npm's search index is a text-relevance index, not a guaranteed-complete/real-time reverse index (results can lag or omit edge cases); results are capped at one page (up to 250 packages, ranked by npm's own relevance/popularity scoring, NOT by recency) so a very large footprint may be truncated (see resultsTruncated/totalPackagesFound) and a real cluster outside that page could be missed; and lastPublished reflects only each package's latest version, not its full history.
| Name | Required | Description | Default |
|---|---|---|---|
| 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 | |
| totalScore | Yes | |
| npmProfileUrl | Yes | |
| packagesReturned | Yes | |
| resultsTruncated | Yes | |
| clusterWindowHours | Yes | |
| maintainerUsername | Yes | |
| totalPackagesFound | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes far beyond the readOnlyHint/openWorldHint/destructiveHint annotations, disclosing that results are relevance-ranked and capped at 250, that lastPublished only reflects the latest version, that scope-shared clusters are dampened, that multiple clusters combine with diminishing returns, and that isCurrentMaintainer may be false because access is often revoked. These are exactly the behavioral quirks an agent needs to interpret results correctly. No annotation contradiction.
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 a crisp purpose and then organized into mechanism, scoring rationale, follow-up, and limitations. It is long, but nearly every sentence carries decision-relevant information; minor redundancy exists around 'not a plain sum' and the chalk/debug example could be shorter, but the structure makes 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 tool with one input, rich output schema, and search-index caveats, the description fully covers invocation, interpretation, output-field semantics (avatarUrl, isCurrentMaintainer, resultsTruncated), and failure modes. An agent has everything needed to know when to call it and how to reason about the result.
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 description already covers the single parameter thoroughly (exact username, example, not email/package/scope), so the description adds no new parameter-level meaning. It consistently reinforces 'npm username' but does not explain formatting, edge cases, or validation 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 action (reverse-lookup every package for an npm maintainer) and a distinctive outcome (flag tight publish clusters) that clearly separates it from siblings like get_maintainer_profile and check_maintainer_changes. The attack-scenario framing gives an agent an immediate mental model of what the tool produces.
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 names check_maintainer_changes as the natural predecessor and instructs exactly when to call this tool: when a maintainer is newly added or fully turned over. It also explains when the tool should NOT be trusted (search-index lag, truncation), giving the agent real decision boundaries rather than vague context.
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
Reconstructs a package's maintainer-change history straight from the npm packument — every published version carries the maintainers-list SNAPSHOT as it stood at that publish plus who actually ran npm publish (_npmUser), so diffing consecutive snapshots in publish-time order recovers exactly who was added or removed and when, with no extra API calls. Flags: (1) a maintainer added recently who then published a release shortly afterward on a package with real prior history — the account-takeover/hostile-handoff shape behind incidents like ua-parser-js, event-stream, and the 2025 chalk/debug ('qix') compromise; (2) a full, sudden replacement of the entire maintainer list; (3) a long-standing maintainer quietly dropped from the list; (4) a maintainer-list change that happened on npm's site AFTER the latest release — not yet tied to any published version, which is the more urgent case since it means access changed hands but nothing has shipped with it yet. Also cross-checks the declared GitHub repository: whether it still resolves to the same owner/name (a transfer/rename), whether it's reachable at all, and whether the latest npm release landed long after any real push activity there — repository.ownerLogin/ownerAvatarUrl name and show the CURRENT owning account (the new one after a transfer, not the one originally declared in package.json), with ownerAvatarUrl served from our own /api/github/avatar proxy rather than linking avatars.githubusercontent.com directly, both null whenever the repo check itself didn't reach GitHub. Use get_package/check_package_provenance first for the package's general health and publish-integrity signals; use this specifically for the 'who controls this package, and did that change recently' question. If this flags a newly added or fully turned-over maintainer, follow up with check_maintainer_blast_radius on that maintainer's username — it lists every other package the same account currently touches and flags a tight publish-time cluster across them, the 'did this compromise hit just one package or a dozen' question this tool can't answer on its own.
| 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?
The description goes well beyond the read-only/destructive annotations by disclosing the data source (npm packument), the method (diffing snapshots in publish-time order), no extra API calls, edge cases (changes after latest release, GitHub reachability failures), and implementation details like the avatar proxy. It sets correct expectations for when fields will be null and how ownership changes are detected.
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 information-dense, with major behavioral details front-loaded and a logical flow from mechanism to flags to follow-up guidance. Some historical incident examples and avatar-proxy details could be trimmed, but they add context rather than pure 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?
Given the tool's complexity, the single-parameter schema, and the existence of an output schema, the description covers all necessary context: method, edge cases, null behavior, fallback paths, and sibling connections. An agent can decide when to invoke this tool and what to do with results without needing additional documentation.
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 input schema already describes the single 'name' parameter fully with exactness requirements and examples, so schema coverage is 100%. The description does not add parameter-level detail beyond the schema, which aligns with the baseline 3; no additional semantics are needed.
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 precise purpose: reconstructing a package's maintainer-change history from the npm packument and flagging specific red flags. It includes concrete patterns (maintainer added then publishing, full list replacement, quiet removal, post-release changes) and explicitly distinguishes itself from sibling tools by framing it as the 'who controls this package, and did that change recently' question.
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 routing: use get_package/check_package_provenance first for general health, use this tool specifically for maintainer control questions, and follow up with check_maintainer_blast_radius when a new or turned-over maintainer is flagged. It clearly states what this tool is not for and what to do next.
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
Given 2-5 candidate packages for the same job (e.g. "axios vs got vs node-fetch"), fetches the same registry/popularity/maintenance/vulnerability enrichment get_package computes for each one in parallel and returns a structured side-by-side plus a deterministic, reasoned pick. Each candidate gets downloads + trend, popularityTier/maintenanceTier, GitHub stars, TypeScript support, license, deprecated status, latest-version vulnerability status, a lightweight installScriptRisk signal (scans lifecycle script command strings for known red flags — does NOT fetch the tarball; call analyze_install_script on a specific candidate for that deeper scan), and installSize (the candidate's own dist.unpackedSize plus a transitive rollup — summed dist.unpackedSize across its resolved dependency tree, walked up to depth 2 / 60 nodes per candidate; installSize.transitive.truncated/sizeUnknownCount flag when that sum is partial rather than pretending it's exact — call analyze_transitive_dependencies on a specific candidate for the full graph). differentiators names which candidates stand out on each dimension (most downloads, only ones with TS types, which are deprecated/vulnerable/flagged as a typosquat/install-script risk, smallest/largest install size). recommendation.pick is chosen deterministically from a weighted score (popularity, maintenance, deprecation, vulnerabilities, typosquat flag, install-script risk, TS support, GitHub stars — install size is reported but not scored) — never a deprecated or typosquat-flagged candidate — with rationale explaining why and confidence reflecting how close the top two scored. A name that can't be resolved (typo, unpublished, malformed) still appears in candidates with found:false and resolutionError set rather than failing the whole call; duplicate names in the input are rejected.
| Name | Required | Description | Default |
|---|---|---|---|
| packages | Yes | 2-5 exact npm package names to compare, e.g. ["axios", "got", "node-fetch"]. |
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 only declare read-only, non-destructive, open-world behavior; the description adds substantial disclosure: parallel fetching, deterministic weighted scoring, never picking deprecated/typosquat-flagged candidates, unresolved names returned as found:false instead of failing, duplicate rejection, and transparent truncation flags on transitive size. No contradictions 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?
Long but dense; every clause adds a distinct behavioral or output detail relevant to correct invocation (truncation flags, no tarball fetch, scoring exclusions, edge cases). The purpose is front-loaded and the nested clarifications are organized, though the parenthetical-heavy style makes it slightly harder to scan.
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?
Covers usage, edge cases (unresolved, duplicates, truncation), scoring logic, and pointers to deeper tools; with annotations and an output schema present, nothing needed for safe/correct invocation is missing. It even explains what the tool deliberately does not do, such as fetching the tarball.
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 the single packages array with counts and an example; the description adds semantic constraints not in the schema: candidates should be for the same job, duplicate names are rejected, and unresolved names still appear with resolutionError. This goes beyond the baseline, though a 5 isn't warranted because the single parameter is already well covered by 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 specific verb and resource ('Compare npm packages side-by-side') and enumerates the enrichment dimensions (popularity, maintenance, vulnerabilities, etc.). It is clearly distinguished from siblings by the side-by-side comparison intent and explicitly references get_package and analyze_* tools for adjacent functionality.
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?
Clearly targets 2-5 candidate packages for the same job, which defines the appropriate context. It names analyze_install_script and analyze_transitive_dependencies as alternatives when deeper or full-graph analysis is needed, and references get_package as the single-package computation baseline.
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
Compares two raw snapshots of a package.json, package-lock.json (npm v1-v3), yarn.lock (classic v1 or Berry), or pnpm-lock.yaml — e.g. before/after a PR — and reports which packages were added, removed, or version-bumped. For every added or bumped package (up to 100 per call), also checks whether its resolved version carries a preinstall/install/postinstall/prepare lifecycle script that the before-version did NOT have (installScriptIntroduced, the highest-signal field here — a routine-looking patch bump quietly adding a postinstall is exactly the shape of a compromised-maintainer supply-chain attack) and batch-checks it against OSV.dev, reporting vulnerabilityDelta (introduced/fixed/still-vulnerable/still-clean) rather than just a bare isVulnerable flag. Scope notes: only direct dependencies are diffed for package.json/package-lock.json/pnpm-lock.yaml (their own formats distinguish direct from transitive); yarn.lock has no such distinction, so its side of the diff covers every resolved package in the file — expect a larger added/removed count when diffing a yarn.lock, and check comparisonNote when the two snapshots are different formats. The install-script check is presence-only (read from the registry packument or lockfile metadata, not a tarball content scan) — use analyze_install_script for a deep-dive on anything flagged here. Ideal for a CI gate reviewing a dependency-changing PR.
| 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 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/openWorld/non-destructive, and the description adds substantial behavioral context: the 100-package cap, installScriptIntroduced semantics, vulnerabilityDelta value set, presence-only install-script detection, and format-scope differences. 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 description is dense but every sentence carries meaningful guidance: core operation, high-signal output fields, scope caveats, detection limitations, and alternative tool. It is front-loaded with the primary purpose and uses the remaining length for genuinely necessary nuances.
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?
Given the tool's complexity, the presence of an output schema, and full annotation coverage, the description is complete: it covers format variants, scope limitations, batch behavior, vulnerability reporting style, mixed-format handling, and the recommended next step for flagged results. No critical calling context 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?
Both parameters are fully documented in the input schema (100% coverage), including raw content, allowed formats, and auto-detection. The description reinforces the before/after relationship and PR use case, but does not add new parameter-level semantics beyond what the schema already provides.
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 and resource: 'Compares two raw snapshots of ... package.json ... and reports which packages were added, removed, or version-bumped.' It clearly distinguishes this from siblings like analyze_install_script by framing it as a before/after dependency diff tool.
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 states the intended context ('e.g. before/after a PR'), recommends it as 'Ideal for a CI gate reviewing a dependency-changing PR,' and explicitly directs the agent to analyze_install_script for deep-dives. It also gives format-specific guidance about yarn.lock vs. direct-dependency diffing and the comparisonNote for mixed formats.
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 patch-now/patch-soon/scheduled/monitor ranking prioritize_remediation exposes for hand-built finding lists. 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?
The annotations already signal a safe read-only operation, and the description adds substantial behavioral context beyond that: it performs external GHSA-to-CVE resolution via OSV.dev, depends on CVE-keyed KEV/EPSS data, carries through npm-specific fields like isDirect and fixAvailable/fixTarget, and only uses the first advisory per package. It even discloses a failure mode (silent degradation to severity-only ranking) and warns about multi-advisory packages, which is genuinely valuable for correct invocation and expectation-setting.
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 dense and every sentence carries distinct information: input format, ranking behavior, CVE resolution caveats, npm-specific context fields, multi-advisory limitation, and unsupported formats. It is front-loaded with the core purpose, though the long parentheticals and nested caveats make it less scannable than it could be. The length is justified by the tool's complexity, so it earns a strong score rather than a penalty.
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 single-parameter tool with an output schema present, the description covers everything an agent needs to call it correctly: accepted input formats, ranking semantics, external resolution behavior, important edge cases (first advisory only, fixTarget naming a different package), and explicit routing to sibling tools for unsupported inputs. No obvious gap remains.
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 fully documents the single `content` parameter and its accepted formats, so the baseline is 3. The description adds semantic value by clarifying that the value is raw stdout from the npm CLI, that no package.json/lockfile re-pasting is needed, and by explaining the npm 7+ vs npm 6 format distinction in the narrative. This elevates the parameter understanding beyond the schema alone.
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 precise verb-resource pair: parse raw `npm audit --json` output and rank vulnerabilities by patch-now/patch-soon/scheduled/monitor priority. It also distinguishes itself from siblings by explicitly noting it works directly on the raw report rather than hand-built finding lists and by naming unsupported formats (`yarn audit --json`, `pnpm audit --json`).
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 an explicit when-to-use condition: when the input is raw npm audit JSON and ranking is desired. It also gives clear exclusions, stating yarn/pnpm audit outputs are not supported and directing the agent to `batch_query_vulnerabilities` with the manifest/lockfile instead, and referencing `prioritize_remediation` for hand-built lists.
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.
| 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. |
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?
Despite readOnlyHint/openWorldHint/destructiveHint annotations already establishing a safe read operation, the description adds substantial behavioral nuance: VEX analysis.state is 'in_triage' and unreviewed, not a claim of exploitability; omitted dependency graphs are deliberately not fabricated; includeVulnerabilities/includeLicenses control costly enrichment passes; and format-specific output placement is disclosed.
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 dense but purposeful: every clause contributes output semantics, format behavior, or parameter interplay. It is front-loaded with the core purpose and the details follow logically, though the single unbroken paragraph could be restructured with line breaks or bullets for easier parsing.
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 9 parameters, nested objects, and format-specific output behavior, the description is remarkably complete: it covers accepted input formats, output format selection, enrichment defaults and toggles, policy integration, VEX semantics, and intentional limitations. Since an output schema exists, the description does not need to separately enumerate return values.
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?
With 89% schema description coverage, the schema already documents most parameters, so the baseline is 3. The description adds real semantic value by explaining that `content` accepts package.json/lockfile/CycloneDX/SPDX JSON, that `packages` is an alternative input, that `policy` mirrors check_license_compliance, and that componentName/componentVersion label the root document.
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 is explicit: it generates a spec-valid CycloneDX 1.6 or SPDX 2.3 SBOM document, naming the concrete output, formats, and embedded vulnerability/license data. It also distinguishes itself from sibling tools like batch_query_vulnerabilities and check_license_compliance by referencing their input/policy shapes while making clear the deliverable is an SBOM.
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 strong contextual guidance: it reuses the batch_query_vulnerabilities input contract, accepts content or packages, points to check_license_compliance for the policy shape, and explains when enrichment passes can be skipped. It does not explicitly state 'use this instead of X when...', so it falls just short of full exclusion-level guidance.
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). 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 | |
| resultsPerPage | No | |
| dateRangeClamped | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/openWorld annotations, the description discloses meaningful behavioral details: KEV and EPSS enrichment semantics, automatic MITRE fallback with a source field, the shared NVD rate limit with retry expectation, and the non-npm-scoped result set. This materially helps an agent interpret outcomes and avoid false failure conclusions.
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: core purpose, enrichment semantics, fallback behavior, ecosystem scope, tool-selection guidance, and rate-limit caveat. It is front-loaded with the primary lookup/search purpose before moving to interpretive guidance and edge cases.
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?
Given the tool's complexity, the description covers the critical operational facts: single-ID vs search behavior, fallback to MITRE, KEV/EPSS interpretation, ecosystem scope, and retry-on-rate-limit. The presence of an output schema means return-value details do not need to be repeated in the description.
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 input schema already documents all 8 parameters, so the baseline is 3. The description adds value above the schema by explaining the cveId-first behavior, its override of search filters, the fallback when no NVD record exists, and why keywordSearch should be used to narrow the otherwise broad NVD result space.
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 pair: 'Look up ... NIST NVD data' for one exact CVE ID or search NVD by several dimensions. It also explicitly contrasts with sibling tools by noting NVD is not npm-scoped, so an agent can distinguish get_cve from query_vulnerabilities and get_latest_advisories.
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 selection guidance: prefer this for authoritative CVSS/vector/KEV/EPSS data on an already-discovered CVE or when a user pastes a CVE ID/link, and prefer get_latest_advisories for npm-specific browsing. It also tells the agent to pass keywordSearch to narrow open-world results.
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, reviewed GitHub Security Advisories for the npm ecosystem. Filter by severity, vulnerability category (XSS, SQL/NoSQL Injection, SSRF, Access Control, Code Injection, etc.), an affected package name, or look up one exact advisory by GHSA or CVE ID. Paginated with an opaque cursor: pass a previous response's nextCursor back in as cursor to fetch the next page.
| Name | Required | Description | Default |
|---|---|---|---|
| cveId | No | Look up one exact advisory by its CVE ID (e.g. "CVE-2024-12345") | |
| 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") | |
| affects | No | Filter to advisories affecting this npm package name | |
| category | No | Filter by vulnerability category. 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) | |
| direction | No | Sort by published date, newest or oldest first (default desc) |
Output Schema
| Name | Required | Description |
|---|---|---|
| category | Yes | |
| severity | Yes | |
| direction | Yes | |
| advisories | Yes | |
| nextCursor | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only and non-destructive, and the description adds useful behavioral context beyond that: it notes advisories are 'reviewed,' explains the opaque cursor pagination mechanism, and clarifies that nextCursor is passed back as cursor. This gives the agent a practical model of how the tool behaves.
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?
Three sentences with no filler: the main action is front-loaded, the filtering options are compactly enumerated, and pagination is explained in a single clear sentence. Every sentence 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?
For a read-only query tool with an output schema and fully described parameters, the description covers all major behaviors: browsing, filtering by severity/category/package, exact ID lookup, and pagination. Nothing needed for correct invocation 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 schema already documents every parameter. The description restates filter dimensions and the pagination flow but does not add substantive new meaning beyond what the schema provides. It meets the baseline without compensating for any schema gaps.
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 and resource: 'Browse recently published, reviewed GitHub Security Advisories for the npm ecosystem.' It clearly distinguishes this tool from generic vulnerability queries or individual package lookups by scoping to npm security advisories. The stated filtering and exact-lookup capabilities make its role 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?
The description implies when to use the tool by listing its capabilities, but it never explicitly contrasts it with siblings like get_cve or query_vulnerabilities, nor states when to prefer one of those instead. The usage context is inferable but not spelled out.
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 — the same Gravatar image npmjs.com's own profile page shows for this account, derived from the email already public in the registry's own maintainer records but served from our own /api/avatar/:hash proxy rather than linking gravatar.com directly (null only if no returned package still lists an email for this exact username). 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.
| Name | Required | Description | Default |
|---|---|---|---|
| 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 | |
| npmProfileUrl | Yes | |
| 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 readOnlyHint, openWorldHint, and non-destructive behavior. The description goes further by explaining the data source, the absence of a dedicated registry endpoint, the derived avatar behavior, and the null condition. This adds meaningful behavioral 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 and dense, especially the first sentence with multiple parenthetical caveats. However, nearly every detail earns its place because it clarifies data provenance, aggregates, and avatar behavior. It is more verbose than strictly necessary but not wasteful.
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 one well-documented parameter and an output schema present, the description covers the important contextual gaps: what the search index returns, what the aggregates mean, what avatarUrl is derived from, and when it is null. It also provides the cross-tool routing needed for correct selection.
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 describes maintainerUsername with strong guidance: exact npm username, not email, not package name or scope, with an example. Schema description coverage is 100%, so the description's 'Given an npm username' adds little beyond the schema. 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?
The description clearly states a specific verb and resource: given an npm username, it returns all packages from npm's maintainer search plus computed aggregates. It also distinguishes itself from check_maintainer_blast_radius, so an agent can immediately tell what this tool is for.
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 this is a plain info lookup and does NOT run compromised-account detection. It names the alternative tool, check_maintainer_blast_radius, and gives the condition for choosing that instead: when the goal is a security read on whether a maintainer looks risky.
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). 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 | |
| isLatestVersionVulnerable | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the agent knows this is a safe, read-only operation. The description adds significant behavioral context beyond these: it discloses that topPackagesRank comes from a "periodically-refreshed snapshot — not live", explicitly states that popularityTier/maintenanceTier are "deterministic rule-based labels, not model-generated", and warns that a long gap since last release "can mean either a stable/finished package or a slowing one" — a critical interpretive caveat. It also flags the possibleTyposquatOf signal and the need to check deprecated and maintenanceSummary. This is rich behavioral context that complements the annotations rather than repeating them. A small deduction: the description does not explicitly describe the output schema's structure (e.g., whether findings are in an array, or the exact field names for each vulnerability), but the output schema exists and is not nested, and the description gives enough field names to be useful. 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?
The description is comprehensive but somewhat long and dense. It front-loads the core purpose and key data fields, which is good, but then includes a long parenthetical about topPackagesRank and a second parenthetical about rule-based labels, making the text feel packed. The mention of "Also checks the LATEST version against OSV.dev" and the advisory to "read deprecated and maintenanceSummary" are valuable, but the description could be more concise by trimming redundant phrasing like "(preinstall/postinstall are a key risk signal)" which, while useful, adds length. The structure is a single paragraph with several clauses chained, which is acceptable but not optimally scannable. It's informative but could be tightened without losing meaning.
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?
Given the tool's complexity (it returns a rich set of fields, including vulnerability data, popularity metrics, and a possible typosquat signal) and the presence of an output schema, the description covers almost everything an agent needs to call it correctly. It explains the return fields, the caveats about the data's freshness and label types, how to interpret maintenance gaps, and directs to alternative tools for specific older version checks. The only missing piece is an explicit note about required authentication or rate limits, but the annotations (readOnlyHint) and openWorldHint suggest no destructive effects, and no auth is mentioned for the sibling tools either—this seems consistent. The description is substantial and covers the key decision points, warranting a 4 rather than a 5 due to the lack of explicit instructions on pagination or why one might prefer this tool over search_packages when searching, but for its purpose, it's nearly complete.
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 input schema has 100% coverage for its single parameter, `name`, with a description including examples and validation constraints. The tool description does not add parameter-specific semantics beyond what the schema already conveys; the parameter is straightforward (a package name string). The description does provide additional context about how the `name` is interpreted (exact npm package name), but this is already in the schema. Since schema coverage is high, the baseline is 3, and the description doesn't need to compensate. There's no additional field-level detail in the description that would elevate the score.
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 clear, specific statement of the tool's purpose: "Fetch npm registry metadata for a package..." immediately enumerating the concrete data fields returned (latest version, install scripts, maintainers, license, etc.). This goes well beyond a simple verb+resource, distinguishing it from siblings like get_package_version and query_vulnerabilities. The explicit mention of "preinstall/postinstall are a key risk signal" and "direct safe/not-safe answer" establishes a clear functional identity, and the later inclusion of "topPackagesRank" and "downloadTrend" further separates it from other package-related 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?
The description provides partial usage guidance. It implicitly establishes when to use this tool (for a broad package health assessment) and explicitly mentions alternatives: "use get_package_version or query_vulnerabilities to check a specific older version instead" when needing to check a specific older version's vulnerabilities. However, it does not explicitly state when NOT to use this tool (e.g., when only a CVE lookup is needed, or when searching for packages — sibling search_packages). The guidance is implied through the mention of alternatives but lacks a clear 'when-not' clause. The conditional instruction to "read deprecated and maintenanceSummary before recommending a package" is useful and effectively guides usage, earning a 3 rather than a 2.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Exact npm package name | |
| version | Yes | Exact version string, e.g. "4.17.21" |
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 | |
| highestSeverity | Yes | |
| vulnerabilities | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses compound behavior: metadata fetch plus vulnerability check, and specifies the response fields (isVulnerable/highestSeverity, severity, summary, fixedVersion). It correctly aligns with readOnlyHint=true and destructiveHint=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?
Two sentences carry the full purpose, usage, and output meaning with no filler. The operation is front-loaded before the usage guidance.
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 annotations, complete input schema, and an output schema, the description covers what remains: when to use it, what data it returns, and how findings are represented. Nothing needed for a correct call 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?
The input schema already fully documents name and version, including length constraints and an example. The description repeats 'exact version' but adds no new semantic detail for either parameter, so the baseline of 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 names the exact operation: fetch registry metadata for one package version and check it against OSV.dev. It makes the resource ('one exact version of a package') and the dual behavior explicit, and separates this tool from any latest-release package lookup.
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 a direct usage directive: use this for a version pinned in a lockfile rather than the latest release. It lacks a named alternative tool, so it doesn't fully route the agent to a sibling, but the when/when-not guidance is clear.
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 declare readOnlyHint=true and destructiveHint=false, and the description adds significant behavior beyond that: duplicate rules are deduplicated, each matched rule gets a distinct situationNote, batch results avoid boilerplate, and unmatched inputs return matched:false with a note instead of throwing. This is rich disclosure of runtime behavior.
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 and dense, but nearly every sentence adds necessary operational detail. It is front-loaded with the tool's core purpose and output. A little more paragraph structuring could improve scannability, but the length is justified by the behavioral nuances.
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 fully covers input sources, batching, deduplication, unmatched findings, output content, and link-to-docs context. Combined with the output schema and annotations, an agent has everything needed to invoke this tool correctly and interpret responses.
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%, but the description enriches both parameters: `rules` are exact values from specific sibling tool outputs, batchable up to 10 with deduplication, and `id` is a playbook slug lookup. It clarifies constraints and relationships that 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?
The description names a specific verb ('maps', 'returns'), a resource (playbooks derived from analyze_install_script, check_maintainer_changes, check_package_provenance), and the concrete output (ordered steps, severity tier, references, prevention tips). It clearly differentiates this from sibling tools by stating it returns the 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 gives explicit input guidance: pass exact `rule` strings from prior findings, batch up to 10, or use an `id` slug. It also explains the edge case where an unrecognized rule/id is not an error, which tells the agent when a matched:false result is acceptable. This is direct, actionable usage guidance.
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
Given a batch of vulnerability findings already flagged elsewhere (e.g. from batch_query_vulnerabilities, analyze_transitive_dependencies, or query_vulnerabilities across a whole package.json/lockfile audit), ranks them by what to actually fix first. Combines CISA KEV status (confirmed active exploitation in the wild — an automatic top-priority override), FIRST.org EPSS (probability of exploitation in the next 30 days — the primary ranking signal, since it measures likelihood rather than just impact), and severity (a secondary/fallback signal, most useful for a GHSA finding with no CVE alias) into one composite score and a patch-now/patch-soon/scheduled/monitor tier per finding. This does NOT re-query OSV/NVD itself — pass in the severity/CVE id findings other tools already returned; it only adds KEV/EPSS enrichment (the same data get_cve returns per-CVE) and ranks the batch. A CVE id shared by multiple findings in the same call is only looked up once.
| 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 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses substantial behavior beyond the annotations: CISA KEV acts as an automatic top-priority override, EPSS is the primary ranking signal, severity is fallback, and the result is a composite score with tiers. It also exposes deduplication behavior for shared CVE IDs, which is valuable operational context not present 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 description is front-loaded with the core purpose and then builds outward into signals, exclusions, and deduplication behavior. Each sentence adds meaningful guidance, and the length is justified by the complexity of the ranking logic and the need to differentiate from sibling tools.
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 parameter, full schema coverage, and an output schema, the description is complete: it explains input provenance, ranking inputs, what enrichment is added, what is not done, and the output tier concept. No critical invocation detail 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 schema already documents the fields including cveId's enrichment role and severity's fallback role. The description adds some clarifying context about passing through existing findings and deduplicating shared CVE IDs, but this is largely behavioral rather than genuinely new parameter-level semantics.
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: it takes a batch of already-flagged vulnerability findings and ranks them by fix priority. It also distinguishes itself from siblings by explicitly saying it does NOT re-query OSV/NVD and that findings come from tools like batch_query_vulnerabilities or query_vulnerabilities.
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 it (after other tools have flagged findings) and what it does not do (no OSV/NVD re-query), naming concrete alternatives. It also clarifies the data flow: pass in severity/CVE findings and receive KEV/EPSS enrichment plus ranking.
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. Use before recommending, installing, or upgrading a package.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | npm package name | |
| version | No | Optional exact version to narrow results, e.g. to check one version pinned in a lockfile | |
| ecosystem | No | OSV ecosystem, default "npm" |
Output Schema
| Name | Required | Description |
|---|---|---|
| package | Yes | |
| version | Yes | |
| npmscanUrl | Yes | |
| isVulnerable | Yes | |
| highestSeverity | Yes | |
| vulnerabilities | 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 covered. The description adds meaningful behavioral context beyond annotations: it queries an external service, returns a distilled answer rather than raw data, and specifies the output fields including fixedVersion, CVE aliases, and plain-language summaries. This is substantial transparency for a read-only tool.
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 two sentences with no filler. It front-loads the core action and scope, then delivers high-value output and usage context. Every sentence 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?
Given the rich schema, existing output schema, and annotations, the description adds exactly what is missing: when to use it, what the returned answer looks like, and the key distinction that it is not a raw advisory dump. Nothing needed for safe invocation 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 parameter semantics are already fully documented in the schema. The description adds a helpful real-world example (lockfile pin check) and reinforces that version is optional, but it does not carry the parameter-documentation burden. 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?
The description states a specific verb and resource: querying OSV.dev for known vulnerabilities affecting an npm package. It further distinguishes itself from a raw advisory dump by promising a direct isVulnerable/highestSeverity answer, and its exact-version scoping differentiates it from broader advisory tools like get_latest_advisories.
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 clear context for when to use the tool: 'Use before recommending, installing, or upgrading a package,' and provides a concrete use case for checking a lockfile-pinned version. However, it does not explicitly mention the sibling batch_query_vulnerabilities or state when not to use this tool, so it stops short of full exclusion guidance.
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 |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses important behavioral nuances beyond the annotations: topPackagesRank is not live, labels are deterministic rather than model-generated, low-popularity/stale results are likely abandoned or squatted, and possibleTyposquatOf should be called out rather than silently filtered. This gives the agent critical interpretation guidance that readOnlyHint/openWorldHint do not 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 long but high-density: every sentence adds interpretive or routing value. It front-loads the core search action and then layers result-signal meaning, warning signs, and follow-up recommendations in a logical order. No sentences are 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 search tool feeding into a security-analysis workflow, the description covers result interpretation, caveats, red flags, and the recommended next step (get_package). The output schema handles structural return details, so the description does not need to restate them. An agent has enough context to use the tool correctly and act on its output.
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 input schema already documents query and limit, including defaults and constraints. The description only restates the query semantics ('by name or keywords') and adds no meaningful parameter-level detail beyond what the schema provides. 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?
The description clearly states a specific action and resource: searching the npm registry by name or keywords. It goes beyond a tautology by explaining what each result contains and how the tool differs from follow-up tools like get_package. An agent can immediately understand this is the entry-point search tool among the sibling set.
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 guidance on when to use the results: use the popularity and maintenance signals rather than name recognition or READMEs, treat possibleTyposquatOf as a red flag, and call get_package on the shortlist for deeper vetting. This actively routes the agent to the correct next tool and prevents misuse.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
simulate_dependency_upgradeSimulate upgrading one package from one version to another, or a whole batch at onceARead-onlyInspect
Given a package and a current/target version, tells you whether that specific upgrade is a safe patch/minor bump or a likely-breaking major bump, before you actually run npm install. Natural follow-up to prioritize_remediation: pass its packageName + currentVersion + fixedVersion straight in to check whether the suggested fix is a drop-in patch or something that needs a review pass. Classifies the jump by semver (major/minor/patch/prerelease), treats a minor bump between two pre-1.0 (0.x) versions as breaking-risk per semver's own "the API isn't stable yet" convention, and flags skipping over multiple major versions in one jump (e.g. 2.x -> 5.x) as needing a per-major changelog review rather than just a diff against the final target. Beyond semver, it also checks the registry for real signals the version number alone won't tell you: whether the target version is marked deprecated, whether it introduces a preinstall/install/postinstall/prepare lifecycle script the current version didn't have, whether it tightens its engines.node requirement, and whether it is itself a prerelease. Finally it batch-checks both versions against OSV.dev and reports vulnerabilityDelta (introduced/fixed/still-vulnerable/still-clean) — catching the case where a suggested "fix" version doesn't actually clear every open CVE. Combines all of this into one riskTier (safe/low-risk/review-recommended/breaking-change-likely/unknown) with a reasons list explaining exactly which signals drove it. This does NOT read the package's changelog/release notes or scan the target tarball's source diff for actual breaking API usage — it's a fast, deterministic pre-check, not a substitute for reading the release notes on a flagged major bump. For simulating more than one upgrade at once — e.g. every "patch-now" finding prioritize_remediation just ranked — pass packages: [{packageName, currentVersion, targetVersion?}, ...] (1-100 items) instead of packageName/currentVersion/targetVersion, not both. Registry fetches are deduped/parallelized and all OSV checks for the whole batch run as one call, so this is not the same cost as N single-item calls. A package that can't be resolved at all (typo, unpublished, registry error) shows up as its own results entry with fetchError set instead of failing the whole batch.
| Name | Required | Description | Default |
|---|---|---|---|
| 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 | |
| installScriptIntroduced | No | |
| requestedCurrentVersion | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/openWorldHint/destructiveHint, so the description's extra behavioral detail is genuinely additive: semver classification rules including pre-1.0 breaking-risk convention, multi-major jump flagging, registry signal checks (deprecated, lifecycle scripts, engines.node, prerelease), OSV.dev vulnerabilityDelta, riskTier output, batch deduplication/parallelization, and per-item fetchError handling. It also explicitly disclaims what it does not do (changelog/source-diff analysis). 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?
The description is long but highly structured: purpose first, then follow-up use case, semver classification, registry signals, OSV integration, riskTier output, explicit exclusions, batch instructions, and error handling. Every sentence adds a distinct piece of information; there is no filler or tautology. The front-loaded first sentence alone captures the core function.
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?
Given the tool's complexity (4 parameters, no required fields, 100% schema coverage, an output schema, and batch mode), the description is remarkably complete. It covers input forms, optional behavior, output fields (riskTier, reasons list, vulnerabilityDelta, fetchError), integration with a sibling tool, cost characteristics of batch calls, and known limitations. Nothing essential is missing for an agent to select and invoke 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?
Although schema coverage is 100%, the description goes far beyond repeating parameter names. It explains that targetVersion is optional and defaults to the registry's 'latest' dist-tag, that packages array items mirror the single-item fields, that the array is 1-100 items, and that prioritize_remediation's fixedVersion can be passed directly. It also clarifies the mutual exclusivity of the single-item and batch forms, which the schema alone does not convey as effectively.
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 pair: 'Given a package and a current/target version, tells you whether that specific upgrade is a safe patch/minor bump or a likely-breaking major bump.' It distinctly differentiates itself from siblings like prioritize_remediation (a ranking pre-check) and get_package (single metadata lookup) by framing itself as a pre-install upgrade risk simulator. The scope is unmistakable.
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 positions the tool as the natural follow-up to prioritize_remediation, naming the exact field mapping (packageName/currentVersion/fixedVersion). It provides clear when-not guidance ('not a substitute for reading the release notes on a flagged major bump') and distinguishes single-item vs batch invocation with a hard constraint (use packages OR packageName/currentVersion, not both).
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. Best for turning a 'don't use this package' warning into an actionable replacement shortlist.
| 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?
The description goes well beyond the readOnlyHint annotation by disclosing the internal pipeline: health checks, combination of deprecation hints, deterministic npm category matching, ranking by category overlap and popularity, filtering of typosquats and weak contenders, and output with whySuggested notes. This fully sets expectations for how the tool behaves.
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 information-dense but each sentence contributes: trigger conditions, method, ranking/filtering behavior, and output format. It is front-loaded with the purpose and follows with the process, making it easy for an agent to quickly grasp when and how to invoke the tool.
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 a multi-step internal algorithm and an output schema, the description covers the inputs, processing logic, ranking criteria, exclusions, and the shape of the result. The presence of an output schema means the return format is already defined, and the description fills the remaining behavioral context.
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?
Parameter schema coverage is 100%, so the schema already documents name, limit, and reason clearly. The description adds contextual meaning around the reason parameter by mentioning 'deprecated, vulnerable, abandoned, or suspicious' and typosquat filtering, but it does not add significant semantic detail 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 uses a specific verb ('suggest') and resource ('better-maintained npm alternatives') and clearly defines the triggering conditions: packages that look deprecated, vulnerable, abandoned, or suspicious. It differentiates the tool's role from sibling tools like search_packages by emphasizing alternative ranking rather than raw search.
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 states this is best for converting a 'don't use this package' warning into an actionable replacement shortlist, giving clear contextual guidance. It does not explicitly name sibling tools or say when not to use it, but the intended scenario is well implied.
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. Dates show when Glama detected each change.
1 tool update
- Changed
check_maintainer_changes3 fields changed- added
Output schema / properties / repository / properties / ownerAvatarUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / repository / properties / ownerLoginAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / repository / requiredPrevious value: -[ - "checked", - "declaredRepository", - "currentFullName", - "transferred", - "archived", - "reachable", - "note" -]New value: +[ + "checked", + "declaredRepository", + "currentFullName", + "transferred", + "archived", + "reachable", + "ownerLogin", + "ownerAvatarUrl", + "note" +]
2 tool updates
- Changed
check_maintainer_blast_radius2 fields changed- added
Output schema / properties / avatarUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / requiredPrevious value: -[ - "maintainerUsername", - "npmProfileUrl", - "totalPackagesFound", - "packagesReturned", - "resultsTruncated", - "clusterWindowHours", - "packages", - "clusters", - "findings", - "totalScore", - "riskTier", - "note" -]New value: +[ + "maintainerUsername", + "npmProfileUrl", + "avatarUrl", + "totalPackagesFound", + "packagesReturned", + "resultsTruncated", + "clusterWindowHours", + "packages", + "clusters", + "findings", + "totalScore", + "riskTier", + "note" +]
- Changed
get_maintainer_profile2 fields changed- added
Output schema / properties / avatarUrlAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / requiredPrevious value: -[ - "maintainerUsername", - "npmProfileUrl", - "totalPackagesFound", - "packagesReturned", - "resultsTruncated", - "currentlyMaintainsCount", - "totalWeeklyDownloads", - "totalDependents", - "packages", - "note" -]New value: +[ + "maintainerUsername", + "npmProfileUrl", + "avatarUrl", + "totalPackagesFound", + "packagesReturned", + "resultsTruncated", + "currentlyMaintainsCount", + "totalWeeklyDownloads", + "totalDependents", + "packages", + "note" +]
1 tool update
- Added
get_maintainer_profile
1 tool update
- Changed
simulate_dependency_upgrade8 fields changed- changed
Input schema / properties / currentVersion / descriptionPrevious value: -"Currently installed version — an exact version (e.g. \"4.17.20\"), a semver range (e.g. \"^4.17.0\"), or a dist-tag"New value: +"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." - changed
Input schema / properties / packageName / descriptionPrevious value: -"Exact npm package name, e.g. \"lodash\" or \"@scope/name\""New value: +"Exact npm package name, e.g. \"lodash\" or \"@scope/name\". Use this (with currentVersion) OR `packages`, not both." - added
Input schema / properties / packagesAdded value: +{ + "description": "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.", + "items": { + "additionalProperties": false, + "properties": { + "currentVersion": { + "description": "Currently installed version — an exact version, a semver range, or a dist-tag", + "maxLength": 128, + "minLength": 1, + "type": "string" + }, + "packageName": { + "description": "Exact npm package name, e.g. \"lodash\" or \"@scope/name\"", + "maxLength": 214, + "minLength": 1, + "type": "string" + }, + "targetVersion": { + "description": "Version to simulate upgrading to — exact version, range, or dist-tag. Omit to use the registry's \"latest\" dist-tag.", + "maxLength": 128, + "minLength": 1, + "type": "string" + } + }, + "required": [ + "packageName", + "currentVersion" + ], + "type": "object" + }, + "maxItems": 100, + "minItems": 1, + "type": "array" +} - changed
Input schema / properties / targetVersion / descriptionPrevious value: -"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."New value: +"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." - removed
Input schema / requiredRemoved value: -[ - "packageName", - "currentVersion" -] - added
Output schema / properties / batchSummaryAdded value: +{ + "additionalProperties": false, + "properties": { + "fetchFailedCount": { + "type": "number" + }, + "riskTierCounts": { + "additionalProperties": false, + "properties": { + "breakingChangeLikely": { + "type": "number" + }, + "lowRisk": { + "type": "number" + }, + "reviewRecommended": { + "type": "number" + }, + "safe": { + "type": "number" + }, + "unknown": { + "type": "number" + } + }, + "required": [ + "safe", + "lowRisk", + "reviewRecommended", + "breakingChangeLikely", + "unknown" + ], + "type": "object" + }, + "totalRequested": { + "type": "number" + }, + "vulnQueryFailedCount": { + "type": "number" + } + }, + "required": [ + "totalRequested", + "fetchFailedCount", + "riskTierCounts", + "vulnQueryFailedCount" + ], + "type": "object" +} - added
Output schema / properties / resultsAdded value: +{ + "items": { + "additionalProperties": false, + "properties": { + "currentIsVulnerable": { + "type": [ + "boolean", + "null" + ] + }, + "currentVersionNote": { + "type": [ + "string", + "null" + ] + }, + "direction": { + "enum": [ + "upgrade", + "downgrade", + "same", + "unresolved" + ], + "type": "string" + }, + "engineChange": { + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "after": { + "type": [ + "string", + "null" + ] + }, + "before": { + "type": [ + "string", + "null" + ] + }, + "tightened": { + "type": "boolean" + } + }, + "required": [ + "before", + "after", + "tightened" + ], + "type": "object" + }, + { + "type": "null" + } + ] + }, + "fetchError": { + "type": [ + "string", + "null" + ] + }, + "installScriptIntroduced": { + "type": [ + "boolean", + "null" + ] + }, + "isBreakingBySemver": { + "type": [ + "boolean", + "null" + ] + }, + "majorVersionsSkipped": { + "type": [ + "number", + "null" + ] + }, + "npmscanUrl": { + "type": "string" + }, + "packageName": { + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "type": "array" + }, + "requestedCurrentVersion": { + "type": "string" + }, + "requestedTargetVersion": { + "type": "string" + }, + "resolvedCurrentVersion": { + "type": [ + "string", + "null" + ] + }, + "resolvedTargetVersion": { + "type": [ + "string", + "null" + ] + }, + "riskTier": { + "enum": [ + "safe", + "low-risk", + "review-recommended", + "breaking-change-likely", + "unknown" + ], + "type": "string" + }, + "semverBump": { + "anyOf": [ + { + "enum": [ + "major", + "premajor", + "minor", + "preminor", + "patch", + "prepatch", + "prerelease" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "targetDeprecated": { + "type": [ + "string", + "null" + ] + }, + "targetIsPrerelease": { + "type": [ + "boolean", + "null" + ] + }, + "targetIsVulnerable": { + "type": [ + "boolean", + "null" + ] + }, + "targetVersionNote": { + "type": [ + "string", + "null" + ] + }, + "targetVulnerabilities": { + "items": { + "$ref": "#/properties/targetVulnerabilities/items" + }, + "type": "array" + }, + "verdict": { + "type": "string" + }, + "vulnerabilityDelta": { + "anyOf": [ + { + "enum": [ + "introduced", + "fixed", + "still-vulnerable", + "still-clean", + "unknown" + ], + "type": "string" + }, + { + "type": "null" + } + ] + }, + "zeroMajorNote": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "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" + ], + "type": "object" + }, + "type": "array" +} - removed
Output schema / requiredRemoved 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" -]
1 tool update
- Changed
audit_github_repository12 fields changed- added
Output schema / properties / findings / items / properties / maintainerFindingsAdded value: +{ + "anyOf": [ + { + "items": { + "$ref": "#/properties/findings/items/properties/installScriptFindings/anyOf/0/items" + }, + "type": "array" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / findings / items / properties / maintainerRiskTierAdded value: +{ + "anyOf": [ + { + "$ref": "#/properties/findings/items/properties/installScriptRiskTier/anyOf/0" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / findings / items / properties / ownershipRiskCheckedAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / findings / items / properties / ownershipRiskEligibleAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / findings / items / properties / ownershipRiskReasonAdded value: +{ + "anyOf": [ + { + "enum": [ + "critical-or-high-severity-vulnerability", + "possible-typosquat", + "deprecated" + ], + "type": "string" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / findings / items / properties / provenanceFindingsAdded value: +{ + "anyOf": [ + { + "items": { + "$ref": "#/properties/findings/items/properties/installScriptFindings/anyOf/0/items" + }, + "type": "array" + }, + { + "type": "null" + } + ] +} - added
Output schema / properties / findings / items / properties / provenanceRiskTierAdded value: +{ + "anyOf": [ + { + "$ref": "#/properties/findings/items/properties/installScriptRiskTier/anyOf/0" + }, + { + "type": "null" + } + ] +} - changed
Output schema / properties / findings / items / requiredPrevious value: -[ - "name", - "requestedVersion", - "resolvedVersion", - "npmscanUrl", - "deprecated", - "possibleTyposquatOf", - "isVulnerable", - "highestSeverity", - "vulnerabilities", - "rawLicense", - "licenseCategory", - "isLicenseCompliant", - "licenseNeedsReview", - "licenseViolation", - "hasLifecycleScripts", - "installScriptRiskTier", - "installScriptScore", - "installScriptScanScope", - "installScriptFindings", - "resolutionError" -]New value: +[ + "name", + "requestedVersion", + "resolvedVersion", + "npmscanUrl", + "deprecated", + "possibleTyposquatOf", + "isVulnerable", + "highestSeverity", + "vulnerabilities", + "rawLicense", + "licenseCategory", + "isLicenseCompliant", + "licenseNeedsReview", + "licenseViolation", + "hasLifecycleScripts", + "installScriptRiskTier", + "installScriptScore", + "installScriptScanScope", + "installScriptFindings", + "resolutionError", + "ownershipRiskEligible", + "ownershipRiskReason", + "ownershipRiskChecked", + "maintainerRiskTier", + "maintainerFindings", + "provenanceRiskTier", + "provenanceFindings" +] - added
Output schema / properties / ownershipCheckNoteAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / ownershipCheckedCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / ownershipRiskFlaggedCountAdded value: +{ + "type": "number" +} - 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", - "warnings", - "truncationNote", - "deepScanNote" -]New 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" +]
1 tool update
- Added
enrich_npm_audit
1 tool update
- Added
generate_sbom
1 tool update
- Changed
compare_packages5 fields changed- added
Output schema / properties / candidates / items / properties / installSizeAdded value: +{ + "anyOf": [ + { + "additionalProperties": false, + "properties": { + "transitive": { + "additionalProperties": false, + "properties": { + "sizeUnknownCount": { + "type": "number" + }, + "transitiveDependencyCount": { + "type": "number" + }, + "transitiveUnpackedSize": { + "type": [ + "number", + "null" + ] + }, + "truncated": { + "type": "boolean" + } + }, + "required": [ + "transitiveUnpackedSize", + "transitiveDependencyCount", + "sizeUnknownCount", + "truncated" + ], + "type": "object" + }, + "unpackedSize": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "unpackedSize", + "transitive" + ], + "type": "object" + }, + { + "type": "null" + } + ] +} - 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", - "score" -]New value: +[ + "name", + "found", + "resolutionError", + "npmscanUrl", + "description", + "license", + "latestVersion", + "deprecated", + "weeklyDownloads", + "downloadTrend", + "githubStars", + "hasBuiltInTypes", + "daysSinceLastPublish", + "popularityTier", + "maintenanceTier", + "maintenanceSummary", + "possibleTyposquatOf", + "isLatestVersionVulnerable", + "highestSeverity", + "vulnerabilityCount", + "installScriptRisk", + "installSize", + "score" +] - added
Output schema / properties / differentiators / properties / largestInstallSizeAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / differentiators / properties / smallestInstallSizeAdded value: +{ + "type": [ + "string", + "null" + ] +} - changed
Output schema / properties / differentiators / requiredPrevious value: -[ - "mostDownloads", - "mostGithubStars", - "hasTypeScriptSupport", - "hasKnownVulnerabilities", - "deprecated", - "possibleTyposquat", - "installScriptRiskFlagged" -]New value: +[ + "mostDownloads", + "mostGithubStars", + "hasTypeScriptSupport", + "hasKnownVulnerabilities", + "deprecated", + "possibleTyposquat", + "installScriptRiskFlagged", + "smallestInstallSize", + "largestInstallSize" +]
1 tool update
- Changed
audit_github_repository5 fields changed- added
Output schema / properties / isMonorepoAdded value: +{ + "type": "boolean" +} - added
Output schema / properties / workspaceNoteAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / workspacePackageCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / workspacePatternsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +} - changed
Output schema / requiredPrevious value: -[ - "summary", - "owner", - "repoName", - "ref", - "defaultBranchUsed", - "manifestPath", - "lockfilePath", - "inputFormat", - "policy", - "findings", - "overflowPackages", - "totalPackages", - "vulnerablePackageCount", - "licenseViolationCount", - "installScriptFlaggedCount", - "deepScannedCount", - "warnings", - "truncationNote", - "deepScanNote" -]New value: +[ + "summary", + "owner", + "repoName", + "ref", + "defaultBranchUsed", + "manifestPath", + "lockfilePath", + "inputFormat", + "isMonorepo", + "workspacePatterns", + "workspacePackageCount", + "workspaceNote", + "policy", + "findings", + "overflowPackages", + "totalPackages", + "vulnerablePackageCount", + "licenseViolationCount", + "installScriptFlaggedCount", + "deepScannedCount", + "warnings", + "truncationNote", + "deepScanNote" +]
1 tool update
- Added
simulate_dependency_upgrade
1 tool update
- Added
get_remediation_playbook
1 tool update
- Added
check_maintainer_blast_radius
1 tool update
- Added
audit_github_repository
1 tool update
- Added
compare_packages
3 tool updates
- Changed
batch_query_vulnerabilities3 fields changed- changed
Input schema / properties / content / descriptionPrevious value: -"Optional raw dependency inventory content: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, CycloneDX JSON, or SPDX JSON."New value: +"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." - changed
Input schema / properties / includeDevDependencies / descriptionPrevious value: -"Only applies when `content` is a package manifest/lockfile format that can distinguish dev dependencies. Default false."New value: +"Ignored when using `packages`; only applies when `content` is a manifest/lockfile format that distinguishes dev dependencies." - changed
Input schema / properties / packages / descriptionPrevious value: -"Optional explicit package list (1-1000 items). Use this OR `content`, not both."New value: +"Explicit package list (1-1000 items). Use this OR `content`, not both."
- Changed
get_cve4 fields changed- changed
Input schema / properties / cveId / descriptionPrevious value: -"Exact CVE ID for a single lookup, e.g. \"CVE-2026-2950\". When given, all search filters below are ignored."New value: +"Exact CVE ID for a single lookup, e.g. \"CVE-2026-2950\". When given, search filters below are ignored and should be omitted." - added
Input schema / properties / publishedUntil / $refAdded value: +"#/properties/publishedSince" - removed
Input schema / properties / publishedUntil / patternRemoved value: -"^\\d{4}-\\d{2}-\\d{2}$" - removed
Input schema / properties / publishedUntil / typeRemoved value: -"string"
- Changed
search_packages2 fields changed- added
Input schema / properties / query / maxLengthAdded value: +64 - changed
Input schema / properties / query / minLengthPrevious value: -1New value: +2
4 tool updates
- Changed
batch_query_vulnerabilities10 fields changed- added
Input schema / properties / contentAdded value: +{ + "description": "Optional raw dependency inventory content: package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, CycloneDX JSON, or SPDX JSON.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / includeDevDependenciesAdded value: +{ + "description": "Only applies when `content` is a package manifest/lockfile format that can distinguish dev dependencies. Default false.", + "type": "boolean" +} - changed
Input schema / properties / packages / descriptionPrevious value: -"1-100 packages to check"New value: +"Optional explicit package list (1-1000 items). Use this OR `content`, not both." - changed
Input schema / properties / packages / maxItemsPrevious value: -100New value: +1000 - removed
Input schema / requiredRemoved value: -[ - "packages" -] - added
Output schema / properties / ignoredCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / inputFormatAdded value: +{ + "type": "string" +} - added
Output schema / properties / parsedPackageCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / queryFailureCountAdded value: +{ + "type": "number" +} - added
Output schema / properties / warningsAdded value: +{ + "items": { + "type": "string" + }, + "type": "array" +}
- Added
diff_dependencies - Added
prioritize_remediation - Added
suggest_alternative
1 tool update
- Added
check_license_compliance
1 tool update
- Added
check_maintainer_changes
Frequently Asked Questions
Claiming proves that you control a remote MCP connector. It does not move, proxy, or interrupt the server.
Open the connector listing, choose Claim ownership, and sign in to Glama.
Complete one verification method:
GitHub identity — fastest for official registry listings. For a namespace such as
io.github.alice/server, link the matching GitHub user, then choose Claim with GitHub. An organization namespace such asio.github.acme/serveralso needs that organization to have installed the Glama AI GitHub App and approved its permissions, because GitHub discloses organization membership only to apps it has installed. Use HTTP or DNS when it has not.HTTP challenge — works when you can deploy a public file. Generate a token, publish the exact JSON Glama shows at
/.well-known/glama.jsonon the same origin as the connector, then choose Check HTTP challenge.DNS challenge — works when you control DNS but cannot change the server. Generate a token, create the exact TXT record Glama shows, wait for it to propagate, then choose Check DNS challenge.
After verification, Glama sends a confirmation email and gives you access to listing details, thumbnails, health checks, and analytics. Keep the HTTP file or DNS record in place: Glama periodically checks it and ownership remains verified while the token is discoverable.
The HTTP ownership file has this structure:
{
"$schema": "https://glama.ai/mcp/schemas/connector.json",
"claim": "glama_claim_..."
}Claim tokens are opaque, stable, and bound to the signed-in Glama account. They contain no email address or other personal information. If Glama can no longer discover a verified HTTP or DNS token, it starts a seven-day grace period before removing claim-based access. Restore the same token during that period to keep ownership verified. Never publish an email address, Glama session token, GitHub token, or connector credential as ownership proof.
If verification fails, confirm that you copied the current token exactly. The HTTP file must be public, return valid JSON with a successful HTTP response, and stay on the connector's origin. DNS changes may need more time to propagate. A claim cannot transfer to a different origin or hostname: if the connector target changes, Glama starts the grace period and the new target must be claimed separately after the previous claim is released.
For a connector linked to the official MCP Registry, registry updates continue to replace its name, description, and URL by default. After claiming, open Manage connector and enable Use Glama listing details as the source of truth if edits made on Glama should be preserved. Categories and thumbnails are always managed on Glama; registry linkage and technical connection settings continue to sync.
Control your server's listing on Glama, including description and metadata
Access analytics and receive server usage reports
Get monitoring and health status updates for your server
Feature your server to boost visibility and reach more users
To improve your MCP server's ranking:
Claim ownership of the server listing
Complete the server profile with an accurate description and thumbnail
Provide a test profile so Glama can connect to and evaluate the server
Keep tool definitions clear and complete to earn a high Tool Definition Quality Score (TDQS)
Route real usage through the Glama Gateway; more recorded successful server uses also improve the ranking
For users:
Full audit trail – every tool call is logged with inputs and outputs for compliance and debugging
Granular tool control – enable or disable individual tools per connector to limit what your AI agents can do
Centralized credential management – store and rotate API keys and OAuth tokens in one place
Change alerts – get notified when a connector changes its schema, adds or removes tools, or updates tool definitions, so nothing breaks silently
For server owners:
Proven adoption – public usage metrics on your listing show real-world traction and build trust with prospective users
Tool-level analytics – see which tools are being used most, helping you prioritize development and documentation
Direct user feedback – users can report issues and suggest improvements through the listing, giving you a channel you would not have otherwise
The connector status is unhealthy when Glama is unable to successfully connect to the server. This can happen for several reasons:
The server is experiencing an outage
The URL of the server is wrong
Credentials required to access the server are missing or invalid
If you are the owner of this MCP connector and would like to make modifications to the listing, including providing test credentials for accessing the server, please contact support@glama.ai.
Discussions
hey guys
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables detection and analysis of pre-public product launches through web search, content extraction, AI-powered scoring, and automated alerting. Provides comprehensive tools for surfacing stealth startup signals before they trend publicly.MIT

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- AlicenseNot gradedqualityCmaintenanceEnables AI chat clients to perform market research and competitive intelligence by gathering company overviews, competitor lists, product portfolios, pricing snapshots, and recent news via live Tavily search.MIT
- AlicenseAqualityAmaintenanceDetects hiring intent signals by scanning job boards for specific companies. Returns structured role data for outbound sales targeting.11961MIT
Glama MCP Gateway
Add one secure layer between your agents and this server.
TDQS
Most tools target a distinct part of the supply-chain lifecycle, and the detailed descriptions include explicit cross-references that reduce misselection. The main ambiguity is among the vulnerability-lookup tools—especially get_latest_advisories and get_cve, which both accept CVE IDs, and query_vulnerabilities versus batch_query_vulnerabilities, which differ mainly in input shape.
Every tool name uses lowercase snake_case with a leading imperative verb or verb phrase: analyze_, audit_, batch_query_, check_, compare_, diff_, get_, prioritize_, query_, search_, and suggest_. The check_* tools form a consistent sub-family, and there are no camelCase or noun-only strays.
18 tools is on the high side, so the server feels slightly heavy rather than lean. However, the domain is broad enough that each tool occupies a meaningful workflow step—metadata lookup, vulnerability querying, transitive analysis, license/maintainer/provenance checks, repo auditing, diffing, and remediation—so the count is still reasonable for a comprehensive npm security server.
The surface covers the full npm supply-chain audit workflow: discovery, exact-version and lockfile vulnerability checks, transitive dependency resolution, install-script deep scans, license compliance, maintainer and provenance history, repo-level audits, dependency diffs, remediation prioritization, and alternative suggestions. There are no obvious dead ends, and the tools consistently point to natural follow-up actions.