MCP shipped a UI. The headless thesis holds.
The protocol built to let machines consume software is about to add a way to show interfaces to humans.
That should be an awkward moment for a publication that keeps arguing UI is becoming optional. The 2026-07-28 MCP specification, the largest revision since the protocol launched, does two things that look contradictory. It strips the protocol down to a stateless, routable, OAuth-hardened machine interface. And it lets servers ship interactive HTML through MCP Apps. The release candidate is already locked, and the final specification ships on July 28, 2026.
Read quickly, the second half looks like the dashboard sneaking back in. It is the opposite. The MCP 2026-07-28 spec is the clearest evidence yet that the interface is not a product you navigate anymore. It is a resource the backend declares and the agent decides whether to render. UI became an API response.
What the MCP 2026-07-28 spec actually changed
Start with the part nobody disputes. The release is a deliberate move toward statelessness, and the details are specific.
The Mcp-Session-Id header is gone, along with the protocol-level session that pinned a client to one server instance (SEP-2567).
Any MCP request can now land on any server instance.
The initialize and initialized handshake is removed too (SEP-2575): protocol version, client info, and capabilities now ride in _meta on every request instead of a connection preamble.
Two new headers, Mcp-Method and Mcp-Name (SEP-2243), let load balancers, gateways, and rate limiters route a request by reading the operation, without parsing the body.
The practical effect is blunt. A remote MCP server that used to need sticky sessions, a shared session store, and deep packet inspection at the gateway can now sit behind a plain round-robin load balancer. This is the shape of infrastructure built for machines, not for browser tabs. Sessions exist because humans hold a connection open and expect the far end to remember them. Agents do not need that, and the protocol stopped pretending they do.
Authorization moved in the same direction.
MCP servers are now formally OAuth 2.1 resource servers, and six separate proposals tighten the alignment with OAuth 2.1 and OpenID Connect.
Clients must validate the iss parameter per RFC 9207 (SEP-2468), declare an OpenID Connect application_type during dynamic client registration (SEP-837), and bind credentials to the issuing authorization server (SEP-2352).
WorkOS called this the change that makes MCP enterprise-ready, and that framing is right.
A protocol that wants to be the interface for machine-consumed software needs a real identity layer, which is exactly the missing primitive we wrote about earlier.
None of this is a UI story. It is a protocol growing the properties a machine-consumed interface has to have: statelessness, routability, and verifiable identity.
MCP Apps: the UI that is not a dashboard
Then there is MCP Apps (SEP-1865), the part that triggers the double take.
MCP Apps lets a server deliver an interactive interface to a host.
A tool declares a UI resource through the ui:// URI scheme and references it in metadata.
The host fetches that resource, renders it in a sandboxed iframe, and the rendered UI talks back to the host over the same JSON-RPC base protocol used everywhere else in MCP.
The initial content type is HTML, tagged text/html;profile=mcp-app.
It is an optional, backwards-compatible extension, negotiated between client and server, authored by Ido Salomon, Liad Yosef, and Olivier Chafik, and shaped by the MCP-UI project and OpenAI’s Apps SDK.
On the surface: a server is shipping a screen again. Look at the mechanics and the story inverts.
The UI is a predeclared resource, not something the server pushes into a tool result at runtime. The host can prefetch it, cache it, and security-review the HTML before anything renders. Every action the UI takes goes back through JSON-RPC, so a button click inside an MCP App is the same auditable, consent-gated tool call as a request made with no UI at all. The interface does not get privileged access to the system. It is sandboxed, and it is subject to the same policy as any other agent action.
That is not a dashboard. A dashboard is the primary surface, the thing a human logs into, the place where the real controls live. An MCP App is a rendering the backend offers for a specific tool, that the host may or may not show, running under tighter constraints than the tool itself. The control plane stayed in the protocol. The pixels are optional.
Does the MCP 2026-07-28 spec mean UI is back?
No. The MCP 2026-07-28 spec lets a server declare an interface, but that interface is a sandboxed, predeclared resource with no authority beyond the tool call behind it. The human-facing screen is now an optional representation the agent chooses to render, not the system of record it used to be. UI became a feature of the protocol, not the product.
The distinction decides how you build. If UI is the product, you design the screens first and expose an API for whatever leaks out. If UI is a representation, you design the tools and their identity first, and render a screen only when a human happens to be in the loop. The 2026-07-28 spec makes the second approach the default path, and the first approach the one you have to work against the grain to keep.
Why this confirms the headless thesis instead of breaking it
Here is the reframe.
The headless argument was never that humans would stop looking at things. It was that the interface would stop being the product, and the API would become the product. UI as an optional, thin layer over a backend that machines drive directly. MCP Apps is that sentence turned into a specification.
Consider what a UI resource is in this model.
It is content addressed by a URI, declared alongside a tool, fetched on demand, and rendered in a constrained frame.
That is an API response.
It has a content type, it is cacheable with a ttlMs, and it carries no authority the underlying tool call did not already have.
The same backend that answers a machine with structured JSON can answer a human-facing host with HTML, from the same tool, governed by the same identity and the same audit trail.
This is the inversion we keep tracking. For thirty years the UI was the system and the API was the integration afterthought bolted on for the few callers who needed it. MCP flips the ordering. The tool call is the system. The interface is one optional representation of a tool call, negotiated as a capability, and stripped of the special status it used to hold.
The people who built MCP Apps understood this, which is why the design fights so hard to keep the UI from becoming a backdoor. Predeclared templates so the host can inspect them. Sandboxed iframes so the UI cannot reach past its frame. JSON-RPC for every message so nothing the UI does escapes the log. Explicit consent for UI-initiated tool calls. Those are not the constraints you put on a product surface. They are the constraints you put on an untrusted attachment to an API.
The protocol is the product surface now
Put the two halves together and the direction is unambiguous.
The stateless core, the routable headers, and the OAuth 2.1 resource-server model are the protocol becoming better infrastructure for machines. MCP Apps is the protocol absorbing the interface as just another thing it can return. Both moves point the same way: the value, the identity, the audit trail, and the control all live at the protocol layer, and everything else is a representation.
This is why the framing of MCP as a two-layer stack matters more, not less, after this release.
We argued in the agent protocol stack that MCP and A2A stopped competing and became the headless interface for machine-consumed software.
The 2026-07-28 spec hardens the bottom layer of that stack into something you can run at scale, secure with standard identity primitives, and observe with W3C trace context carried in _meta (SEP-414).
The Tasks extension (SEP-2663) reshapes long-running work around the same stateless model, with tools/call returning a task handle that the client drives through tasks/get, tasks/update, and tasks/cancel.
A protocol does not get a task lifecycle and a trace format because it expects humans to babysit it.
It gets them because it expects to be the substrate that other software, and the agent control plane above it, runs on.
If you are designing systems today, the instruction that falls out of this is direct. Build the backend as a set of tools with real identity and a clean audit path, and treat every interface, human or machine, as a representation of those tools. Do not build a UI and expose an API for the parts that leaked out. Build the protocol surface, and let the UI be a resource you declare when a human happens to be watching.
What breaks when you migrate
The stateless turn is not free, and the spec is honest about the cost.
Three capabilities are deprecated on a twelve-month minimum lifecycle (SEP-2577): Roots, Sampling, and Logging.
The schema moves to full JSON Schema 2020-12 (SEP-2106), so tool definitions that relied on older draft quirks need revalidation.
The missing-resource error code changes from -32002 to -32602 (SEP-2164), which will break any client that string-matched the old number.
List and resource responses gain ttlMs and cacheScope fields (SEP-2549), so caching becomes an explicit contract instead of a guess.
None of this is cosmetic, and that is the point. Removing sessions, deprecating connection-scoped features, and forcing explicit cache and identity contracts are what it takes to turn a stateful, human-shaped protocol into a stateless, machine-shaped one. The migration cost is the bill for building an interface that assumed a person on the other end. Paying it down is the same work as going headless: you stop designing for a held-open human session and start designing for any machine, on any instance, at any time.
What to watch next
Two things will tell you whether this direction holds.
The first is adoption of the stateless model in production gateways. Removing sessions is easy to write in a spec and harder to migrate to when your existing MCP deployment assumed sticky routing. Watch whether the API gateway vendors that already support MCP ship the routable-header path, because that is the signal that the stateless design is real and not aspirational. The 4sysops breakdown of the routable-header changes is a good map of what has to move.
The second is what servers do with MCP Apps. If servers use it to ship thin, tool-scoped renderings, the headless reading is confirmed: UI as a representation. If servers try to smuggle whole applications back in through external iframes and turn the host into a browser, the tension becomes real, and the sandbox and consent model will be tested hard. The MCP vendors most exposed to that pressure are the ones with the largest existing UI surface, and you can track their agent-readiness the same way we track everyone else in The Headless Index.
The short version is the one worth remembering. MCP shipped a UI, and it stayed headless, because the UI it shipped is an API response. The interface did not come back. It got demoted to a resource.