Skip to main content
MCP Apps SDK MCP App HTML comes from an MCP server and runs inside an AI host. Treat the View as untrusted web content, treat every View request as untrusted server input, and let the Host mediate access between them. This page maps the security rules in the stable MCP Apps 2026-01-26 specification to the parts app developers control.

Trust Boundaries

The iframe prevents direct DOM access to the Host. It does not make View requests trusted and does not replace authorization on the MCP server.

Host Isolation Requirements

For web hosts, the MCP Apps specification requires an intermediate sandbox proxy on a different origin from the Host. The sandbox uses allow-scripts and allow-same-origin, loads the View with a restrictive CSP, and forwards protocol messages between the Host and View. The Host must not send requests or notifications to the View until the View finishes the ui/initialize handshake and sends ui/notifications/initialized. App authors normally do not implement this transport:
Use the SDK so message schemas, request IDs, lifecycle ordering, and protocol versions stay aligned with the specification.

Content Security Policy

The server declares the View’s external origins under _meta.ui.csp on the resource content returned by resources/read:
Omitted origins stay blocked. Hosts may make the policy stricter, but they must not allow undeclared domains. Keep these lists small because each origin adds code or data that can interact with the View. See CSP and CORS for configuration examples and Resource _meta for every field.

View-to-Host Messages

MCP Apps uses JSON-RPC 2.0 over postMessage. The Host must validate incoming messages, reject malformed methods, and decide which requests it will proxy or ask the user to approve. View code should:
  • Use the App SDK instead of hand-written postMessage listeners.
  • Check Host capabilities before calling an optional API.
  • Treat tool results, host context, and server resources as untrusted input before placing strings into the DOM.
  • Use DOM text nodes or framework escaping for text. Avoid passing result strings to innerHTML.
  • Keep dependencies current and avoid enabling allowUnsafeEval unless the Host CSP permits it and you control the code path.

Tool Access and Authorization

_meta.ui.visibility controls discovery and routing:
  • ["model", "app"] lets both the model and View call the tool.
  • ["model"] blocks calls from the View.
  • ["app"] hides the tool from the model and allows calls only from a View connected to the same server.
The Host must reject View calls to tools without "app" visibility. App-only tools cannot be called across server connections. Visibility is not authorization. A button click is still an untrusted tools/call request. Every tool handler must validate input, authenticate the caller, check access to the target record, rate limit when needed, and protect destructive operations against replay. Use standard tool annotations to describe read-only, destructive, idempotent, and open-world behavior. Hosts must treat those annotations as untrusted hints, so server checks remain required.

Tool Result Data

Choose result fields based on who should read the data: _meta keeps data out of model context, but it is not encrypted storage and does not bypass the Host. Do not send secrets the View does not need. Check authorization before returning any field. See Tool Results and Model Context for examples. Camera, microphone, geolocation, and clipboard access are optional permission requests under _meta.ui.permissions. Hosts may deny them, so the View must feature-detect each API and keep a fallback path. Use Host-mediated APIs for actions outside the sandbox:
  • openLink() asks the Host to open a URL under its own policy.
  • downloadFile() asks the Host to download content or a resource.
  • callServerTool() routes a tool call through the Host to the originating server.

Pre-Ship Security Check

  • The UI resource uses ui:// and text/html;profile=mcp-app.
  • CSP lists only the external origins the built View loads.
  • The View works when optional browser permissions are denied.
  • Every View-callable tool includes "app" visibility.
  • Every tool validates input and enforces server-side authorization.
  • Destructive calls are honestly annotated and safe against retries.
  • Model-safe data goes in content or structuredContent; View-only data goes in _meta.
  • Result strings render through escaped text APIs.
  • The app works in a real separate-origin sandbox, not only a same-origin development iframe.

Primary References

MCP Apps 2026-01-26 Specification

Normative sandbox, CSP, visibility, transport, and threat-model requirements.

Core MCP Security Principles

Consent, privacy, tool safety, and server input validation requirements.