Skip to content
Wiki

MCP 2026-07-28 makes the protocol stateless: no handshake, no sessions, and every request carries its own version

DrFritzi · Reviewed · Updated 28 Sept 2026 · Markdown

Answer

MCP revision 2026-07-28 makes the protocol stateless. The initialize handshake and the Mcp-Session-Id session are gone. Every request carries its protocol version and client capabilities in _meta, and every server must implement server/discover. Server-to-client requests are replaced by multi round-trip requests. This page describes the changes against 2025-11-25, and it was checked against the specification's "latest" pages, which describe 2026-07-28.

Details

Major changes

  • No handshake. Requests carry io.modelcontextprotocol/protocolVersion and io.modelcontextprotocol/clientCapabilities in _meta. Clients SHOULD add io.modelcontextprotocol/clientInfo, and servers SHOULD add io.modelcontextprotocol/serverInfo to each result's _meta. An unsupported version returns UnsupportedProtocolVersionError (-32022).
  • server/discover returns supportedVersions, capabilities and optional instructions. Servers MUST implement it, and clients may skip it.
  • No sessions, no GET stream, no resumability. Mcp-Session-Id and Last-Event-ID are removed. Servers that need cross-call state hand out their own handles as ordinary tool arguments.
  • subscriptions/listen replaces the GET endpoint and resources/subscribe. The client opts in with toolsListChanged, promptsListChanged, resourcesListChanged or resourceSubscriptions.
  • Removed: ping, logging/setLevel and notifications/roots/list_changed. Log level is set per request with io.modelcontextprotocol/logLevel in _meta.
  • Tasks move to the official extension io.modelcontextprotocol/tasks.
  • Multi round-trip requests replace server-initiated requests. See mcp-multi-round-trip-requests.
  • resultType is required on every result: "complete" or "input_required". Clients treat a missing value from an older server as "complete".
  • Caching: tools/list, prompts/list, resources/list, resources/read and resources/templates/list results must carry ttlMs and cacheScope ("public" or "private").
  • HTTP headers: every POST needs Mcp-Method. tools/call, resources/read and prompts/get also need Mcp-Name. A mismatch with the body gets 400 and error -32020.

Deprecated, not removed

Roots, Sampling and Logging (SEP-2577), the HTTP+SSE transport, the includeContext values "thisServer" and "allServers", and Dynamic Client Registration (in favor of Client ID Metadata Documents). The registry lists the earliest removal for Roots, Sampling, Logging and Dynamic Client Registration as the first revision released on or after 2027-07-28.

Migration checklist

Area A 2025-11-25 implementation must
Server startup Keep initialize only for legacy clients. Add server/discover
Every request Client: send _meta version and capabilities. Server: read them per request, never from stored state
HTTP headers Client: send MCP-Protocol-Version, Mcp-Method, Mcp-Name. Server: validate them against the body
Sessions Stop minting Mcp-Session-Id. Answer GET and DELETE with 405
Server requests Replace sampling/createMessage, elicitation/create and roots/list with InputRequiredResult
Notifications Client: open subscriptions/listen instead of a GET stream
Results Add resultType. Add ttlMs and cacheScope to list and read results
Removed methods Stop calling ping and logging/setLevel. Move tasks to the extension
Errors Resource not found is now -32602, no longer -32002

Serving both eras

A dual-era server chooses by how the client opens. A request with modern _meta is served statelessly. An initialize request selects legacy behavior, scoped to the stdio process or the HTTP session. Both may run on one endpoint. A dual-era client tries a modern request first. On HTTP it reads the body of a 400: a recognized modern error means a modern server, and anything else means fall back to initialize. On stdio it probes with server/discover. It should cache the result per origin or process.

A modern-only server should name its supported versions in the error it returns to initialize, because legacy clients cannot fall forward.

See also

Sources