How does session management work over the Streamable HTTP transport?

5 minadvancedmcphttpsessionstreamable-http

Quick Answer

When a client initializes a session over Streamable HTTP, the server can return an Mcp-Session-Id header alongside its initialize response. The client must then include that same Mcp-Session-Id header on every subsequent request in that session, letting a stateless-looking HTTP server correlate requests to the right in-memory (or persisted) session state — negotiated capabilities, subscriptions, any server-side context built up since initialization. A client can explicitly end a session with an HTTP DELETE to the same endpoint carrying that session ID, and a server may reject requests carrying an unrecognized or expired session ID (typically with an HTTP 404), signaling the client it needs to re-initialize.

Detailed Answer

HTTP is fundamentally stateless. MCP's initialize/capability-negotiation model is inherently stateful. A session has to bridge that gap.

The header

POST /mcp HTTP/1.1
Content-Type: application/json

{"jsonrpc": "2.0", "id": 1, "method": "initialize", "params": {...}}

--- Response ---
HTTP/1.1 200 OK
Mcp-Session-Id: 3fa2c1e0-9b4d-4a11-8f7a-1d0e9c2b7a55
Content-Type: application/json

{"jsonrpc": "2.0", "id": 1, "result": {...}}

Every subsequent request in this session repeats the header:

POST /mcp HTTP/1.1
Mcp-Session-Id: 3fa2c1e0-9b4d-4a11-8f7a-1d0e9c2b7a55

{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}

Ending a session

DELETE /mcp HTTP/1.1
Mcp-Session-Id: 3fa2c1e0-9b4d-4a11-8f7a-1d0e9c2b7a55

This lets a client explicitly release server-side session resources, instead of leaving them to expire on a timeout.

What the server does with the session ID

It's the key into whatever server-side state needs to persist across requests: which capabilities were negotiated at initialize, active resource subscriptions, any per-session authorization context. Without it, every POST would look like an isolated, brand-new connection with no memory of the handshake that already happened.

Failure handling

If a client sends a session ID the server doesn't recognize — expired, evicted, or never issued — the server typically responds with an HTTP 404. The client should treat that as "this session is gone" and re-run initialize to start fresh, rather than continuing to retry the same stale session ID.

Security implication

The session ID is effectively a bearer credential for that session's context. It should be generated with cryptographically secure randomness and treated like a session cookie. Predictable or guessable session IDs would let an attacker hijack another user's in-progress session.

Related Resources