MCP Drops the Handshake: What Developers Need to Know
Published Sep 21, 2026 by Editorial Team

The newest stable revision of the Model Context Protocol, 2026-07-28, removes the familiar initialize / notifications/initialized handshake from the modern protocol path. It also removes protocol-level sessions and the Mcp-Session-Id header from Streamable HTTP. (MCP 2026-07-28 changelog)
That sounds like a small wire-protocol change. It is not.
MCP is moving from a connection-oriented model to a stateless request/response model. For teams operating remote MCP servers, that changes the practical architecture: a request no longer needs to return to the process that handled the last one; a server cannot rely on a previous exchange to know a client’s capabilities; and a gateway can inspect enough metadata to route and enforce policy without parsing every JSON-RPC body.
The upgrade is not a reason to panic. Older MCP versions remain part of compatibility negotiation. But it is a reason to stop treating a long-lived connection as the place where an MCP integration keeps its truth.
The Handshake Is Gone; Context Is Not
In the earlier model, a client opened a connection, sent initialize, received the server’s capabilities, and acknowledged initialization before useful work began. Session identity and negotiated capabilities could live around that connection.
In MCP 2026-07-28, every request is self-describing. The client supplies its protocol version and capabilities in _meta; client information is recommended on each request, and server information can be included in result metadata. A server must not infer capabilities from prior requests—even if they happened on the same connection. (Basic protocol overview)
Conceptually, the new baseline looks like this:
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/call",
"params": {
"name": "search_accounts",
"arguments": { "query": "Ada" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {},
"io.modelcontextprotocol/clientInfo": {
"name": "Example client",
"version": "1.0.0"
}
}
}
}
This is the important mental shift: connection lifetime is no longer the unit of protocol state. If an operation needs to continue across calls, the server issues an explicit, ordinary handle and the client passes that handle back. The specification calls for cross-call state to use server-minted handles in tool arguments rather than an implicit session. (MCP 2026-07-28 changelog)
That makes the system a little more explicit in application code—and much less special in production infrastructure.
Why Stateless MCP Is an Operational Upgrade
Stateful remote MCP servers made ordinary infrastructure decisions oddly consequential. A load balancer might need affinity. Multiple replicas might need a shared session store. Restarting a worker could interrupt context that existed only in memory. Debugging an intermittent request sometimes began with finding out which server instance owned a connection.
With self-contained requests, any healthy replica can serve an eligible request. That makes plain round-robin load balancing possible, without a permanently open bidirectional stream carrying protocol state. (MCP 2026-07-28 changelog)
That has practical consequences:
- Horizontal scaling becomes conventional HTTP scaling rather than session management.
- A deployment can replace or restart instances without treating each established protocol session as a special object.
- Server logs, traces, and rate limits can be organized around requests, task handles, and user identity rather than connection affinity.
- A long-running request can still stream notifications, but its state belongs to that request—not the underlying connection. (Basic protocol overview)
Statelessness does not mean an MCP application may not have state. A research job, checkout draft, database cursor, or approval workflow still has state. The difference is where it lives: in an explicit durable store and identifier that your application manages, rather than in a protocol session that a particular server process remembers.
Discovery Replaces Initialization—But Is Not a Mandatory Ceremony
server/discover is the modern way to retrieve supported protocol versions, server capabilities, identity, and instructions. Servers must implement it. Its result can be cached, and it is useful when a client wants to present or inspect a server before making a tool call. (Discovery)
But discovery is not another handshake under a new name. A client does not have to call it before every useful operation; it may send another RPC directly and handle a version error if necessary. That distinction is worth preserving in client code. Treat discovery as an optional, cacheable capability lookup—not as invisible connection setup. (Discovery)
For a client that must support older servers, a sensible strategy is to attempt the modern path, distinguish a genuine modern protocol error from an older endpoint, and only then fall back to the legacy initialize flow. The Streamable HTTP specification defines that compatibility behavior in detail. (Streamable HTTP transport)
The New Headers Are a Gateway Feature—and a Security Responsibility
The release mirrors selected request details into Streamable HTTP headers. MCP-Protocol-Version is required on POST requests; Mcp-Method is required for all requests; and Mcp-Name is required for tool calls, resource reads, and prompt retrieval where it applies. (Streamable HTTP transport)
This gives reverse proxies and API gateways a useful view of MCP traffic. They can route by method or tool name, produce meaningful telemetry, and apply narrowly scoped policy without having to decode JSON-RPC first.
It also creates a non-negotiable rule: the headers and body must agree. A gateway that authorizes Mcp-Name: read_customer while the server executes a different tool named in the body would be a split-brain security problem. The specification requires servers that process the body to validate the mirrored values and reject mismatches. (Streamable HTTP transport)
In other words, do not treat the new headers as handy logging fields. Treat them as a contract between the edge and the server.
Server-to-Client Interaction Now Needs an Explicit Round Trip
The move away from permanently bidirectional sessions affects servers that need more input in the middle of work. MCP’s answer is Multi-Round-Trip Requests (MRTR): rather than a server independently calling back to the client on an open session, the server returns the input it needs and the client continues the interaction in a later request. Sampling and elicitation are central examples. (MCP 2026-07-28 changelog)
This is a design change, not just a transport substitution. Tool authors should model interruption points deliberately:
- return a durable task or workflow handle;
- record what additional human or model input is required;
- validate the next request against that workflow state;
- make retries safe, because network retries are normal in stateless systems.
The benefit is that the interaction no longer depends on a live socket surviving for the duration of a complex workflow. The cost is that application authors have to make the workflow state explicit. That is usually a worthwhile trade when an MCP server is expected to scale beyond one process.
Caching Is Now Part of the Protocol Conversation
The new revision adds caching metadata and deterministic list ordering. Results from discovery and catalog-like operations can include ttlMs and cacheScope; the specification also calls for a stable tool order. (MCP 2026-07-28 changelog)
That may look like a small performance optimization. It matters more than that for servers with substantial tool catalogs. A client can avoid repeatedly fetching the same inventory, and stable output gives upstream prompt caches a better chance of recognizing the same context from one request to the next.
Server developers should decide their cache policy intentionally. A static catalog can advertise a useful TTL. A catalog that changes per tenant or authorization state may need a private scope, a short TTL, or no meaningful caching at all. “Cacheable” is not the same as “safe to share.”
What to Change in an Existing Server
The migration checklist is architectural before it is syntactic:
- Find session-bound state. Replace in-memory maps keyed by a session ID with durable state keyed by an explicit task, workflow, or application identifier.
- Stop assuming initialization happened. Validate the required per-request
_metafields and use the current request’s declared capabilities. - Audit callback-style flows. Recast sampling, elicitation, and similar mid-call interactions as resumable multi-round-trip workflows.
- Update the HTTP edge. Forward the MCP headers, route only on headers you validate, and make sure observability systems record the protocol version and method.
- Set cache metadata deliberately. Especially for
server/discover,tools/list, prompts, and resources. - Retain a compatibility plan. A modern client or server may need to negotiate down when it meets a peer that only understands the handshake era.
Also take the deprecations seriously. The release formally deprecates Roots, Sampling, and Logging features, and classifies the older HTTP+SSE transport as deprecated. New implementations should target Streamable HTTP and the newer interaction patterns rather than adding fresh dependence on retiring features. (MCP 2026-07-28 changelog)
The Point Is Not Fewer Messages
It would be easy to summarize this release as “MCP no longer has a handshake.” That is accurate but incomplete.
The real change is that MCP is becoming easier to operate as shared infrastructure. Connections are no longer where a server stores its working memory. Discovery is data, not ceremony. Long-running interactions are workflows, not callbacks that happen to be open. And gateways can finally see enough of the request to do their job—provided they validate what they see.
For developers, the immediate task is to move hidden connection assumptions into explicit protocol and application state. Once that work is done, MCP servers become easier to scale, easier to replace, and easier to trust in the same environments where the rest of your production services already run.