import type { ActionMcpAppResourceConfig } from "../action.js"; import { MCP_APP_CHAT_BRIDGE_QUERY_PARAM } from "../shared/embed-auth.js"; const MCP_APP_IMPORT = "https://esm.sh/@modelcontextprotocol/ext-apps@1.7.2/app-with-deps"; export const MCP_APP_REQUEST_ORIGIN_CSP_SOURCE = "$requestOrigin"; const MCP_APP_WRAPPER_CHROME_HEIGHT = 44; export const DEFAULT_MCP_APP_SHELL_HEIGHT = 560; export const DEFAULT_MCP_APP_VIEWPORT_HEIGHT = DEFAULT_MCP_APP_SHELL_HEIGHT - MCP_APP_WRAPPER_CHROME_HEIGHT; export interface EmbedAppOptions { title?: string; description?: string; iframeTitle?: string; openLabel?: string; embedByDefault?: boolean; startToolName?: string; connectDomains?: string[]; resourceDomains?: string[]; baseUriDomains?: string[]; frameDomains?: string[]; height?: number; } function attr(value: string | undefined): string { return String(value ?? "") .replace(/&/g, "&") .replace(/"/g, """) .replace(//g, ">"); } export function embedApp( options: EmbedAppOptions = {}, ): ActionMcpAppResourceConfig { const title = options.title ?? "Open app"; const iframeTitle = options.iframeTitle ?? "Agent Native app"; const openLabel = options.openLabel ?? "Open in app"; const startToolName = options.startToolName ?? "create_embed_session"; const embedByDefault = options.embedByDefault !== false; const height = Math.max( 320, Math.min(900, options.height ?? DEFAULT_MCP_APP_SHELL_HEIGHT), ); const viewportHeight = height - MCP_APP_WRAPPER_CHROME_HEIGHT; const frameDomains = [ MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, ...(options.frameDomains ?? []), ]; return { title, ...(options.description ? { description: options.description } : {}), html: () => `
${attr(title)}
Preparing app
`, csp: { connectDomains: [ "https://esm.sh", MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, ...(options.connectDomains ?? []), ...(options.frameDomains ?? []), ], resourceDomains: [ "https://esm.sh", MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, ...(options.resourceDomains ?? []), ...(options.frameDomains ?? []), ], baseUriDomains: [ MCP_APP_REQUEST_ORIGIN_CSP_SOURCE, ...(options.baseUriDomains ?? []), ], frameDomains, }, prefersBorder: false, }; }