From 345c8be71a027cb16204bb003594d3ef7e6bed33 Mon Sep 17 00:00:00 2001 From: Andrew Harvard Date: Thu, 5 Feb 2026 12:04:30 -0500 Subject: [PATCH] Add frame_domains and base_uri_domains to CspMetadata, remove ExtendedCspMetadata workaround --- crates/goose/src/goose_apps/resource.rs | 6 ++++++ ui/desktop/openapi.json | 16 +++++++++++++++ ui/desktop/src/api/types.gen.ts | 8 ++++++++ ui/desktop/src/components/McpApps/utils.ts | 23 ++++++---------------- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/crates/goose/src/goose_apps/resource.rs b/crates/goose/src/goose_apps/resource.rs index 6afbdcc4b1..8236efb049 100644 --- a/crates/goose/src/goose_apps/resource.rs +++ b/crates/goose/src/goose_apps/resource.rs @@ -12,6 +12,12 @@ pub struct CspMetadata { /// Domains allowed for resource loading (scripts, styles, images, fonts, media) #[serde(skip_serializing_if = "Option::is_none")] pub resource_domains: Option>, + /// Domains allowed for frame-src (nested iframes) + #[serde(skip_serializing_if = "Option::is_none")] + pub frame_domains: Option>, + /// Domains allowed for base-uri + #[serde(skip_serializing_if = "Option::is_none")] + pub base_uri_domains: Option>, } /// Sandbox permissions for MCP Apps diff --git a/ui/desktop/openapi.json b/ui/desktop/openapi.json index cda0170459..4d6331c5b6 100644 --- a/ui/desktop/openapi.json +++ b/ui/desktop/openapi.json @@ -3672,6 +3672,14 @@ "type": "object", "description": "Content Security Policy metadata for MCP Apps\nSpecifies allowed domains for network connections and resource loading", "properties": { + "baseUriDomains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Domains allowed for base-uri", + "nullable": true + }, "connectDomains": { "type": "array", "items": { @@ -3680,6 +3688,14 @@ "description": "Domains allowed for connect-src (fetch, XHR, WebSocket)", "nullable": true }, + "frameDomains": { + "type": "array", + "items": { + "type": "string" + }, + "description": "Domains allowed for frame-src (nested iframes)", + "nullable": true + }, "resourceDomains": { "type": "array", "items": { diff --git a/ui/desktop/src/api/types.gen.ts b/ui/desktop/src/api/types.gen.ts index eca80ef670..6c071b5c9d 100644 --- a/ui/desktop/src/api/types.gen.ts +++ b/ui/desktop/src/api/types.gen.ts @@ -143,10 +143,18 @@ export type CreateScheduleRequest = { * Specifies allowed domains for network connections and resource loading */ export type CspMetadata = { + /** + * Domains allowed for base-uri + */ + baseUriDomains?: Array | null; /** * Domains allowed for connect-src (fetch, XHR, WebSocket) */ connectDomains?: Array | null; + /** + * Domains allowed for frame-src (nested iframes) + */ + frameDomains?: Array | null; /** * Domains allowed for resource loading (scripts, styles, images, fonts, media) */ diff --git a/ui/desktop/src/components/McpApps/utils.ts b/ui/desktop/src/components/McpApps/utils.ts index c3478fd87b..465c4cb20e 100644 --- a/ui/desktop/src/components/McpApps/utils.ts +++ b/ui/desktop/src/components/McpApps/utils.ts @@ -2,14 +2,6 @@ import type { CspMetadata, PermissionsMetadata } from './types'; export const DEFAULT_IFRAME_HEIGHT = 200; -// Extended CSP metadata type that includes all fields (some may not be in generated types yet) -interface ExtendedCspMetadata { - connectDomains?: string[] | null; - resourceDomains?: string[] | null; - frameDomains?: string[] | null; - baseUriDomains?: string[] | null; -} - /** * Create a secure MCP App Proxy URL. * @@ -26,7 +18,7 @@ interface ExtendedCspMetadata { * 2. Backend stores it temporarily and returns a token * 3. Use the returned URL as iframe src * 4. Backend serves HTML with proper CSP headers - * 5. Token expires after 60 seconds + * 5. Token expires after 5 minutes */ export async function createMcpAppProxyUrl( html: string, @@ -41,9 +33,6 @@ export async function createMcpAppProxyUrl( return null; } - // Cast to extended type to access all CSP fields - const extendedCsp = csp as ExtendedCspMetadata | null | undefined; - console.log('[MCP App Proxy] Creating proxy URL', { baseUrl, secretKeyLength: secretKey?.length }); const response = await fetch(`${baseUrl}/mcp-app-proxy`, { method: 'POST', @@ -53,11 +42,11 @@ export async function createMcpAppProxyUrl( body: JSON.stringify({ secret: secretKey, html, - csp: extendedCsp ? { - connectDomains: extendedCsp.connectDomains || [], - resourceDomains: extendedCsp.resourceDomains || [], - frameDomains: extendedCsp.frameDomains || [], - baseUriDomains: extendedCsp.baseUriDomains || [], + csp: csp ? { + connectDomains: csp.connectDomains || [], + resourceDomains: csp.resourceDomains || [], + frameDomains: csp.frameDomains || [], + baseUriDomains: csp.baseUriDomains || [], } : {}, permissions: permissions ? { camera: permissions.camera || false,