The first official MCP extension · stable 2026-01-26

MCP Apps

MCP Apps (SEP-1865) let a tool return an interactive HTML interface instead of a wall of JSON. The UI is a ui:// resource the host renders in a sandboxed iframe. It is new, it is spreading fast, and almost nobody is checking these apps for safety yet. That is the gap Sigistry fills.

Already renders in
ClaudeChatGPTVS CodeGoosePostman

How an MCP App works

1

Declare a UI resource

The server registers an interface as a resource under the ui:// scheme with mimeType text/html;profile=mcp-app. Pre-declaring it lets the host fetch and review the template before anything runs.

2

Link it to a tool

A tool points at its UI through _meta.ui.resourceUri. The tool still returns a normal content array, so hosts that have not adopted the extension degrade to text.

3

Render in a sandboxed iframe

The host renders the HTML in a sandboxed iframe and builds the CSP from the domains the server declared. Undeclared origins are blocked, even if the server asks for them.

4

Talk back over JSON-RPC

The UI and host exchange MCP JSON-RPC messages over postMessage: tool input, tool result, display-mode and size changes. Every message is auditable, and tool-initiated calls can require user consent.

Why safety is the hard part

MCP Apps bring a classic web attack surface into the agent. The host gives you a sandbox and a CSP; everything else is on the app author. These are the failure modes the sandbox will not catch for you.

The sandbox is the floor, not the ceiling

A sandboxed iframe limits what the app can reach. It does not stop your own code from mishandling data. Your app renders tool output and host messages; route any of it through innerHTML or eval and you have a stored-XSS path inside an interface layered over the user's files and other servers.

The CSP is only as tight as your declarations

Hosts construct the Content Security Policy from the domains in your resource metadata and must not loosen it. A wildcard connect origin, or a fetch to a domain you forgot to declare, either defeats the policy or breaks at runtime.

Secrets in the HTML are secrets in the clear

The UI resource ships to every client and is visible in the host. Any key, token, or credential baked into that HTML is exposed. Keys stay server-side, behind a tool call.

Untrusted messages are untrusted input

A message listener with no origin check trusts whatever arrives. Validate the sender, or let the MCP SDK transport handle the framing so you are not hand-rolling the security boundary.

Check your app before you ship it

The MCP App Safety Checker runs this split of checks against your ui:// resource and its metadata, free and entirely in your browser. Spec conformance: the scheme, the exact mimeType, the tool-to-UI link, a text fallback, and whether your external origins are declared in the CSP. Security hygiene: unsafe DOM sinks, embedded secrets, host-message handling, and remote scripts.

Open the checker

Where this fits with Sigistry

  • The app, checked. An MCP App is HTML plus tool metadata. The safety checker grades that surface against the spec and for the security the sandbox does not provide.
  • The server behind it, graded. An MCP App is still served by an MCP server. The MCP scorecards grade that server against the 2026-07-28 spec: transport, stateless core, lifecycle, authorization, tool design, and security hygiene.
  • The plugin that ships it, verified. If the app rides inside a Claude Code plugin, the same eight-check verification that gates every listed plugin applies to it.

Build on the spec

Primary sources, not a tutorial. Read these before you ship.