Protocol Deep Dive

MCP 2026 Spec: Stateless Core, Tasks, and MCP Apps

The Model Context Protocol's 2026-07-28 release candidate is the largest revision since launch. It removes the session layer so MCP servers run on ordinary HTTP, promotes MCP Apps and Tasks to first-class extensions, and hardens auth. Here is what changes, what breaks, and what to do about it — grounded in the spec and its SEPs.

Editorial hero illustration for MCP 2026 Spec: Stateless Core, Tasks & MCP Apps

The One-Sentence Version

On May 21, 2026 the MCP maintainers locked the release candidate for spec version 2026-07-28 — which they call "the largest revision of the protocol since launch" — and final publication is scheduled for July 28, 2026. The one change everything else hangs off: MCP goes stateless, so servers can run on ordinary, boring HTTP infrastructure instead of the session machinery the current spec forces on you. Those dates and the release scope come from the official release-candidate announcement.

If you operate MCP servers in production — and if you do, our roundup of the best MCP servers for Claude Code is a good map of the landscape — this is the release that touches your infrastructure, your auth, and any client that pattern-matches on error codes. The rest of this guide is the field manual.

Why Stateless Is the Headline

In 2025-11-25, every connection begins with an initialize/initialized exchange. Separately, a Streamable HTTP server may issue Mcp-Session-Id; when it does, the client must send that ID on later HTTP requests in the session. Stateful deployments commonly need sticky routing or a shared session store. Stdio never uses that HTTP header.

The 2026-07-28 RC removes both the handshake and the session. The initialize/initialized handshake is gone (SEP-2575): protocol version and client capabilities now ride in _meta on every request, while client identity is recommended but optional. A new server/discover method lets a client fetch capabilities up front only when it wants them. The Mcp-Session-Id header and the protocol-level session are gone too (SEP-2567). The official draft changelog lists both as major changes.

Operationally, the maintainers say remote deployments no longer need protocol-session affinity. Operators can use round-robin routing, route with the new MCP headers, and let clients cache eligible list responses. Application state still has to be resolvable from an explicit handle when requests land on different instances.

Area2025-11-252026-07-28 (RC)
SessionA Streamable HTTP server may issue Mcp-Session-Id; the client then sends it on later HTTP requests.The protocol session and Mcp-Session-Id are removed; cross-call state uses explicit handles.
Handshakeinitialize / initialized round-trip is required before any tool call.Removed. Protocol version and capabilities ride in _meta on every request; clientInfo is recommended but optional. server/discover fetches capabilities on demand.
RoutingGateways do deep packet inspection to route traffic.Mcp-Method and Mcp-Name headers are required, so gateways route without reading the body.
CachingNo protocol-level caching contract.list and read results carry ttlMs and cacheScope, modeled on HTTP Cache-Control.
TasksExperimental core feature.Moves out to an official extension; tasks/list is removed.
TracingUnspecified.W3C Trace Context keys (traceparent, tracestate, baggage) locked in _meta for OpenTelemetry.

Here is the same collapse on the wire for Streamable HTTP. The legacy flow starts with initialize, may establish an HTTP session, and then makes tool calls. The modern flow sends a self-contained request with no protocol session:

# 2025-11-25: initialize first; include Mcp-Session-Id later only if the server issued one
# 2026-07-28: one self-contained request, no session
POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
{"jsonrpc":"2.0","id":1,"method":"tools/call",
 "params":{"name":"search","arguments":{"q":"otters"},
 "_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28",
          "io.modelcontextprotocol/clientCapabilities":{},
          "io.modelcontextprotocol/clientInfo":{"name":"my-app","version":"1.0"}}}}

TypeScript SDK Beta.5: Migrate to the Final RC Wire Shape

Two identity fields changed while SDKs were implementing the RC. Spec PR #3002, merged on July 16, 2026, moved server identity out of the server/discover result body and made request-side client identity optional. The TypeScript SDK implemented that revision in @modelcontextprotocol/[email protected] on July 21. As of July 23, 2026, beta.5 is still a prerelease, and the specification repository still labels 2026-07-28 as an RC rather than a final release. Treat this as the current release-candidate wire, not a guarantee that no later prerelease or publication correction will appear.

Wire or type surfacePre-#3002 prerelease shapeBeta.5 and current draft
DiscoverResult.serverInfoRequired in the result body.Removed. Read identity from result _meta, or use client.getServerVersion().
_meta["io.modelcontextprotocol/serverInfo"]Not the canonical discovery location.Optional, self-reported server identity. The TypeScript beta.5 server stamps it on 2026-era responses by default.
RequestMetaEnvelope.clientInfoRequired by the TypeScript schema.Optional in the schema and a protocol SHOULD. The beta.5 client still sends it by default.
Identity trustEasy to mistake a required field for a dependable identity signal.Display, logging, and debugging only; never authorization, security, or behavior selection.

