Skip to main content

shadow-mcp

Discover and risk-grade the MCP servers actually present on this machine.

Most MCP security tooling assumes you already have a list of servers to audit. On a real developer machine you don't: servers are scattered across Claude Code, Codex, Claude Desktop, project-local .mcp.json files, DXT extensions, and live processes that bind no port. shadow-mcp finds them first, then grades them.

This is the local-first answer to OWASP MCP09:2025 — Shadow MCP Servers.

What it does

discover  ->  inventory  ->  risk-grade  ->  report
  1. Discover (read-only) every place an MCP server is declared or running: Claude Code (~/.claude.json, user + project scope), claude mcp list (catches remote + plugin servers no file contains), Codex (~/.codex/config.toml + profiles), project .mcp.json, Claude Desktop config + DXT extension manifests, and the live process table.
  2. Inventory: merge sightings into one entry per logical server, even when a server appears under different names across hosts (personal-ops vs personal_ops), tracking every provenance.
  3. Risk-grade by delegating to the existing engines rather than reimplementing them:
    • MCPAudit for a 0-10 capability composite + injection findings
    • mcp-trust for an authoritative A-F danger grade (when known)
    • a thin local layer for the config-shaped OWASP dimensions the engines under-cover (secrets/MCP01, supply-chain provenance/MCP04, transport exposure/MCP07).
  4. Report: a ranked terminal table, a machine-readable JSON inventory, or markdown — plus a Shadow & attention section for the deltas that matter (running-but-unconfigured, broad blast radius, capable-but-ungraded).

The risk model and its OWASP mapping live in docs/risk-model.md.

Install

uv sync                 # installs deps incl. MCPAudit as a local editable engine

shadow-mcp grades against your local checkouts of MCPAudit (../MCPAudit) and mcp-trust (../mcp-trust/registry.db). Override with SHADOW_MCP_MCPTRUST_DB or --registry-db.

Use

uv run shadow-mcp scan                      # full pipeline, terminal report
uv run shadow-mcp scan --json out.json      # machine-readable inventory
uv run shadow-mcp scan --format markdown    # markdown report
uv run shadow-mcp discover                  # inventory only, no grading
uv run shadow-mcp sources                   # per-collector counts
uv run shadow-mcp grade-missing             # A-F for servers the registry hasn't scanned
uv run shadow-mcp deep-scan cost-tracker    # connect to a server, grade its real tools

Useful flags: --no-processes (skip the live process scan), --no-cli (skip claude mcp list), --no-mcpaudit (inventory + mcp-trust only), --home PATH (point discovery at a fixture tree).

Static vs connected grading

By default grading is static (config-only): no server is spawned, so grades reflect what's visible in the config. That's safe but coarse — a server's real capability only shows once you connect and list its tools.

shadow-mcp scan --connect (or deep-scan [names...]) spawns each stdio server and enumerates its real tools, delegating to MCPAudit's connected engine for a capability grade that actually differentiates (a filesystem server jumps from a static A to a connected D). This is opt-in because connecting executes the server; remote endpoints are never spawned (that's the network-scan tier), and a server that needs real secrets to start falls back to its static grade.

Development

uv sync                       # dev tools + grading engines (the default groups)
uv run pytest                 # full suite (61 + engine-backed tests)
uv run ruff check .           # lint

The grading engines are an optional engines dependency-group, resolved to your local checkouts of ../MCPAudit and ../mcp-trust via [tool.uv.sources]. The tool degrades to discovery-only without them (engine-backed tests skip cleanly), so CI installs without them:

uv sync --no-group engines    # discovery + local OWASP layer only (what CI runs)

Safety

  • Read-only discovery. Collectors parse configs and list processes; nothing they find is ever mutated. (--connect/deep-scan is the one path that executes servers, and only when you explicitly ask.)
  • Secrets stay out. We record env variable names (to flag secret-bearing servers per MCP01) but never their values. A captured inventory still contains real local paths and hostnames, so treat *.inventory.json as private (it is git-ignored by default).

Use as an MCP server

shadow-mcp can serve its own inventory tools as an MCP server so an agent can query your local MCP surface without leaving the conversation.

Tools

Tool Description
scan_local Full pipeline (discover → inventory → grade → report). Returns JSON.
discover_local Inventory every MCP server without grading. Returns JSON.
deep_scan Grade only the named servers (static, no spawning). Accepts names: list[str]. Returns JSON.
list_sources Per-collector source counts from a discover run. Returns JSON.

Run the server

# directly from a local checkout
shadow-mcp mcp-serve

# via uvx (once published to PyPI)
uvx shadow-mcp mcp-serve

LOCAL only. The MCP server never connects to hosted MCP endpoints — all grading is static (config-based). connect=False is enforced unconditionally; no server is ever spawned from an MCP tool call.

Scope

This is the local-first tool: it inventories one machine from its configs and processes. A later network-scan expansion (probing hosts/ports for remote MCP endpoints, org-wide fleet inventory, typosquat-distance provenance checks) is deliberately out of scope here — see the bottom of docs/risk-model.md and the project notes for what that would add.

Release files for shadow-mcp 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for shadow-mcp 0.2.0
File Size Uploaded
shadow_mcp-0.2.0.tar.gz 47.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for shadow-mcp 0.2.0
File Interpreter ABI Platform
shadow_mcp-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 90.6 kB

Release files / shadow_mcp-0.2.0.tar.gz

Download URL shadow_mcp-0.2.0.tar.gz
Size 47.4 kB
Tags Source
SHA-256 checksum
How to use checksums
31d35cb30155fbfc350e280f6cdcc67174f44d11e52c6bbf8280b3b4710ae936
BLAKE2b-256 checksum
How to use checksums
0d7d86a3ac8feeab9bd1f6aa8ae7dea9c96082ada4f743d00a8145b790e29076
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 3, 2026.

Transparency log

Release files / shadow_mcp-0.2.0-py3-none-any.whl

Download URL shadow_mcp-0.2.0-py3-none-any.whl
Size 43.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
dcb2781cdb427c5f749b3b622a2e9453708b2f5e863e2ba253d7fda0bbb18366
BLAKE2b-256 checksum
How to use checksums
1eb4faad9868db3c4a15997ffae000ef1059e241fbdade324a0307c49f394356
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jul 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page