Chapter 6: Transports — stdio and HTTP/SSE


A transport is the mechanism by which a client and server exchange MCP messages. The protocol is transport-agnostic — the same JSON-RPC messages flow over any transport. Your choice of transport affects how the server is deployed and how clients connect to it.

MCP defines two standard transports: stdio and HTTP with Server-Sent Events (SSE).


stdio Transport

How It Works

With stdio transport, the host process spawns your server as a child process. Messages flow over stdin/stdout:

The server lives and dies with the connection. When the host terminates the process, the session ends.

When to Use stdio

Use stdio when:

stdio is the default for all local MCP servers. It is the transport you should start with.

Running With stdio

mcp.run() defaults to stdio:

if __name__ == "__main__":
    mcp.run()          # stdio transport, default
    # or equivalently:
    mcp.run(transport="stdio")

Important: Keep stdout Clean

With stdio transport, any output written to stdout (other than valid JSON-RPC) will corrupt the protocol stream and crash the connection. This means:

Configure logging to stderr:

import logging
import sys

logging.basicConfig(stream=sys.stderr, level=logging.INFO)
logger = logging.getLogger(__name__)

HTTP/SSE Transport

How It Works

With HTTP/SSE transport, your server runs as a persistent HTTP service. The client connects over the network:

This is a long-lived HTTP connection. The server runs independently of any client and can serve multiple clients simultaneously.

When to Use HTTP/SSE

Use HTTP/SSE when:

Running With HTTP/SSE

if __name__ == "__main__":
    mcp.run(transport="sse")

By default this starts on http://localhost:8000/sse. Configure the host and port:

mcp.run(transport="sse", host="0.0.0.0", port=9000)

Full example: code/05_http_sse_server.py

Connecting Clients to an HTTP/SSE Server

In client configuration, instead of a command to run, you provide the server URL. See Chapters 7–9 for client-specific configuration details.


Choosing a Transport

Factor stdio HTTP/SSE
Deployment Local process Network service
Multi-client No (1:1) Yes
Setup complexity Minimal Requires running server
Security Process isolation Network security needed
Latency Minimal Network overhead
Best for Local tools, dev Shared services, remote

Start with stdio. It is simpler to develop, test, and configure. Move to HTTP/SSE only when you need remote access or multi-client support.


Streamable HTTP (Newer Alternative)

The MCP specification also defines a newer “Streamable HTTP” transport that unifies request and response over a single HTTP endpoint (without requiring SSE). As of early 2026, the Python SDK supports this as transport="streamable-http".

Streamable HTTP is better suited for serverless environments (AWS Lambda, Cloudflare Workers) where long-lived SSE connections are impractical.

mcp.run(transport="streamable-http", host="0.0.0.0", port=8000)

Check the SDK documentation for the latest transport options.


Running Behind a Reverse Proxy

For production HTTP/SSE servers, run behind a reverse proxy like nginx or Caddy:

Example nginx location block:

location /mcp/ {
    proxy_pass http://localhost:8000/;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
    proxy_buffering off;
    proxy_cache off;
}

The proxy_buffering off setting is critical for SSE — buffering breaks the streaming connection.


Key Takeaways


← Chapter 5: Prompt Templates Table of Contents Chapter 7: Connecting to Claude Desktop →