Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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/initialized handshake and the Mcp-Session-Id header are gone. Every request carries its protocol version and client capabilities in _meta. Servers must implement a new server/discover method, 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 and resources/subscribe / resources/unsubscribe. SSE resumability (Last-Event-ID) is removed: if a response stream breaks, the client re-issues the request. POST requests must carry Mcp-Method and Mcp-Name headers.
  • 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 with inputResponses. Every result now carries a resultType field.
  • Tasks moved to an extension. Tasks now live in the official io.modelcontextprotocol/tasks extension. The redesign drops tasks/result and tasks/list, polls with tasks/get, and adds tasks/update for input while a task is running.
  • Removed utilities. ping, logging/setLevel and notifications/roots/list_changed are 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 iss parameter (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 extensions field 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 deterministic tools/list ordering.

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.

RevisionHeadline changeWhat breaks if a peer is behind
2024-11-05Launch: tools, resources and prompts over stdio and HTTP+SSEThe peer speaks only HTTP+SSE, now Deprecated; clients must probe and fall back
2025-03-26Streamable HTTP, OAuth 2.1 baseline, tool annotationsOlder peers can’t use Streamable HTTP or annotations
2025-06-18outputSchema/structuredContent, RFC 9728/8707 auth, elicitation, resource links, MCP-Protocol-Version header; batching removedOlder clients ignore structuredContent, so also return it as text; servers may treat a missing version header as 2025-03-26
2025-11-25Experimental Tasks, URL-mode elicitation, Client ID Metadata DocumentsOlder clients can’t run Tasks and register through DCR instead
2026-07-28Stateless: per-request _meta, MRTR, Tasks as an extension, Mcp-Method/Mcp-NameOlder 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.

LayerState (September 2026)Decision
Core specification, per-request versioningMature; 2026-07-28 still broke the wire formatBuild on it; pin the revision
Tier 1 SDKs (TypeScript, Python)Track the spec closelyBuild on it
Lower-tier and community SDKsCan lag a revisionUse with fallback: verify parity first
Local workflow (stdio, Inspector, desktop config)ReliableBuild on it
Remote shared deploymentViable; auth, handles and observability are your jobBuild on it, and budget for Parts VI and VII
Client features beyond toolsUnevenUse with fallback: tools still work alone
MCP AppsBroadest extension supportUse with fallback: return structured data too
Auth extensions (client credentials, enterprise-managed)Official, patchy client supportUse with fallback: standard OAuth
Tasks, Skills over MCPOfficial; Tasks still changingDon’t depend yet
Deprecated features (Sampling, Roots, Logging, DCR)Removal-eligible from the first revision on or after 2027-07-28Use with fallback: only for older peers
Official RegistryPreview, API frozen at v0.1Use with fallback: your docs stay canonical
Server Cards, cross-client configProposed or absentDon’t depend yet
Enterprise patterns (audit, agent identity, gateway semantics)EmergingDon’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:

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:

  1. 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/listen and progress notifications, plus server-initiated events such as webhooks. If you built on Tasks, expect further changes.
  2. 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.
  3. 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.
  4. Improved Primitives. A redesign of the tools/call result shape (today’s content plus structuredContent split confuses implementers) and progressive discovery, so clients learn tools as they need them.
  5. 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

  1. Record the pinned revision and your SDK release’s target revision in the README.
  2. Write the maturity-map decision for every layer you depend on.
  3. List your target clients and check each feature you expose against their documentation.
  4. Test in at least two clients as well as Inspector.
  5. Test every “use with fallback” path with the feature turned off.
  6. Choose the auth strategy from the deployment model (local or remote), not from convenience.
  7. Log requests, errors and latency from day one.
  8. 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.