The first MCP request returns 200. The next tools/call returns 400 with Unknown MCP session. The endpoint did not change, the tool schema is valid, and the network is healthy. What changed was the replica.
In a legacy Streamable HTTP flow, initialize can create protocol state in Replica A and return Mcp-Session-Id. A round-robin proxy may send the following tool call to Replica B. If the session lives only in A's memory, B cannot resolve it.
POST /mcp initialize
-> Replica A
<- 200
<- Mcp-Session-Id: session_a_123
POST /mcp tools/call
Mcp-Session-Id: session_a_123
-> Replica B
<- 400 Unknown MCP session
I built a small fixture with two legacy replicas, two draft-shaped stateless replicas, a real localhost round-robin proxy, and an external SQLite store. The legacy path produced a deterministic 200/400 result. The self-contained path alternated between draft-a and draft-b successfully. The wire lab passed 6/6 cases.
The important boundary is not 'state versus no state.' It is protocol state versus application state.
Protocol facts such as version, client information, capabilities, and routing metadata should be available on the current request. Durable product state still exists, but it should use explicit domain handles such as basket_id, approval_id, browser_id, or task_id, backed by storage every replica can reach.
That makes the application contract inspectable:
- the handle has an owner and tenant;
- the record has an explicit lifecycle;
- expired or completed objects are rejected intentionally;
- concurrent writes can use versions or ETags;
- side-effecting tools can use idempotency keys.
Sticky sessions can reduce the immediate failure rate during migration, but they do not preserve process memory after restarts, rolling deployments, or connection movement. A shared session store can support the old protocol temporarily, but it should not become a permanent opaque blob containing client capabilities, identity, business objects, and recovery state.
The locked MCP 2026-07-28 revision is still labeled RC / pre-release as of publication. This is therefore an RC experiment and migration plan, not a final-spec conformance claim. Package version, SDK API shape, and the wire protocol also need to be verified separately; installing an SDK v2 prerelease does not prove that production traffic is speaking the new protocol.
The complete article includes the request examples, replica routing evidence, explicit-handle lifecycle, SDK v2 smoke test, old/new client-server compatibility matrix, rollout gates, and rollback criteria.
Read the full experiment and migration checklist: https://www.xbstack.com/en/ai/mcp-2026-07-28-stateless-migration/?utm_source=devto&utm_medium=referral&utm_campaign=mcp_2026_07_28_stateless_migration&utm_content=article_body
Top comments (0)