TECHNICAL DEEP DIVE

How MCP Works

A complete technical breakdown of the Model Context Protocol: architecture, transports, message formats, and protocol flow.

Architecture Overview

┌────────────────────────────────────────────────────────────────┐
│                     MCP CLIENT                                 │
│                                                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │  Claude       │  │   Cursor     │  │   Windsurf   │       │
│  │  Desktop      │  │              │  │              │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
│                                                                │
│  Capabilities:                                                 │
│  • Sends requests via JSON-RPC 2.0                           │
│  • Discovers server capabilities                             │
│  • Invokes tools and reads resources                         │
│  • Renders prompts to user                                   │
│                                                                │
└────────────────────────────────────────────────────────────────┘
                             ↕
                    MCP PROTOCOL
              (JSON-RPC 2.0 over stdio or SSE)
                             ↕
┌────────────────────────────────────────────────────────────────┐
│                     MCP SERVER                                 │
│                                                                │
│  Exposes 3 Core Primitives:                                  │
│                                                                │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐       │
│  │   TOOLS      │  │  RESOURCES   │  │   PROMPTS    │       │
│  ├──────────────┤  ├──────────────┤  ├──────────────┤       │
│  │ Functions    │  │ Data sources │  │ Templates    │       │
│  │ AI can call  │  │ AI can read  │  │ AI can use   │       │
│  └──────────────┘  └──────────────┘  └──────────────┘       │
│                                                                │
│  Examples:                                                     │
│  • GitHub: create_issue(), list_prs(), search_code()         │
│  • Postgres: run_query(), list_tables(), describe_schema()   │
│  • Filesystem: read_file(), write_file(), search_files()     │
│                                                                │
└────────────────────────────────────────────────────────────────┘
                             ↕
                     EXTERNAL SYSTEMS
              (Databases, APIs, File Systems, etc)

Protocol Foundation

JSON-RPC 2.0

MCP uses JSON-RPC 2.0 as its message format. This is a lightweight, language-agnostic protocol for remote procedure calls.

Example Request:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "search_files",
    "arguments": {
      "pattern": "*.tsx",
      "path": "/src"
    }
  }
}

Example Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "Found 42 files matching *.tsx in /src"
      }
    ]
  }
}

Transport Mechanisms

MCP supports two transport mechanisms for sending JSON-RPC messages:

STDIO

Standard input/output streams

  • Use case: Local servers (files, git, DB)
  • Security: Process isolation
  • Latency: Ultra-low (~1ms)
  • Example: Filesystem server

SSE

Server-Sent Events over HTTP

  • Use case: Remote servers (cloud APIs)
  • Security: HTTPS + auth tokens
  • Latency: Network dependent
  • Example: GitHub API server

The 3 Core Primitives

1. TOOLS — Functions AI Can Call

Tools are functions that the AI can execute. Each tool has a name, description, and typed parameters defined with JSON Schema.

Tool Definition Example:

{
  "name": "create_github_issue",
  "description": "Creates a new issue in a GitHub repository",
  "inputSchema": {
    "type": "object",
    "properties": {
      "repo": {
        "type": "string",
        "description": "Repository name (owner/repo)"
      },
      "title": {
        "type": "string",
        "description": "Issue title"
      },
      "body": {
        "type": "string",
        "description": "Issue description"
      },
      "labels": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Labels to apply"
      }
    },
    "required": ["repo", "title", "body"]
  }
}

TOOL INVOCATION FLOW:

  1. Client sends tools/list request
  2. Server responds with array of available tools
  3. AI selects appropriate tool based on user request
  4. Client sends tools/call with arguments
  5. Server executes tool and returns result

2. RESOURCES — Data AI Can Read

Resources are data sources that the AI can access. Each resource has a URI and can optionally support subscriptions for updates.

Resource Definition Example:

{
  "uri": "file:///Users/you/project/README.md",
  "name": "README.md",
  "description": "Project readme file",
  "mimeType": "text/markdown"
}

Resource Read Request:

{
  "jsonrpc": "2.0",
  "method": "resources/read",
  "params": {
    "uri": "file:///Users/you/project/README.md"
  }
}

KEY FEATURES:

  • URI-based addressing: file://, db://, api://, etc.
  • Subscriptions: Get notified when resources change
  • Templates: URIs can include variables {user_id}
  • Pagination: For large datasets

3. PROMPTS — Templates AI Can Use

Prompts are pre-built templates that servers provide. Users can select them from the client UI, fill in arguments, and the prompt is sent to the AI.

Prompt Definition Example:

{
  "name": "git-commit",
  "description": "Generate a conventional commit message",
  "arguments": [
    {
      "name": "changes",
      "description": "Git diff output",
      "required": true
    }
  ]
}

USE CASES:

  • • Code review templates
  • • Documentation generation prompts
  • • Test case generators
  • • Bug report formatters

Connection & Capability Negotiation

STEP-BY-STEP CONNECTION FLOW

1

Client Initiates Connection

Client starts the MCP server process (stdio) or connects to HTTP endpoint (SSE)

2

Initialize Handshake

Client sends initialize request with its capabilities

{
  "method": "initialize",
  "params": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "roots": { "listChanged": true },
      "sampling": {}
    },
    "clientInfo": {
      "name": "Claude Desktop",
      "version": "1.0.0"
    }
  }
}
3

Server Responds with Capabilities

Server declares what it supports (tools, resources, prompts)

{
  "result": {
    "protocolVersion": "2024-11-05",
    "capabilities": {
      "tools": {},
      "resources": { "subscribe": true },
      "prompts": {}
    },
    "serverInfo": {
      "name": "filesystem-server",
      "version": "1.0.0"
    }
  }
}
4

Client Sends Initialized Notification

Confirms handshake complete, connection ready

5

Normal Operation Begins

Client can now list tools, read resources, invoke prompts

Security Model

STDIO TRANSPORT

  • Process Isolation: Each server runs in its own process
  • Sandboxing: Servers only access configured directories
  • No Network Access: Stdio servers can't make outbound connections
  • User Consent: Client prompts before tool execution

SSE TRANSPORT

  • HTTPS Required: All traffic encrypted in transit
  • Authentication: OAuth, API keys, or bearer tokens
  • CORS Protection: Server validates origin
  • Rate Limiting: Prevent abuse via per-client limits

Error Handling

MCP uses standardized JSON-RPC error codes. Servers return detailed error objects:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Invalid params",
    "data": {
      "details": "Missing required parameter 'repo'",
      "expected": {
        "repo": "string",
        "title": "string",
        "body": "string"
      }
    }
  }
}

STANDARD ERROR CODES

  • -32700 Parse error
  • -32600 Invalid request
  • -32601 Method not found
  • -32602 Invalid params
  • -32603 Internal error

CUSTOM ERROR CODES

  • -32000 Tool execution failed
  • -32001 Resource not found
  • -32002 Permission denied
  • -32003 Rate limit exceeded