Chapter 14

Understand the Modern Lifecycle of the 2026-07-28 Revision

The 2026-07-28 revision is not a cosmetic update but a shift of the mental model. Version and capabilities moved into the metadata of every request, protocol-level sessions were removed, and multi-round trips, notifications, caching, and tasks changed. The old initialize-centric approach, where a connection first establishes a session, can no longer be applied by inertia - it will silently break on a modern server.

The client now explicitly allows revision negotiation.

TypeScript
  const client = new Client(
    { name: "developer-release-client", version: "1.0.0" },
    {
      versionNegotiation: { mode: "auto" },
      enforceStrictCapabilities: true,
      defaultCacheTtlMs: 5_000
    }
  );

And every request carries version, client info, and capabilities in _meta itself - no separate session is needed for that.

JSON
{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/list",
  "params": {
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientInfo": {
        "name": "developer-release-client",
        "version": "1.0.0"
      },
      "io.modelcontextprotocol/clientCapabilities": {
        "extensions": {}
      }
    }
  }
}

What exactly changed and the engineering consequence of each point is convenient to keep alongside.

Before the modern era · 2026-07-28 · Engineering consequence

  • Initialize creates a protocol session - Each request describes version/client/capabilities itself; A gateway can route a request independently
  • Mcp-Session-Id - The protocol-level session is removed; Hold business state by an explicit handle
  • Server-initiated elicitation/sampling - A Multi Round-Trip Request with input_required; Retry the original request with a new JSON-RPC id
  • Core tasks experiment - An official tasks extension; The core stays more compact
  • Optional cache hints - ttlMs and cacheScope in list/read results; The client designs the cache explicitly

The logic of the changes is one - to make the protocol stateless and scalable. Since initialize no longer creates a session, a gateway can route any request independently. Since Mcp-Session-Id was removed, business state must be held by an explicit handle, not tied to a connection. Server-initiated patterns were replaced with a Multi Round-Trip Request using input_required, and optional cache hints (ttlMs, cacheScope) hand cache design to the client.

To check which revision and transport to choose for your inputs, use the builder.

Interactive lab 4

Version and transport

Transport: stdio; the launcher owns the process and environment. Version: pin 2026-07-28 and reject unknown versions.

And the main practical takeaway from dropping sessions.

Don't imitate a remote session with hidden process memory. If an operation is long, return an explicit task or request handle, store state in durable storage, and tie it to the authorization context. A repeat HTTP request may land on a different instance - and all that "process memory" will be somewhere else.

We've understood the modern lifecycle - now let's apply it to the remote transport, where the stateless nature stops being theory.

Knowledge check

The 2026-07-28 revision removed the protocol-level session. Where do you keep the state of a long operation now?

Links