Why
The reason to build one now rather than a year ago is that the shape of the answer changed. Until this revision an MCP server was a stateful conversation: an initialize/initialized handshake, an Mcp-Session-Id header, and a server that had to remember which client it was talking to. The 2026-07-28 revision removes both — every request is self-contained, with protocol version, client identity and capabilities travelling in _meta, Streamable HTTP requests routed by Mcp-Method and Mcp-Name headers, and list and resource-read results cacheable.
What that changes practically is deployment. A stateless request/response service runs on serverless or edge without sticky sessions, which is the difference between an MCP server is a process I keep running and an MCP server is a function I deploy.
The second change carries more weight for real work. Authorization now aligns with deployed OAuth 2.0 and OIDC practice, so pointing a server at an enterprise identity provider like Entra or Okta stops being a workaround. That is the half that decides whether an MCP server may ever touch company data, and it is why building against the new spec is not the same exercise as building against the old one. The adoption figure is context rather than argument: SDK downloads passed 400 million a month, roughly 4× this year.
The three positions are the same protocol from different seats, and the ordering is the useful part. Building a server is the protocol question. Consuming Zapier's — 8,000+ app integrations exposed as tools — is the client question, and it is where the security decision lives rather than the interesting engineering. Serving an agent as an MCP server, which Google's ADK Python 2.5 release added alongside sandboxed code execution on Cloud Run and a fresh ADK Go, is the framework question. Doing the protocol one first turns the other two into wrapper exercises instead of two unknowns at once.
One caution before building: Roots, Sampling and Logging are deprecated with documented replacements and a minimum twelve-month removal window, and Tasks is an explicit breaking change — poll-based tasks/get, tasks/update, cooperative tasks/cancel. Porting an old server means learning the old model twice.
How it works
Three seats, one protocol
| Seat | The question | What it decides | Do it |
|---|---|---|---|
| Build a server | Protocol — what does a request carry now that there is no session? | Whether the thing can be deployed and authorized at all | First |
| Consume a server (Zapier) | Client — how do I hold a connection and constrain what it may do? | Blast radius, not architecture | Second |
| Serve an agent as a server (ADK) | Framework — can an existing subagent be wrapped? | Reuse | A 30-minute skim, last |
What actually changed on 2026-07-28
| Before | After | |
|---|---|---|
| Session | initialize/initialized handshake, Mcp-Session-Id |
None — every request self-contained |
| Identity and capabilities | Negotiated once | Carried in _meta per request |
| Routing | Session-scoped | Mcp-Method / Mcp-Name headers |
| list / resource-read | Per-session | Cacheable |
| Authorization | Ad hoc | OAuth 2.0 / OIDC — Entra, Okta |
| Deployment | A process you keep running | A function you deploy |
| Tasks | — | Breaking change: tasks/get, tasks/update, tasks/cancel |
| Roots, Sampling, Logging | Current | Deprecated, 12-month minimum removal window |
Three things worth verifying by doing rather than reading
- That a cold-started serverless instance can serve a request with no prior state at all. That is the whole claim of the stateless core, and it either holds on a real cold start or it does not.
- What
_metamust actually carry for a client to work without the handshake — the part a spec summary never makes concrete enough to implement from. - Whether cacheability of list and resource-read survives a real deployment, since that is where the stateless design either pays for its extra per-request payload or does not.
The authorization half deserves the most time: put the server behind an OAuth/OIDC provider and walk the token path end to end, because the approval path for company data is standardised now is a claim that is either true in an hour or false all week.
The client side, where the decision is a security decision
A server-side route holds the Zapier MCP connection — URL and auth token never reaching the browser — and either forwards tool calls through the Anthropic API's native MCP connector or acts as a generic client via @modelcontextprotocol/sdk, listing available tools and executing whichever the model selects. Scope it to an explicit allowlist (e.g. send email to self) rather than handing an agent unrestricted access to real accounts. That allowlist is the entire engineering decision; everything else is plumbing, and the-harness-not-the-model is where the general version of it lives.
The framework side, in one paragraph
Google's Agent Development Kit release adds sandboxed code execution isolation on Cloud Run, the ability to serve an agent as an MCP server, and an improved Live API; ADK Go shipped alongside. The 30-minute question is whether an existing subagent can be wrapped in ADK and called from Claude over MCP. Once the protocol question is answered that is a wrapper exercise, which is exactly why it is last.
The fourth seat — the gateway between the agent and the tool
This card has three seats: build a server, consume one, wrap an agent as one. A fourth has appeared, and it is where the attention moved once the protocol stopped being the open question. With the MCP npm SDK at roughly 196M downloads a month, whether to speak MCP is settled. What is contested is the layer above it: the gateway that sits between the agent and everything it calls.
Three things currently occupying that layer, and they are not the same product:
| What it actually sells | |
|---|---|
| LiteLLM | One API surface over 100+ model providers, with per-call cost tracking — a routing and billing layer |
| TrueFoundry | Per-agent identity and spending caps — an authorization layer |
| vLLM | The default once the model is hosted rather than called — an inference layer |
The shape is familiar: this is the reverse proxy, arriving for agents. Every line in that table is something you would otherwise write badly yourself — a retry policy, a key vault, a budget, an audit log — and the reason it wants to be a separate box is that an agent cannot be trusted to enforce a limit on itself. That is the same argument as the-harness-not-the-model, and agentic-intent-veto is the warning about which limit to pick: a spending cap is the wrong invariant if what you actually care about is what the agent is for.
This lands directly on the client seat above, where the conclusion was that consuming an MCP server is a security decision — hold the connection server-side, never let the URL and token reach the browser. A gateway is that answer, productised. So the question to ask before adopting one is which of the four it is actually giving you — routing, identity, cost, or observability — because they are sold as a single product and needed one at a time, and the cheapest version of three of them is a server-side route you already know how to write.