What is the Streamable HTTP transport, and how did it replace the older HTTP+SSE transport?
Quick Answer
Streamable HTTP is MCP's current remote transport: a single HTTP endpoint that accepts POSTed JSON-RPC messages, where the server's response can be either a plain JSON body (for a simple request/response) or an upgrade to a Server-Sent Events stream (for cases needing multiple messages back — progress notifications followed by a final result, or server-initiated requests like sampling). This replaced an earlier (2024-11-05 spec) transport that required two separate endpoints — one for the client to POST individual messages, one long-lived GET-initiated SSE stream for the server to push messages — which was more complex to implement and had rougher edge cases around reconnection and load balancing across multiple server instances. Streamable HTTP consolidates everything onto one endpoint, making it far closer to how a typical stateless HTTP API is built, while still allowing streaming when the server actually needs it.
Detailed Answer
MCP's remote transport went through a real redesign once real-world deployments surfaced problems with the original approach.
The old model (HTTP+SSE, 2024-11-05 spec)
Client --GET--> /sse (opens a long-lived SSE stream; server pushes messages here)
Client --POST-> /messages (client sends its own messages here, separately)
Two endpoints, and the client had to correlate a persistent SSE connection with a separate POST channel. This made load-balancing across multiple stateless server instances awkward: the SSE connection is pinned to one server instance, but POSTs might land on a different instance behind a load balancer, unless you add sticky sessions or shared state.
The current model (Streamable HTTP)
Client --POST--> /mcp (single endpoint; body is a JSON-RPC message)
Response is EITHER:
- a single JSON object (simple request/response), OR
- an upgrade to an SSE stream, if the server needs to send multiple
messages related to that request (progress, then final result)
One endpoint, and streaming becomes an opportunistic upgrade rather than a permanently separate channel a client must always maintain.
Why this is a real improvement
- Simpler to implement and deploy. One route to expose, one set of auth/middleware to apply — closer to conventional REST/JSON API patterns most infrastructure already handles well.
- Friendlier to standard HTTP infrastructure. Load balancers, API gateways, and serverless platforms handle a single POST endpoint far more naturally than a long-lived, connection-pinned SSE stream that must route to the same backend instance for its whole lifetime.
- Streaming becomes optional per-request, not a mandatory always-on second connection. Simple servers with no need for server push don't pay for that complexity at all.
What stayed the same
The messages themselves — JSON-RPC requests, responses, notifications — are identical to the old transport. Only the framing and connection model changed. That's exactly the kind of change transport independence is meant to absorb, without touching anything else in the spec.