For two years, running an MCP server in production meant building infrastructure that had nothing to do with what the server was actually supposed to do. The protocol's session model forced sticky routing, shared session stores, and affinity cookies onto teams who otherwise had no reason to build stateful infrastructure at all. On July 28, 2026, the MCP specification removed the session entirely — and with it, the justification for that entire category of workaround.
What the old transport forced on you
An MCP initialize handshake returned an Mcp-Session-Id header, and every subsequent request in that conversation had to carry the same ID back to the same server instance. Keeping that session alive in production meant one of three things: sticky sessions at the load balancer, a shared session store like Redis so any instance could serve any request, or a client-side retry strategy that tolerated session loss and re-initialized when a pod restarted.
Each solution adds a moving part that fails in a specific, familiar way during a rolling deployment. A pod gets terminated, its in-memory session state goes with it, and every client pinned to that pod either gets a connection reset mid-conversation or silently starts talking to a session that no longer exists.
# Pre-2026-07-28: sticky routing required
apiVersion: v1
kind: Service
metadata:
name: mcp-server
annotations:
alb.ingress.kubernetes.io/target-group-attributes: |
stickiness.enabled=true,
stickiness.type=lb_cookie,
stickiness.lb_cookie.duration_seconds=3600
What SEP-2567 actually removes
The core change removes protocol-level sessions and the Mcp-Session-Id header from the Streamable HTTP transport entirely — not deprecates, removes. Every request is now self-describing: protocol version, client identity, and capabilities travel in _meta on that request rather than being negotiated once and remembered by a pinned server instance.
This does not mean MCP servers can no longer carry state across calls. If a server needs to remember something between tool calls, it mints an explicit handle and returns it from the first call. The client passes that handle back as an ordinary argument — the same way any REST API has always handled state. What disappears is the requirement that the same pod be the one to look it up.
Header-based routing: the other half of the change
Statelessness solves scaling, but creates a new problem: how does a gateway make intelligent routing decisions without parsing every JSON-RPC body? SEP-2243 answers this: Streamable HTTP requests must now carry Mcp-Method and Mcp-Name headers. A load balancer can now route, throttle, and meter MCP traffic on headers — without ever being MCP-aware at the body level.
# AWS ALB post-2026-07-28 — no stickiness, header-based routing
annotations:
alb.ingress.kubernetes.io/conditions.mcp-tasks: |
[{"field":"http-header","httpHeaderConfig":{"httpHeaderName":"Mcp-Method","values":["tasks/*"]}}]
alb.ingress.kubernetes.io/actions.mcp-tasks: |
{"type":"forward","forwardConfig":{"targetGroups":[{"serviceName":"mcp-tasks-pool","servicePort":8443}]}}
Long-running task calls route to a differently-sized backend pool. Ordinary tool calls go elsewhere. No custom MCP-parsing logic in the gateway.
Per-request auth: the security implication
Removing the session also removes the one place authentication used to be established once and implicitly trusted for the rest of the conversation. Every request now carries its own client identity in _meta, which means authorization is evaluated per request. A revoked credential takes effect on the very next call instead of only once the session naturally expires. The infrastructure implication: your gateway now performs an identity check on every request rather than once per conversation — real added latency on every call, worth budgeting for explicitly when sizing the gateway layer.
The migration window
The specification's deprecation policy gives a twelve-month compatibility runway for features being phased out. What is removed outright — with no grace period — is the session header and initialize handshake. The realistic migration path is running both transport paths side by side behind the same ingress until every client you support has moved. The sticky-routing configuration doesn't disappear the day you upgrade — it stays live serving the old path while new traffic routes to the stateless pool through header-based rules.
Read the Full Article
This summary covers the core protocol changes and their infrastructure implications. The full article includes:
- Complete before/after Kubernetes Service and Ingress YAML for both AWS ALB and Azure Application Gateway
- The
ttlMs/cacheScopecaching signals (SEP-2549) and what they mean for CDN/edge caching - W3C Trace Context propagation in
_meta(SEP-414) and distributed tracing implications - How the removal of
Last-Event-IDstream resumability simplifies liveness probe design - Detailed dual-path migration strategy to avoid mid-migration outages
Top comments (0)