MCPScan
Offensive MCP server auditor β detects tool poisoning, credential leaks, RCE vectors, SSRF, session hijacking, and supply chain vulnerabilities across stdio, HTTP, and SSE transports.
Ask AI about MCPScan
Powered by Claude Β· Grounded in docs
I know everything about MCPScan. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
The first dedicated offensive security auditor for MCP servers
Threat Landscape Β· Checks Β· Install Β· Usage Β· CVEs Β· Output
π₯ Threat Landscape
MCP has become the standard for connecting AI agents to the real world β and attackers got there first. Researchers have already documented:
| Threat | Impact | Scale |
|---|---|---|
| Tool Poisoning | Hidden instructions hijack LLM behavior | >72% attack success rate |
| RCE via mcp-remote | Full OS command execution | ~500,000 developers affected |
| Exposed Servers | Unauthenticated access to tools and data | 492+ servers found publicly |
| Credential Leakage | API keys embedded in tool metadata | Thousands of installations |
| Supply Chain | Compromised npm packages spawning malicious MCP modules | Active in the wild |
No dedicated offensive scanner existed. MCPScan fills that gap.
π Checks
MCPScan runs 8 check categories covering the full MCP attack surface:
| ID | Category | What It Finds |
|---|---|---|
| MCP-1xx | tool-poisoning | Hidden Unicode (zero-width, RTL override), HTML/XML injection, prompt injection keywords, base64 payloads, overlong descriptions, markdown exfiltration |
| MCP-2xx | credential-leak | AWS keys, API tokens (Anthropic, OpenAI, GitHub, Stripe, Slack), JWTs, private keys, DB connection strings |
| MCP-3xx | overprivileged | Shell+filesystem combos, shell+network combos, unrestricted path params, code eval, sensitive path access (~/.ssh, ~/.aws) |
| MCP-4xx | auth-missing | Unauthenticated server enumeration, CORS wildcard, 0.0.0.0 binding, missing security headers |
| MCP-5xx | session-hijack | Session IDs in URL params, predictable/time-based IDs, missing Secure/HttpOnly cookie flags |
| MCP-6xx | ssrf | User-supplied URL parameters, webhook/callback endpoints, HTTP resource URI templates with variables |
| MCP-7xx | rce-vectors | command/exec/eval parameter names, execution language in descriptions, sanitization claim detection |
| MCP-8xx | supply-chain | CVE version ranges, missing lockfiles, typosquatted MCP package names |
π CVE References
| CVE | Package | CVSS | Summary |
|---|---|---|---|
| CVE-2025-6514 | mcp-remote | 9.6 | Arbitrary OS command execution β first full system compromise via MCP |
| CVE-2025-49596 | @modelcontextprotocol/inspector | 9.4 | Unauthenticated RCE via inspector-proxy |
| CVE-2025-59536 | @anthropic-ai/claude-code | 9.1 | Project file RCE + API token exfiltration |
| CVE-2025-53967 | figma-developer-mcp | 8.2 | Command injection via shell string interpolation |
| CVE-2026-25536 | @modelcontextprotocol/sdk | 7.5 | StreamableHTTP data leakage across clients (v1.10.0β1.25.3) |
β‘ Install
Requires Node.js β₯ 18
git clone https://github.com/sahiloj/MCPScan.git
cd MCPScan
npm install
npm run build
Link globally and run from anywhere:
npm link
mcpscan --help
π Usage
Scan a stdio server
mcpscan scan --command "npx" --args "-y @modelcontextprotocol/server-filesystem /home/user"
Scan from your AI client config
# Claude Desktop (macOS)
mcpscan scan --config ~/Library/Application\ Support/Claude/claude_desktop_config.json
# Auto-discover all known config locations (Claude, Cursor, etc.)
mcpscan scan --all-configs
Scan a remote HTTP / SSE server
mcpscan scan --target http://localhost:3000/mcp
Sweep localhost for exposed MCP servers
mcpscan scan --all-configs --network
Run targeted checks only
mcpscan scan --all-configs --checks tool-poisoning,credential-leak,rce-vectors
Severity filtering
# Only report high and critical
mcpscan scan --all-configs --severity high
CI/CD integration
# Exit code 2 = critical findings, exit code 1 = high findings
mcpscan scan --all-configs --severity high --output sarif > findings.sarif
Discover without scanning
mcpscan discover --all-configs --network
mcpscan discover --all-configs --output json
βοΈ All Options
mcpscan scan [options]
-c, --config <path> Path to claude_desktop_config.json or .mcp.json
-t, --target <url> Direct HTTP/SSE MCP server URL
--command <cmd> Spawn and scan a stdio server
--args <args> Space-separated args for --command
--all-configs Auto-discover all known MCP config locations
--network Also probe localhost ports for exposed HTTP servers
--checks <list> Comma-separated checks to run (default: all)
-o, --output <format> terminal | json | sarif (default: terminal)
--severity <level> critical | high | medium | low | info (default: info)
--timeout <ms> Per-server connection timeout (default: 30000)
--verbose Show check errors and debug output
Config locations searched by --all-configs:
| Platform | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Linux | ~/.config/claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Any | .mcp.json Β· .cursor/mcp.json Β· ~/.config/mcp/config.json |
π Output Formats
Terminal (default)
Severity-colored findings with CVE references and a summary box. Built for humans.
JSON
Machine-readable report for SIEMs, custom dashboards, and automation:
{
"tool": "mcpscan",
"version": "0.1.0",
"timestamp": "2026-03-10T12:00:00.000Z",
"summary": {
"serversScanned": 3,
"totalFindings": 8,
"findingsBySeverity": { "critical": 2, "high": 4, "medium": 1, "low": 1, "info": 0 }
},
"results": [...]
}
SARIF 2.1.0
Drop directly into GitHub Code Scanning, VS Code SARIF Viewer, or any SARIF-aware security platform. Each finding maps to a rule with security-severity CVSS scores.
ποΈ Architecture
src/
βββ cli.ts Entry point β commander argument parsing
βββ scanner.ts Orchestrator: enumerate β checks β deduplicate β report
βββ types.ts Shared interfaces (Finding, ScanResult, CheckFn β¦)
βββ discovery/
β βββ config-reader.ts Parses all known MCP config formats (Zod-validated)
β βββ network-scan.ts Probes localhost ports for exposed HTTP servers
βββ transport/
β βββ stdio-client.ts StdioClientTransport + timeout + process cleanup
β βββ http-client.ts StreamableHTTP with SSE fallback; captures response headers
βββ checks/
β βββ tool-poisoning.ts MCP-1xx β Unicode, injection, base64, exfil
β βββ credential-leak.ts MCP-2xx β 16 credential patterns with FP suppression
β βββ overprivileged.ts MCP-3xx β Dangerous capability combinations
β βββ auth-missing.ts MCP-4xx β Unauthenticated access, CORS, 0.0.0.0
β βββ session-hijack.ts MCP-5xx β Session ID exposure and predictability
β βββ ssrf.ts MCP-6xx β User-controlled URL parameters
β βββ rce-vectors.ts MCP-7xx β Shell execution patterns
β βββ supply-chain.ts MCP-8xx β CVE ranges, lockfiles, typosquats
βββ report/
βββ terminal.ts Chalk + Boxen rich terminal output
βββ json.ts JSON and SARIF 2.1.0 serialization
Each check exports async function check(data: ServerData): Promise<Finding[]>. All checks run in parallel via Promise.allSettled β a broken check never blocks the rest.
π‘οΈ Finding Schema
interface Finding {
id: string; // "MCP-701"
title: string; // "RCE Vector: Shell/Execution Parameter Name"
severity: "critical" | "high" | "medium" | "low" | "info";
category: string; // "rce-vectors"
description: string; // Full explanation of the risk
evidence: string; // The exact value that triggered the finding
location: string; // "tool: bash_exec > inputSchema.properties.command"
cve?: string; // "CVE-2025-6514"
cvss?: number; // 9.6
remediation: string; // Actionable fix guidance
}
π§ Development
# Type-check without building
npm run typecheck
# Run directly without building (uses tsx)
npm run dev -- scan --all-configs
# Full rebuild
npm run build
π References
- MCP Specification (2025-11-25)
- OWASP MCP Top 10 (2025)
- Tool Poisoning Attacks β Invariant Labs
- MCP Attack Vectors β Palo Alto Unit 42
- CVE-2025-6514 Deep Dive β JFrog
- MCP Security Best Practices
- Network-Exposed MCP Servers β Trend Micro
Released under the MIT License Β· Built for the security community
