Verdict: MCP Apps — the first official extension to the Model Context Protocol, finalized on January 26, 2026 — let any MCP server return a live, interactive HTML interface (a dashboard, a form, a 3D map, a multi-step checkout) that renders inside the AI conversation itself, in a sandboxed iframe, and talks back to the host over JSON-RPC. If you build tools for people who use Claude, ChatGPT, VS Code, or Goose, this is the single spec that means "write once, run in every assistant." The architectural bet it makes is bigger than the feature: that the next surface for software is not a browser tab or an app store, but a chunk of branded UI an AI assistant composes for you, on the fly, from atoms.
Last verified: 2026-08-03 · Volatile facts: client list, partner list, spec version (the spec is live but the working group meets tri-weekly, so names and capabilities shift).
TL;DR
- MCP Apps = official MCP extension (SEP-1865); tools declare a
ui://resource and the host renders it in a sandboxed iframe.- Live on Claude, Claude Desktop, ChatGPT, VS Code (GitHub Copilot), Microsoft 365 Copilot, Goose, Postman, MCPJam as of mid-2026 (modelcontextprotocol.io).
- 9 day-one launch partners shipped apps on January 26, 2026: Amplitude, Asana, Box, Canva, Clay, Figma, Hex, monday.com, Slack (MCP blog).
- Build with the
@modelcontextprotocol/ext-appsSDK; React, Vue, Svelte, Solid, Preact, or vanilla JS all work.- It is not the same as Claude Artifacts: Artifacts are static pages the model generates; MCP Apps serve live data from your server and can call back to your tools.
What are MCP Apps, and why does the protocol exist?
MCP Apps are the standardized way for an MCP server to send a rich, interactive user interface — not just text — into an MCP-compatible chat host, where the user can click, filter, fill a form, and trigger follow-up actions without leaving the conversation. The spec is published as SEP-1865 under the io.modelcontextprotocol/ui extension identifier, and the canonical repo + SDK live at github.com/modelcontextprotocol/ext-apps.
The motivation is concrete. Before this extension, MCP tools returned text. That is fine when the answer is a sentence. It falls apart the moment the answer is a funnel chart you want to filter by region, a 3D model you want to rotate, or a checkout flow with a payment form. As the MCP blog puts it: "MCP is great for connecting models to data and giving them the ability to take actions. But there's still a context gap between what tools can do and what users can see" (MCP Apps announcement). MCP Apps closes that gap by letting the model stay in the loop while the user gets a real UI — branded by your company, served by your server, rendered by the host.
The deeper reason, though, is about identity and distribution. Companies that built MCP servers in 2024–2025 had a real complaint: "we spent years on our UX, and now our product is reduced to a wall of text inside someone else's chat." (If you have already connected a tool server to an AI agent — see how to connect Higgsfield MCP to an AI agent for automated video and image generation for the pattern — you have felt this exact gap.) MCP Apps lets you ship your brand's visual identity into the place users already are, instead of forcing users to context-switch to your website. That trade — come to where the user is, keep your identity — is what makes this more than a rendering trick.
How does an MCP App actually work under the hood?
An MCP App combines two existing MCP primitives in a new, standardized way: a tool and a UI resource. The execution flow, as documented in the official overview and the specification, is:
- You send a message — e.g., "show me this month's analytics."
- The model calls your tool — standard
tools/callover JSON-RPC. Your tool's definition carries a_meta.ui.resourceUrifield pointing at aui://resource. - The server returns the UI resource — the host fetches the
ui://resource, which is a bundled HTML/JavaScript/CSS payload (MIME typetext/html;profile=mcp-app). - The host renders it in a sandboxed iframe — the iframe cannot touch the parent page's DOM, cookies, or localStorage. All communication goes through
postMessagecarrying JSON-RPC messages. - The user interacts — clicking a chart, filtering a table, or submitting a form sends a JSON-RPC message back up to the host.
- The host decides what happens next — the host can forward a
tools/callrequest back to your MCP server for fresh data, push the new result down to the iframe (ui/notifications/tool-result), update the model's context, or log a message. The model stays in the loop the whole time.
The bidirectional channel is the part that separates MCP Apps from a static embed. The iframe can call four message types back to the host:
| Direction | Method | What it does |
|---|---|---|
| View → Host | tools/call |
App asks the host to run a tool on the MCP server (the host proxying keeps consent + audit with the host) |
| View → Host | ui/message |
App sends a message that can trigger the model to follow up |
| View → Host | ui/update-model-context |
App updates what the model "knows" for the next turn |
| View → Host | resources/read |
App reads another resource from the server through the host |
| Host → View | ui/notifications/tool-input / tool-result |
Host streams fresh tool data back into the app |
(specification: bidirectional communication)
The host — not the app — is the one that ends up calling the MCP server, which is the whole point: the host keeps the consent, audit, and security boundary. Your iframe never holds the user's credentials; the host proxies every privileged call. Apps that push UI into the host also accept that they no longer "own" the user's journey — the host does. That is the trade for being allowed to render inside the conversation at all.
How do you build your first MCP App?
The minimum viable MCP App, using the official @modelcontextprotocol/ext-apps SDK and the @modelcontextprotocol/sdk server package, is short. The shape below is adapted from the ext-apps quickstart and the SDK README.
Step 1 — Install the SDKs.
npm install -S @modelcontextprotocol/sdk @modelcontextprotocol/ext-apps
Step 2 — Register a UI resource on your MCP server.
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({
name: "my-analytics-server",
version: "1.0.0",
});
// The UI payload — a self-contained HTML string with your JS/CSS inlined.
// In real code you bundle this from a React/Vue/Svelte build step.
const dashboardHtml = `<!doctype html><html><body>
<div id="root"></div>
<script type="module">
import { App } from "@modelcontextprotocol/ext-apps";
const app = new App();
await app.connect();
app.ontoolresult = (result) => {
// Render the tool result into your UI
document.getElementById("root").innerText = JSON.stringify(result.data);
};
</script>
</body></html>`;
server.resource("dashboard-ui", "ui://dashboard", async (uri) => ({
contents: [{ uri: uri.href, mimeType: "text/html", text: dashboardHtml }],
}));
Step 3 — Wire a tool to the UI with _meta.ui.resourceUri.
server.tool(
"show_dashboard",
"Show an interactive analytics dashboard",
{ month: z.string() },
async ({ month }) => ({
content: [{ type: "text", text: `Dashboard data for ${month}` }],
// This is what binds the tool's result to a live UI:
_meta: { ui: { resourceUri: "ui://dashboard" } },
}),
);
Step 4 — On the UI side, use the App class to receive data and call back.
import { App } from "@modelcontextprotocol/ext-apps";
const app = new App();
await app.connect();
// Host pushes tool results into your UI:
app.ontoolresult = (result) => renderChart(result.structuredContent);
// Your UI calls back to the server through the host:
const fresh = await app.callServerTool({
name: "fetch_details",
arguments: { id: "123" },
});
// Update what the model knows for the next turn:
await app.updateModelContext({
content: [{ type: "text", text: "User drilled into the Q1 cohort" }],
});
Step 5 — Pick your framework and test locally. The SDK ships starter templates for React, Vue, Svelte, Preact, Solid, and vanilla JavaScript; the server side is identical across all of them. The repo's examples/basic-host directory has a minimal host you can run locally so you do not need to tunnel into Claude just to debug your iframe. Real examples in the repo include a CesiumJS interactive globe, a Three.js 3D server, and a shader playground. For a wider tour of the agent tools landscape this ecosystem sits inside, the 13 best free AI agent tools roundup covers the hosts and stacks worth knowing; the ext-apps SDK slots into most of them.
The five-step minimum hides one important contract: everything the iframe needs must be inlined or allow-listed. External scripts have to be declared in _meta.ui.csp; capabilities like camera or microphone have to be requested in _meta.ui.permissions. The host reviews this metadata before it ever renders your UI. There is no "just fetch a CDN at runtime" escape hatch — that is the security trade.
MCP Apps vs. Claude Artifacts vs. Google A2UI — which is which?
There are three "interactive UI inside an AI" approaches shipping in 2026, and the differences are not cosmetic. They decide how much control you keep, where the data lives, and who has to trust whom.
| MCP Apps (SEP-1865) | Claude Artifacts (incl. connector-backed) | Google A2UI | |
|---|---|---|---|
| Where the UI comes from | Your MCP server returns bundled HTML/JS | The model generates an HTML page in the conversation | Your server returns a declarative JSON blueprint |
| Where the data comes from | Live, from your server, via tools/call through the host |
Static at publish time, unless connector-backed (live via claude.ai connectors, Pro+ only) | Rendered by the host's native widgets (Flutter, SwiftUI, React) |
| Who renders | The host, in a sandboxed iframe | Claude's artifact renderer (also sandboxed, strict CSP, 16 MiB cap) | The host, with native components that inherit its theme |
| Cross-host portability | Write once, run in any MCP-compatible host | Claude-only | Host must implement A2UI; meaningful overlap with Gemini |
| Best for | Dashboards, forms, multi-step workflows on your live data | Self-contained reports / demos / one-off pages | Apps that should feel native to the host (themed, accessible) |
| Trade-off | iframe visual disconnect from host styling; the host owns the journey | Static (or live-but-Claude-locked); 16 MiB cap; no arbitrary backend calls except declared connectors | Limited to the host's component vocabulary — no arbitrary HTML |
Sources: MCP Apps spec (ext-apps repo); Claude Artifacts + connector behavior (Anthropic docs and explainx.ai analysis); A2UI declaration shape (paperclipped.de comparison).
The practical read: MCP Apps is the only one of the three that is portable across assistants by design. An Artifact is a deliverable Claude produces for you; an A2UI blueprint is a description Gemini renders; an MCP App is a thing you ship, that runs in Claude and ChatGPT and VS Code with the same code. If your goal is "let my customers use my tool from inside whichever AI they already pay for," MCP Apps is the spec, and the other two are either the model's output format or a competing host's standard.
Which AI clients and partners actually support MCP Apps today?
As of mid-2026, MCP Apps is supported as a host (i.e., the host renders the iframe and proxies tool calls) by:
- Claude (claude.ai web + Claude Desktop) — available at GA launch
- ChatGPT — rolling out from launch week; OpenAI recommends MCP Apps as the protocol for building ChatGPT apps (OpenAI Apps SDK)
- VS Code with GitHub Copilot — VS Code Insiders channel
- Microsoft 365 Copilot — landed April 2026 with Outlook, Power Apps, Adobe Express, Coursera, Figma, and monday.com partner experiences (Microsoft 365 Dev Blog)
- Goose (by Block) — the first client to support the predecessor MCP-UI, and an early MCP Apps host (goose blog, Jan 6 2026)
- Postman, MCPJam, and Archestra.AI — community and enterprise hosts
The nine day-one launch partners (Jan 26, 2026) that shipped MCP App experiences are: Amplitude, Asana, Box, Canva, Clay, Figma, Hex, monday.com, and Slack, with Salesforce arriving shortly after on the Microsoft 365 Copilot surface (MCP blog, byteiota analysis). A wider set of companies — Shopify, Hugging Face, Postman, ElevenLabs, and PostHog among them — were early adopters of the community MCP-UI spec that MCP Apps built on top of; their work is what proved the pattern before the official extension shipped.
The spec itself lives in two places worth bookmarking: the ext-apps repo (the SDK + spec), and the SEP-1865 proposal page. An open working group in the MCP steering committee meets tri-weekly; the spec is live but explicitly extensible, and the team calls out reusable views, "view tools" (host → app direction), and interoperability with A2UI as the active work.
Is the MCP Apps security model actually safe enough to ship?
The security model is the part most teams under-invest in reading before they ship, and it is where the spec is most prescriptive. MCP Apps mandates four mitigations, all documented in the spec's Security Implications section and summarized on the SEP-1865 page:
- Mandatory iframe sandboxing. All UI content runs in a sandboxed iframe with restricted permissions. It cannot reach the parent window's DOM, cookies, localStorage, or navigation. This is why the spec chose predeclared HTML resources over inline embedding — the host can review the HTML before it ever renders.
- Predeclared resources, not inline blobs. Tools reference
ui://resources by URI; the host fetches and reviews the HTML before rendering. There is no "the model just sentiment-executed an arbitrary script" path. - Auditable JSON-RPC over
postMessage. Every UI → host message goes through a loggable JSON-RPC dialect of MCP. Nothing happens behind a function call inside the iframe; every action is a message the host can record, rate-limit, or refuse. - User consent for UI-initiated tool calls. Hosts can require explicit approval before a UI click turns into a privileged
tools/callagainst your MCP server. The host — not the app — owns the permission boundary.
What the spec does not do for you: it does not vet your MCP server, it does not provide a sandbox escape hatch for capability-stretching, and it does not stop you from shipping a sloppy server that leaks data through its own endpoints. The sandbox stops the iframe from reaching the host; it does not stop the server behind the iframe from being malicious. The MCP blog's own note is explicit: "Users should continue to thoroughly vet MCP servers before connecting them."
For a small business shipping its first MCP App, the honest guidance is: start with read-only tools, declare every external origin in csp, and never accept the iframe's claim about who the user is — always re-check through a host-proxied tools/call. Treat the iframe like a public web page you do not fully control, because that is what it is.
What is the "agentic web," and why does this spec matter beyond a feature?
Here is the original framing worth borrowing from. The argument for MCP Apps is not just "interactive widgets in chat are nicer than text." It is that the unit of software is changing.
Up to now, the web has been organized around tabs — full applications you visit in a browser. Each app has to convey your intent to it through its own UI, and 99% of that UI is built for an anonymous user who knows nothing about. To plan an anniversary today, you open 20 tabs and re-state your intent to each one: the calendar, the booking site, the gift shop, the map. Every service is a walled garden trying to own "your" journey.
The bet MCP Apps makes is that this is temporary. The thesis, sketched in the original MCP-UI work by Ido Salomon and Liad Yosef and carried into the official spec, is that those full apps break into atoms — small, branded UI chunks a personal AI assistant composes for you, in context, because it knows you. A Google Calendar atom shows your next anniversary. A Booking.com atom shows a map of hotels near the restaurant. An Amazon atom shows a gift card flow. You do not leave the assistant. Each company keeps its identity (you can see the Google branding inside the calendar atom) but loses full control of the journey, because the host — your assistant — now decides what to call next and writes every action to an auditable transcript.
That framing — we are entering an interactive web where websites surface as UI atoms inside personal assistants, and a single protocol lets any company ship into any assistant — is why MCP Apps matters even if you never build one. The "AI that acts, not just answers" trajectory is already visible elsewhere in the stack — the contrast between Large Action Models and LLMs shows why a model that can Do Things needs an interface that lets the human stay in control of what those things are. MCP Apps is the UI half of that shift: an "agentic web" needs a way for the agent to show you what it just did, branded, interactive, and reversible.
What this means for you
If you build tools people use at work, three moves are worth making now:
- If you already run an MCP server, add a UI resource to your most-asked-for tool this quarter. The lift is small (one
ui://resource, one_meta.ui.resourceUrifield) and the payoff is that users stop coping with text dumps. Pick a tool that returns data people want to filter or drill into — that is where text fails hardest and an MCP App wins most. If you want a worked pattern for what an "agent that ships a tool on demand" looks like end-to-end, the build-an-agent-OS-that-ships-any-AI-tool-you-ask-for guide covers the loop from request to runnable tool; adding aui://resource is the natural next layer once that loop runs. - If you are choosing a UI approach for an AI feature, prefer MCP Apps over a vendor-locked widget. The whole spec is built so the same app renders in Claude, ChatGPT, and VS Code. A Claude-only Artifact or a ChatGPT-only connector buys you speed now and a rewrite later; an MCP App buys you portability and a vote in the spec's future. The same logic that makes plugging a new LLM into any agent framework worth doing applies here — the moment the integration layer converges on a standard, betting against it is paying for the rewrite twice.
- If you are an end user, expect your assistants to start showing you branded apps inline. Not as a gimmick — as the default. When you ask Claude for "this month's signups," the future answer is an Amplitude funnel you can click into, not a paragraph. Knowing this is how the agentic layer works helps you ask for it (and call out the tools that still answer in walls of text).
The honest caveat: MCP Apps shipped its first production cut in January 2026, and the spec is still being extended (reusable views, host → app "view tools," and A2UI interop are all in flight). What is live today is real and shipped; what is coming is not. Build for the spec that exists, and keep an eye on the ext-apps repo for the next cut.
FAQ
Q: Are MCP Apps the same as MCP tools?
A: No. MCP tools return text or structured data; MCP Apps are an extension on top of MCP that lets a tool also declare a ui:// resource the host renders as an interactive HTML iframe. Every MCP App is served by an MCP server, but not every MCP tool is an MCP App.
Q: Do MCP Apps work in Claude and ChatGPT with the same code?
A: Yes, that is the headline benefit. The _meta.ui.resourceUri binding is part of the MCP wire format, so an app built once against the spec renders in any MCP-compliant host — Claude, ChatGPT, VS Code, Goose, Postman, and MCPJam as of mid-2026. Host-specific rendering differences exist (styling, CSP enforcement), but the protocol layer is shared.
Q: What is the difference between MCP Apps and Claude Artifacts?
A: Artifacts are HTML pages the model generates in the conversation; they are static at publish time unless connector-backed (live via claude.ai connectors, Pro+ plans only, and Claude-locked). MCP Apps are served by your MCP server, pull live data through host-proxied tools/call, and run in any MCP-compatible host — not just Claude.
Q: Is the MCP Apps SDK free, and which frameworks does it support?
A: The @modelcontextprotocol/ext-apps SDK is open-source under the Linux Foundation-hosted MCP project. Framework starter templates ship for React, Vue, Svelte, Preact, Solid, and vanilla JavaScript; the server side is framework-agnostic.
Q: Are MCP Apps production-ready? A: The first production cut shipped January 26, 2026, with nine launch partners going live the same day. The spec is live (Final track, SEP-1865), but the working group meets tri-weekly and is actively working on reusable views, host → app "view tools," and A2UI interoperability. Build for what is in the spec today, and check the ext-apps repo before you ship anything that depends on a draft capability.
Q: How is MCP Apps secured against a malicious MCP server?
A: Four layers: mandatory iframe sandboxing (no access to parent DOM/cookies/localStorage), predeclared HTML resources (host reviews before rendering), auditable JSON-RPC over postMessage (every UI → host message is loggable), and user-consent gates for UI-initiated tool calls. The sandbox stops the iframe; it does not vet your server — so users must still vet MCP servers before connecting them.

Discussion
0 comments