What’s actually changing
The MCP specification changelog for the 2026-07-28 revision states it directly:
“Eliminated
Mcp-Session-Idheader from Streamable HTTP transport; list endpoints no longer vary per-connection; servers use explicit handles for cross-call state”
This is tracked as SEP-2567, “Sessionless MCP via Explicit State Handles.” The reasoning: implicit, transport-level session state is invisible to the model and to anyone debugging a multi-step interaction. Making state explicit, an ordinary string the model actually sees and passes around, is the same pattern HTTP APIs have used for years: a basket_id, a browser_id, minted once and referenced afterward.
Structural Comparison Matrix
| Operational Aspect | Before (protocol-level sessions) | After (2026-07-28+) |
|---|---|---|
| Where cross-call state lives | Implicit, keyed by Mcp-Session-Id | Explicit, an ordinary handle string |
| Visibility to the model | Hidden in transport metadata | Visible, passed as a normal tool argument |
| List endpoint behavior | Could vary per connection | No longer varies per connection |
| Handle shape (recommended) | N/A | Opaque, e.g. bsk_a1b2c3, not cart_user42_2026-03-11 |
Fix it: mint and pass an explicit handle
Keep handles opaque, not descriptive
A handle that encodes internal structure invites clients to parse it or models to guess adjacent ones. Use an opaque token, not something human-readable like a username or a date embedded in the string.
// Client relied on the Mcp-Session-Id header to keep cart state
// scoped to this connection across multiple tool calls.{
"content": [{ "type": "text", "text": "Cart created." }],
"structuredContent": {
"basket_id": "bsk_a1b2c3"
}
}{
"name": "add_item_to_cart",
"arguments": {
"basket_id": "bsk_a1b2c3",
"item": "widget-42"
}
}The server mints basket_id once, from whatever tool call first needs a piece of persistent state, and returns it in structuredContent. Every subsequent tool call that touches the same state passes it back as an ordinary string argument, no different from any other parameter. A server implementation with connection-scoped in-memory state needs to move that state into whatever store the handle actually looks up, not just stop reading the removed header.
Confirmed version
Sourced from the official Model Context Protocol specification changelog, 2026-07-28 revision, published 2026-07-28, and SEP-2567’s own specification text for the explicit-handle pattern’s recommended shape. Browse more posts like this in the AI Productivity archive.







