Skip to content

MCP Goes Stateless: The Migration Guide for Shipped Servers

37 min read

MCP Goes Stateless: The Migration Guide for Shipped Servers

· 37 min read
An editorial illustration on warm cream paper in black ink line work, divided into two panels by a vertical rule. In the left panel, a heavy filing cabinet labelled SHARED SESSION STORE hangs above three identical cloakroom counters, roped to each of them, while one figure stands at the middle counter holding up a paper tag labelled MCP-SESSION-ID and the outer two counters sit empty and unreachable. A horizontal arrow labelled STATELESS crosses the divider to the right panel, where the same cabinet is drawn as a dashed outline struck through with a single diagonal line, and three figures each carry a stamped envelope labelled _META toward a different counter along parallel arrows. A thin ink-blue line runs across the bottom of the frame.

David Soria Parra helped write this revision, and his summary of it is not reassuring. “A lot of things that made MCP are gone,” he told The Register. “If you built your own implementation, it’s going to be a lot of uplift to make this correct” (The Register, 2026-07-23).

The change list is already everywhere. Every MCP stateless migration guide published so far enumerates what changed; none of them sequences the work. Six breaking changes with wildly different blast radius, one of which isn’t a code change at all, and a deadline that is not the date on the specification. This post is the migration for a server that already runs in production, ordered by what will actually hurt. It’s the second MCP transport migration in three months on my code-intelligence server, after dropping stdio for an HTTP daemon in May.

Key Takeaways

  • The 2026-07-28 revision is “the largest revision of the protocol since launch”. The initialize handshake is gone (SEP-2575), Mcp-Session-Id and protocol-level sessions are gone (SEP-2567), and the protocol version plus client capabilities now ride in _meta on every request (Model Context Protocol, 2026).
  • Nothing breaks on the day the spec ships, because old revisions stay valid. Your real deadline is the day your clients’ SDKs stop sending initialize, which is a date set by Anthropic, Cursor, and everyone else shipping a client.
  • Roots, Sampling, and Logging are deprecated (SEP-2577). The lifecycle policy (SEP-2596) sets a floor of at least twelve months before removal, with a ninety-day expedited exception. The floor buys planning time, not interoperability.
  • Migrate in this order: sessions, then server-to-client calls, then Sampling, then Tasks and auth.
  • Sampling is the one that changes your architecture rather than your code. Your server now holds the provider API key, the egress path, the rate limit, and the token bill.

What actually changed in the MCP 2026-07-28 core?

The protocol core went stateless. Three removals do the work. The initialize and notifications/initialized exchange is gone (SEP-2575). Mcp-Session-Id and protocol-level sessions are gone from Streamable HTTP (SEP-2567). The protocol version and client capabilities that used to be negotiated once now travel in _meta on every request (Model Context Protocol, 2026). Identifying the client (io.modelcontextprotocol/clientInfo) is a SHOULD rather than a MUST, so treat it as present-but-not-guaranteed in your logging.

That leaves discovery, which is your first work item and an easy one to miss. Servers MUST implement the new server/discover method; clients MAY call it. Anything a client used to learn from your initialize response now has to be answerable there.

Three headers come with the new request shape, and they aren’t uniformly required. MCP-Protocol-Version must be present and must match the version in _meta, or the server rejects the request with -32020. Mcp-Method is required on every request. Mcp-Name is required only on tools/call, resources/read, and prompts/get (SEP-2243). The release notes state the point plainly: they exist “so load balancers, gateways, and rate-limiters can route on the operation without inspecting the body”. Routing, rate limiting, and observability become layer-7 config instead of code you write.

Here is what one tool call used to look like.

POST /mcp HTTP/1.1
Content-Type: application/json
Mcp-Session-Id: 7f3a9c1e-4b2d-11f0-9cd6-0242ac120002

{"jsonrpc":"2.0","id":42,"method":"tools/call",
 "params":{"name":"search_code","arguments":{"q":"isVisible"}}}

And here is the same call after the revision. No prior handshake, and every routing fact the infrastructure needs is in a header.

POST /mcp HTTP/1.1
Content-Type: application/json
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search_code

{"jsonrpc":"2.0","id":42,"method":"tools/call",
 "params":{"name":"search_code","arguments":{"q":"isVisible"},
 "_meta":{"io.modelcontextprotocol/clientInfo":{"name":"claude-code","version":"3.4.0"}}}}

