Transport Layers
Relevant source files
The following files were used as context for generating this wiki page:
- src/mcp/server/streamable_http.py
- src/mcp/server/websocket.py
- src/mcp/server/stdio.py
- src/mcp/client/streamable_http.py
- tests/shared/test_streamable_http.py
- tests/server/fastmcp/test_integration.py
- examples/servers/simple-streamablehttp/README.md
- examples/servers/simple-streamablehttp-stateless/README.md
Transport layers in the MCP Python SDK are responsible for the underlying communication mechanism between an MCP client and an MCP server. They abstract the specifics of how JSON-RPC messages are exchanged, allowing the core MCP logic to remain independent of the network protocol. The SDK provides several transport options to suit different deployment scenarios, from local inter-process communication to stateful, resumable web-based interactions.
The primary transport layers implemented are StreamableHTTP, WebSocket, and Stdio. Each offers a different set of features regarding connection persistence, state management, and communication patterns. The choice of transport is a key architectural decision when building an MCP application, as it directly impacts scalability, reliability, and the types of interactions possible between the client and server.
Transport Layer Comparison
The following diagram illustrates the available transport layers.
| Feature | StreamableHTTP | WebSocket | Stdio |
|---|---|---|---|
| Connection | HTTP/S | Persistent WebSocket | Standard I/O Pipes |
| Primary Use Case | Web clients, stateless/scalable deployments | Stateful, low-latency web clients | Local process communication |
| Statefulness | Stateful (session-based) or Stateless | Stateful | Stateful |
| Server-side Push | Yes (via SSE on GET stream) | Yes (native) | Yes (native) |
| Resumability | Yes (with EventStore) | No | No |
| Key Server Class | StreamableHTTPServerTransport | WebsocketServerTransport | StdioServerTransport |
| Key Client Function | streamablehttp_client | websocket_client (not present) | stdio_client |
Sources: src/mcp/server/streamable_http.py, src/mcp/server/websocket.py, src/mcp/server/stdio.py, examples/servers/simple-streamablehttp/README.md, examples/servers/simple-resource/README.md
StreamableHTTP Transport
This is the most feature-rich transport, designed for robust communication over HTTP. It supports both request/response and server-push models, session management, and connection resumption.
Sources: src/mcp/server/streamable_http.py, src/mcp/client/streamable_http.py
Architecture
The StreamableHTTP transport uses a combination of HTTP methods to manage a session:
POST /mcp: Used by the client to send requests to the server (e.g.,initialize,tools/call). The response can be a single JSON object or a Server-Sent Events (SSE) stream containing multiple messages.GET /mcp: Used by the client to establish a long-lived SSE stream. The server uses this stream to push asynchronous notifications (e.g.,$/log,workspace/resourceUpdated) to the client.DELETE /mcp: Used by the client to terminate the session.
A key component is the StreamableHTTPSessionManager, which manages the lifecycle of sessions, routing requests to the appropriate Server instance.
Sources: src/mcp/server/streamable_http.py:311-316, tests/shared/test_streamable_http.py:1003-1010, tests/shared/test_streamable_http.py:770-776
Session Management
Sessions are identified by a unique mcp-session-id HTTP header. The client generates this ID for new sessions or reuses an existing one to resume. The server maintains the state for each session.
The following diagram shows the session lifecycle:
Key HTTP Headers
| Header | Direction | Description |
|---|---|---|
mcp-session-id | Client -> Server | Identifies the session for a request. Must be composed of visible ASCII characters. |
mcp-session-id | Server -> Client | Sent in the response to an initialize request to establish the session ID. |
mcp-protocol-version | Both | Specifies the MCP protocol version being used. Negotiated during initialization. |
Accept | Client -> Server | Must include text/event-stream for streaming responses or application/json. |
Content-Type | Client -> Server | Must be application/json for POST requests. |
Last-Event-ID | Client -> Server | Used in GET requests to resume an event stream from a specific point. |
Sources: src/mcp/server/streamable_http.py:39-42, src/mcp/server/streamable_http.py:43-46, src/mcp/server/streamable_http.py:61-63
Resumability
A powerful feature of the StreamableHTTP transport is its ability to resume a disconnected session. This is facilitated by an EventStore on the server side.
- The server assigns a unique ID to each event sent to the client.
- The client tracks the ID of the last event it received.
- If the client disconnects and reconnects, it sends a
GET /mcprequest with theLast-Event-IDheader. - The server's
EventStorereplays all missed events to the client, bringing it back to the current state.
This flow is depicted below:
Stateless Mode
The StreamableHTTP transport can also operate in a stateless mode by setting mcp_session_id=None. In this configuration, each request is treated as an ephemeral connection, and no session state is maintained between requests. This is suitable for multi-node deployments behind a load balancer where requests may be routed to different server instances.
Sources: examples/servers/simple-streamablehttp-stateless/README.md
WebSocket Transport
The WebSocket transport provides a persistent, full-duplex communication channel between the client and server. It is simpler than StreamableHTTP as it does not need to manage complex session state over a stateless protocol.
Architecture
- The client initiates a WebSocket handshake with the server.
- Once the connection is established, both client and server can send and receive JSON-RPC messages at any time over the single, persistent connection.
- The connection remains open until explicitly closed by either party.
The WebsocketServerTransport class handles the server-side implementation.
Sources: src/mcp/server/websocket.py.
Stdio Transport
The Stdio (Standard I/O) transport is designed for communication between processes running on the same machine.
Architecture
- The client application spawns the server application as a subprocess.
- The client writes JSON-RPC messages to the server's standard input (
stdin). - The server writes JSON-RPC responses and notifications to its standard output (
stdout). - The client reads from the server's
stdoutto receive messages.
This transport is ideal for local development or for tools where the client and server are tightly coupled, such as a command-line interface running a background language server. The stdio_client function in the client library facilitates this process.
Sources: src/mcp/server/stdio.py, examples/servers/simple-resource/README.md
Conclusion
The MCP Python SDK's transport layer architecture provides significant flexibility. The StreamableHTTP transport is a robust and feature-complete solution for web-based and distributed systems, offering session management and resumability. The WebSocket transport offers a simpler, persistent connection model for low-latency applications. Finally, the Stdio transport provides an efficient mechanism for local inter-process communication. This variety allows developers to choose the most appropriate communication strategy for their specific application needs.