Transport Mechanisms
Understand how MCP messages travel between client and server.
What is a Transport?
A transport is the mechanism that carries MCP messages between client and server. Think of it as the "pipe" through which JSON-RPC messages flow.
MCP supports two official transports, each suited for different use cases:
1. STDIO Transport
The STDIO (Standard Input/Output) transport runs the server as a subprocess of the client. Messages flow through stdin and stdout.
┌─────────────────────────────────────────────────┐
│ MCP Client Process │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ Server Subprocess │ │
│ │ (python mcp_server.py) │ │
│ │ │ │
│ │ stdin ◄───── JSON messages │ │
│ │ stdout ─────► JSON messages │ │
│ │ stderr ─────► Logs (ignored) │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────┘
How It Works
- Client launches your server as a subprocess
- Client writes JSON messages to server's stdin
- Server reads from stdin, processes, writes responses to stdout
- Each message is a single line of JSON, terminated by newline
import sys
import json
# Read a message from the client
line = sys.stdin.readline()
message = json.loads(line)
# Process and respond
response = {"jsonrpc": "2.0", "id": message["id"], "result": {}}
# Write response back to client
sys.stdout.write(json.dumps(response) + "\n")
sys.stdout.flush()
With STDIO transport, never print to stdout except for MCP messages.
Use stderr for logs and debugging. Random print statements will break
the protocol!
When to Use STDIO
- Local servers (running on the same machine as the client)
- Simple deployments (no network configuration needed)
- Claude Desktop and most IDE integrations
- Maximum performance (no network overhead)
2. HTTP/SSE Transport
The Streamable HTTP transport uses HTTP POST requests and Server-Sent Events (SSE) for responses. The server runs independently as an HTTP server.
┌──────────────┐ ┌──────────────┐
│ MCP Client │ │ MCP Server │
│ │ HTTP POST │ │
│ │ ─────────────────►│ :8080 │
│ │ (JSON-RPC) │ │
│ │ │ │
│ │ SSE Response │ │
│ │ ◄─────────────────│ │
│ │ (streaming JSON) │ │
└──────────────┘ └──────────────┘
Network Connection (localhost or remote)
How It Works
- Server runs as an independent HTTP server
- Client sends POST requests with JSON-RPC messages
- Server responds with SSE events containing JSON-RPC responses
- Sessions can be maintained with
MCP-Session-Idheader
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
class MCPHandler(BaseHTTPRequestHandler):
def do_POST(self):
# Read the request body
length = int(self.headers['Content-Length'])
body = self.rfile.read(length)
message = json.loads(body)
# Process the message
response = {"jsonrpc": "2.0", "id": message["id"], "result": {}}
# Send SSE response
self.send_response(200)
self.send_header('Content-Type', 'text/event-stream')
self.end_headers()
self.wfile.write(f"data: {json.dumps(response)}\n\n".encode())
server = HTTPServer(('localhost', 8080), MCPHandler)
server.serve_forever()
When to Use HTTP/SSE
- Remote servers (running on different machines)
- Shared servers (multiple clients connecting)
- Web-based deployments
- When you need session management
Transport Comparison
| Aspect | STDIO | HTTP/SSE |
|---|---|---|
| Connection | Subprocess | Network |
| Location | Local only | Local or remote |
| Clients | One per process | Multiple concurrent |
| Setup | Simple | More complex |
| Use Case | Desktop apps, CLIs | Web, shared services |
For this course, we'll start with STDIO transport because it's simpler and works directly with Claude Desktop. We'll add HTTP/SSE later in Lesson 8.