Security scanner for Model Context Protocol (MCP) servers
Project description
MCP Security Scanner
This is a Python-based penetration testing tool for Model Context Protocol (MCP) servers. It supports Streamable HTTP and SSE transports, runs a suite of checks mapped to scanner_specs.schema (auth, transport, tools, prompts, resources), and includes a deliberately insecure MCP-like server for testing.
Note: SSE transport is discontinued in the latest version of MCP. Support for SSE in this tool is purely experimental and may not work!!!
Install
# 1) Clone
git clone https://github.com/sidhpurwala-huzaifa/mcp-security-scanner
cd mcp-security-scanner
# 2) Create venv (Python >= 3.10)
python -m venv .venv
source .venv/bin/activate
# 3) Install dependencies
pip install -r requirements.txt
# 4) (Optional) Dev install for CLI entrypoints
pip install -e .
Usage
Quick test
# Verify CLI is available
mcp-scan --help
# Reachability preflight example
mcp-scan scan --url http://127.0.0.1:65000
# -> Will fail fast with a clear error if nothing is listening
Run insecure test server (HTTP)
# Basic (HTTP JSON-RPC). Supports --test modes (Defaults to 0, otherwise choose a vulnerable model from below)
insecure-mcp-server --host 127.0.0.1 --port 9001
# Test modes currently supported
# --test 0 (default): basic insecure MCP-like server
# --test 1: prompt injection-style vulnerable server
# --test 2: tool poisoning-style vulnerable server
# --test 3: rug-pull tool mutation between listings
# --test 4: excessive permissions (admin tools exposed), private:// resource leakage
# --test 5: token theft (server leaks upstream access tokens to clients)
# --test 6: indirect prompt injection (external resource carries hidden instructions)
# --test 7: remote access control exposure (unauth tool enables remote access)
insecure-mcp-server --host 127.0.0.1 --port 9001 --test 0/1/2/3/4/5/6/7
Scan the server (HTTP or SSE)
# HTTP: Text report (no discovery; --url is the JSON-RPC endpoint)
mcp-scan scan --url http://127.0.0.1:9001/mcp --format text
# HTTP: JSON report
mcp-scan scan --url http://127.0.0.1:9001/mcp --format json --output report.json
# HTTP: Verbose tracing (real-time)
mcp-scan scan --url http://127.0.0.1:9001/mcp --verbose
# SSE: connect to explicit SSE endpoint, then scan via emitted /messages?sessionId=...
mcp-scan scan --url https://your-mcp.example.com --transport sse --sse-endpoint /sse --timeout 30 --verbose
New: RPC passthrough (Inspector-like)
# List tools
mcp-scan rpc --url https://your-mcp.example.com/mcp --method tools/list --transport http
# Call a tool
mcp-scan rpc --url https://your-mcp.example.com/mcp \
--method tools/call \
--params '{"name":"weather","arguments":{"city":"Paris"}}' \
--transport http
# With SSE transport
mcp-scan rpc --url https://your-mcp.example.com --method tools/list --transport sse --sse-endpoint /sse
Explanations
--explain <ID>prints a focused explanation for a single finding (e.g.,--explain X-01). It includes:- Test (ID and title)
- Expected outcome
- Got (scanner-observed details)
- Result (why PASS/FAIL)
- Remediation (from the spec)
Example:
mcp-scan scan --url https://your-mcp.example.com/mcp --explain X-01
Only health
--only-healthprints server details and enumerations without running the full scan.- Works for HTTP and SSE (SSE uses the provided endpoint and the stream-emitted POST path).
- Supports
--format textand--format json.
Examples:
# HTTP
mcp-scan scan --url https://your-mcp.example.com/mcp --only-health --format text
# SSE
mcp-scan scan --url https://your-mcp.example.com --transport sse --sse-endpoint /sse --only-health --format json
Authentication
# Bearer token
mcp-scan scan \
--url http://your-mcp.example.com/mcp \
--auth-type bearer \
--auth-token "$TOKEN"
# OAuth2 Client Credentials
mcp-scan scan \
--url http://your-mcp.example.com/mcp \
--auth-type oauth2-client-credentials \
--token-url https://issuer.example.com/oauth2/token \
--client-id "$CLIENT_ID" --client-secret "$CLIENT_SECRET" \
--scope "mcp.read mcp.tools"
Transport, timeouts, session
- --transport auto|http|sse: Hint preferred transport; no dynamic discovery. Provide working URLs.
- --timeout : Per-request read timeout (default 12s). Increase for slow streams.
- --session-id : Pre-established session (
Mcp-Session-Idheader).
Acknowledgements
- Vulnerability ideas inspired by
Damn Vulnerable MCP Server- https://github.com/harishsg993010/damn-vulnerable-MCP-server - Ye Wang from Red Hat for all his help in resolving
initproblems with certain MCP servers
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_security_scanner-0.1.0.tar.gz.
File metadata
- Download URL: mcp_security_scanner-0.1.0.tar.gz
- Upload date:
- Size: 41.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d18629d338bdf0189ca5909cff1b2bd2afbadf5e54aaaaa49b84bd69d75e91e1
|
|
| MD5 |
60abe8de77f7b17b526aa35e3ec4ef98
|
|
| BLAKE2b-256 |
da5c4c48c38a131eb99fc61947ef22ff782de13c2026316bdbd6d03838511ce5
|
File details
Details for the file mcp_security_scanner-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcp_security_scanner-0.1.0-py3-none-any.whl
- Upload date:
- Size: 44.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.11
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a8d3b28f314f09dd6128203c9641bd02d595294a4228fb32675ffe10d1d20772
|
|
| MD5 |
9be07fadf9dd3475cf16faf71fb57440
|
|
| BLAKE2b-256 |
a190f253a900858f303e3b5a9a161f756a8873195b4c57fd40a022103c1cafb0
|