MCP Apps Renders a Server's HTML In Your Bot. What's Actually Sandboxed?
MCP Apps is now a finalized extension that lets an MCP server attach an interactive HTML interface to a tool call, rendered inside a sandboxed iframe in your bot's host. The sandbox locks down outbound network access from that iframe by default, but it does not restrict what the linked tool itself can already do once a UI action is proxied back through your host. If you're deciding whether to turn this extension on for a small-team bot, the question isn't whether the UI is safe to look at — it's whether the tool behind it already has a permission boundary you'd accept from a text-only call.
AI-assisted editorial: researched and drafted with AI using the primary sources linked below. Examples are illustrative; they are not measured product results. Editorial policy.
Key takeaways
- MCP Apps (SEP-1865) is an optional extension, not a core protocol feature — your host and the server must negotiate it under the identifier io.modelcontextprotocol/ui before any UI renders.
- The sandbox is real but narrow: it blocks the iframe from making its own network calls by default, it does not add any new restriction on what the linked tool can do once the host proxies an action back to the server.
- Treat a UI-triggered tool call exactly like a text-triggered one — same consent gate, same scopes — because the spec routes it through the same JSON-RPC audit path, not a separate, lighter one.
What MCP Apps Actually Adds
MCP Apps is an extension to the Model Context Protocol, not a change to the core spec. It lets a server declare an HTML interface and attach it to a tool, so a bot's host can render a dashboard, form, or chart instead of a wall of text. The extension is identified as io.modelcontextprotocol/ui and must be explicitly negotiated between client and server through the extension capabilities mechanism before anything renders — a server that supports it does not force a host that doesn't into rendering HTML it can't handle.
The mechanism has two parts. A server publishes a predeclared resource using the ui:// URI scheme, with the content type fixed at text/html;profile=mcp-app, and a tool points to that resource through metadata. When the tool runs, the host fetches the declared template, places it in a sandboxed view, and the view can then talk back to the host over MCP's own JSON-RPC base protocol — the same wire format used for every other MCP message, not a separate side channel.
Sources: SEP-1865: MCP Apps - Interactive User Interfaces for MCP - Model Context Protocol, Overview.
What the Sandbox Actually Covers
The spec is specific about what gets locked down: UI content runs inside a sandboxed iframe, and the host builds that iframe's Content Security Policy out of domains the server explicitly declares ahead of time. If a server declares nothing, the default posture denies the iframe any outbound network access at all. That means a malicious or sloppy UI resource can't quietly phone home, load a remote script, or exfiltrate whatever data the tool result handed it to display — the rendered page is boxed in before it ever runs.
The other half of the design is that tools declare their UI templates ahead of time, so a host can prefetch, cache, and security-review the HTML before anything executes, rather than discovering it live. Combined with the mandatory iframe sandbox, this is what SEP-1865 calls maintaining security and auditability alongside MCP's existing architecture — the UI layer is additive, and it's built to be inspectable before a user ever sees it render.
Sources: SEP-1865: MCP Apps - Interactive User Interfaces for MCP - Model Context Protocol, ext-apps/specification/2026-01-26/apps.mdx at main · modelcontextprotocol/ext-apps · GitHub.
What Still Crosses the Boundary
Here's the part worth sitting with: the sandbox restricts what the iframe itself can reach over the network. It does not restrict what happens when the rendered UI triggers an action. The official release notes describe UI-initiated actions going through the same audit and consent path as a direct tool call, because they're carried over the same JSON-RPC protocol used everywhere else in MCP. In practice, that means a button inside the rendered dashboard that calls back into the server is not a lesser, UI-scoped action — it's the same tool call your bot would make from a plain text instruction, with whatever scope that tool already has.
So the UI doesn't add a new attack surface for the tool call itself; it adds a new attack surface for the presentation layer, which the iframe sandbox is built to contain. If the underlying tool can delete a record, approve a payment, or send an email, giving it an MCP Apps interface doesn't make those actions any safer or any more dangerous on their own — it just changes how the request for that action gets generated. The permission boundary you should be checking is the one on the tool, not the one on the iframe.
Worked example, illustrative: say a small-team bot connects to an invoicing MCP server that exposes an approve_invoice tool, now wired to a ui:// dashboard showing pending invoices with an "Approve" button in each row. The iframe sandbox stops that dashboard from leaking invoice totals to a third-party domain. It does nothing to stop the Approve button from firing approve_invoice with full write access if that's the scope the tool was given when you connected the server. If you wouldn't let the bot approve invoices from a plain-text command without a human check, wrapping the same call in a dashboard button doesn't change that answer — you still need the approval gate on the tool, independent of how the request for it got generated.
Sources: The 2026-07-28 MCP Specification Release Candidate, SEP-1865: MCP Apps - Interactive User Interfaces for MCP - Model Context Protocol.
Before You Turn This On
MCP Apps is useful the moment a tool's output is naturally visual — a cost breakdown, a capability matrix, a status board someone needs to scan rather than read line by line. It's a presentation upgrade, and the sandbox design genuinely limits what a rogue UI resource can do on its own. That's a real, checkable property: look for whether the server declares its CSP domains, and treat an undeclared policy as the safer default-deny case rather than something to relax.
What it is not is a new permission system. Before enabling an MCP Apps-capable server for a bot, check the scopes on the tools it links UI to, exactly as you would for a text-only tool. If a tool needs a human approval gate when called from a prompt, it needs the same gate when called from a dashboard button, because the spec routes both through identical consent handling. The question to answer before adoption isn't "is the UI sandboxed" — it almost certainly is. It's "would I trust this tool's scope if there were no UI at all?" If the answer is no, a nicer rendering of the same request doesn't change it.
Sources: The 2026-07-28 MCP Specification Release Candidate.
Primary sources
Sources checked 2026-10-25. Standards and product documentation can change; follow the linked version when implementing.
- SEP-1865: MCP Apps - Interactive User Interfaces for MCP - Model Context Protocol — Model Context Protocol
- Overview — Model Context Protocol
- ext-apps/specification/2026-01-26/apps.mdx at main · modelcontextprotocol/ext-apps · GitHub — Model Context Protocol
- The 2026-07-28 MCP Specification Release Candidate — Model Context Protocol
BotBento is in development. Suggest a correction.