shadow-mcp

io.github.saagpatel由 GitHub 账号 saagpatel 发布v0.2.0更新于 Oct 24, 2026

Local MCP server that inventories and risk-grades MCP servers configured on this machine.

已验证STDIO仅桌面开发者工具安全与监控

概览

AI 生成的概览

本地 MCP 服务器,用于发现本机已配置的 MCP 服务器、汇总清单并进行风险评级。

可以做什么
  • 运行发现、汇总、评级、报告的完整流程并返回 JSON
  • 在不评级的情况下清点本地配置与进程表中的所有 MCP 服务器
  • 对指定服务器或全部服务器进行基于配置的静态评级
  • 显示各采集器在一次发现运行中的来源计数
  • 合并跨主机重复出现的同一服务器,并标出运行中但未配置或权限过大的服务器
适用场景
适合让助手在不离开对话的情况下核查开发机上实际安装了哪些 MCP 服务器、来源何处、风险如何。适用于本机影子 MCP 的合规检查,而非远程或全组织范围的扫描。
运行要求
以 stdio 本地进程运行,通过 uvx 从 PyPI 的 shadow-mcp 包启动,需要 Python 3.11 或更高版本;评级引擎在运行时从 PyPI 获取。未声明账号、API 密钥或环境变量。会读取本机配置文件与进程表。
安装前请注意
MCP 工具仅限本地,读取配置与进程表,结果会包含本地路径和主机名,生成的清单 JSON 应视为私密数据。命令行可选地启动服务器进行评级,但 MCP 工具强制静态评级,不会启动或连接服务器。README 指出采集器失败可能悄无声息,报告写入非原子操作。

安装

在 SourceWeft 中

  1. 打开 控制台中的 shadow-mcp,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。

其他 MCP 客户端

参照 仓库 中的启动说明。

README

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) MCP servers from supported configuration and runtime sources: 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

From this repository root, use uv:

bash
make setup

The grading engines (mcp-audits and mcp-trust) are runtime dependencies resolved from PyPI, not editable sibling checkouts or an engines group. The installed mcp-trust package supplies its seed catalog; --registry-db or SHADOW_MCP_MCPTRUST_DB selects an explicitly chosen local registry instead.

Use

bash
uv run shadow-mcp scan                      # full pipeline, terminal reportuv run shadow-mcp scan --json out.json      # machine-readable inventoryuv run shadow-mcp scan --format markdown    # markdown reportuv run shadow-mcp discover                  # inventory only, no gradinguv run shadow-mcp sources                   # per-collector countsuv run shadow-mcp grade-missing             # A-F for servers the registry hasn't scanneduv 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 and safe verification

The committed uv.lock fixes the PyPI runtime and development graph. From the repository root, run:

bash
make check

The suite uses synthetic homes. Keep SHADOW_MCP_RUN_CONNECT unset: the explicitly opted-in connected test is a separate server-execution lane. CI runs the same aggregate gate on Python 3.11 through 3.15; see the workflow. make build creates the wheel and sdist used by the release workflow.

Do not use the normal scan, discover, sources, grade-missing or MCP tool calls as a development smoke: they inventory the machine by default. CLI deep-scan and scan --connect additionally execute servers. For changed JSON or Markdown reports, check the corresponding fixture tests (tests/test_report.py) and inspect synthetic output; this CLI has no browser UI. Actual workstation or connected behavior requires its own explicitly authorized qualification.

Safety

  • Read-only discovery. Collectors parse configs, invoke claude mcp list (unless --no-cli is set), 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. Inline credentials in command arguments, URLs, and process parent commands are redacted before storage. A captured inventory still contains 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

ToolDescription
scan_localFull pipeline (discover → inventory → grade → report). Returns JSON.
discover_localInventory every MCP server without grading. Returns JSON.
deep_scanGrade the named servers, or all servers when the list is empty (static, no spawning). Accepts names: list[str]. Returns JSON.
list_sourcesPer-collector source counts from a discover run. Returns JSON.

Run the server

bash
# directly from a local checkoutuv run shadow-mcp mcp-serve
# via uvx (once published to PyPI)uvx shadow-mcp mcp-serve

LOCAL only. MCP tools read local configs and the process table, skip claude mcp list, and never connect to hosted MCP endpoints or spawn servers. Grading is static (config-based); connect=False is enforced unconditionally.

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.

Status

Stack

Python 3.11+; uv-managed locked dependencies; Ruff, mypy, and pytest checks; Hatchling wheel and sdist builds.

Known risks

  • The minimum Python version remains 3.11 pending an owner decision about raising it to 3.12.
  • The MCP tool name deep_scan remains unchanged pending an owner decision; the similarly named CLI command can connect to servers.
  • Identity collisions in identity and inventory matching.
  • Process sightings are deduplicated by name before owner classification.
  • Grading evidence is limited to eight findings, and critical ranks below low.
  • Collector failures can be silent.
  • --json is ignored by sources and grade-missing.
  • Report writes are not atomic.
  • Markdown and Rich output escaping differs.
  • Dependency major upgrades, moving off Hatchling, a coverage threshold, package publishing, tags, and releases remain out of scope.

Next steps

Resolve the Python floor and MCP tool naming decisions, then address the listed behavior risks in a follow-up wave.

来源:README.md,提交 f6e3b69

工具

0
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.2.0最新Sep 16, 2026

评分

已满足适用检查项的 40%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分

    请在仓库或注册中心条目中声明许可证。