Overview
Unlike regular web apps, MCP Apps run in sandboxed iframes with no same-origin server. Any app that makes network requests must configure Content Security Policy (CSP) and possibly CORS. Read the MCP Apps Security Model first if you need the full trust boundary, tool authorization, message validation, and result-data rules. CSP controls what the browser allows. Declare all origins in_meta.ui.csp — including localhost during development. No external connections are allowed by default.
CORS controls what the API server allows. Public APIs that respond with Access-Control-Allow-Origin: * work without CORS configuration. For APIs that allowlist specific origins, use _meta.ui.domain to give the app a stable origin.
CSP configuration
Set CSP fields inMcpUiResourceCsp via _meta.ui.csp on resource content items:
CORS
Public APIs withAccess-Control-Allow-Origin: * or API key authentication work without CORS configuration.
For APIs that allowlist specific origins, you need a stable origin. MCP Apps served as srcdoc or blob: URLs don’t have a meaningful origin by default. Use _meta.ui.domain to assign one.
Stable origins for Claude
Claude computes a stable origin from the MCP server URL. Use this pattern to set_meta.ui.domain:
Cross-platform servers
When your server connects to multiple hosts, each host expects a different domain format. The sunpeak framework handles this with a per-host domain map:clientInfo.name. The framework resolves the correct value at request time. Use default as a fallback for hosts you haven’t mapped.
Without sunpeak, detect the host via clientInfo.name from the MCP initialize handshake and return the appropriate domain string in your resources/read handler.
The
domain format is host-specific. Check each host’s documentation for its supported format.
The Claude pattern above uses SHA-256 hashing of the MCP server URL.Metadata location
_meta.ui.csp and _meta.ui.domain are set in the contents[] objects returned by the resource read callback — not in registerAppResource()’s config object. This allows dynamic CSP based on request context.
CSP can also be declared in resources/list responses as static defaults. When both are present, the value in resources/read (content item) takes precedence.
See also
Resource Metadata
Full reference for
McpUiResourceMeta including CSP and permissions.McpUiResourceCsp
TypeScript type definition for CSP fields.