Back to blog

npm-audit for MCP security: A deep-dive on mcp-scan

Auth & identity

May 2, 2025

Author: Reed McGinley-Stempel

npm-audit for MCP security: A deep-dive on mcp-scan

“If your agent reads every tool description as gospel, one poisoned line of YAML is all an attacker needs.”

mcp-scan is the lint-plus-SAST that stops that line from ever reaching production.

TL;DR

  • Model Context Protocol (MCP) supply-chain attacks are now practical (prompt injection, tool poisoning, “rug pulls,” cross-origin shadowing).
  • mcp-scan is an Apache-2-licensed CLI that crawls every MCP server you’ve installed, hashes the tool manifests, and runs local + cloud guardrails to flag anything evil.
  • Add it into GitHub Actions with three lines of YAML and you’ll break the build on any “High” finding.
  • Think of it as npm audit / trivy for the agent world—but tailor-made for Model Context Protocol.

Why MCP needs a scanner at all?

Elena Cross’s recent article “The ‘S’ in MCP stands for Security” set Hacker News ablaze debating the threat landscape for model context protocol servers. The debate highlighted two core issues with MCP security today:

  1. Tool descriptions are executable instructions. Hide one malicious sentence in the send_email description and the LLM happily exfiltrates your inbox.
  2. One-time approval is brittle. An MCP server can mutate its schema tomorrow and no mainstream client warns you.

In other words: we don’t just have runtime risk, we have a classic software-supply-chain problem—exactly the niche npm audit solved for JavaScript packages.

Meet mcp-scan

An open-source CLI (>500 github stars) that:

  • Discovers installed MCP configs for clients like Claude Desktop, Cursor & Windsurf.
  • Fetches every registered tool description.
  • Checks for four classes of vulns:
    • Prompt-injection / tool-poisoning
    • Cross-origin escalation (tool shadowing)
    • “Rug pulls” via Tool Pinning (hash diff)
    • Generic prompt-security issues reported by Invariant Guardrails.

Quick start

# zero-setup scan
uvx mcp-scan@latest        # or:  npx mcp-scan@latest

How it works under the hood

  1. Discovery: Expect a red/green summary and a JSON SARIF file in ~/.mcp-scan. Walks well-known paths (~/.config/**/mcp/*.json) or any file you pass on the CLI.
  2. Harvest: Sends read-only calls to each MCP server, caching the full manifest.
  3. Local heuristics: Regex & AST checks catch obvious no-nos ({{system}}, curl, rm -rf /).
  4. Guardrail analysis: Tool names + descriptions go to Invariant Guardrails for ML-based
  5. Pin & diff: Tool names + descriptions go to Invariant Guardrails for ML-based prompt-injection detection (opt-out flag: --local-only)

All findings wind up in a single JSON; the CLI renders a human table and lets you drill in with:

uvx mcp-scan@latest inspect <TOOL_NAME>

Shipping it in CI/CD

# .github/workflows/security.yml
name: MCP security

on: [push, pull_request, schedule]
schedule:
  - cron: "0 3 * * *"   # nightly drift scan

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: pipx run uv mcp-scan@latest --storage-file results.json
      - name: Fail on Highs
        run: |
          HIGH=$(jq '.summary.high' results.json)
          [ "$HIGH" -eq 0 ] || { echo "$HIGH high findings"; exit 1; }

Add three lines; get an early-warning system for free.

Life after the first scan

  • Whitelist real false-positives
mcp-scan whitelist tool "ok-tool" <SHA>
  • Show the delta — commit results.json; a diff in PR shows new vulns.
  • Dashboard it — parse SARIF in Grafana for a monthly “MCP Risk Score.”

Limitations & trade-offs

  • Cloud call means text leaves your perimeter. Self-host Guardrails or toggle --local-only.
  • Static only. Runtime arguments and LLM jailbreaks still need sandboxing and policy enforcement.
  • False positives exist. The whitelist command is your escape valve.

New and roadmap nuggests

  • WASM sandbox probes to catch tools that shell out.
  • Signed manifests so hash-pinning can travel across orgs.
  • Native VS Code extension for in-editor diff alerts.

Try it today

  1. pipx run uv mcp-scan@latest
  2. Read the report.
  3. Brag that your agent pipeline now has the npm-audit moment it was missing.

Pro-tip: Drop the before/after diff in your next security review. Nothing sells risk reduction like a build log that turns from red to green.

Further reading

Secure agents are possible—but only if you treat tool descriptions like code and scan them every time you ship. mcp-scan makes that a one-line habit.



Share this article