Smaller removals ride along with the session and hit the same code paths. ping, logging/setLevel, and notifications/roots/list_changed are gone outright. resources/subscribe and unsubscribe become subscriptions/listen. SSE resumability goes too, along with Last-Event-ID, so a broken response stream now loses the in-flight request instead of resuming it, and the old HTTP+SSE transport is reclassified as Deprecated (Model Context Protocol, 2026). If your retry logic assumes stream resumption, that code sits right next to the session code you’re already touching.

The reason for all of this is origin, not fashion. “The stateful nature of MCP was really a by-product of its origin as a way to support developers using coding tools (that tend to run locally) to access things,” Stacklok CEO and Kubernetes co-creator Craig McLuckie told The Register (The Register, 2026-07-23). The 2026 roadmap said it more bluntly five months earlier: stateful sessions fight with load balancers (Model Context Protocol, 2026-03-09). A protocol designed for a subprocess on a laptop grew into a protocol running behind a fleet, and the session was the part that didn’t survive the move.

Citation capsule: The MCP 2026-07-28 revision removes the initialize handshake (SEP-2575) and Mcp-Session-Id (SEP-2567), moving the protocol version and client capabilities into a _meta object on every request. New Mcp-Method and Mcp-Name headers (SEP-2243) let a load balancer route without parsing the body, and servers must implement server/discover for clients that still want capabilities up front. The practical result is that any request can land on any instance (Model Context Protocol, 2026).

Nothing breaks on July 28, and that is the trap

Your server keeps working. The specification publication is informational, old revisions stay valid, and the official line is that “for existing clients and servers nothing breaks today, and nothing breaks on July 28 either” (Model Context Protocol, 2026). It breaks later, on somebody else’s release schedule.

There’s an apparent contradiction in the coverage, and it’s worth resolving because it changes what you put in the ticket. Arcade’s Nate Barbettini states it the other way round: “A client built for version 2025-11-25 expects to initialize and carry a session ID, so it can’t talk to a server expecting 2026-07-28” (Arcade, 2026-07-20). Both statements are true. Old revisions remain valid, and version negotiation is the escape hatch that lets one server serve both. Barbettini’s own caveat is the important half: “supporting multiple versions at once takes real work and is difficult to sustain”.

So when is the deadline, if it isn’t the spec date? It’s the date the clients you care about ship SDK v2 and stop sending initialize. You’re waiting on Claude Code, Cursor, and every other client vendor, and you find out on their schedule rather than yours. That is an unusual position for a migration, and it has one obvious response: instrument for it before it happens.

The concrete tell is cheap to watch for. A server that treats initialize as a required first message fails the moment a v2 client connects. Read the protocol version off _meta, log it per request, and alert on the first 2026-07-28 request you receive. The cutover then arrives as a dashboard event instead of a page.

You can estimate the clock from the SDK state. Beta SDKs landed on 2026-06-29 across four Tier 1 languages: Python 2.0.0b1, Go v1.7.0-pre.1, C# 2.0.0-preview.1, and TypeScript v2, which splits into @modelcontextprotocol/server and @modelcontextprotocol/client and retires the monolithic @modelcontextprotocol/sdk. TypeScript v1.x keeps getting bug fixes and security updates for at least six months; Python v1.x gets critical fixes with no stated window (Model Context Protocol, 2026). Six months is your outer bound, and client vendors will move well before it.

Adopting a revision ahead of the ecosystem has a cost. It’s the same cost A2A adoption carries today: you pay for the new shape while still carrying the old one. The second implementation is always the expensive one.

Citation capsule: Nothing breaks in a shipped MCP deployment when the 2026-07-28 specification publishes, because old revisions stay valid and version negotiation lets one server serve both. Cross-revision calls do fail: a 2025-11-25 client cannot talk to a 2026-07-28 server (Arcade, 2026-07-20). The operative deadline is the date client vendors ship SDK v2, not the specification date.

Step one: delete the session, not the state

You aren’t deleting state. You’re moving it onto the wire. Soria Parra’s framing is the honest one: it’s “a very smart and nice way to just move … state away from the server onto the wire protocol and hope that bandwidth is for free” (The Register, 2026-07-23). The specification names the replacement pattern precisely: servers needing cross-call state use “explicit, server-minted handles passed as ordinary tool arguments”, not a server-side lookup keyed by connection.