The failure can happen before TypeScript reports a compile error. A client built against the earlier prerelease schema can reject a conforming discovery response because body serverInfo is absent. The probe then misclassifies the peer as legacy and tries the removed initialize handshake. A modern-only server rejects that fallback, so the connection fails before the first real method call. In the opposite direction, an older prerelease TypeScript server can reject a conforming request that omits clientInfo.

// beta.5/current RC: serverInfo is no longer a DiscoverResult body field
const discover = await client.discover();
const server = client.getServerVersion();

// Equivalent wire location when inspecting the result directly:
const serverFromMeta =
  discover._meta?.["io.modelcontextprotocol/serverInfo"];

// Keep sending clientInfo unless you have a reason not to.
// A conforming server must also accept the request when this key is absent.

For TypeScript migrations, update every @modelcontextprotocol/* 2.0 package used by the same process to the beta.5 release train; do not mix a beta.5 core schema with beta.4 client or server packages. Replace direct reads of discover.serverInfo, remove validators that require that body field, and allow requests without clientInfo. Keep malformed present values strict: optional means the key may be absent, not that an invalid identity object is valid.

  1. Pin the exact prerelease versions in lockfiles; avoid a floating beta range during interop testing.
  2. Test discovery against a modern-only server that returns identity only in result _meta.
  3. Test the server with a request that omits clientInfo, then with a malformed present value that must still fail validation.
  4. Verify missing or malformed server identity does not break the connection. In beta.5, an unstamped server is anonymous and getServerVersion() returns undefined.
  5. Do not route, authorize, or share security-sensitive cache state based on either self-reported identity field.

These rules come from the merged specification PR #3002 and the TypeScript SDK's beta.5 release notes. Re-run cross-SDK tests when the final specification and stable SDK packages are published.

Two supporting mechanics make this work. Because gateways can no longer read a session, Mcp-Method and Mcp-Name headers are now required so routing happens without parsing the body (SEP-2243). And because there is no session to hang caching off, list/read results carry ttlMs and cacheScope modeled on HTTP Cache-Control (SEP-2549), while W3C Trace Context keys are locked into _meta (SEP-414) for end-to-end OpenTelemetry spans.

Stateless Protocol, Stateful Apps

The obvious worry: does stateless mean my app has to forget everything between calls? No. The maintainers are explicit that a stateless protocol does not require a stateless app. The recommended pattern is the explicit handle: a tool mints a basket_id or browser_id and the model passes it back as an ordinary argument on later calls.

The maintainers argue that explicit handles are easier for a model to reason about, compose across tools, and pass between steps than hidden session state. In practice it looks like this:

// Stateless protocol, stateful app: the "explicit handle" pattern
// 1) a tool mints an id and returns it as normal output
tools/call open_cart   ->  { "basket_id": "bskt_9f2" }
// 2) the model passes it back as an ordinary argument later
tools/call add_item        { "basket_id": "bskt_9f2", "sku": "otter-plush" }
tools/call checkout        { "basket_id": "bskt_9f2" }
// no protocol session; app state is resolved by basket_id (for example, from shared storage)

Server-to-client mid-call requests — think an elicitation like "Delete 3 files?" — are rebuilt for a stateless world. A server may only issue one while it is actively processing a client request (SEP-2260), and Multi-Round-Trip Requests (SEP-2322) replace the held-open SSE stream with an InputRequiredResult plus an echoed requestState blob the client hands back. That means any instance can pick up the retry, which is the whole point.

Extensions Become First-Class

Extensions existed in 2025-11-25 but had no formal process. SEP-2133 gives them reverse-DNS IDs, an extensions capability map, their own ext-* repos, and independent versioning. This is the machinery that lets the two headline features ship without bloating — or destabilizing — the core protocol. Two extensions ship as official on day one: MCP Apps and Tasks.

MCP Apps: Sandboxed Server-Rendered UI

MCP Apps (SEP-1865) lets servers ship interactive HTML that the host renders in a sandboxed iframe. Tools declare their UI templates ahead of time so hosts can prefetch, cache, and security-review them. The rendered UI talks back over the same JSON-RPC base protocol, so every UI-initiated action goes through the same audit and consent path as a direct tool call. That is the design detail that matters: a button in an MCP App is not a side channel; it is a tool call wearing a UI.

MCP Apps was announced as an official extension in January 2026. Support still has to be negotiated by both host and server; the extension announcement and its specification, rather than a third-party demo, are the authority for its security and capability model. See the official MCP Apps announcement.

Tasks Graduates to an Extension

Tasks shipped as an experimental core feature in 2025-11-25. Production use forced a redesign, so it moves out of the spec into an extension (PR #2663) reshaped around the stateless model. A tools/call can return a task handle, and the client drives tasks/get, tasks/update, and tasks/cancel. Task creation is server-directed.

Migration flag. tasks/list is removed — it cannot be scoped safely once sessions are gone. Anyone who built against the 2025-11-25 experimental Tasks API has to migrate; there is no drop-in compatibility here. The method changes are enumerated in the official draft changelog.

Auth Hardening

Authorization moves closer to real-world OAuth 2.0 and OIDC across six SEPs. The two that will bite most people:

  • Validate iss per RFC 9207 (SEP-2468). This is a mix-up-attack mitigation that matters because MCP's single-client, many-server shape is unusually exposed to it. Clients must check the issuer parameter on the response; see SEP-2468.
  • Declare OIDC application_type in Dynamic Client Registration (SEP-837). A CLI or desktop client stops getting mis-defaulted to web and rejected on its localhost redirect.

The remaining auth work — credential-to-issuer binding, refresh-token guidance, and scope plus .well-known clarifications — is the kind of tidy-up that only shows up when a protocol starts carrying real traffic.

Deprecations and Breaking Changes

Most deprecations are annotation-only and keep working for at least twelve months (SEP-2577), so you have runway. The one that needs immediate attention is the error code change: a client that matches the literal -32002 for a missing resource will silently stop matching when it becomes the standard -32602 (SEP-2164). The status and migrations are summarized in the official key-changes page.

CapabilityStatusMigrate to
RootsDeprecated (annotation-only, keeps working 12+ months)Tool params, resource URIs, or config
SamplingDeprecatedDirect LLM-provider APIs
LoggingDeprecatedstderr (stdio) plus OpenTelemetry
Missing-resource error -32002ChangedStandard -32602 (update any literal match)
Tool inputSchema / outputSchemaUpgradedFull JSON Schema 2020-12

Sampling going away is the philosophical one. The maintainers point you at direct LLM-provider APIs instead of asking the host to sample on the server's behalf — if you are choosing a model for that path, our Claude Sonnet 5 vs Opus 4.8 comparison is a decent starting point. Tool inputSchema and outputSchema are also lifted to full JSON Schema 2020-12 (SEP-2106), so validators built for the old subset should be re-tested.

What Antigravity Users Should Do

The source-backed conclusion is deliberately narrow: the release candidate does not require an Antigravity config migration by itself. mcp_config.json is a host configuration format; the MCP revision is a wire-protocol contract between client and server.

As of July 21, 2026, Google's current Antigravity MCP documentation documents local stdio servers with command/args and remote servers with serverUrl. It does not state that Antigravity 2.0, the IDE, or agy already speaks the 2026-07-28 draft. Do not infer draft support from the calendar.

Your Antigravity setupAction before July 28
Local stdio entry using command and argsNo speculative config edit. Track the client and server release notes.
Remote SSE or Streamable HTTP entryKeep the documented serverUrl spelling and verify both ends advertise compatible revisions before upgrading.
Existing deadline or startup failureDiagnose it with /mcp status and logs; Tasks in a future revision does not repair today's launch path.
Config containing timeout or an Antigravity timeout environment variableDo not rely on it: neither appears in the documented Antigravity MCP property list.

Antigravity's global config is ~/.gemini/config/mcp_config.json; workspace-local config is .agents/mcp_config.json. Back up the relevant file, use the MCP manager to reload it, and verify a read-only tool after any real client or server upgrade. For current connection failures, use the supported Antigravity MCP deadline diagnostic.

Timeline and Validation

The validation timeline now has four checkpoints. May 21, 2026: RC locked. July 16, 2026: the core maintainers merged the final identity-metadata revision in PR #3002. July 21, 2026: the TypeScript SDK published beta.5 with that wire shape. July 28, 2026: final publication is scheduled. The ten-week window exists so SDK maintainers and clients can validate against the RC, and Tier-1 SDKs are expected to ship support within it. The full RC lives in the draft spec with a changelog against 2025-11-25.

There is also governance meant to stop this churn from recurring: a feature-lifecycle policy (Active, then Deprecated, then Removed, over 12+ months), the extensions framework itself, and a rule that no Standards-Track SEP reaches Final until a matching scenario lands in the conformance suite (SEP-2484).

Until final publication, treat 2026-07-28 as a release candidate, test against the current draft schema, and do not claim production client support without that client's release notes. In particular, do not treat an older prerelease SDK's successful self-test as proof that it accepts the post-#3002 wire. If you are wiring MCP into an IDE today, our Antigravity MCP tutorial walks through a working setup on the current spec.

This update uses the draft specification, official release-candidate post, official SEPs, official SDK migration guidance, and Google's Antigravity documentation. The sources below are primary links you can verify directly.

FAQ

What is the MCP 2026-07-28 spec?

It is the release candidate for the next Model Context Protocol revision. The maintainers locked it on May 21, 2026 and scheduled final publication for July 28, 2026. Its defining change is that MCP becomes stateless.

What does it mean that MCP goes stateless?

The initialize handshake is removed across transports, while the Streamable HTTP session and its optional Mcp-Session-Id header are removed. Protocol version and capabilities now travel in _meta on every request, clientInfo is recommended but optional, and server/discover supports up-front capability discovery.

Do I have to rewrite my MCP server to be stateless?

No. The maintainers frame it as stateless protocol, stateful apps. Your app can still hold state; you just expose it with the explicit-handle pattern, where a tool mints an ID and the model passes it back as a normal argument on later calls instead of relying on a hidden session.

What are MCP Apps?

MCP Apps (SEP-1865) is an official extension that lets servers ship interactive HTML that the host renders in a sandboxed iframe. Tools declare their UI templates ahead of time so hosts can prefetch, cache, and security-review them, and every UI-initiated action goes back through the same JSON-RPC consent and audit path as a direct tool call.

What breaks in the Tasks API?

Tasks shipped as an experimental core feature in 2025-11-25 and moves out to an extension reshaped for the stateless model. Task creation is server-directed, and tasks/list is removed because it cannot be scoped safely without sessions. Anyone who built against the experimental Tasks API must migrate.

What auth changes should I make?

Clients must validate the iss parameter per RFC 9207 (SEP-2468), a mix-up-attack mitigation that matters because MCP's single-client, many-server shape is unusually exposed to it. Clients also declare an OIDC application_type during Dynamic Client Registration (SEP-837) so a CLI or desktop client stops being mis-defaulted to web and rejected on its localhost redirect.

When does it ship and will my SDK be ready?

Final publication is scheduled for July 28, 2026. The ten-week window after the May 21 RC lock is for SDK maintainers and clients to validate, and Tier-1 SDKs are expected to ship support within it. The full RC lives in the draft spec with a changelog against 2025-11-25.

Glossary

  • Stateless protocolThe protocol no longer depends on hidden per-client session state. Cross-call app state travels through an explicit handle and must be resolvable by whichever instance receives the request.
  • _metaMetadata carried with requests and results. Request _meta requires the protocol version and client capabilities; clientInfo is recommended but optional. Result _meta can carry self-reported serverInfo.
  • server/discoverA new method a client calls when it actually wants the server's capability list up front, instead of getting it from a mandatory handshake.
  • Explicit handleAn ID a tool mints (like basket_id or browser_id) and returns as ordinary output. The model passes it back as a normal argument on later calls, replacing hidden session state.
  • SEPSpec Enhancement Proposal. The numbered proposals (for example SEP-2575) that define each change in the release candidate.
  • ExtensionA versioned, reverse-DNS-namespaced add-on to the base protocol. MCP Apps and Tasks both ship as official extensions rather than core spec features.

Verdict

The stateless design removes protocol-level session affinity from modern MCP, while explicit handles preserve application state in ordinary tool arguments. That can simplify remote deployment, but it is also a breaking protocol transition, not an automatic upgrade for every installed client and server.

The work is real but bounded. Before July 28, do three things: stop matching the literal -32002 error code, migrate anything built on experimental Tasks (remember tasks/list is gone), and add iss validation to your OAuth client. Roots, Sampling, Logging, HTTP+SSE, and selectedincludeContext values enter the formal deprecation path; the changelog's other breaking changes are immediate for implementations that opt into the new revision. If you are testing the TypeScript 2.0 prerelease, align all SDK packages on beta.5 or later, move serverInfo reads to result _meta, and accept requests that omit clientInfo. Pin SDK versions and run conformance plus cross-SDK tests against the current RC before enabling it.

All Sources and Links

Primary sources (official spec and maintainer blog):

Official implementation and host documentation:

Spec proposals (SEPs and PRs):

Get the latest on AI, LLMs & developer tools

New MCP servers, model updates, and guides like this one — delivered weekly.