npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@miaggy/mcp-audit

v0.3.0

Published

Audits the MCP servers configured on a machine for supply-chain risk: unpinned versions, inline secrets, missing provenance, install scripts, maintenance signals

Readme

@miaggy/mcp-audit

Audits the MCP servers a machine is configured to run, for supply-chain risk and tool-manifest poisoning. It reads the config files of Claude Desktop, Claude Code (including project-scoped servers), Cursor, VS Code, and Goose, checks each configured npm or PyPI package against its public registry, and reports findings with threat rationale, a posture score, and a remediation roadmap. Every discovered server is accounted for — see Coverage.

Two modes with an explicit line between them: the static audit never executes a discovered server. The manifest scan (--manifests, or the scan_mcp_manifests tool) is the opt-in that does: it starts each configured stdio server with a handshake-only MCP client — initialize and tools/list, never a tool call — then shuts it down. Scanned servers receive their configured env, which they need to start; you already run them with exactly that env.

Static checks

| Rule | Severity | What it catches | |---|---|---| | unpinned-server-version | high | npx -y some-mcp or uvx some-mcp with no @version: every client start runs whatever the registry serves | | secrets-in-env-block | high | Literal API keys or tokens in a config env block (the finding names the variable, never the value) | | server-no-provenance | medium | Package has no npm provenance attestation binding it to a source build | | server-install-scripts | medium | Package declares preinstall/install/postinstall hooks | | server-low-maintenance-signal | low | Single maintainer and no publish in over 540 days |

Manifest checks (opt-in scan)

| Rule | Severity | What it catches | |---|---|---| | tool-description-injection-pattern | critical | A tool description that matches a prompt-injection signature family — instructions addressed to the model, not documentation | | tool-shadowing-collision | high | The same tool name exposed by two servers; calls routed by name alone can land on the wrong one | | destructive-tool-unannotated | medium | Delete/send/pay/execute-sounding tools with neither readOnlyHint nor destructiveHint | | oversized-tool-description | low | Multi-thousand-character descriptions, where smuggled instructions hide |

Drift detection

Record a baseline once, then flag anything that changes:

npx -y @miaggy/mcp-audit snapshot                       # writes mcp-audit-baseline.json
npx -y @miaggy/mcp-audit audit --baseline mcp-audit-baseline.json

The diff flags changed servers (manifest-drift-since-baseline, high — including the rug-pull shape where tool names stay identical but a description changes) and additions (new-server-since-baseline, medium). The baseline stores env variable names and hashed tool descriptions, never values; the format is specified in docs/baseline-format.md. Accept expected changes by taking a fresh snapshot. Snapshotting captures live manifests, so it performs the same handshake as --manifests.

Unreadable config files, failed registry lookups, unscannable servers, and unreadable baselines become skip findings, never a silent empty: the report always states what was not checked.

Coverage

Clients discovered. A config file for a client you don't run is simply absent, not a gap.

  • Full support: Claude Desktop, Claude Code (top-level and project-scoped servers in ~/.claude.json), Cursor, VS Code, Goose (config.yaml).
  • VS Code family: the Code, Code - Insiders, and VSCodium product directories are all checked (per-OS), so forks are covered. Cline rides the same variant paths (its config lives in VS Code extension storage).
  • Best-effort: Windsurf, Cline, Continue, Zed. These are younger and their config schema/paths churn between versions; an unrecognized shape yields zero servers (a graceful no-op), never a crash or a false finding. Covered on a best-effort basis rather than guaranteed.

What gets assessed depends on how a server is launched. Every discovered server appears in the report — assessed, or a named NOT_APPLICABLE coverage-skip stating exactly what was not checked and why:

| Launch shape | Example | Assessment | |---|---|---| | npm | npx, bunx | full: pinning, provenance, install scripts, maintenance | | PyPI | uvx, pipx | pinning + maintenance. PyPI publishes no provenance or install-script data, so those two are named as a residual rather than assumed to pass | | node / python / local binary | node, python, a path | inline-secrets only; no package registry to query — named as a coverage-skip | | remote (url) | an SSE/HTTP endpoint | not locally assessable by the static audit — named as a coverage-skip (the opt-in --manifests scan can inspect a stdio server's live tools) |

An empty findings list therefore means "looked and found nothing," never "did not look."

Deliberately out of scope: container images

Servers launched via docker/podman are discovered and named (each gets a coverage-skip), but their images are not assessed, by design. npm and PyPI can be assessed cleanly because each is a single public registry with an anonymous read API. Container images break all three assumptions: they come from many registries (Docker Hub, GHCR, GCR, ECR, Quay, private/self-hosted), most requiring authentication — and a read-only auditor should not hold registry credentials, so many images are structurally unassessable. Deep assessment means pulling and inspecting image layers, which is the job of a dedicated image scanner (Trivy, Grype, Docker Scout), not a config-layer auditor. We name every container-launched server so coverage stays honest, and defer to those tools for the image itself. This boundary is version-scoped — if container-launched MCP servers become common, it is worth revisiting.

Usage

As a CLI, for humans and CI:

npx -y @miaggy/mcp-audit audit
# exit 0 clean, 1 on any high-severity finding, 2 on bad args

As an MCP server (ask your client to audit its own configuration):

{
  "mcpServers": {
    "mcp-audit": {
      "command": "npx",
      "args": ["-y", "@miaggy/[email protected]"]
    }
  }
}

Yes, the config above pins the version. The rules in this package encode the same practices this project ships with: pinned versions, provenance (verify with npm audit signatures), no install scripts.

Built on @miaggy/core. Findings map to the OWASP Top 10 for Agentic Applications, OWASP LLM Top 10 (2025), NIST AI RMF, and MITRE ATLAS. The full rule catalog with per-rule threat and rationale is committed at examples/rules-catalog.json.

MIT.