CSP & CORS
Unlike regular web apps, MCP Apps HTML is served as an MCP resource and runs in a sandboxed iframe with no same-origin server. Any app that makes network requests must configure Content Security Policy (CSP) and possibly CORS.
CSP controls what the browser allows. You must declare all origins in {@link types!McpUiResourceMeta.csp _meta.ui.csp} ({@link types!McpUiResourceCsp McpUiResourceCsp}) — including localhost during development. Declare connectDomains for fetch/XHR/WebSocket requests and resourceDomains for scripts, stylesheets, images, and fonts.
CORS controls what the API server allows. Public APIs that respond with Access-Control-Allow-Origin: * or use API key authentication work without CORS configuration. For APIs that allowlist specific origins, use {@link types!McpUiResourceMeta.domain _meta.ui.domain} to give the app a stable origin that the API server can allowlist. The format is host-specific, so check each host’s documentation for its supported format.
// Computes a stable origin from an MCP server URL for hosting in Claude.function computeAppDomainForClaude(mcpServerUrl: string): string { const hash = crypto .createHash("sha256") .update(mcpServerUrl) .digest("hex") .slice(0, 32); return `${hash}.claudemcpcontent.com`;}
const APP_DOMAIN = computeAppDomainForClaude("https://example.com/mcp");
registerAppResource( server, "Company Dashboard", "ui://dashboard/view.html", { description: "Internal dashboard with company data", }, async () => ({ contents: [ { uri: "ui://dashboard/view.html", mimeType: RESOURCE_MIME_TYPE, text: dashboardHtml, _meta: { ui: { // CSP: tell browser the app is allowed to make requests csp: { connectDomains: ["https://api.example.com"], }, // CORS: give app a stable origin for the API server to allowlist // // (Public APIs that use `Access-Control-Allow-Origin: *` or API // key auth don't need this.) domain: APP_DOMAIN, }, }, }, ], }),);Note that _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.
[!NOTE] For full examples that configures CSP, see:
examples/sheet-music-server/(connectDomains) andexamples/map-server/(connectDomainsandresourceDomains).