Handbooks  /  MCP Apps
Handbook~13 min readMCPworked protocol + runnable code
Handbook

MCP
apps.

Assistants have mostly spoken in text. MCP Apps change that: a tool can now render a real interactive UI — a form, a chart, a booking widget — right inside Claude or ChatGPT. But an interactive surface shipped by a third party, running inside your trusted assistant, is a security problem wearing a friendly face. The answer is an old, well-understood pattern: put it in a sandboxed iframe, and make every request it wants to send cross a single bridge the host controls.

01

UI, not just text

An MCP server gives a model tools and data. An MCP App adds the missing layer: a rendered, interactive UI the human sees and clicks, displayed by the host assistant. Reported as the first official UI extension to the Model Context Protocol — with cross-vendor backing and day-one partners — it lets a tool return a control panel instead of a paragraph.

That's a genuine capability jump, and a genuine trust problem. The UI is third-party code you didn't write, running inside an app that holds the user's conversation, credentials, and context. You can't just drop it into the page. Everything about how MCP Apps are built is shaped by that one fact — the UI is untrusted, and the host is not.

02

The sandbox: a locked room with one door

MCP App UIs render in a sandboxed iframe. By construction, a sandboxed iframe cannot reach into the host page's DOM, read its storage, or make network calls on the host's behalf. It's isolated — a locked room. The only way anything gets in or out is a message channel the host explicitly wires up.

Untrusted UI, isolated — one monitored door out
Host (trusted)
conversation, creds
postMessage bridge
the ONLY door
Sandboxed iframe
3rd-party UI (untrusted)

This is sandboxing applied to UI: assume the code inside is hostile, give it no ambient authority, and force every request through a single, inspectable channel. The isolation isn't a nice-to-have — it's the entire reason it's safe to render someone else's UI inside your assistant.

03

The bridge speaks JSON-RPC

The door between iframe and host is postMessage, and the language spoken across it is JSON-RPC — the same structured request/response protocol MCP itself uses. The iframe posts a message naming a method and params with an id; the host posts back a response carrying the same id and either a result or an error.

iframe → host: { "jsonrpc":"2.0", "id":7, "method":"getWeather", "params":{…} }
host → iframe: { "jsonrpc":"2.0", "id":7, "result":{…} } // same id

Structured, typed, correlated by id. Nothing free-form crosses the boundary — just named method calls the host knows how to reason about.

Using a real RPC protocol rather than ad-hoc messages is what makes the boundary auditable. The host isn't parsing arbitrary strings from untrusted code; it's receiving discrete, named requests it can accept or reject one at a time.

04

The host mediates every request

Here's where the security actually lives. The host doesn't execute whatever the iframe asks — it checks each method against an allowlist of capabilities it has chosen to expose. Method on the list? Execute and return a result. Method not on the list? Return an error and do nothing. The iframe cannot reach a capability the host didn't deliberately hand it, because the sandbox gives it no other path.

host_handle(req): method ∈ allowlist ? execute → result : error(−32601)

Least privilege at the UI boundary: the app gets exactly the capabilities the host exposes, and a request for anything else — including host internals — is refused by default.

The key idea

Sandbox + bridge + allowlist is the whole model. The sandbox removes ambient authority; the JSON-RPC bridge makes every request explicit; the allowlist decides which requests are honored. An MCP App is powerful because it can ask the host to do things — and safe because the host, not the app, decides what "things" means.

The runnable host below is that mediator: it round-trips an allowlisted call, refuses everything else with a structured error, and shows that even a host-internal method name can't be reached through the bridge.

05

Why it matters

MCP Apps turn assistants from text terminals into UI platforms — a big deal for what tools can do, and a reminder that every new capability surface is a new trust boundary. The pattern here is the reassuring part: it's the same sandbox-and-mediate model browsers have used for embedded content for years, ported to the AI-assistant context. Nothing exotic, which is exactly why it's trustworthy.

It also sharpens the map of the MCP world. The MCP server is the capability backend; the MCP App is the interactive frontend; and the untrusted-component discipline from agent supply-chain security applies to both — an app you install is another dependency whose blast radius the host's allowlist is there to bound.

Read next

The protocol underneath: MCP. The isolation pattern: Sandboxing. The trust discipline: Agent Supply-Chain Security.

RUN IT YOURSELF

The host as gatekeeper: mediate every iframe request

This is the entire MCP App security model in one function. A sandboxed iframe posts JSON-RPC requests; the host handles each by checking the method against an allowlist of capabilities it chose to expose. An allowlisted call round-trips (same id, a result); anything else — including a made-up destructive method or a host-internal name — comes back as a structured error and never executes. Change the allowlist and the requests, and watch what does and doesn't get through the door.

CPython · WebAssembly
Frequently asked

Quick answers

What are MCP Apps?

Interactive UIs that render inside an assistant like Claude or ChatGPT instead of plain text — a form, chart, or control panel shipped by an MCP server and shown in a sandboxed iframe. The first official UI extension to the Model Context Protocol.

How is the app isolated?

It runs in a sandboxed iframe that can't touch the host page, its DOM, storage, or network directly. The only way out is a message channel — a locked room with a single monitored door.

How does it talk to the host?

Via postMessage carrying JSON-RPC: the iframe sends a method + params + id, the host checks the method against an allowlist, executes if permitted, and returns a response with the same id. Everything crosses this one mediated bridge.

How is it different from an MCP server?

The server is the capability backend (tools/data over JSON-RPC); the app is the interactive frontend (the UI the human clicks, sandboxed). They compose, but the app adds presentation plus a new untrusted-code boundary to mediate.

The MCP Apps Handbook · Vibe Engines · 2026 · reported protocol details from public sources · more handbooks →
Finished this one? 0 / 160 Handbooks done

Explore the topic

See this alongside everything else on the same subject — handbooks, system designs, challenges and tools, in one place.