Streamable HTTP in MCP: How Bidirectional Streaming Works Without SSE
Most people think MCP streaming disappeared when SSE was deprecated.
That is wrong.
Streaming did not go away — permanent connections did.
This article explains how Streamable HTTP works and why it is superior to the old SSE model.
The Old Model (SSE Transport)
Originally MCP used:
GET /mcp → server → client stream (SSE)
POST /messages → client → server commands
A permanent connection stayed open forever.
This caused:
- idle sockets
- memory pressure
- reconnection complexity
- load-balancer nightmares
The New Model — Streamable HTTP
Now MCP uses:
POST /mcp ↔ streaming response
No permanent pipe.
No session IDs.
No idle sockets.
Every request owns its own stream.
What “Streamable” Actually Means
The server does not immediately close the POST response.
It keeps the socket open and flushes JSON-RPC messages over time.
Example:
POST /mcp
{ "method":"tool/call" }
Response:
HTTP/1.1 200 OK
Transfer-Encoding: chunked
{ "progress": 10 }
{ "progress": 50 }
{ "awaitingHuman": true, "taskId":"t123" }
The connection remains open.
Human-in-the-Loop Flow
1. Tool pauses
Server streams:
{ "awaitingHuman": true, "taskId":"t123" }
2. Human approves
Client opens a new POST:
POST /mcp
{ "method":"task/approve", "taskId":"t123" }
3. Server resumes the original stream
The server finds the open response stream for task t123 and continues writing:
{ "approved": true }
{ "final": "done" }
Then it closes the first POST.
Multiple Requests at the Same Time
Clients can run many tools concurrently:
POST /mcp → stream A
POST /mcp → stream B
POST /mcp → stream C
Each is independent.
When Does a Stream Close?
A POST stream closes when:
- tool finishes
- error occurs
- client aborts
- server times out
No stream lives forever.
Why This Is Better Than SSE
| SSE Transport | Streamable HTTP |
|---|---|
| One permanent pipe per client | Only pipes when work exists |
| Needs session map | Task-scoped streams |
| Hard to scale | Scales like REST |
| Two endpoints | One endpoint |
| Idle sockets everywhere | Zero idle sockets |
The Golden Rule
Every MCP task owns its own temporary HTTP stream.
When the task ends, the connection ends.
Final Takeaway
Streamable HTTP gives MCP:
- real-time streaming
- human-in-loop
- concurrency
- fault tolerance
— without permanent connections.
That’s why SSE was deprecated — not because streaming was wrong, but because idle pipes were.