MCP Permission Auditor — scan, enumerate, and risk-score all locally configured MCP servers
Project description
mcp-audit
You're giving AI direct access to your computer. Do you actually know what you've installed?
mcp-audit gives you x-ray vision into every MCP server configured on your system: what it can do, how risky it is, whether its descriptions are hiding adversarial instructions, and whether it's changed since you last looked. It is local-first, needs no API key by default, and makes networked LLM analysis opt-in.
PyPI package: mcp-permission-audit. Installed command: mcp-audit.
Features
- Capability inventory — catalogs server tools, prompts, and resources; tool, prompt, and resource capabilities are classified across six permission categories:
file_read,file_write,network,shell_execution,destructive,exfiltration - Config-only inference —
scan --skip-connectinfers conservative risks from declared commands, transports, credential key names, package runners, and remote URLs - Risk scoring — composite 0–10 per server as a weighted sum of tool permission categories, with a five-dimension breakdown (file access, network, shell, destructive, exfiltration); prompt/resource findings also produce an additive
non_tool_risksignal without changingrisk_score.composite - Stable finding metadata — permission and prompt-injection findings include stable rule IDs, severity, evidence, and suggested remediation so reports are easier to triage
- Local policy gates —
scan --policy policy.yamlevaluates reports against local YAML rules and exits nonzero for CI enforcement - Report redaction — terminal, JSON, and SARIF report paths share a redaction layer for likely credential values
- Prompt injection detection —
scan --inject-checkscans tool, prompt, and resource text for instruction-override patterns, hidden directives, fake role turns, and adversarial phrasing; pattern-based, no LLM required - Schema drift tracking —
mcp-audit pinconnects to servers and snapshots current tool schemas; subsequentscan --pin-checkflags added, removed, and changed tools with plain-language summaries, changed-field hints, suggested actions, and a dry-run refresh workflow for reviewed upgrades - Multi-client support — reads configs from Claude Desktop, Claude Code, Cursor, VSCode, and Windsurf — plus custom paths via
--config; use--config-onlyfor isolated scans of one config file - Structured output — Rich terminal report plus JSON and SARIF 2.1.0 export for ingestion by GitHub Advanced Security and SARIF-aware SAST pipelines
- Documented output contract — JSON, SARIF rule IDs, and policy exit codes are documented in
docs/OUTPUT-CONTRACT.md - Watch mode —
mcp-audit watchre-scans on config file changes viawatchfiles(optional extra: install withmcp-permission-audit[watch])
Quick Start
Prerequisites
- Python 3.11+
uv(recommended) orpip
Installation
uvx --from mcp-permission-audit mcp-audit discover
# or install permanently:
uv tool install mcp-permission-audit
# with watch mode support:
uv tool install 'mcp-permission-audit[watch]'
Usage
mcp-audit --version
# Discover configured MCP servers without connecting to them
mcp-audit discover
# Scan all configured MCP servers
mcp-audit scan
# Config-only scan that does not spawn or connect to servers
mcp-audit scan --skip-connect
# Filter to specific clients (comma-separated)
mcp-audit scan --clients claude_desktop,cursor
# Scan only one explicit MCP config file
mcp-audit scan --config ./mcp.json --config-only
# Check tools, prompts, and resources for prompt-injection patterns
mcp-audit scan --inject-check
# Pin current tool schemas, then detect drift on later scans.
# Pinning connects to servers so it can capture real tool schemas.
mcp-audit pin
mcp-audit pin --status
mcp-audit pin --status --json
mcp-audit pin --stale
mcp-audit pin --stale --json
mcp-audit scan --pin-check
# Review expected drift for one server before refreshing its baseline.
mcp-audit pin --refresh github
mcp-audit pin --refresh github --json
mcp-audit pin --refresh github --apply
# Export JSON or SARIF 2.1.0
mcp-audit scan --json audit.json --sarif audit.sarif
# Fail CI on local policy violations
mcp-audit scan --policy policy.yaml
# Optional LLM-assisted classification (requires ANTHROPIC_API_KEY)
mcp-audit scan --llm-analysis
# Watch mode — re-scan on config change; use --skip-connect for config-only watching
mcp-audit watch
Tech Stack
| Layer | Technology |
|---|---|
| Language | Python 3.11+ |
| CLI | Click 8 |
| Output | Rich |
| MCP protocol | mcp SDK 1.27+ |
| Validation | Pydantic v2 |
| Config parsing | PyYAML + json5 |
| Watch mode | watchfiles (optional extra) |
| Optional LLM | Anthropic SDK |
Architecture
The scanner enumerates MCP client config files, connects to each configured server, and calls tools/list, prompts/list, and resources/list over the MCP protocol when those capabilities are available. Stdio servers are started as subprocesses via anyio; HTTP/SSE servers are contacted at their configured URL. Returned tool schemas, prompt arguments, and resource URIs flow into the permission classifier (schema walker + regex ruleset over six permission categories) and the optional injection detector (pattern ruleset for instruction-override, role-switch, and hidden-directive phrasing). The risk scorer composes a per-category weighted sum clamped to 0–10 from tool findings, then separately reports additive non_tool_risk for prompt and resource capability or injection findings. non_tool_risk is for triage and output consumers; it does not change risk_score.composite. Reports render via Rich; JSON and SARIF 2.1.0 export are first-class. The pin store serializes SHA256 schema hashes plus reviewable tool snapshots to ~/.mcp-audit-pins.yaml for actionable drift detection on subsequent --pin-check scans. Use mcp-audit pin --refresh <server> to preview expected drift for one reviewed server, then rerun with --apply to replace that server's pins. Use mcp-audit pin --stale to review pinned servers that are no longer present in discovered MCP configs before clearing them explicitly with mcp-audit pin --clear <server>.
Local Policy Gates
Policies are local YAML files evaluated after a scan. A failing policy exits with code 2 after terminal, JSON, or SARIF output is written.
fail_on:
severity: high
injection: medium
capabilities: medium
drift: true
require:
pins:
servers:
- github
deny:
permissions:
- shell_execution
max_risk: 7
allow_servers:
- github
servers:
github:
max_risk: 5
deny:
permissions:
- shell_execution
See docs/ADOPTION-GUIDE.md for local review, team CI, and GitHub code
scanning setup paths. See docs/1.1-ADOPTION.md for non_tool_risk parsing
examples and policy selection notes, and examples/consumers/ for runnable
JSON consumer examples. See examples/policies/ for starter policies. See
docs/GOLDEN-ROLLOUT.md for the recommended config-only to policy-gated
rollout path. See docs/STABLE-READINESS.md for the stable-release bar. See
docs/PIN-MAINTENANCE.md for reviewed pin refresh and stale server cleanup
workflows. See docs/PROMPT-RESOURCE-SCORING.md and
docs/SCORING-MIGRATION.md for the current prompt/resource scoring boundary
and migration path. See examples/ci/pin-stale-review.yml and
examples/maintenance/stale-pin-review.sh for routine stale pin review flows.
See docs/FEEDBACK-TO-FIXTURES.md for turning false positives, missing
detections, output issues, and pin lifecycle feedback into safe regression
fixtures. See docs/ROADMAP-1.1.md for additive product depth lanes.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcp_permission_audit-1.1.3.tar.gz.
File metadata
- Download URL: mcp_permission_audit-1.1.3.tar.gz
- Upload date:
- Size: 47.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64d945cdc85241425e2337b587a3a2fb29348d95779a28e8366b091badf219af
|
|
| MD5 |
52825caea875b84f02505544b8b47358
|
|
| BLAKE2b-256 |
52441c551d5452a0dfaf18c5cba47124dabbf3ce27276a43ecc770f054c770d5
|
Provenance
The following attestation bundles were made for mcp_permission_audit-1.1.3.tar.gz:
Publisher:
publish.yml on saagpatel/MCPAudit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_permission_audit-1.1.3.tar.gz -
Subject digest:
64d945cdc85241425e2337b587a3a2fb29348d95779a28e8366b091badf219af - Sigstore transparency entry: 1489810765
- Sigstore integration time:
-
Permalink:
saagpatel/MCPAudit@f6b21032b953306f3ea520528cc56c3150055f9d -
Branch / Tag:
refs/tags/v1.1.3 - Owner: https://github.com/saagpatel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f6b21032b953306f3ea520528cc56c3150055f9d -
Trigger Event:
push
-
Statement type:
File details
Details for the file mcp_permission_audit-1.1.3-py3-none-any.whl.
File metadata
- Download URL: mcp_permission_audit-1.1.3-py3-none-any.whl
- Upload date:
- Size: 61.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5eb4e29afec886367c4848e858d9f2a7756ebf6e6575089134e9c6877121756d
|
|
| MD5 |
43828f0c1c82c8da67d3d014f4af4382
|
|
| BLAKE2b-256 |
237f7647031d90207ed002ca7a54d065ac265db5cbf2d319ff2c84a791a1d254
|
Provenance
The following attestation bundles were made for mcp_permission_audit-1.1.3-py3-none-any.whl:
Publisher:
publish.yml on saagpatel/MCPAudit
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mcp_permission_audit-1.1.3-py3-none-any.whl -
Subject digest:
5eb4e29afec886367c4848e858d9f2a7756ebf6e6575089134e9c6877121756d - Sigstore transparency entry: 1489810892
- Sigstore integration time:
-
Permalink:
saagpatel/MCPAudit@f6b21032b953306f3ea520528cc56c3150055f9d -
Branch / Tag:
refs/tags/v1.1.3 - Owner: https://github.com/saagpatel
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@f6b21032b953306f3ea520528cc56c3150055f9d -
Trigger Event:
push
-
Statement type: