Newssoftware7 min read
MCP Apps put a real interface in the chat, and both ends have to opt in
Ahmad JSep 13, 2026Updated Sep 15, 2026

An MCP server used to be able to return text, images, structured data and file-like resources. The host would display them as part of the conversation and that was the end of its influence over your screen. An extension to the protocol, MCP Apps, changes that. In the documentation's words:
MCP Apps "let servers return interactive HTML interfaces (data visualizations, forms, dashboards) that render directly in the chat".
That is a bigger change than it sounds, and it comes with a restriction that is easy to miss and expensive to discover late. Client support is only half of what you need.
Everything below is read off two pages of the Model Context Protocol documentation, the MCP Apps overview and the extension support matrix, as they stood on 13 September 2026. Extension support moves, and one of those two pages says outright that it is maintained by the community, so treat the client names here as a snapshot and check the matrix itself before you plan around any of them.
If you are new to the protocol underneath this, what MCP actually does, as opposed to function calling and agent loops is the piece to read first. This one assumes it.
What the extension actually adds#
The mechanism is deliberately small. It reuses two primitives the protocol already had, rather than inventing a UI channel.
So the flow is:
Once it is on screen, the interface is not a screenshot. It talks back. The app and the host exchange JSON-RPC messages over postMessage, in what the documentation calls "its own dialect of MCP". Some of those messages are the ordinary protocol, tools/call among them. Others are new and carry a ui/ prefix. The practical effect is that the interface can call tools on the server that served it, and the host can push fresh results back into the interface without another turn of conversation.
The extension has an identifier, io.modelcontextprotocol/ui, and that identifier is the thing both ends negotiate on. Hold that thought.
What the sandbox stops#
This is the part worth reading closely if you are the one deciding whether to turn it on, because a server you do not control is now putting executable markup on a user's screen.
The documentation is specific. MCP Apps run in a sandboxed iframe, and on top of that, capability is granted rather than assumed: "The host controls which capabilities your app can access."
That design is what makes the feature shippable at all. As the overview puts it, hosts can render third-party apps "without trusting the server author completely".
It is worth being clear about what this does and does not protect you from. The sandbox is an answer to a malicious or careless app reaching out of its box. It is not an answer to a malicious instruction reaching the model. Those are different problems with different fixes, and prompt injection remains the one that the iframe boundary does nothing about. A server that can draw a convincing interface is a server that can draw a convincing lie, and the sandbox is indifferent to the content of what it renders.
Who renders it#
Two pages of the documentation answer this, and they are a different page and a different question.
The half that is easy to miss#
Here is the sentence that changes how you should read every client list above. From the matrix page:
"Extensions are always opt-in: a client only uses an extension if both client and server declare support in the
extensionsfield of their capabilities."
Both. A client that supports MCP Apps will not render your interface because it can. It renders it because your server said, in its capabilities, that it speaks this extension, and the client said the same, and the two matched. Miss that and your carefully built UI resource is an unused file on a server, and the failure is silent, because a host that never negotiated the extension has no reason to report that it did not use one.
The negotiation itself is unglamorous and worth knowing. A client declares its extensions in the extensions field of the io.modelcontextprotocol/clientCapabilities it sends in the _meta of each request, and reads the server's extensions from the server's server/discover response.
The reason this matters beyond a debugging session is that it makes "supported" a two-sided word in a market that keeps publishing one-sided tables. Every extension support list you will read, this one included, describes one end of a handshake.
When it earns its complexity#
The documentation is unusually direct about when not to use this.
"If your use case doesn't benefit from these properties, a regular web app might be simpler."
The properties it means are the ones a link cannot give you.
The cases it suggests are the ones where text genuinely runs out: exploring data you want to click into rather than read, configuring something with a dozen interdependent options that would otherwise be a dozen conversational turns, and viewing media that a description cannot substitute for.
If you are building agents or picking up an assistant that speaks MCP, the thing to take from this is narrow and practical. The interface is now a first-class thing a server can return. Whether a user ever sees it is decided by a capability match, at connection time, at both ends.
Sources
- MCP Apps, Model Context Protocol documentationmodelcontextprotocol.io
- Extension Support Matrix, Model Context Protocol documentationmodelcontextprotocol.io



Discussion