Skip to main content

MCP Grew a UI Layer: The First Official Extension Renders Apps in Your Chat

· 5 min read
TheMCPGuy
MCP Developer & Educator

A chat window containing an interactive revenue widget rendered inside a sandboxed iframe, with an Export button that triggers a tool call

For its entire life, MCP has spoken in text. Tools return strings and JSON; the model narrates the result back to you in prose. That was a deliberate, sensible constraint, and it was always going to hit a ceiling. Some answers are a paragraph. Others are a chart, a date picker, a seat map, a diff you want to click.

As of early 2026, MCP has an answer: MCP Apps, the protocol's first official extension, which lets a tool ship interactive UI that renders right inside the conversation.

Version disclosure (as of June 2026)

MCP Apps is specified in SEP-1865, stabilized 2026-01-26, and developed collaboratively with the MCP-UI community and maintainers from OpenAI and Anthropic. It targets the MCP spec 2025-11-25. The official SDK published in the ext-apps repo is TypeScript/JavaScript (@modelcontextprotocol/ext-apps); OpenAI's Apps SDK is built on the same MCP Apps foundation. Note the SDK language situation below; it matters if, like us, you live in the Java world.

The text-only ceiling

You have felt this. You ask an agent for "revenue by region this quarter" and get back a tidy ASCII-ish table that you immediately want to sort, filter, or export. The model has the data; the channel just can't render anything you can interact with. Every rich interaction had to bounce out to a separate app.

MCP Apps closes that gap without abandoning the protocol's safety model.

What MCP Apps actually is

It is not a new transport or a new primitive grab-bag. It is a focused extension built on two pieces you already know, resources and tools:

  • A tool can advertise a UI resource via _meta.ui.resourceUri. That resource is HTML, served with the MIME type text/html;profile=mcp-app.
  • The host renders that HTML inside a sandboxed iframe, isolated from the page, the model, and your other tools.
  • The iframe talks back to the host over JSON-RPC sent across postMessage, brokered by the App SDK.

So a tool result is no longer just text. It can be "here is the data, and here is a sandboxed widget to render it."

The first question a security-minded engineer asks is "so a server can now run arbitrary UI in my client?" The reassuring answer: the widget is sandboxed, and actions still flow through the same tool-call consent path you already trust.

When a user clicks "Export" in the widget, the iframe doesn't get to quietly do something. It sends a JSON-RPC message that becomes a tool call, and that tool call goes through the host's normal approval flow, the same gate that governs every other tool invocation. The UI is new; the trust boundary is not.

Write once, render across hosts

The reason this is a big deal and not just a vendor feature: it is a shared extension, and the early host list is broad, with Claude, ChatGPT, VS Code, Goose, Postman, and MCPJam among the documented adopters. An MCP App you build is meant to render across compliant hosts rather than being locked to one assistant. That cross-host portability is exactly what made base MCP win, now applied to UI.

What this means if you build MCP servers

  • Your reach just expanded from "return good text" to "return a usable interface" (pickers, dashboards, confirmations, forms) without shipping a separate frontend app.
  • The widget is HTML/JS, by design. It renders in a browser iframe, so the UI layer is web tech regardless of what your server is written in.
  • For the Java crowd (us included): there is real nuance here. You can absolutely serve an MCP App from a Java server by exposing the ui resource and wiring the tool's _meta.ui.resourceUri through the Java SDK. But the widget itself is HTML/JS, and the official App SDK published in the ext-apps repo today is TypeScript/JavaScript. So the honest framing is: Java server, web widget. Don't expect to write the UI in Java.

The bottom line

MCP Apps is the protocol admitting that some answers aren't sentences. It does it the right way, by building on resources and tools, sandboxing the UI, and keeping every action on the existing consent rails. If you've been treating MCP as a backend-only concern, this is the moment it became a product-surface concern too.

We're building a full Building MCP Apps course around this: the ui resource, the iframe security model, the postMessage/App SDK bridge, the consent path, and a widget built end-to-end (served from a Java MCP server, with an honest accounting of where the web layer begins).