The session assumption hides in four places, and only one of them is in your server code:

  1. Transport setup. Any assumption of a long-lived SSE channel that outlives a single request.
  2. The session store. Redis, an in-process map, or a database table keyed by session id.
  3. Routing rules. Sticky affinity in the load balancer, ingress, or API gateway.
  4. Client reconnection logic. Retry paths that assumed a persistent channel and a resumable id.

That spread is why the migration is harder than the diff suggests. Amit Jena, AI development manager at Kanerika, put it in one line: “The code change is small; finding everywhere the assumption lives is what takes time” (InfoWorld, 2026-07-24). Three of those four layers live outside the repository you’re about to grep.

The payoff is concrete. A server that needed sticky routing plus a shared store can now sit behind a plain round-robin balancer. Barbettini’s framing of the target scale makes it click: “You’re running a server for millions of users, behind a load balancer whose entire job is to route each request to whatever server in the farm is free, sometimes in a different region” (TechCrunch, 2026-07-20).

The SDKs do the mechanical part for you. TypeScript ships a codemod, Python ships a v2 beta with a migration guide, and Go makes statelessness an explicit option (Model Context Protocol, 2026).

# TypeScript: mechanical v1 to v2 rewrite, path argument required
npx @modelcontextprotocol/codemod@beta v1-to-v2 .

# Python: v2 beta, then follow the migration guide
pip install "mcp[cli]==2.0.0b1"
// Go: statelessness is an explicit opt-in
opts := &mcp.StreamableHTTPOptions{Stateless: true}

None of that touches your gateway config, and the gateway is where the sticky rule lives.

So I audited my own. The code-intelligence server is at v4.8.1, runs Streamable HTTP only, advertises 2025-11-25, exposes 39 tools, and carries 1,371 tests. Here is what the eight changes that touch it cost, meaning the six breaking ones plus the new headers and the OAuth requirement.

ChangeVerdictWhere
SEP-2575 handshake removalNeeds codeProxy synthesizes initialize on session recovery
SEP-2567 session id removalNeeds codeThe join key between two components
SEP-2243 new headersNo-opHeader forwarding is an 8-name denylist, not an allowlist
SEP-2260 server-initiated callsNeeds codeOne illegal roots/list from a notification handler
SEP-2663 Tasks to extensionConfig onlyOne capability field to drop
SEP-2164 error code changeNo-opZero occurrences of -32002; no resources primitive
SEP-2577 Roots, Sampling, LoggingNeeds codeRoots is a live fallback; Sampling is unreachable; Logging isn’t MCP
SEP-2468 OAuth issNo-opNo OAuth at all, localhost-only by construction

Four need code, one needs config, three are no-ops. Roughly 26 files and 2,100 lines, and the distribution is the interesting part: about 770 of the 800 production lines sit in two files, mcp_proxy.rs and standalone.rs. Against 102,490 lines of Rust, that is a 0.8% blast radius. The indexer, retrieval, graph, and storage layers are untouched by all eight.

One finding was worse than I expected, and it’s the kind of thing an audit is for. The proxy is the only component that can see the ?repo= query parameter. The SDK handler is the only component that can act on it. mcp-session-id is the sole join key between them. All four of my workspace-binding mechanisms write session-keyed state, and the one whose decision doesn’t need a session disables itself as soon as a second repository is registered. Under SEP-2567, a user with two or more repositories would have no working binding path at all. That isn’t a line count. It’s a design that has to change.

The first thing to break isn’t a test, either. It’s a compile error: rust-mcp-schema 0.9.4 has no 2026-07-28 variant, and the SDK returns 400 for a protocol-version header it can’t parse. My migration is gated on an SDK release, not on my own repository. Which is the whole thesis of the previous section, arriving as a build failure instead of an argument.

Apply the caveats before generalizing. This server is single-tenant, localhost-only, unauthenticated, and implements one primitive, so three of the eight changes cost nothing precisely because of what it doesn’t do. It is also narrow because the transport migration in May already deleted the session assumption. A multi-tenant server with OAuth, real resources, and a shared session store is a different piece of work. A stdio server is worse off still: SEP-2577 takes away roots, and a pipe has no URL to put a replacement in.

Citation capsule: Migrating an MCP server to the 2026-07-28 revision means moving session state onto the wire as explicit handles in tool arguments, not deleting state. The session assumption hides in four layers: transport setup, the server-side session store, sticky routing rules in the gateway, and client reconnection logic. Three of the four sit outside the server codebase (InfoWorld, 2026-07-24).

Step two: server-to-client calls become round trips

