Explain how Streamable HTTP functions as an MCP transport, what HTTP mechanism enables streaming, and describe a concrete deployment where it is the correct choice versus stdio.
Streamable HTTP is one endpoint the client POSTs JSON-RPC to; the server replies with plain JSON or upgrades to SSE for streaming, making remote and serverless MCP servers practical.
Picture a drive-through window instead of a dedicated phone line into the kitchen. You pull up to one window and place your order (POST a request). For a quick item, the cook hands it straight back. For something that takes a while, they keep passing you pieces as they finish, so you are not stuck staring at a blank window. The old design needed a permanent open phone line plus a separate window, which is awkward when many cooks share the work or the kitchen shuts down between orders. The single-window design works even if a different cook handles each visit, because your receipt number tells everyone which order is yours. That is the whole trick: one door, optional trickle-back, and a ticket that survives across cooks.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Concept explanation~2 min read
Everything you need to truly understand this topic: intuition, mechanics, step by step explanation, code, formulas, and worked example. Click to expand.
Streamable HTTP is the transport that made remote MCP servers practical. When MCP launched in late 2024, remote servers used an HTTP+SSE design: the client opened a long-lived GET /sse connection to receive messages and POSTed its own messages to a second endpoint. That worked on a laptop running a local proxy, but it fought modern deployment realities. Serverless runtimes spin down between requests and cannot hold a stream open. Load balancers route each request independently and do not know that two endpoints belong to one logical session. Auto-scaling fleets add and remove instances under load, so a connection pinned to one box becomes a liability rather than an asset.
The 2025 spec revision replaced that pair with a single design. The client POSTs JSON-RPC to one endpoint. The server answers with either a plain JSON body or an upgraded Server-Sent Events stream, depending on whether it has more than one message to send. Session identity moves out of the connection and into an Mcp-Session-Id header. The streaming case stays available for long tools and server-initiated traffic, but it is no longer the mandatory backbone of every conversation.
The shift is best understood as decoupling three things the old transport fused together: message direction, streaming, and session identity. The old design tied client-to-server traffic to one endpoint, server-to-client traffic to a separate held-open stream, and session identity to that stream's lifetime. Streamable HTTP unbundles them. This deep dive walks the wire contract, the JSON-versus-SSE decision, the session and resumability model, the deployment story, and the line where you should still reach for stdio instead.
The single-endpoint POST model
The defining move of Streamable HTTP is that the client sends every message the same way: an HTTP POST to one endpoint, conventionally /mcp. The request body is a JSON-RPC 2.0 message, identical in shape to what stdio carries. There is no separate channel for client-to-server traffic and no protocol handshake beyond ordinary HTTP plus the MCP initialize call.
What differs is the response. The client sends an Accept header listing both application/json and text/event-stream. The server then chooses. If the request is a single JSON-RPC request with a quick answer, the server returns a normal JSON body and the HTTP request completes. Nothing streams, nothing stays open.
If the server needs to send more than one message back, for example progress notifications during a long tool call, or its own requests to the client, it sets the response content type to text/event-stream and emits each JSON-RPC message as an SSE event on that open response. The connection closes when the server has nothing left to send for that request.
Under the hood, the SSE stream rides on HTTP chunked transfer encoding: the server writes events incrementally without declaring a fixed Content-Length up front, so the client receives bytes as they are produced rather than after the full body is buffered. That is the standard HTTP feature that makes progressive streaming possible over an ordinary POST response, and it is why intermediaries that understand HTTP/1.1 can carry the stream without special support.
Situations where this technique stops working.
2–4 min · Everything important, quickly.
| Concern | Streamable HTTP | Old HTTP+SSE | stdio |
|---|---|---|---|
| Endpoints | One POST endpoint | POST endpoint plus GET SSE channel | stdin and stdout of a child process |
| Streaming | Optional SSE upgrade per request | Always via the separate SSE channel | Line-delimited over the pipe |
| Session | Mcp-Session-Id header | Tied to the held-open SSE socket | Bound to the process lifetime |
| Serverless fit | Works; no pinned connection | Poor; needs a long-lived stream | Impossible; needs local spawn |
| Load balancers | Any worker serves any request | Splits the two endpoints awkwardly | Not applicable, local only |
Real products, models, and research that use this idea.
- GitHub's remote MCP server runs on Cloudflare Workers and uses Streamable HTTP so hosts POST tool calls over HTTPS.
- Cloudflare's Agents SDK ships a Streamable HTTP MCP server template that deploys to Workers without a held-open connection.
What an interviewer would ask next. Try answering before peeking at the approach.
QHow does resumability work after a Streamable HTTP stream drops mid-response?
Each SSE event carries an id; the client reconnects with Last-Event-ID and the server replays from the next event so no messages are lost.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Red flags & common mistakes
The phrases that signal junior thinking. Click to expand.
Calling Streamable HTTP just HTTP+SSE renamed. The shift is one endpoint with optional SSE upgrade, not a separate long-lived SSE channel plus a POST endpoint.
60 second bullets to scan on the way to the call.
Why all client messages go to one POST endpoint
When the server returns plain JSON versus upgrading to SSE
Primary sources. Browse if you want the original framing.
Same topic, related formats. Practice these next.