Chapter 29: State of the Ecosystem
Pin a revision. MCP removed its handshake and its sessions in July 2026, and your clients, SDKs and gateways will not all follow at the same speed. The rule for this chapter: before you depend on any layer of the ecosystem, decide whether you build on it, use it with a fallback, or don’t depend on it yet, and write that decision down next to the revision you pinned.
Upgrading from 2025-11-25
The 2026-07-28 revision is the largest change since Streamable HTTP. These are its protocol-level changes, taken from the official changelog (Appendix A has them as a checklist, each linked to its chapter):
- No sessions, no handshake. The
initialize/notifications/initializedhandshake and theMcp-Session-Idheader are gone. Every request carries its protocol version and client capabilities in_meta. Servers must implement a newserver/discovermethod, which clients may call up front. State that has to survive across calls now travels as explicit, server-minted handles passed as ordinary tool arguments. - Streamable HTTP simplified.
subscriptions/listen, a single long-lived stream for the change notifications a client opts into, replaces the HTTP GET stream andresources/subscribe/resources/unsubscribe. SSE resumability (Last-Event-ID) is removed: if a response stream breaks, the client re-issues the request. POST requests must carryMcp-MethodandMcp-Nameheaders. - Multi Round-Trip Requests (MRTR). Servers no longer send their own requests to the client for sampling, elicitation or roots. The server returns an
InputRequiredResult(resultType: "input_required"), and the client retries the original request withinputResponses. Every result now carries aresultTypefield. - Tasks moved to an extension. Tasks now live in the official
io.modelcontextprotocol/tasksextension. The redesign dropstasks/resultandtasks/list, polls withtasks/get, and addstasks/updatefor input while a task is running. - Removed utilities.
ping,logging/setLevelandnotifications/roots/list_changedare gone. The log level is now set per request in_meta. - Authorization. Dynamic Client Registration (RFC 7591) is deprecated in favour of Client ID Metadata Documents. Clients must validate the
issparameter (RFC 9207) when an authorization response includes it, and must bind stored client credentials to the authorization server that issued them. - Deprecations with a clock. Roots, Sampling, Logging and DCR are Deprecated. They still work, but they become eligible for removal in the first revision released on or after 2027-07-28. The old HTTP+SSE transport is Deprecated on a shorter clock: it becomes eligible for removal three months after the lifecycle SEP (SEP-2596) reaches Final.
- Smaller additions. An
extensionsfield in capabilities, OpenTelemetry trace context conventions for_meta, cache hints (ttlMs,cacheScope) on list and read results, looser JSON Schema 2020-12 support in tool schemas, and deterministictools/listordering.
Here is the same search_tickets call under both revisions, headers trimmed to the ones that changed. Under 2025-11-25 (legacy), the call takes three POSTs and a session:
POST /mcp → initialize
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25",
"capabilities":{},"clientInfo":{"name":"ExampleClient","version":"1.0.0"}}}
← 200 Mcp-Session-Id: 1868a90c-3f2b
POST /mcp Mcp-Session-Id: 1868a90c-3f2b → notifications/initialized
POST /mcp Mcp-Session-Id: 1868a90c-3f2b MCP-Protocol-Version: 2025-11-25
{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"search_tickets","arguments":{"query":"login timeout"}}}
Under 2026-07-28 it is one POST that carries everything the server needs:
POST /mcp MCP-Protocol-Version: 2026-07-28 Mcp-Method: tools/call Mcp-Name: search_tickets
{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"search_tickets","arguments":{"query":"login timeout"},
"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28",
"io.modelcontextprotocol/clientCapabilities":{}}}}
Three consequences follow. Any server replica can answer any request, because nothing lives in a session. A gateway can route or rate-limit on Mcp-Method and Mcp-Name without parsing the body. And against a 2025-11-25 peer, the handshake, the session header and server-initiated requests are what break first. The current 2.x releases of the official Python and TypeScript SDKs support 2026-07-28. Read your SDK’s migration notes before upgrading; the Python SDK’s v1-to-v2 guide shows what to check.
Every Revision Left Peers Behind
Five revisions have shipped, and each still has clients in the wild. The useful question about each one is what breaks when the peer is a revision behind.
| Revision | Headline change | What breaks if a peer is behind |
|---|---|---|
| 2024-11-05 | Launch: tools, resources and prompts over stdio and HTTP+SSE | The peer speaks only HTTP+SSE, now Deprecated; clients must probe and fall back |
| 2025-03-26 | Streamable HTTP, OAuth 2.1 baseline, tool annotations | Older peers can’t use Streamable HTTP or annotations |
| 2025-06-18 | outputSchema/structuredContent, RFC 9728/8707 auth, elicitation, resource links, MCP-Protocol-Version header; batching removed | Older clients ignore structuredContent, so also return it as text; servers may treat a missing version header as 2025-03-26 |
| 2025-11-25 | Experimental Tasks, URL-mode elicitation, Client ID Metadata Documents | Older clients can’t run Tasks and register through DCR instead |
| 2026-07-28 | Stateless: per-request _meta, MRTR, Tasks as an extension, Mcp-Method/Mcp-Name | Older peers expect initialize and a session; version negotiation must fall back |
Peers on different revisions interoperate only through that fallback. A server that speaks only 2026-07-28 answers a legacy GET or DELETE with 405 and ignores an Mcp-Session-Id header, so a 2025-11-25 client that can’t fall back simply stops working.
SDKs: Broad Coverage, Uneven Depth
The official SDK list covers ten languages, all under the modelcontextprotocol GitHub organization and ranked in tiers by feature completeness and maintenance commitment. TypeScript, Python, C#, Go and Rust are Tier 1; Java and Ruby are Tier 2; Swift, PHP and Kotlin are Tier 3.
For Python, be careful which “FastMCP” you mean. The official mcp package renamed its FastMCP class to MCPServer in 2.x, so from mcp.server.fastmcp import FastMCP only works on mcp<2. The standalone fastmcp package is a separate project that still uses the name. The examples in this book use MCPServer. Older material that imports mcp.server.fastmcp needs either the mcp<2 pin or the one-line port to from mcp.server.mcpserver import MCPServer.
Coverage is broad. Depth is uneven.
Tier 1 SDKs track the specification closely. Lower tiers and community SDKs can lag by a full revision, which is exactly the skew 2026-07-28 made expensive. A server built around 2026-07-28 features (MRTR elicitation, subscriptions/listen, per-request _meta) on an SDK release that still speaks 2025-11-25 produces partial failures that look like network bugs. Check which revision your SDK release targets before you write the first tool.
Outside Tier 1, budget time to verify feature parity against the revision you pinned.
Clients: Tools Are Universal, Everything Else Varies
modelcontextprotocol.io keeps a community-maintained client matrix for the official extensions. For core features such as resources, prompts, elicitation and the authorization options, each client’s own documentation is the source. No single client supports every feature, and each major client (Claude’s surfaces, VS Code with GitHub Copilot, Cursor, ChatGPT, Goose) has its own mix.
That mix decides what you can build:
- Resources. If your target clients don’t support resources, your schema-as-resource and index-as-resource patterns are invisible. Claude’s web and desktop surfaces support them; others vary.
- Elicitation. A server that asks the user to confirm a destructive action needs a client that supports elicitation. Under 2026-07-28 that client must also speak MRTR, because the server returns an input-required result and the client retries.
- Tasks. Since 2026-07-28, Tasks is an optional extension (
io.modelcontextprotocol/tasks). A long-running export built on Tasks needs a client that implements the extension.
MCP Apps, which lets a server return interactive HTML rendered in a sandboxed iframe, launched as the first official extension on 2026-01-26 and has the broadest client support: Claude, VS Code, Goose, Postman, MCPJam and Cursor.
“Build once, run anywhere” is an aspiration, not a guarantee. Design the server to degrade: if a client lacks resources, the tools still work; if it lacks elicitation, the server uses safe defaults. Then test in the clients you target, not in Inspector alone.
Extensions Turn Features Into Portability Decisions
Extensions add capabilities without destabilizing the core. They are declared in the extensions field of each side’s capabilities and are strictly additive: a client that doesn’t recognize one skips it.
The official extensions are:
- MCP Apps (
io.modelcontextprotocol/ui): interactive HTML interfaces in the conversation. - OAuth Client Credentials (
io.modelcontextprotocol/oauth-client-credentials): machine-to-machine authentication without interactive login. - Enterprise-Managed Authorization (
io.modelcontextprotocol/enterprise-managed-authorization): access control through an enterprise identity provider. - MCP Tasks (
io.modelcontextprotocol/tasks): asynchronous execution for long-running operations. - Skills over MCP (
io.modelcontextprotocol/skills): discovering and reading Agent Skills from MCP servers.
The risk is fragmentation. If a capability you need lives in an extension that only one or two clients support, you are building a single-client integration, not a portable MCP server. Make that call on purpose.
No Single Vendor Controls the Standard
MCP is a Linux Foundation project under the Agentic AI Foundation (AAIF), with a Contributor Ladder, Working Groups, Interest Groups and maintainers drawn from several companies. The roster and the group list change, so read them on modelcontextprotocol.io rather than in a book. For a builder, that settles the two-year question: MCP’s evolution no longer depends on any single organization’s priorities. It also means spec changes arrive through the SEP process, on a timeline of months.
Distribution has its own infrastructure: the Official MCP Registry, the Anthropic Connectors Directory and community catalogs. Chapter 30 covers each one and shows a server.json.
Where Teams Still Lose Time
Setup friction. Absolute paths in JSON config, environment variables set before the client launches, and SDK mismatches still make the first local connection the ecosystem’s weakest moment.
Mental model confusion. The specification separates host from client, tool from resource from prompt, and protocol errors from tool errors; working documentation blurs them, and the result is tools that should have been resources.
Overbuilding the first server. Thirty tools where five would validate the design. Catalog bloat and description rot follow.
Debugging opacity. A failed call can live in the server, the transport, the client’s routing, the model’s reading of the schema, or the client’s rendering. Inspector covers only the first two.
A Maturity Map With Decisions
“Is MCP mature?” has no useful answer. Ask which layer is mature enough for your use case, and what you will do about it.
| Layer | State (September 2026) | Decision |
|---|---|---|
| Core specification, per-request versioning | Mature; 2026-07-28 still broke the wire format | Build on it; pin the revision |
| Tier 1 SDKs (TypeScript, Python) | Track the spec closely | Build on it |
| Lower-tier and community SDKs | Can lag a revision | Use with fallback: verify parity first |
| Local workflow (stdio, Inspector, desktop config) | Reliable | Build on it |
| Remote shared deployment | Viable; auth, handles and observability are your job | Build on it, and budget for Parts VI and VII |
| Client features beyond tools | Uneven | Use with fallback: tools still work alone |
| MCP Apps | Broadest extension support | Use with fallback: return structured data too |
| Auth extensions (client credentials, enterprise-managed) | Official, patchy client support | Use with fallback: standard OAuth |
| Tasks, Skills over MCP | Official; Tasks still changing | Don’t depend yet |
| Deprecated features (Sampling, Roots, Logging, DCR) | Removal-eligible from the first revision on or after 2027-07-28 | Use with fallback: only for older peers |
| Official Registry | Preview, API frozen at v0.1 | Use with fallback: your docs stay canonical |
| Server Cards, cross-client config | Proposed or absent | Don’t depend yet |
| Enterprise patterns (audit, agent identity, gateway semantics) | Emerging | Don’t depend yet |
The decision column is the part to copy into your design doc. A “use with fallback” row is a promise to test the fallback, not just to have one.
What the Ecosystem Still Needs
Five gaps affect architecture today.
Cost attribution. No standard exists for tracking what a server costs in tokens, API calls or compute. Chapter 13 covers token economics, but if your server wraps a paid API, you build the metering.
Distributed tracing. 2026-07-28 documents OpenTelemetry trace context in _meta (traceparent, tracestate, baggage). Client adoption is uneven, so end-to-end traces from user request to downstream dependency remain mostly your own work.
Configuration portability. The same server needs a different configuration file for Claude Desktop, VS Code and Cursor. Some clients read a shared project-root .mcp.json; no cross-client standard exists.
Client capability parity. Building for tools only is safe and gives up resources, prompts and elicitation. Building for the most capable client works there and degrades unpredictably elsewhere.
Model-in-the-loop testing. Inspector verifies protocol compliance. Nothing standard tests how a real model reads your descriptions, orders its calls or recovers from your errors. Chapter 12 shows how to build that yourself.
What to re-check every quarter. Everything in this chapter was checked on 2026-09-27. These pages move faster than a book:
- the specification changelog and deprecated features registry: what breaks, and when;
- the SDK list and your SDK’s release notes: which revision your release targets;
- the extension client matrix and extensions overview: which clients support what you use;
- the roadmap and the Working and Interest Groups page: what is coming and who owns it;
- the Official Registry and the Connectors Directory requirements: what publishing requires.
Where the Specification Is Going
The official roadmap, last updated 2026-08-22, describes itself as current thinking rather than firm commitments. Its five priority areas:
- Agentic Messaging Primitives. Long-running work, server push, streaming results and steering work mid-flight. The goal is one lifecycle, cancellation model and error surface for Tasks,
subscriptions/listenand progress notifications, plus server-initiated events such as webhooks. If you built on Tasks, expect further changes. - HTTP-Native Transport Unification and Hardening. 2026-07-28 made a remote MCP server a normal HTTP workload. The Transports WG is exploring Streamable HTTP as the single binding, spoken over stdio for local servers, plus ETag-style caching on top of
ttlMs/cacheScope. - Agent Identity and Enterprise-Ready Security. DPoP (proof-of-possession tokens) and a way for agents to reach MCP servers under their own or a delegated identity, using workload identity federation, the ID-JAG grant behind Enterprise-Managed Authorization, and RFC 8693 token exchange. These are the gaps Chapters 18, 19 and 26 kept running into.
- Improved Primitives. A redesign of the
tools/callresult shape (today’scontentplusstructuredContentsplit confuses implementers) and progressive discovery, so clients learn tools as they need them. - Improved SDK Developer Experience. The SDK WG is defining the extension contract SDKs must support and experimenting with generating a Tier 1 SDK from the specification and conformance suite.
None of these has a date, and none needs one to shape what you build now. All five reward the same server: stateless over plain HTTP, with structured results, a small catalog and identity taken from the token. Build that and each item arrives as an upgrade rather than a rewrite.
Failure Modes
Spec-SDK lag. A feature from a newer revision that your SDK hasn’t implemented fails partially and confusingly.
Registry-reality drift. Registries validate manifest format, not runtime behavior. A listed third-party server may no longer work as described.
Extension lock-in. A critical capability in an extension that one client supports turns a portable server into a single-client integration.
Waiting on the spec. Work that depends on a SEP landing waits months. Treat the future specification as upside, not as a dependency.
Stale guidance. Posts written against 2024-11-05 or 2025-03-26 still rank in search and recommend removed patterns: HTTP+SSE, JSON-RPC batching, sessions, pre-OAuth auth.
Implementation Checklist
- Record the pinned revision and your SDK release’s target revision in the README.
- Write the maturity-map decision for every layer you depend on.
- List your target clients and check each feature you expose against their documentation.
- Test in at least two clients as well as Inspector.
- Test every “use with fallback” path with the feature turned off.
- Choose the auth strategy from the deployment model (local or remote), not from convenience.
- Log requests, errors and latency from day one.
- Put the quarterly re-check pages on a calendar with an owner.
What Comes Next
Knowing the terrain doesn’t tell you when your own server is ready to be on it. A server can pass every check in this chapter and still become a liability the day a stranger depends on it. Chapter 30 is about that line: what “publishable” means, where to publish, and what you owe the people who install your server.