If your server ever asks the client for something mid-call, that code is dead. Server-initiated requests may now only be issued while the server is actively processing a client request (SEP-2260). The replacement is Multi Round-Trip Requests (SEP-2322): return an InputRequiredResult carrying inputRequests and an opaque requestState, and let the client re-issue the call with inputResponses plus the echoed state (Model Context Protocol, 2026).

{
  "resultType": "input_required",
  "inputRequests": [
    { "type": "elicitation",
      "message": "Which branch should I index?",
      "requestedSchema": { "type": "string", "enum": ["main", "develop"] } }
  ],
  "requestState": "eyJzdGVwIjoyLCJyZXBvIjoiL3NyYyJ9"
}

Note the resultType field. It’s now required on every result, not just this one, and the two values are complete and input_required. That’s a small change with wide reach, because it touches every response your server has ever returned.

The shape exists for the same reason step one exists. State lives in the token you hand back to the client, so the retry can land on any instance. It’s the stateless trick applied to elicitation and confirmation flows instead of to transport.

The practical consequence is less pleasant than the diff. Any interactive tool handler becomes a state machine with resumable steps, and requestState becomes a serialization boundary you have to version. Treat it like a cookie you need to read in six months, because that’s what it is. And the unglamorous part: sign or encrypt it and you now own key rotation for it.

There’s a second change hiding in the same area. JSON Schema 2020-12 support (SEP-2106) loosens both inputSchema and outputSchema to any 2020-12 keywords, so oneOf, anyOf, allOf, conditionals, and $ref are all now legal. That’s more expressive, and expressiveness is not free. A schema the model reads to fill those inputs is a description-budget problem before it’s a validation problem. The same discipline applies as to any tool schema: composition you can validate is worth little if the model can’t infer intent from it.

Citation capsule: Server-initiated requests in MCP 2026-07-28 may only be issued while the server is actively processing a client request (SEP-2260). Interactive flows use Multi Round-Trip Requests (SEP-2322): the server returns an InputRequiredResult with inputRequests and an opaque requestState, and the client re-issues the call with inputResponses and the echoed state, so the retry can land on any instance (Model Context Protocol, 2026).

Step three: Sampling is dead, so call the provider yourself

This is the change that alters your architecture rather than your code. Sampling let a server ask the client’s own model for a completion. It’s deprecated, and the guidance is to “integrate directly with LLM provider APIs instead of Sampling” (Model Context Protocol, 2026). Host-mediated model calls are over.

