Skip to content

sidhpurwala-huzaifa/mcp-security-scanner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

54 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MCP Security Scanner

This is a Python-based penetration testing tool for Model Context Protocol (MCP) servers. It supports HTTP, stdio, and experimental 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, stdio, 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

# stdio: Scan local MCP servers via stdin/stdout
mcp-scan scan --transport stdio --command "npx -y @modelcontextprotocol/server-memory" --format json

# 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)

Note: RPC commands only support HTTP and SSE transports, not stdio.

# List tools (HTTP)
mcp-scan rpc --url https://your-mcp.example.com/mcp --method tools/list --transport http

# Call a tool (HTTP)
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-health prints server details and enumerations without running the full scan.
  • Works for HTTP, stdio, and SSE transports.
  • Supports --format text and --format json.

Examples:

# HTTP
mcp-scan scan --url https://your-mcp.example.com/mcp --only-health --format text

# stdio
mcp-scan scan --transport stdio --command "npx -y @modelcontextprotocol/server-memory" --only-health --format json

# 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|stdio|sse: Hint preferred transport; no dynamic discovery.
    • http: Requires --url for JSON-RPC endpoint
    • stdio: Requires --command for local MCP server process
    • sse: Requires --url and --sse-endpoint (experimental)
  • --timeout : Per-request read timeout (default 12s). Increase for slow streams.
  • --session-id : Pre-established session (Mcp-Session-Id header).

Testing

Running Tests

# Set up environment (if not already done)
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e .

# Run all tests
python -m pytest tests/ -v

# Run specific test module
python -m pytest tests/test_stdio_scanner.py -v
python -m pytest tests/test_security_checks.py -v

# Run specific test class
python -m pytest tests/test_stdio_scanner.py::TestStdioIntegration -v

Running with Container

# Build container

podman build -t mcp-scan .

# Run
podman run --rm mcp-scan scan --url ${MCP_SERVER} --format text

Acknowledgements

About

Scan any running MCP server to produce an actionable security report of vulnerabilities and misconfigurations.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •