The latest stable Model Context Protocol revision, released July 28, 2026, makes a deliberate break with MCP’s original session-oriented transport model. The important change is not a new tool API; it is that a remote MCP server can now behave like an ordinary stateless HTTP service. (github.com)
The handshake is gone
Previous remote MCP implementations opened a protocol session with initialize, received an Mcp-Session-Id, and often needed sticky load balancing or shared session storage. The new core removes the initialize / notifications/initialized exchange and retires the session header.
Instead, each request identifies the protocol version, client, and client capabilities in _meta. A client may call server/discover to fetch a server’s capabilities first, but discovery is optional: a valid request contains enough information for any compatible server instance to process it. (blog.modelcontextprotocol.io)
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 42,
"method": "tools/call",
"params": {
"name": "search",
"arguments": { "query": "open pull requests" },
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientInfo": {
"name": "review-bot",
"version": "1.0.0"
},
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}
That removes a real operational constraint. Put several MCP instances behind a round-robin load balancer, deploy a replacement during an active agent run, or retry a failed request on another instance without reconstructing protocol state. This is a better default for remote servers.
It does not mean your product must be stateless. If a workflow spans several tool calls, create an explicit application-level handle and return it to the model. For example, create_export can return an exportId; get_export_status and download_export accept it later. Explicit state is observable, auditable, and survives a request landing on another instance. Hidden transport state was none of those things.
Server-to-client interaction becomes a retry protocol
The old approach to elicitation, sampling, and roots depended on the server initiating JSON-RPC requests back to the client. That design fit a held-open, bidirectional connection. It does not fit a stateless request/response service.
The replacement is Multi Round-Trip Requests (MRTR). A tool that needs user confirmation, a missing field, a model response, or root information returns resultType: "input_required" plus the requested inputs. The client gathers them and retries the original call with inputResponses and the supplied request state. (blog.modelcontextprotocol.io)
Treat MRTR as a resumable interaction state machine, not as a special kind of long-running HTTP request:
- The client calls a tool.
- The server either completes or asks for named input.
- The client obtains that input through its UI or model runtime.
- The client retries with the answers.
- The server validates the state and either completes or asks again.
This creates clear implementation requirements. Persist request state somewhere durable if the operation outlives a process. Make retry handling idempotent. Bind the state to the caller or authorization context so one client cannot resume another client’s operation. Never treat a repeated tools/call as proof that the user intended to perform an action twice.
Gateways can finally see what they are routing
Streamable HTTP now carries Mcp-Method and Mcp-Name headers. A proxy can identify tools/call for search before parsing the JSON body. That matters for rate limits, authorization decisions, request metrics, and routing.
A practical policy might allow a low-risk search tool broadly, require stronger identity for deployment tools, and send expensive report generation to a dedicated worker pool. You can implement those controls at the edge without writing an MCP-aware JSON body parser in every gateway.
The revision also makes list results deterministic and allows servers to attach cache hints such as ttlMs. Cache tools/list, resources/list, and other catalog-style responses only within the advertised lifetime. Stable ordering is especially useful because it avoids needless prompt-cache churn when a client reconnects or another instance serves the response. (blog.modelcontextprotocol.io)
The caveat is simple: caching a tool catalog is not permission checking. A tool can remain visible in a cached list while a later invocation is denied because the user, tenant, policy, or server state changed. Authorize the call itself.
Extensions and authorization are now explicit protocol surfaces
Tasks are no longer an experimental core feature. They live in the io.modelcontextprotocol/tasks extension and provide poll-oriented lifecycle operations including tasks/get and tasks/update. This fits work that cannot or should not complete during one HTTP exchange: repository scans, batch exports, and human approval queues are common examples. (blog.modelcontextprotocol.io)
The broader design is that optional capabilities ship as named extensions rather than permanently expanding the core. MCP Apps and Enterprise Managed Authorization follow the same model. For implementers, that means capability negotiation must be a first-class test dimension: a client should not assume a server supports an extension merely because both support MCP.
Authorization also tightened. The revision adds issuer validation aligned with RFC 9207 and moves away from Dynamic Client Registration toward client metadata documents (CIMD). If you operate OAuth-protected servers, validate the issuer and intended resource rather than accepting an access token because it is structurally valid. Authorization bugs at this boundary are cross-server credential bugs. (blog.modelcontextprotocol.io)
What to change in an existing server
Do not rewrite a working stdio server just to adopt the new remote transport. The payoff is strongest for HTTP deployments that currently carry connection-bound state.
A migration order that avoids a flag day
- Inventory session coupling. Find uses of session IDs, in-memory client capability maps, open-stream callbacks, and server-initiated requests.
- Move durable state into your domain. Replace hidden session data with operation IDs, database rows, or signed opaque handles passed as tool arguments.
- Add stateless HTTP coverage. Verify that two sequential calls can hit different instances and still work.
- Model interactive tools with MRTR. Test cancellation, duplicate retries, expired request state, and a client that declines to provide requested input.
- Use the routing headers at the edge. Add metrics and policy incrementally; do not make body-derived authorization rules disagree with header-derived rules.
- Keep version negotiation enabled. Existing clients and servers may still negotiate an earlier protocol revision, so exercise both paths until your client fleet has moved.
Roots, sampling, and logging are deprecated in this revision. Do not build new product behavior around those legacy core APIs. For new interactive flows, use MRTR; for observability, use your normal application logging and tracing pipeline rather than a protocol-level log subscription. (modelcontextprotocol.io)
The interview answer worth practicing
A strong explanation of this update starts with the constraint, not the feature list: session-bound MCP made remote deployments unnecessarily dependent on connection affinity. The new protocol puts client metadata on every request, moves interactive server-to-client flows into explicit retries, and exposes routing information in headers.
Then state the trade-off: stateless transport improves failure recovery and horizontal scaling, but it shifts responsibility to the application. You must design handles, idempotency, authorization binding, retry semantics, and task persistence deliberately. That is a better engineering boundary than assuming an HTTP connection will remain alive.
callout{title="Practice the system-design angle" desc="Explain how you would make an approval-gated MCP tool idempotent across retries and load-balanced instances." href="/skills" label="Start practicing"}
FAQ
What is the biggest change in the latest MCP update?
MCP’s protocol core is now stateless for the new HTTP model. Servers no longer depend on a protocol handshake or session ID; each request supplies the metadata needed to process it.
Does stateless MCP mean my application cannot keep state?
No. It means transport state should not be your application state. Return explicit operation IDs or opaque handles from tools, persist the associated state yourself, and require later calls to provide the handle.
What replaces server-initiated elicitation and sampling requests?
Multi Round-Trip Requests (MRTR). A server responds that input is required, the client obtains the input, and the client retries the original request with the answers and request state.
Should I remove roots, sampling, and logging immediately?
Existing compatibility paths may still need them, but do not add new dependencies on those deprecated core APIs. Build new interactive flows around MRTR and use standard application telemetry for logs.