The rationale comes from the SEP itself. Sampling was “complex to implement (human-in-the-loop, model selection, security), low client adoption”, and all three deprecated features were “identified during a core contributor meeting as having low adoption relative to their implementation complexity” (modelcontextprotocol PR #2577, 2026). The same PR leaves a door open, and it’s worth knowing about before you burn a sprint: “if there’s demand for sampling, it would make sense to re-introduce an improved version as an experimental extension.” Plan for the deprecation, but don’t assume the capability is gone forever.

The rewrite itself is small. That is the misleading part.

// Before: ask the host's model, on the host's dime
const out = await server.createMessage({
  messages: [{ role: "user", content: { type: "text", text: prompt } }],
  maxTokens: 512,
});

// After: your server owns the key, the model choice, and the bill
const out = await anthropic.messages.create({
  model: "claude-sonnet-5",
  max_tokens: 512,
  messages: [{ role: "user", content: prompt }],
});

So why call it an architecture change? Because four things cross the boundary with those six lines, and none of them are code changes:

  • The API key. Secret storage, rotation, and per-tenant scoping become yours.
  • Network egress. Your server now talks to a provider endpoint from inside your VPC. That’s a firewall change and, in some environments, a compliance one.
  • The rate limit. Previously the host absorbed it. Now your server queues, retries, and degrades.
  • Cost attribution. There’s a new line item, and it scales with tool calls.

Jena named the same shift precisely: “Your server now calls the model provider directly. That changes your network architecture, your auth model, and depending on how you’ve built cost attribution, your billing flow” (InfoWorld, 2026-07-24).

There’s an honest upside. Under Sampling you inherited whichever model the host chose, which was a feature for cost and a liability for quality. Direct calls mean you pick the model, pin the version, and evaluate it yourself. More work, better engineering, and the reason an MCP server that owns an LLM bill needs a different design conversation than one that doesn’t.

Citation capsule: MCP Sampling is deprecated under SEP-2577, and the guidance is to “integrate directly with LLM provider APIs instead of Sampling” (Model Context Protocol, 2026). The SEP cites “complex to implement (human-in-the-loop, model selection, security), low client adoption”. The rewrite is roughly six lines, but it moves the provider API key, the network egress path, the rate limit, and the token bill from the host to the server operator.

Step four: Tasks, error codes, and the OAuth iss check

Three smaller changes, one of which isn’t optional. Tasks moved from experimental core to an extension (SEP-2663), and tasks/list is removed outright, because scoping a task list is unsafe without sessions. Anyone who shipped against the 2025-11-25 experimental Tasks API has to migrate (Model Context Protocol, 2026).

The new lifecycle is a polling loop. A tools/call returns a task handle, and the client drives it with tasks/get, tasks/update, and tasks/cancel. If you built on the blocking result call, that assumption is gone.

The error code change is the cheapest fix here and the easiest to forget. Missing-resource errors move from the MCP-specific -32002 to the JSON-RPC standard -32602 (SEP-2164). Any client matching the literal -32002 needs a one-line change. Miss it and it sits in a catch block for a year, quietly turning a specific error into an unhandled one.

The auth hardening is the not-optional one, and the modal verbs matter. Authorization servers SHOULD include the iss parameter per RFC 9207. Clients MUST validate an iss that is present, checking it against the recorded issuer before redeeming the authorization code (SEP-2468). Future revisions will reject responses that omit it, so that SHOULD is on its way to a MUST. Credentials are also bound to the issuer now, so migrating issuers means re-registering (SEP-2352).

One awkward wrinkle sits next to it that nobody seems to be flagging. Clients declare application_type at Dynamic Client Registration (SEP-837), so servers stop defaulting desktop and CLI clients to "web" and rejecting localhost redirects. Useful fix, except the same revision deprecates RFC 7591 Dynamic Client Registration itself in favour of Client ID Metadata Documents. SEP-837 improves a mechanism this release also marks for replacement. Building auth from scratch this quarter? Read the Client ID Metadata Documents path first.

One last change deserves real values rather than a shrug. A new CacheableResult interface (SEP-2549) makes ttlMs and cacheScope required on tools/list, prompts/list, resources/list, resources/read, and resources/templates/list. It’s modeled on HTTP Cache-Control, and cacheScope is public or private. If your tool list is expensive to build, you get latency back for the trouble.

Citation capsule: Tasks drop from core to an extension in MCP 2026-07-28, and tasks/list is removed outright (SEP-2663). Missing-resource errors move from -32002 to the JSON-RPC standard -32602 (SEP-2164), and clients must validate the iss parameter per RFC 9207 (SEP-2468). Only the error code is a one-line fix; the iss requirement is mandatory, and future revisions will reject responses that omit it (Model Context Protocol, 2026).

What does the MCP deprecation policy actually buy you?

A floor, not a promise. The new lifecycle policy (SEP-2596) gives every feature an “Active, Deprecated, and Removed lifecycle with at least twelve months between deprecation and the earliest possible removal” (Model Context Protocol, 2026). Deprecation in this release is advisory: “No wire-level protocol changes … deprecation is advisory only, signaling the ecosystem to plan for eventual removal” (modelcontextprotocol PR #2577, 2026).

Read the floor honestly, because it has two holes. The first is in the policy text itself: features stay in the specification for at least twelve months, “or at least ninety days” under the expedited-removal exception (Model Context Protocol, 2026). Twelve months is the headline, ninety days is the worst case, and only one of those numbers appears in the coverage.

The second hole is bigger. The floor buys planning time, not interoperability. A client that ships v2 and drops Roots tomorrow is fully compliant, and your server doesn’t get the twelve months back. The guarantee binds the specification, not the clients implementing it.

I have a small piece of field evidence that Roots earned this. In May 2026 I surveyed seven popular MCP clients for roots support. One implemented it correctly. The rest either omitted the capability or advertised it and then returned Method not found on the actual call (mcp-stdio-doesnt-scale, 2026-05). Two months later, SEP-2577 deprecated Roots with a one-line verdict: “Vague semantics, overlaps with tool parameters and server configuration.” A capability nobody implements is already removed in practice. The policy just wrote it down.

The structural change in this release isn’t the deprecations, though. It’s extensions. MCP Apps (SEP-1865) ships as an official extension alongside Tasks: servers provide HTML that hosts render in a sandboxed iframe, addressed by a ui:// resource and referenced from _meta.ui.resourceUri. Extensions “are identified by reverse-DNS IDs, negotiated through an extensions map on client and server capabilities, live in their own ext-* repositories with delegated maintainers” (SEP-2133), and version independently of the specification. Den Delimarsky of Anthropic put the intent plainly: “I think the extensions are a model for us to really test out things in the protocol before we bake them into the protocol” (The Register, 2026-07-23).

Notice what one detail is really for. Hosts receive UI templates during connection setup, before any tool executes, so they can review server-supplied HTML before rendering it. That makes predeclaration a supply-chain control, not a UI nicety. Server-supplied HTML is a supply-chain surface, and it’s a good sign that the extension shipping it treats it as one.

Citation capsule: Every MCP feature now moves through an Active, Deprecated, Removed lifecycle (SEP-2596) with “at least twelve months between deprecation and the earliest possible removal”, subject to a ninety-day expedited-removal exception (Model Context Protocol, 2026). The floor guarantees deprecated methods keep working, not that clients keep calling them. A client shipping SDK v2 without Roots is compliant, so the twelve months buy planning time rather than interoperability.

FAQ

What breaks in the MCP 2026-07-28 spec?

Six things: the initialize and notifications/initialized handshake (SEP-2575), Mcp-Session-Id and protocol-level sessions (SEP-2567), server-initiated requests outside an active client call (SEP-2260), tasks/list (SEP-2663), the -32002 error code, which becomes -32602 (SEP-2164), and any dependency on Roots, Sampling, or Logging, which are now deprecated (SEP-2577) (Model Context Protocol, 2026).

Do I still need sticky sessions for my MCP server?

No. Sticky routing and shared session stores are no longer required at the protocol layer, so a remote server can sit behind a plain round-robin load balancer. The two new Mcp-Method and Mcp-Name headers let a balancer route without inspecting the body (Model Context Protocol, 2026).

Is MCP Sampling deprecated, and what replaces it?

Yes. Sampling is deprecated under SEP-2577, and the guidance is to integrate directly with LLM provider APIs instead. Your server calls the provider itself, which moves the API key, the egress path, the rate limit, and the token bill to your side (modelcontextprotocol PR #2577, 2026; InfoWorld, 2026).

How long do I have before Roots, Sampling, and Logging are removed?

At least twelve months from the deprecating revision under SEP-2596, so the nominal earliest removal is mid-2027. The policy also carries a ninety-day expedited-removal exception, so treat twelve months as the plan and ninety days as the worst case. Either way it guarantees the methods keep working, not that any client keeps calling them (Model Context Protocol, 2026).

Conclusion

The core went stateless, so sessions move onto the wire as _meta and headers. Nothing breaks on the specification date, and the real deadline is whenever your clients ship SDK v2. Migrate sessions first, then server-to-client calls, then Sampling, then Tasks and auth. Sampling is the architecture change, because your server inherits the key, the egress, and the bill. The twelve-month deprecation floor buys planning time, not interoperability.

Do two things this week. Log the protocol version off _meta and alert on the first 2026-07-28 request you see, so the cutover lands as a dashboard event instead of an incident. Then grep your codebase for initialize, Mcp-Session-Id, -32002, tasks/list, and your Sampling call site, and put those five results in a ticket in that order. The transport migration that preceded this one is the case study; the server design framework is the part that now has to own an LLM bill.

Sources

Every claim above was verified against the release candidate and the draft specification pages on 2026-07-25, three days before ratification. At that point the specification’s own versioning page still listed 2025-11-25 as the current revision, and the 2026-07-28 text lived under /specification/draft/. If the ratified text diverges from the release candidate on any point here, lastUpdated gets bumped and the difference gets named in this block rather than quietly edited into the body.

One further note on sources. The Arcade analysis and the TechCrunch article both quote Nate Barbettini, and he wrote the former, so they count as one voice rather than two independent confirmations. The genuinely independent perspectives here are the MCP maintainers, Craig McLuckie of Stacklok, Barbettini of Arcade, and Amit Jena of Kanerika.

Share this post

If it was useful, pass it along.

What the link looks like when shared.
X LinkedIn Bluesky

Search posts, projects, resume, and site pages.

Jump to

  1. Home Engineering notes from the agent era
  2. Resume Work history, skills, and contact
  3. Projects Selected work and experiments
  4. About Who I am and how I work
  5. Contact Email, LinkedIn, and GitHub