MCP in 2026: The Protocol State After the Linux Foundation Move
If you wrote an MCP integration in early 2025, the thing you built then is not the thing you’d build today. The protocol’s core is the same — JSON-RPC over a stateful transport, with resources, tools, prompts, sampling, roots, and elicitation — but everything around it has moved: governance, distribution, authentication, and even the kind of UI a server is allowed to render. If you’ve been treating MCP as a curiosity, this is the point where that view gets expensive.
What follows is the honest mid-2026 picture: where MCP has settled, where it is still in motion, and what is worth your engineering time right now. It is not a tutorial. You can find those elsewhere and they are mostly fine. This is closer to a field report.
The core architecture, in one paragraph
MCP is still JSON-RPC 2.0 between a host (the LLM application), a client (the connector inside the host), and a server (the tool or data provider). The host owns consent. The server exposes three core primitives — resources (file-like data the model can read), tools (functions the model can call), and prompts (templated workflows) — plus three client-side primitives the server can request: sampling (recursive LLM calls), roots (filesystem boundaries), and elicitation (asking the user for input).
Two things are different now. First, the current spec revision is 2025-06-18 — that’s the protocol version clients and servers negotiate at handshake. If you’re still pinning to a 2024-11 revision, your client and server may silently lose capabilities. Second, the official SDKs now exist for nine languages: TypeScript, Python, Java, Kotlin, Swift, C#, Go, PHP, and Rust. The SDK tiering system (introduced in early 2026) ranks them by feature completeness, so you can pick one based on which extensions you need instead of guessing.
How SDK tiering actually works
Tier 1 SDKs — TypeScript and Python — are expected to support every core protocol feature, every official extension that has graduated past experimental, and ship with backward-compatible release notes. Tier 2 SDKs (Java, C#, Go, Swift, Kotlin, Rust) cover the core and most extensions, with some lag. Tier 3 (PHP, plus community-maintained ports) covers core only, and the tier 3 status is sometimes used as a polite way of saying “this SDK is fine for reading data but don’t bet production on it.” The honest way to pick is to list the extensions you plan to use and check the SDK’s published coverage matrix. Skipping this step is how teams end up writing client code against extension methods that don’t exist yet in their language of choice.
Five shifts that matter since late 2025
1. Governance moved to the Linux Foundation
Anthropic launched MCP in late 2024. By Q1 2026, the project moved under a multi-vendor Linux Foundation structure with formal Working Groups and Interest Groups, a published governance charter, and a contributor ladder that defines how you go from a first commit to a core maintainer role. The steering group is no longer a single company.
For you as a builder, this changes two things. You no longer need to bet on a vendor’s roadmap — extension proposals go through a documented SEP (Specification Enhancement Proposal) process with working-group backing. And if you build a server today, you can publish it to the official Registry with a moderation process rather than hoping someone finds your GitHub repo.
The SEP process, in one paragraph
If you’ve ever watched a critical protocol feature get stuck because one vendor disagreed with another, the SEP process is designed to prevent that. A SEP is a written proposal with motivation, design, and reference implementation. It goes to a relevant Working Group first; if the WG accepts it, the SEP moves to Core Maintainer review. Core Maintainers have final authority over inclusion in the core spec or as an official extension. Extension-track SEPs go through the same pipeline but graduate as “official extensions” rather than core features. This separation matters because it lets the spec evolve conservatively on the core and aggressively on the edges.
What this means in practice: if you build something the protocol doesn’t support, you have a real path to propose it. Working Groups have public charters, quarterly reviews, and a contributor ladder that lets committed community members become maintainers. The skill floor for participating is “can write a design doc with code samples,” not “works at Anthropic.”
2. The MCP Registry is live
The Official MCP Registry at registry.modelcontextprotocol.io launched in late 2025 and now indexes published MCP servers with version history, package metadata, and publisher authentication. There are also independent registry aggregators that pull from multiple sources and add their own curation.
The practical effect: discovery is no longer a Google search. When you write a client, you can pull from a registry instead of asking the user to paste a JSON config. When you ship a server, you can get distribution without marketing. Publishing is gated by GitHub authentication and a moderation policy, which is the right trade-off — open distribution would have turned the registry into a malware buffet. The aggregator story is also interesting: third-party registries can layer trust signals on top of the official one, so enterprises can publish private indexes without forking the spec.
3. Authorization is now OAuth 2.1 with a real spec
For most of 2025, MCP servers either ran locally over STDIO with environment-based credentials, or they shipped with homegrown auth bolted onto the transport. That is no longer the recommended path. The current authorization tutorial walks through an RFC-aligned OAuth 2.1 flow using Protected Resource Metadata (RFC 9728) and either pre-registration or Dynamic Client Registration.
The wire-level change: an MCP server now responds with a 401 and a WWW-Authenticate header that points the client to a .well-known/oauth-protected-resource document. The client discovers the authorization server, registers itself, performs the standard authorization-code-with-PKCE flow, and comes back with a bearer token. From the server’s side, you can stand this up against Keycloak, Auth0, Okta, or any RFC 8414 / OIDC-compliant identity provider.
4. MCP Apps: interactive UI inside the chat
The MCP Apps extension (still labeled experimental but shipping in real hosts) lets a server return rendered UI — a chart, a form, a video player, an embedded canvas — alongside the standard tool result. The client advertises support via the io.modelcontextprotocol/ui extension capability with allowed MIME types, typically text/html;profile=mcp-app. Servers opt in by advertising the same extension in their initialize response.
The interesting design choice is graceful degradation. A server that supports UI should still return meaningful text content for clients that don’t, so you don’t break older hosts. This is the right call — the worst outcome would be a wave of servers that only work in one client.
5. Tasks: async without the long-lived connection
The MCP Tasks extension solves a problem every production team has hit: some tool calls take minutes (CI pipelines, batch jobs, human approvals) and holding a connection open that long is not realistic. Tasks let the server return a durable task handle instead of a synchronous result. The client polls via tasks/get, or subscribes to notifications/tasks for push updates.
The cleanest detail: the task can transition into input_required, at which point the server surfaces an elicitation request inside the tasks/get response. The client answers via tasks/update. This is the human-in-the-loop pattern people have been hand-rolling with separate HTTP endpoints, now done correctly inside the protocol.
Choosing a transport in mid-2026
MCP now supports two transports, and the choice matters more than most blog posts admit.
| Transport | Best for | Tradeoffs |
|---|---|---|
| STDIO | Local development, single-user desktop apps, anything where the server runs as a subprocess of the host. | Simple. No auth needed because the OS handles process isolation. Logging must go to stderr, never stdout — print statements will corrupt JSON-RPC frames. Cannot scale beyond one user. |
| Streamable HTTP | Remote servers, multi-user deployments, anything behind a load balancer. | Stateless-friendly when configured correctly. Supports OAuth 2.1. Sits behind standard HTTP infrastructure. Needs careful session handling if you want resumption across server restarts — this is on the Transport WG roadmap but not fully solved yet. |
The mistake teams keep making is deploying STDIO servers to production. A STDIO server assumes it has the host’s full filesystem, environment, and trust. The moment you wrap it in a container and call it “production,” you’ve created a confused deputy problem with extra steps. If your server needs to serve more than one user, you need Streamable HTTP and you need to think about auth from day one.
The authorization model, in plain terms
The OAuth 2.1 walkthrough reads more complicated than it is. The flow is:
- Client connects. Server replies
401with a WWW-Authenticate header pointing to a Protected Resource Metadata (PRM) document. - Client fetches the PRM to learn which authorization servers and scopes are valid.
- Client registers itself (either pre-registered or via Dynamic Client Registration).
- Client opens a browser to
/authorize, user logs in, returns an authorization code. - Client exchanges code for tokens, attaches bearer token to MCP requests.
The pain point is step 3. If your identity provider doesn’t support Dynamic Client Registration and your client isn’t pre-registered, you fall back to a manual entry flow — and that “manual entry” UX is the kind that ends with users pasting client secrets into Discord. For enterprise deployments, this is one reason the Enterprise-Managed Authorization extension exists: it lets IT pre-register clients and route through the same SSO they use for everything else.
The OAuth Client Credentials extension covers the other half of the problem — machine-to-machine flows where there is no human in the loop. If your MCP server is a backend service calling other backends, you want this extension, not the user-facing authorization code flow.
What the OAuth 2.1 spec actually requires from you
For server authors, the non-obvious parts are: validate the resource claim in incoming tokens so a token issued for one MCP server cannot be replayed against another (the spec calls this the “audience” check and the consequences of skipping it are not theoretical). Use PKCE on every authorization-code flow, including confidential clients — leaving it off for “trusted” first-party clients is how mix-up attacks happen. And treat token introspection and revocation as a first-class concern: if your server caches tokens, build a revocation hook so a leaked token doesn’t stay valid for an hour.
For client authors, the equivalent non-obvious bits: never trust the token’s scope claim blindly — re-derive scopes from the server’s PRM document. Handle 401 with a token refresh, not a hard reconnect. And log every authorization attempt with the user, client, requested scopes, and timestamp. Audit trails are what separate a hobby MCP deployment from one that survives an enterprise security review.
Build versus install: when to write your own server
There are now thousands of MCP servers in the wild. Writing your own is the right call in three situations:
- The integration is internal. If you need a server that talks to your private database, your internal CI, or your proprietary API, no registry entry will help. Build it, secure it, host it on your own infrastructure.
- The existing servers are unmaintained. Many community servers shipped in early 2025 have not been updated since. If a server’s last commit predates the 2025-06-18 spec revision, treat it as abandonware and plan to fork or replace it.
- Your use case needs an extension that isn’t widely supported yet. If you need Tasks with custom elicitation flows, or MCP Apps with a specific MIME profile, you’ll write more code than you’d copy. Build it.
For everything else, install. The Official Registry has a moderation policy that catches the worst abuse. Independent aggregators give you breadth. The time you save goes into your actual product.
When MCP is the wrong tool
MCP is not a universal answer, and pretending otherwise leads to bad architectures.
Skip MCP when the integration is a single function call from one model. If you have a chatbot that needs one tool, an HTTP endpoint and a function-calling schema is less infrastructure than an MCP server. MCP earns its complexity when there are multiple tools, shared state, or a long-lived host-client relationship.
Skip MCP when latency is critical. Every MCP call adds JSON-RPC framing, capability negotiation, and (for HTTP) a full HTTP round-trip. For tight latency budgets, an inline function call beats the protocol.
Skip MCP when you control the whole stack. If the same team owns the model, the tool, and the UI, MCP is overhead. It exists to solve cross-vendor interoperability — if there is no cross-vendor, you’re paying for flexibility you don’t use.
Common pitfalls in production
These are the issues that show up in real deployments, not the ones in the spec.
Logging into stdout
If your STDIO server prints anything to stdout, it corrupts the JSON-RPC stream and the client sees garbage. Use stderr or a logging library. The official tutorial calls this out, but every team relearns it the hard way.
Trusting tool descriptions from untrusted servers
The spec is explicit: tool descriptions are untrusted unless they come from a server you’ve verified. A malicious server can put prompt-injection payloads in tool descriptions. Hosts must surface descriptions to users, not to the model, and let the user decide what to authorize.
Forgetting the protocol version
Pin the protocol version in your initialize handshake. If you don’t, you get the server’s default, which might be older than your client supports. This shows up as missing capabilities — and the failure mode is silent, not a crash.
Mixing transport modes mid-session
A session is bound to a transport. If you start over STDIO and try to reconnect over HTTP with the same session ID, things will go wrong. Treat transport choice as a deployment-time decision, not a runtime fallback.
Long-lived synchronous calls
If you find yourself wanting to block a TCP connection for ten minutes waiting on a CI run, you want Tasks. If you find yourself wanting to do that anyway because “it’s simpler,” you will lose work to network timeouts, container restarts, and OAuth token expiry. Use the extension.
Skipping the initialize handshake validation
The handshake is where capabilities are negotiated. If your client skips checking the server’s advertised capabilities, you’ll discover at runtime that a tool you expected doesn’t exist — usually during a demo. Always validate that the capabilities the server advertised match the tools, resources, and extensions your client code expects.
Not having a versioning story
Servers evolve. Tools get renamed, parameters change, prompts get rewritten. If your client breaks every time the server ships a new minor version, you don’t have an MCP integration — you have a coupling problem with extra steps. Use semver properly: bump major for breaking tool signature changes, minor for additions, patch for bugfixes. The MCP Registry indexes versions, and clients that respect the version pin will thank you.
A practical decision checklist
- One user, local app? STDIO, no auth, env-var credentials.
- Multi-user SaaS? Streamable HTTP, OAuth 2.1, Keycloak or your existing IdP.
- Server-to-server with no human? Streamable HTTP, OAuth Client Credentials extension.
- Long-running operations? Tasks extension, with
input_requiredif any step needs approval. - Need to render UI? MCP Apps extension, advertise
text/html;profile=mcp-app, always return a text fallback. - Enterprise IT in the loop? Enterprise-Managed Authorization extension, pre-register clients, route through SSO.
- Distributing a server? Publish to the Official Registry, not just GitHub releases.
- Picking an SDK? Check the SDK tiering document — TypeScript and Python are tier 1, the rest vary by extension coverage.
Frequently asked questions
Do I still need to ship a custom auth layer if I use Streamable HTTP?
If your server has any user-specific data, yes. STDIO with environment variables is fine for single-user local use, but the moment a remote server touches user data, you need OAuth 2.1 with PRM discovery. Building auth yourself is what the spec calls “strongly discouraged” — use an existing identity provider and the standard flow.
What’s the difference between MCP Apps and just returning HTML from a tool?
Tools return text or structured content. MCP Apps return rendered UI in a sandboxed iframe inside the host, with explicit lifecycle events so the host knows when to tear the UI down. If you return raw HTML from a tool, the host will either ignore it or render it in an unsafe way. Use the extension.
Is Tasks the same as Celery / Temporal / a job queue?
No. Tasks is a protocol-level pattern — the server returns a handle, the client polls. If you need durable, retryable, multi-step orchestration, you still want Temporal or a job queue inside your server. Tasks solves the wire-level problem of long-running operations between MCP client and server.
Should I wait for the protocol to stabilize before building?
If you’re building an internal tool, you’ve already waited too long. The core spec is stable, the SDKs are production-grade, and the extensions are additive — opt-in, with graceful degradation. If you’re building something that has to live for five years, pin your protocol version, design against the extension capability negotiation, and you can adopt new extensions as they stabilize.
Why did governance move to the Linux Foundation?
Because multi-vendor adoption needs multi-vendor governance. A protocol that defines how every AI agent talks to every tool cannot be steered by one company — vendors will not commit without a neutral home. The Linux Foundation move was the prerequisite for the enterprise and SDK investments that followed.
What to do this week
If you have an existing MCP integration, audit it against the 2025-06-18 spec revision and your SDK’s tier level. If you’re starting fresh, build the smallest viable thing first — one tool, STDIO transport, no auth — and only add Streamable HTTP, OAuth 2.1, or Tasks when the use case demands it.
MCP is no longer the “USB-C for AI” metaphor that launched it. It’s the working substrate underneath a growing share of agentic products. The protocol got there by becoming more boring — more spec, more governance, fewer surprises. That’s the right kind of progress, and it’s the right time to start building.
What to watch in the next six months
The roadmap is public, which is itself a sign of maturity. Three things are likely to land before the end of 2026:
- Stateless Streamable HTTP with proper session migration. The Transport WG is finishing SEPs on a wire format that works across load balancers and server restarts. If you deploy MCP servers at scale today, you’re doing manual session-stickiness hacks. That gets cleaner.
- Server Cards. A standardized metadata document at a
.well-knownURL that describes what a server does without requiring a connection. This unlocks discovery in places where a live handshake isn’t possible — search engines, agent marketplaces, enterprise catalogs. - Triggers and events. Right now, clients learn about server-side changes by polling or holding an SSE connection open. A standardized webhook-style notification mechanism would let servers push updates without burning client connections. The WG charter exists; the SEP is in review.
Also on the horizon, but longer-term: streamed and reference-based tool results (so a 200MB tool response doesn’t have to fit in one JSON-RPC frame), DPoP for sender-constrained tokens, and Workload Identity Federation so your CI can call MCP servers without static credentials. None of these are reasons to wait. All of them are reasons to keep an eye on the roadmap.

