Skip to main content
Glama

Find every package an npm maintainer account touches, and flag a tight publish cluster

check_maintainer_blast_radius
Read-only

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. npmscanUrl is this account's profile page on npmscan itself; npmProfileUrl is the account's actual page on npmjs.com, included for verification since that's the authoritative record of the account.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
maintainerUsernameYesExact npm username, e.g. "sindresorhus" — as shown at npmjs.com/~username. Not an email address, not a package name or scope.

Output Schema

TableJSON Schema
NameRequiredDescriptionDefault
noteYes
clustersYes
findingsYes
packagesYes
riskTierYes
avatarUrlYes
npmscanUrlYes
totalScoreYes
npmProfileUrlYes
packagesReturnedYes
resultsTruncatedYes
clusterWindowHoursYes
maintainerUsernameYes
totalPackagesFoundYes

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • addedOutput schema / properties / npmscanUrl
      Added value: +{
      +  "type": "string"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "maintainerUsername",
      -  "npmProfileUrl",
      -  "avatarUrl",
      -  "totalPackagesFound",
      -  "packagesReturned",
      -  "resultsTruncated",
      -  "clusterWindowHours",
      -  "packages",
      -  "clusters",
      -  "findings",
      -  "totalScore",
      -  "riskTier",
      -  "note"
      -]New value: +[
      +  "maintainerUsername",
      +  "npmscanUrl",
      +  "npmProfileUrl",
      +  "avatarUrl",
      +  "totalPackagesFound",
      +  "packagesReturned",
      +  "resultsTruncated",
      +  "clusterWindowHours",
      +  "packages",
      +  "clusters",
      +  "findings",
      +  "totalScore",
      +  "riskTier",
      +  "note"
      +]
  2. Changed2 schema fields changed
    • addedOutput schema / properties / avatarUrl
      Added value: +{
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • changedOutput schema / required
      Previous 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"
      +]
  3. Added

TDQS

A4.6/5.0
Behavior5/5

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

The description is highly transparent about behavior: it is read-only, uses npm's possibly lagging text-relevance index, caps results at one page, cross-checks current maintainer status because access is often revoked, and explains how scoring dampens monorepo-style scope clusters and combines multiple clusters with diminishing returns. It also clarifies the avatar proxy and null conditions.

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

Conciseness4/5

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

The description is long and dense, but nearly every sentence carries necessary context about scoring rationale, false positives, follow-up usage, and known limitations. It is front-loaded with the core purpose and then layers caveats and examples without obvious fluff, though it could be slightly better structured with paragraphs or bullets.

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

Completeness5/5

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

Given the tool's nuanced scoring and many edge cases, the description is exceptionally complete. It explains the query mechanism, the compromised-account pattern, monorepo dampening, diminishing returns for multiple clusters, output fields like resultsTruncated and isCurrentMaintainer, known limitations, and verification URLs.

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

Parameters3/5

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

The single parameter maintainerUsername is already fully described in the schema, including the example, the exact npmjs.com form, and exclusions for emails/package names/scopes. The tool description adds contextual behavior around the parameter but does not materially extend the parameter's semantic meaning beyond what the schema already provides.

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

Purpose5/5

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

The description clearly states the tool takes an npm username, queries npm's search index for all packages by that maintainer, and looks for tight publish clusters indicative of a compromised account. It distinguishes itself from related tools like check_maintainer_changes and search_packages by focusing on blast radius and coordinated publish timing.

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

Usage Guidelines5/5

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

The description explicitly positions this tool as the natural follow-up to check_maintainer_changes, telling agents to call it with a flagged maintainer's username to see if the same account touched other packages. It also gives important usage caveats such as search-index lag, truncation at 250 results, and the fact that results are relevance-ranked rather than recency-ranked.

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

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources