MCP Transports
Protocol Revision: 2025-11-25
Transport Types
stdio
Local subprocess communication
- Best for local development
- NPX packages, Python scripts
- Newline-delimited JSON-RPC
Streamable HTTP
HTTP POST/GET with SSE streaming
- Production deployments
- Official SDK
streamablehttp_client - Auth via custom headers
WebSocket
Bidirectional real-time
- Long-lived connections
- Cloud-native (hibernatable)
- Lower protocol overhead
SSE (Legacy)
Server-Sent Events
- Backward compatibility
- Protocol version 2024-11-05
- URLs ending in
/sse
Quick Start
Transport Auto-Detection
The MCP class automatically selects the appropriate transport based on the URL:Streamable HTTP: the URL is used verbatim. Include whatever endpoint path your server exposes (commonly
/mcp); a bare-host URL will POST to / and fail with Session terminated.stdio Transport
The stdio transport runs MCP servers as subprocesses, communicating via standard input/output.Features
- ✅ JSON-RPC messages over stdin/stdout
- ✅ Newline-delimited messages
- ✅ UTF-8 encoding enforced
- ✅ Environment variable support
Usage
Parallel Tool Calls
MCP stdio tool calls are safe to run in parallel — each call gets its own response channel, so results never cross.timeout parameter on MCP() controls the per-call wait time (default 60s). On timeout, the tool result is the string "Error: MCP tool call timed out after {N} seconds" — the agent sees this as a tool error and can retry. The timeout also bounds the initial MCP handshake.
Streamable HTTP Transport
This is the current standard transport (Protocol Revision 2025-11-25)
Requirements
The Streamable HTTP transport is powered by the official MCP SDK’sstreamablehttp_client (httpx-based). It requires an up-to-date mcp package.
Features
- ✅ Single MCP endpoint for all communication
- ✅ Powered by the official
mcp.client.streamable_http.streamablehttp_client(httpx, not aiohttp) - ✅ Session lifecycle managed by the official SDK client
- ✅ Custom headers for authentication
- ✅ Clean context unwinding — a failed
initialize()handshake unwinds already-entered contexts, so no httpx/anyio connection or half-open remote session is leaked
Usage
The URL is used exactly as provided; there is no client-side rewriting. Pass the full endpoint your server exposes (commonly.../mcp).
Supported Options
The HTTP-Stream transport reads only these two options:session, resumability, cors, and responseMode are still accepted as keyword arguments but are no-ops on this transport — session and resumability are fully managed by the official SDK client. Use headers and timeout only.Troubleshooting
ImportError: streamablehttp_client not found
ImportError: streamablehttp_client not found
Your
mcp package predates the Streamable HTTP client. Upgrade it:session=True / resumability=True have no effect
session=True / resumability=True have no effect
These options are no-ops on the HTTP-Stream transport. Session and resumability are managed internally by the official
streamablehttp_client. Remove them — pass headers and timeout instead.AttributeError on http_stream_client.transport
AttributeError on http_stream_client.transport
The internal
transport attribute is now None; session management is owned by the official SDK client. Do not access http_stream_client.transport.session_id or .terminate_session().McpError: Session terminated on initialize
McpError: Session terminated on initialize
The Streamable HTTP transport posts to the URL exactly as you provided. It does not silently append
/mcp to a bare-host URL any more (this convenience was removed in the fix for PraisonAI #3032). If your server exposes tools at https://server.example.com/mcp, pass that full URL — a bare https://server.example.com will POST to /, get HTTP 404, and the SDK will surface it as McpError: Session terminated during session.initialize().WebSocket Transport
Based on SEP-1288 (in review)
Features
- ✅
ws://andwss://URL detection - ✅ JSON-RPC message framing
- ✅ Session ID handling
- ✅ Reconnection with exponential backoff
- ✅ Authentication token support
- ✅ Ping/pong keepalive
Usage
Advanced WebSocket Options
Reconnection
WebSocket transport automatically reconnects with exponential backoff:SSE Transport (Legacy)
The SSE transport is maintained for backward compatibility with servers using protocol version 2024-11-05.Usage
Security
Origin Validation (DNS Rebinding Prevention)
Authentication
Secure Session IDs
Backward Compatibility
Supporting Older Servers
The MCP class automatically handles backward compatibility:Protocol Versions Supported
Custom Transports
You can implement custom transports by extending theBaseTransport class:
Best Practices
Transport Selection
- stdio: Local development, NPX packages
- Streamable HTTP: Production web services
- WebSocket: Real-time, cloud-native apps
- SSE: Legacy server compatibility
Streamable HTTP
- Upgrade with
pip install -U 'mcp' - Pass
headersfor authentication - Session lifecycle is handled by the SDK client
Timeouts
- Set
timeoutfor slow servers - The timeout bounds each tool call
- It also bounds the initial handshake
Security
- Validate Origin headers
- Use HTTPS/WSS in production
- Implement proper authentication
- Bind to localhost for local servers
Next Steps
MCP Tools
Learn about MCP tool integration
MCP Servers
Explore available MCP servers
SSE Transport Details
Deep dive into SSE transport
Custom MCP Servers
Build your own MCP servers

