Skip to content

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

mcp-scan surface ./my-mcp-server

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

# Detected patterns
jwt.decode(token, ...)
jose.jwt.decode(...)
jsonwebtoken.verify(...)

OAuth2

# Detected patterns
oauth2.authorize(...)
OAuthFlow(...)
/oauth/callback route

API Keys

# Detected patterns
api_key = request.headers.get("X-API-Key")
Authorization: Bearer ...

Session

# Detected patterns
session["user_id"]
request.session

JSON Output

mcp-scan surface . --format json
{
  "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

  1. Exploitability Assessment
  2. Tools are directly accessible via MCP protocol
  3. Transport determines network exposure

  4. Severity Adjustment

  5. Vulnerabilities in tool handlers get 1.5x MSSS penalty
  6. Direct user input more likely

  7. Remediation Priority

  8. Tools named dangerously need immediate review
  9. Auth-less tools are higher priority

Common Surface Patterns

Minimal Safe Server

Transport: stdio
Tools: 2 (read-only)
Auth: Not required (local only)

API Server

Transport: HTTP
Tools: 10+
Auth: JWT + OAuth2
Resources: Database access

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