• Uncategorised

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 TransportStreamable HTTP
One permanent pipe per clientOnly pipes when work exists
Needs session mapTask-scoped streams
Hard to scaleScales like REST
Two endpointsOne endpoint
Idle sockets everywhereZero 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.

You may also like...