Streamable HTTP Overview
Learn how MCP uses HTTP POST for requests and Server-Sent Events for streaming responses.
What You'll Build
In this lesson, you'll build http_sse_transport.py — a reusable
HTTP/SSE transport module, plus http_example.py to demonstrate it.
By the end, your server will:
- Handle JSON-RPC requests via HTTP POST
- Support both JSON and SSE response modes
- Manage client sessions with the
Mcp-Session-Idheader - Stream progress updates for long-running operations
- Support CORS for browser-based clients
Each step builds on the previous one, and you'll test your server with curl commands.
The Streamable HTTP Transport
MCP's Streamable HTTP transport combines standard HTTP POST requests with Server-Sent Events (SSE) for streaming responses. This approach provides the best of both worlds: familiar HTTP semantics with real-time streaming capabilities.
Unlike STDIO transport (which is great for local tools), HTTP/SSE works over networks, supports multiple concurrent clients, and integrates with existing web infrastructure like load balancers and proxies.
How It Works
The transport uses a simple request-response pattern with optional streaming:
┌──────────────────────────────────────────────────────────────┐
│ STREAMABLE HTTP TRANSPORT │
├──────────────────────────────────────────────────────────────┤
│ │
│ CLIENT SERVER │
│ │ │ │
│ │─── POST /mcp (JSON-RPC request) ────►│ │
│ │ │ │
│ │◄── Response Option 1: ───────────────│ │
│ │ Content-Type: application/json │ │
│ │ (single JSON-RPC response) │ │
│ │ │ │
│ │◄── Response Option 2: ───────────────│ │
│ │ Content-Type: text/event-stream │ │
│ │ (SSE stream with multiple events) │ │
│ │ │ │
└──────────────────────────────────────────────────────────────┘
Request Format
Clients send JSON-RPC requests via HTTP POST. The request body contains the JSON-RPC message, just like in STDIO transport:
POST /mcp HTTP/1.1
Host: localhost:8080
Content-Type: application/json
Accept: application/json, text/event-stream
Mcp-Session-Id: abc123
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list"
}
Response Options
The server can respond in two ways depending on the operation:
Option 1: Direct JSON Response
For simple, non-streaming operations:
HTTP/1.1 200 OK
Content-Type: application/json
Mcp-Session-Id: abc123
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [...]
}
}
Option 2: SSE Stream
For operations that may produce multiple messages or need progress updates:
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
Mcp-Session-Id: abc123
event: message
data: {"jsonrpc":"2.0","id":1,"result":{"tools":[...]}}
Key Concepts
| Concept | Description |
|---|---|
| POST Endpoint | Single endpoint (e.g., /mcp) receives all JSON-RPC requests |
| Session ID | The Mcp-Session-Id header tracks client sessions |
| Content Negotiation | Client uses Accept header to indicate SSE support |
| SSE Format | Events use event: and data: fields |
When to Use HTTP/SSE
Choose the HTTP/SSE transport when you need:
- Network-accessible MCP servers (not just local)
- Multiple clients connecting to the same server
- Integration with web applications
- Streaming responses for long-running operations
- Load balancing and horizontal scaling
In the next step, we'll dive deep into Server-Sent Events — the technology that enables real-time streaming from server to client.