Skip to main content
People find your server on npm or PyPI before they ever run it. A listing with no license or no source link loses them before the first npx. --package scores that listing from registry metadata.
The package is never downloaded and never executed, so no install script runs on your machine. The whole audit is one HTTPS request to the registry.

Step 1: Audit a package on npm

A coordinate is the registry, a colon, and the package name as that registry spells it. Scoped npm packages keep their @:
The output is the one above: six packaging rules, 16/16. A rule is one check, such as “a license is declared”. The rules reference lists all six with their weights.

Step 2: Pin a release on PyPI

A PyPI coordinate works the same way as an npm one. Add == and a version to audit one release instead of the latest:
That release shipped without a repository URL, so the source check fails and prints the fix. The latest release of the same package scores 16/16. Pinning lets you check the exact version your users install. npm pins use @: npm:name@1.2.3, or npm:@scope/name@1.2.3.

Step 3: Gate CI on the package score

--fail-under works on a package audit the same way it works on a server audit. The run exits 3 when the score is below the threshold:
Run it in your release pipeline after publishing. A release that drops its license or source link fails the job instead of reaching users.

Step 4: Get the JSON report

--json prints the same report shape as a server audit, with a package block filled in:
executed is always false. A non-null package object marks a report as a package audit, and the stability contract describes each field.

Package score and server score

A package audit tells you whether the server is well published. A server audit tells you whether it speaks MCP. The two use disjoint rule sets, so their scores share no denominator and cannot be compared or averaged. Any tool that aggregates reports must branch on the package field. To score the server itself, run the same package through its runner with --stdio:
These commands download and run the package, which a package audit never does.

When it fails

❌ Package "@scope/name" was not found on npm., then Final score: 0/5
  • Cause: no package by that name exists on that registry, so the other five rules have nothing to read and skip.
  • Fix: check the spelling and the scope. Scoped npm names keep their @: npm:@scope/name.
❌ Version "0.0.1" was not found for "mcp-server-fetch" on pypi.
  • Cause: the pinned version was never published, or was removed.
  • Fix: drop the pin to audit the latest release, or pin one that exists.
Usage error: Missing registry prefix in 'server-everything' (exit 1)
  • Cause: the coordinate has no npm: or pypi: prefix.
  • Fix: add the prefix, as in npm:server-everything.
Could not read npm metadata: ... (exit 2)
  • Cause: the registry did not answer, or answered with something that is not package metadata.
  • Fix: retry once the registry is reachable. Nothing is scored until it answers.

Recap

  • Audit a package with --package npm:name or --package pypi:name.
  • Pin a release with @1.2.3 on npm or ==1.2.3 on PyPI.
  • Gate a release pipeline with --fail-under.
  • Read the package block from --json.
  • Score the running server separately, with --stdio.

What’s next

Rules reference

The six packaging rules and their weights

Audit a local server

Score the server itself over stdio