MCP Surface Detection¶
MCP-Scan automatically identifies MCP-specific elements in your codebase.
What is MCP Surface?¶
The "MCP Surface" represents the attack surface exposed through the Model Context Protocol:
- Tools: Functions that LLMs can invoke
- Resources: Data sources exposed to LLMs
- Prompts: Pre-defined prompt templates
- Transport: Communication method (stdio, HTTP, WebSocket)
- Auth Signals: Authentication mechanisms
Surface Extraction¶
Command¶
Output Example¶
MCP Surface Analysis
====================
Transport: stdio
Tools (4 detected):
┌─ read_file
│ Description: Read contents of a file from disk
│ Handler: handle_read_file (src/tools.py:45)
│ Parameters: path (string, required)
│
├─ write_file
│ Description: Write contents to a file
│ Handler: handle_write_file (src/tools.py:78)
│ Parameters: path (string), content (string)
│
├─ execute_command
│ Description: Execute a shell command
│ Handler: handle_execute (src/tools.py:112)
│ Parameters: command (string, required)
│ ⚠ WARNING: Tool name suggests dangerous operation
│
└─ list_files
Description: List files in a directory
Handler: handle_list (src/tools.py:145)
Parameters: directory (string)
Resources (1 detected):
└─ config://settings
Description: Application configuration
Handler: get_config (src/resources.py:23)
Auth Signals:
├─ JWT verification (src/auth.py:23)
└─ OAuth2 flow (src/auth.py:67)
Transport Details:
Type: stdio
Input: stdin
Output: stdout
Detection Patterns¶
Python MCP SDK¶
# Tool detection
@mcp.tool()
def my_tool(param: str) -> str:
"""Tool description."""
pass
# Alternative decorator
@server.tool("tool_name")
def handler(args):
pass
TypeScript MCP SDK¶
// Tool detection
server.tool("tool_name", "Description", {
param: z.string()
}, async (args) => {
// handler
});
// Alternative pattern
server.setRequestHandler(ListToolsRequestSchema, async () => {
return { tools: [...] };
});
Tool Analysis¶
Extracted Information¶
| Field | Description |
|---|---|
| name | Tool identifier |
| description | Tool description (checked for poisoning) |
| handler | Function handling the tool call |
| parameters | Input parameters with types |
| location | File and line number |
Tool Warnings¶
MCP-Scan flags potentially dangerous tools:
⚠ Tool name suggests dangerous operation: execute_command
⚠ Tool description contains suspicious phrases: "ignore previous"
⚠ Tool has write access: write_file
⚠ Tool performs network operations: fetch_url
Transport Detection¶
Supported Transports¶
| Transport | Detection Pattern |
|---|---|
| stdio | StdioServerTransport, stdin/stdout usage |
| HTTP | HTTPServerTransport, Express routes |
| WebSocket | WebSocketServerTransport, ws server |
| SSE | Server-Sent Events patterns |
Transport Security Implications¶
| Transport | Attack Surface |
|---|---|
| stdio | Local process only |
| HTTP | Network accessible |
| WebSocket | Persistent connection |
| SSE | One-way server push |
Auth Signal Detection¶
MCP-Scan identifies authentication patterns:
JWT¶
OAuth2¶
API Keys¶
Session¶
JSON Output¶
{
"transport": {
"type": "stdio",
"details": {
"input": "stdin",
"output": "stdout"
}
},
"tools": [
{
"name": "read_file",
"description": "Read contents of a file from disk",
"handler": {
"name": "handle_read_file",
"location": {
"file": "src/tools.py",
"line": 45
}
},
"parameters": [
{
"name": "path",
"type": "string",
"required": true
}
],
"warnings": []
},
{
"name": "execute_command",
"description": "Execute a shell command",
"handler": {
"name": "handle_execute",
"location": {
"file": "src/tools.py",
"line": 112
}
},
"parameters": [
{
"name": "command",
"type": "string",
"required": true
}
],
"warnings": [
"Tool name suggests dangerous operation"
]
}
],
"resources": [
{
"uri": "config://settings",
"description": "Application configuration",
"handler": {
"name": "get_config",
"location": {
"file": "src/resources.py",
"line": 23
}
}
}
],
"auth_signals": [
{
"type": "jwt",
"location": {
"file": "src/auth.py",
"line": 23
},
"pattern": "jwt.decode"
},
{
"type": "oauth2",
"location": {
"file": "src/auth.py",
"line": 67
},
"pattern": "OAuthFlow"
}
]
}
Integration with Scanning¶
Surface information enhances vulnerability detection:
MCP Context in Findings¶
{
"finding": {
"rule_id": "MCP-A003",
"mcp_context": {
"tool_name": "execute_command",
"handler_name": "handle_execute",
"transport": "stdio",
"description": "Execute a shell command"
}
}
}
Why MCP Context Matters¶
- Exploitability Assessment
- Tools are directly accessible via MCP protocol
-
Transport determines network exposure
-
Severity Adjustment
- Vulnerabilities in tool handlers get 1.5x MSSS penalty
-
Direct user input more likely
-
Remediation Priority
- Tools named dangerously need immediate review
- Auth-less tools are higher priority
Common Surface Patterns¶
Minimal Safe Server¶
API Server¶
High-Risk Server¶
Transport: HTTP (public)
Tools: execute_command, write_file, fetch_url
Auth: API key only
⚠ Multiple dangerous tool patterns
Surface Review Checklist¶
- [ ] All tools have clear, non-manipulatable descriptions
- [ ] Dangerous tool names are avoided or renamed
- [ ] Transport matches deployment model (stdio for local, HTTP for network)
- [ ] Authentication is appropriate for transport type
- [ ] Write operations have proper authorization
- [ ] Network operations are documented and allowlisted