🔒 MCP-Scan
Security scanner for MCP server configurations and AI agent tool permissions.
Detect dangerous shell commands, exposed API keys, over-permissive file access, high-risk tools, and prompt injection patterns — before they reach production.
Quick Start · Example Output · Rules · Library API · Dashboard · CI/CD · Contributing
🚨 The Problem
AI agents are now connecting to tools, files, GitHub, Slack, Gmail, Notion, databases, and internal systems via MCP (Model Context Protocol). This creates serious security risk:
- 🔓 Unrestricted shell access (
bash -c "$USER_INPUT") - 🔑 API keys and tokens hard-coded in configuration files
- 📁 Over-permissive file system access (
/,/etc/shadow,~/.ssh) - 📧 Tools that can send emails, delete files, or drop database tables with no confirmation
- 💉 Prompt injection patterns that could hijack agent behavior
- ⚠️ Binaries running from untrusted paths (
/tmp/Downloads/sketchy-tool)
OWASP now has an MCP Top 10 covering tool poisoning, excessive agency, and context spoofing. GitHub added secret scanning support for MCP workflows. The attack surface is real and growing.
MCP-Scan catches these risks in seconds.
⚡ Quick Start
Install
pip install mcp-agent-security-scanner
Scan
mcp-scan scan ./mcp-config.json
That's it. 3 lines.
📥 Example Input
Here's a dangerous MCP configuration:
{
"mcpServers": {
"terminal.run": {
"command": "bash",
"args": ["-c", "eval $USER_INPUT"],
"env": {
"OPENAI_API_KEY": "sk-proj-abc123def456ghi789jkl012mno"
}
},
"gmail.send": {
"command": "node",
"args": ["gmail-mcp-server", "--no-confirm"],
"env": {
"GMAIL_TOKEN": "ya29.a0AfH6SMBx_FAKE_TOKEN"
}
},
"filesystem": {
"command": "/tmp/Downloads/sketchy-binary",
"args": ["/", "/etc/shadow", "/root/.ssh"]
}
}
}
📊 Example Output
┌──────────────────────────────────────────────────────────┐
│ MCP Security Scan Report │
│ File: mcp-config.json │
│ Version: 0.1.1 │
└──────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────┐
│ Findings: 8 HIGH | 3 MEDIUM | 3 LOW (14 total) │
└──────────────────────────────────────────────────────────┘
Severity │ Rule │ Server │ Message
──────────┼─────────┼────────────────┼──────────────────────────────────────
HIGH │ MCP-001 │ terminal.run │ Uses dangerous command: "bash"
HIGH │ MCP-002 │ terminal.run │ OpenAI API key exposed in env
HIGH │ MCP-006 │ gmail.send │ High-risk tool: email sending
HIGH │ MCP-008 │ filesystem │ Binary from untrusted path: /tmp/
MEDIUM │ MCP-003 │ filesystem │ Access to sensitive path: /etc/shadow
MEDIUM │ MCP-003 │ filesystem │ Access to sensitive path: /root/.ssh
LOW │ MCP-005 │ terminal.run │ No allowedTools defined
🔍 Scanning Rules
| Rule | Name | Severity | What it catches |
|---|---|---|---|
| MCP-001 | Dangerous Shell Commands | 🔴 HIGH | bash, powershell, eval, sudo, ssh, piped curl |
| MCP-002 | Exposed Secrets | 🔴 HIGH | OpenAI keys, GitHub PATs, AWS keys, Slack tokens, private keys |
| MCP-003 | Over-permissive Paths | 🟡 MEDIUM | /, /etc, ~/.ssh, C:\Windows\System32 |
| MCP-004 | Untrusted MCP Server | 🟡 MEDIUM | Binaries from /tmp, Downloads, unverified sources |
| MCP-005 | Missing Tool Allowlist | 🔵 LOW | No allowedTools restriction → full agent access |
| MCP-006 | High-Risk Tools | 🔴 HIGH | Email send, file delete, DB write, Slack post without gates |
| MCP-007 | Prompt Injection | 🟡 MEDIUM | "Ignore previous instructions", template injection, jailbreaks |
| MCP-008 | Unsafe Binary Execution | 🔴 HIGH | Executing from /tmp/, Downloads/, .cache/ |
🐍 Python Library API
Use mcp-scan programmatically in your own tools:
from mcp_scan import scan_config, scan_file, ScanPolicy
# Scan a config dictionary
result = scan_config({
"mcpServers": {
"my-server": {
"command": "bash",
"args": ["-c", "rm -rf /"]
}
}
})
print(result.has_errors) # True
print(result.highest_severity) # "HIGH"
print(result.total_findings) # 3
for finding in result.findings:
print(f"[{finding.severity}] {finding.rule_id}: {finding.message}")
# Scan with a custom policy
policy = ScanPolicy(
allowed_commands=["node", "python"],
trusted_servers=["@modelcontextprotocol/"],
ignored_rules=["MCP-005"],
)
result = scan_config(config, policy=policy)
# Scan a file directly
result = scan_file("./mcp-config.json")
# Export to SARIF
from mcp_scan import to_sarif_json
print(to_sarif_json(result))
🌐 Web Dashboard
Start the built-in dashboard:
pip install mcp-agent-security-scanner[server]
mcp-scan serve
Open http://localhost:8000 — paste your config, click Scan Now, and get instant visual results with severity cards, findings table, and SARIF export.
🐳 Docker
cd docker
docker compose up --build
Dashboard available at http://localhost:8000. Mount your config files:
docker run --rm -v $(pwd):/configs mcp-scan mcp-scan scan /configs/mcp-config.json
⚙️ CI/CD Integration
GitHub Actions
- name: Install mcp-scan
run: pip install mcp-agent-security-scanner
- name: Scan MCP configs
run: mcp-scan scan ./mcp-config.json --fail-on HIGH
- name: Upload SARIF (optional)
run: mcp-scan scan ./mcp-config.json --output sarif > results.sarif
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: results.sarif
The scanner exits with code 1 when HIGH-severity findings are detected, automatically failing your CI pipeline.
📋 Custom Scanning Policy
Create mcp-policy.yaml to customize behavior:
trusted_servers:
- "@modelcontextprotocol/"
- "npx"
allowed_commands:
- "node"
- "python"
ignored_rules:
- "MCP-005"
max_severity: HIGH
mcp-scan scan ./config.json --policy ./mcp-policy.yaml
🏗️ Architecture
Input (CLI / API / Library)
↓
Parser (JSON / YAML → Pydantic McpConfig)
↓
Engine (8 security rules + policy filtering)
↓
Output (Rich terminal / JSON / SARIF / Dashboard)
See docs/architecture.md for the full architecture diagram and threat model.
🎯 Real Use Cases
- AI coding agents — Teams using Cursor, Windsurf, or Claude Code with MCP servers need to audit tool permissions before granting agents access to codebases and infrastructure.
- Enterprise AI deployments — Companies rolling out Claude, GPT, or Gemini with tool use need security gates for email, Slack, database, and file system access.
- Platform engineering — Platform teams can run
mcp-scanin CI/CD to enforce security policies across all MCP configurations in the org. - Compliance — Security teams can generate SARIF reports for audit trails and integrate with GitHub Advanced Security.
🗺️ Roadmap
- Custom rule engine — Write your own rules in YAML
- Continuous monitoring — Watch config files for changes and alert
- Slack/Discord alerts — Send notifications when new risks are found
- VS Code extension — Inline warnings in your editor
- MCP runtime analysis — Monitor actual tool invocations at runtime
- Organization-wide policies — Centralized policy management
- SBOM integration — Software Bill of Materials for MCP server dependencies
🤝 Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
Development Setup
git clone https://github.com/martian7777/mcp-agent-security-scanner.git
cd mcp-scan
pip install -e ".[all]"
pytest
Adding a New Rule
- Add your detection function to
mcp_scan/engine.py - Register it in the
ALL_RULESlist - Add tests in
tests/test_engine.py - Update the rule table in this README
🏷️ Good First Issues
Looking to contribute? Start here:
- Add GitLab CI template — Create a
.gitlab-ci.ymlexample for GitLab users - Add
--config-formatauto-detection — Detect JSON vs YAML from file content, not just extension - Add Slack webhook rule — Detect Slack webhook URLs (
https://hooks.slack.com/...) in configs - Improve remediation messages — Make fix suggestions more specific and actionable
- Add
--quietflag — Only print findings, no header/footer
📄 License
MIT — see LICENSE.
Built for teams shipping AI agents safely.
Release files for mcp-agent-security-scanner 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_agent_security_scanner-0.1.1.tar.gz | 21.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_agent_security_scanner-0.1.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size:41.7 kB
Release files / mcp_agent_security_scanner-0.1.1.tar.gz
| Download URL | mcp_agent_security_scanner-0.1.1.tar.gz |
|---|---|
| Size | 21.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0375ec0cdb0b6d4c33e7453e9890c07d81decec986f8de22f351b9ae85f3753a
|
|
BLAKE2b-256 checksum How to use checksums |
6ee2689d9c4f8cd455066ebff1b82593ceb60e7168b12c4d63881df6e789c7ef
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.5
|
Release files / mcp_agent_security_scanner-0.1.1-py3-none-any.whl
| Download URL | mcp_agent_security_scanner-0.1.1-py3-none-any.whl |
|---|---|
| Size | 20.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ff13dab08c4877949d9ce47c25c014e1d90ae3cbfeb0a2e436f5ba17602cc319
|
|
BLAKE2b-256 checksum How to use checksums |
57b717cb8d877486b91811a697b1d8fad860d588e4f0c3905c21a1993e555293
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.5
|