Improve documentation for CSP and permissions types

Add detailed JSDoc comments to `McpUiResourceCsp`, `McpUiResourcePermissions`,
and `McpUiResourceMeta` interfaces:

- Document CSP directive mappings for `connectDomains`, `resourceDomains`,
  `frameDomains`, and `baseUriDomains`
- Add usage examples showing typical domain patterns
- Clarify Permission Policy mappings for `camera`, `microphone`, `geolocation`,
  and `clipboardWrite`
- Explain `domain` field's host-dependent behavior with concrete examples
- Document `prefersBorder` semantics including true/false/omitted behavior

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Jonathan Hefner 2026-01-30 11:30:44 -06:00
commit c02eb4d006
No known key found for this signature in database
GPG key ID: 0DA40AFD21043691
3 changed files with 293 additions and 82 deletions

View file

@ -134,25 +134,25 @@
"type": "object",
"properties": {
"camera": {
"description": "Request camera access (Permission Policy `camera` feature).",
"description": "Request camera access.\n\nMaps to Permission Policy `camera` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"microphone": {
"description": "Request microphone access (Permission Policy `microphone` feature).",
"description": "Request microphone access.\n\nMaps to Permission Policy `microphone` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"geolocation": {
"description": "Request geolocation access (Permission Policy `geolocation` feature).",
"description": "Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"clipboardWrite": {
"description": "Request clipboard write access (Permission Policy `clipboard-write` feature).",
"description": "Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
@ -165,28 +165,28 @@
"type": "object",
"properties": {
"connectDomains": {
"description": "Origins for network requests (fetch/XHR/WebSocket).",
"description": "Origins for network requests (fetch/XHR/WebSocket).\n\n- Maps to CSP `connect-src` directive\n- Empty or omitted → no external connections (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"resourceDomains": {
"description": "Origins for static resources (scripts, images, styles, fonts).",
"description": "Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no external resources (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"frameDomains": {
"description": "Origins for nested iframes (frame-src directive).",
"description": "Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)",
"type": "array",
"items": {
"type": "string"
}
},
"baseUriDomains": {
"description": "Allowed base URIs for the document (base-uri directive).",
"description": "Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)",
"type": "array",
"items": {
"type": "string"
@ -2480,25 +2480,25 @@
"type": "object",
"properties": {
"camera": {
"description": "Request camera access (Permission Policy `camera` feature).",
"description": "Request camera access.\n\nMaps to Permission Policy `camera` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"microphone": {
"description": "Request microphone access (Permission Policy `microphone` feature).",
"description": "Request microphone access.\n\nMaps to Permission Policy `microphone` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"geolocation": {
"description": "Request geolocation access (Permission Policy `geolocation` feature).",
"description": "Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"clipboardWrite": {
"description": "Request clipboard write access (Permission Policy `clipboard-write` feature).",
"description": "Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
@ -2511,28 +2511,28 @@
"type": "object",
"properties": {
"connectDomains": {
"description": "Origins for network requests (fetch/XHR/WebSocket).",
"description": "Origins for network requests (fetch/XHR/WebSocket).\n\n- Maps to CSP `connect-src` directive\n- Empty or omitted → no external connections (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"resourceDomains": {
"description": "Origins for static resources (scripts, images, styles, fonts).",
"description": "Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no external resources (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"frameDomains": {
"description": "Origins for nested iframes (frame-src directive).",
"description": "Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)",
"type": "array",
"items": {
"type": "string"
}
},
"baseUriDomains": {
"description": "Allowed base URIs for the document (base-uri directive).",
"description": "Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)",
"type": "array",
"items": {
"type": "string"
@ -3874,28 +3874,28 @@
"type": "object",
"properties": {
"connectDomains": {
"description": "Origins for network requests (fetch/XHR/WebSocket).",
"description": "Origins for network requests (fetch/XHR/WebSocket).\n\n- Maps to CSP `connect-src` directive\n- Empty or omitted → no external connections (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"resourceDomains": {
"description": "Origins for static resources (scripts, images, styles, fonts).",
"description": "Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no external resources (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"frameDomains": {
"description": "Origins for nested iframes (frame-src directive).",
"description": "Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)",
"type": "array",
"items": {
"type": "string"
}
},
"baseUriDomains": {
"description": "Allowed base URIs for the document (base-uri directive).",
"description": "Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)",
"type": "array",
"items": {
"type": "string"
@ -3909,32 +3909,32 @@
"type": "object",
"properties": {
"csp": {
"description": "Content Security Policy configuration.",
"description": "Content Security Policy configuration for UI resources.",
"type": "object",
"properties": {
"connectDomains": {
"description": "Origins for network requests (fetch/XHR/WebSocket).",
"description": "Origins for network requests (fetch/XHR/WebSocket).\n\n- Maps to CSP `connect-src` directive\n- Empty or omitted → no external connections (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"resourceDomains": {
"description": "Origins for static resources (scripts, images, styles, fonts).",
"description": "Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no external resources (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"frameDomains": {
"description": "Origins for nested iframes (frame-src directive).",
"description": "Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)",
"type": "array",
"items": {
"type": "string"
}
},
"baseUriDomains": {
"description": "Allowed base URIs for the document (base-uri directive).",
"description": "Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)",
"type": "array",
"items": {
"type": "string"
@ -3944,29 +3944,29 @@
"additionalProperties": false
},
"permissions": {
"description": "Sandbox permissions requested by the UI.",
"description": "Sandbox permissions requested by the UI resource.",
"type": "object",
"properties": {
"camera": {
"description": "Request camera access (Permission Policy `camera` feature).",
"description": "Request camera access.\n\nMaps to Permission Policy `camera` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"microphone": {
"description": "Request microphone access (Permission Policy `microphone` feature).",
"description": "Request microphone access.\n\nMaps to Permission Policy `microphone` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"geolocation": {
"description": "Request geolocation access (Permission Policy `geolocation` feature).",
"description": "Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"clipboardWrite": {
"description": "Request clipboard write access (Permission Policy `clipboard-write` feature).",
"description": "Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
@ -3975,11 +3975,11 @@
"additionalProperties": false
},
"domain": {
"description": "Dedicated origin for view sandbox.",
"description": "Dedicated origin for view sandbox.\n\nUseful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.\n\n**Host-dependent:** The format and validation rules for this field are determined by each host. Servers MUST consult host-specific documentation for the expected domain format. Common patterns include:\n- Hash-based subdomains (e.g., `{hash}.claudemcpcontent.com`)\n- URL-derived subdomains (e.g., `www-example-com.oaiusercontent.com`)\n\nIf omitted, host uses default sandbox origin (typically per-conversation).",
"type": "string"
},
"prefersBorder": {
"description": "Visual boundary preference - true if UI prefers a visible border.",
"description": "Visual boundary preference - true if view prefers a visible border.\n\nBoolean requesting whether a visible border and background is provided by the host. Specifying an explicit value for this is recommended because hosts' defaults may vary.\n\n- `true`: request visible border + background\n- `false`: request no visible border + background\n- omitted: host decides border",
"type": "boolean"
}
},
@ -3990,25 +3990,25 @@
"type": "object",
"properties": {
"camera": {
"description": "Request camera access (Permission Policy `camera` feature).",
"description": "Request camera access.\n\nMaps to Permission Policy `camera` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"microphone": {
"description": "Request microphone access (Permission Policy `microphone` feature).",
"description": "Request microphone access.\n\nMaps to Permission Policy `microphone` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"geolocation": {
"description": "Request geolocation access (Permission Policy `geolocation` feature).",
"description": "Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"clipboardWrite": {
"description": "Request clipboard write access (Permission Policy `clipboard-write` feature).",
"description": "Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
@ -4082,28 +4082,28 @@
"type": "object",
"properties": {
"connectDomains": {
"description": "Origins for network requests (fetch/XHR/WebSocket).",
"description": "Origins for network requests (fetch/XHR/WebSocket).\n\n- Maps to CSP `connect-src` directive\n- Empty or omitted → no external connections (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"resourceDomains": {
"description": "Origins for static resources (scripts, images, styles, fonts).",
"description": "Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted → no external resources (secure default)",
"type": "array",
"items": {
"type": "string"
}
},
"frameDomains": {
"description": "Origins for nested iframes (frame-src directive).",
"description": "Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted → no nested iframes allowed (`frame-src 'none'`)",
"type": "array",
"items": {
"type": "string"
}
},
"baseUriDomains": {
"description": "Allowed base URIs for the document (base-uri directive).",
"description": "Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted → only same origin allowed (`base-uri 'self'`)",
"type": "array",
"items": {
"type": "string"
@ -4117,25 +4117,25 @@
"type": "object",
"properties": {
"camera": {
"description": "Request camera access (Permission Policy `camera` feature).",
"description": "Request camera access.\n\nMaps to Permission Policy `camera` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"microphone": {
"description": "Request microphone access (Permission Policy `microphone` feature).",
"description": "Request microphone access.\n\nMaps to Permission Policy `microphone` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"geolocation": {
"description": "Request geolocation access (Permission Policy `geolocation` feature).",
"description": "Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature.",
"type": "object",
"properties": {},
"additionalProperties": false
},
"clipboardWrite": {
"description": "Request clipboard write access (Permission Policy `clipboard-write` feature).",
"description": "Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.",
"type": "object",
"properties": {},
"additionalProperties": false

163
src/generated/schema.ts generated
View file

@ -187,61 +187,138 @@ export const McpUiSandboxProxyReadyNotificationSchema = z.object({
/**
* @description Content Security Policy configuration for UI resources.
*
* Servers declare which external origins their UI needs to access.
* Hosts use this to enforce appropriate CSP headers.
*
* > [!IMPORTANT]
* > MCP App HTML runs in a sandboxed iframe with no same-origin server.
* > **All** origins must be declared—including where your bundled JS/CSS is
* > served from (`localhost` in dev, your CDN in production).
*/
export const McpUiResourceCspSchema = z.object({
/** @description Origins for network requests (fetch/XHR/WebSocket). */
/**
* @description Origins for network requests (fetch/XHR/WebSocket).
*
* - Maps to CSP `connect-src` directive
* - Empty or omitted → no external connections (secure default)
*
* @example
* ```ts
* ["https://api.weather.com", "wss://realtime.service.com"]
* ```
*/
connectDomains: z
.array(z.string())
.optional()
.describe("Origins for network requests (fetch/XHR/WebSocket)."),
/** @description Origins for static resources (scripts, images, styles, fonts). */
.describe(
"Origins for network requests (fetch/XHR/WebSocket).\n\n- Maps to CSP `connect-src` directive\n- Empty or omitted \u2192 no external connections (secure default)",
),
/**
* @description Origins for static resources (images, scripts, stylesheets, fonts, media).
*
* - Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives
* - Wildcard subdomains supported: `https://*.example.com`
* - Empty or omitted → no external resources (secure default)
*
* @example
* ```ts
* ["https://cdn.jsdelivr.net", "https://*.cloudflare.com"]
* ```
*/
resourceDomains: z
.array(z.string())
.optional()
.describe("Origins for static resources (scripts, images, styles, fonts)."),
/** @description Origins for nested iframes (frame-src directive). */
.describe(
"Origins for static resources (images, scripts, stylesheets, fonts, media).\n\n- Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives\n- Wildcard subdomains supported: `https://*.example.com`\n- Empty or omitted \u2192 no external resources (secure default)",
),
/**
* @description Origins for nested iframes.
*
* - Maps to CSP `frame-src` directive
* - Empty or omitted → no nested iframes allowed (`frame-src 'none'`)
*
* @example
* ```ts
* ["https://www.youtube.com", "https://player.vimeo.com"]
* ```
*/
frameDomains: z
.array(z.string())
.optional()
.describe("Origins for nested iframes (frame-src directive)."),
/** @description Allowed base URIs for the document (base-uri directive). */
.describe(
"Origins for nested iframes.\n\n- Maps to CSP `frame-src` directive\n- Empty or omitted \u2192 no nested iframes allowed (`frame-src 'none'`)",
),
/**
* @description Allowed base URIs for the document.
*
* - Maps to CSP `base-uri` directive
* - Empty or omitted → only same origin allowed (`base-uri 'self'`)
*
* @example
* ```ts
* ["https://cdn.example.com"]
* ```
*/
baseUriDomains: z
.array(z.string())
.optional()
.describe("Allowed base URIs for the document (base-uri directive)."),
.describe(
"Allowed base URIs for the document.\n\n- Maps to CSP `base-uri` directive\n- Empty or omitted \u2192 only same origin allowed (`base-uri 'self'`)",
),
});
/**
* @description Sandbox permissions requested by the UI resource.
*
* Servers declare which browser capabilities their UI needs.
* Hosts MAY honor these by setting appropriate iframe `allow` attributes.
* Apps SHOULD NOT assume permissions are granted; use JS feature detection as fallback.
*/
export const McpUiResourcePermissionsSchema = z.object({
/** @description Request camera access (Permission Policy `camera` feature). */
/**
* @description Request camera access.
*
* Maps to Permission Policy `camera` feature.
*/
camera: z
.object({})
.optional()
.describe("Request camera access (Permission Policy `camera` feature)."),
/** @description Request microphone access (Permission Policy `microphone` feature). */
.describe(
"Request camera access.\n\nMaps to Permission Policy `camera` feature.",
),
/**
* @description Request microphone access.
*
* Maps to Permission Policy `microphone` feature.
*/
microphone: z
.object({})
.optional()
.describe(
"Request microphone access (Permission Policy `microphone` feature).",
"Request microphone access.\n\nMaps to Permission Policy `microphone` feature.",
),
/** @description Request geolocation access (Permission Policy `geolocation` feature). */
/**
* @description Request geolocation access.
*
* Maps to Permission Policy `geolocation` feature.
*/
geolocation: z
.object({})
.optional()
.describe(
"Request geolocation access (Permission Policy `geolocation` feature).",
"Request geolocation access.\n\nMaps to Permission Policy `geolocation` feature.",
),
/** @description Request clipboard write access (Permission Policy `clipboard-write` feature). */
/**
* @description Request clipboard write access.
*
* Maps to Permission Policy `clipboard-write` feature.
*/
clipboardWrite: z
.object({})
.optional()
.describe(
"Request clipboard write access (Permission Policy `clipboard-write` feature).",
"Request clipboard write access.\n\nMaps to Permission Policy `clipboard-write` feature.",
),
});
@ -490,22 +567,55 @@ export const McpUiInitializedNotificationSchema = z.object({
* @description UI Resource metadata for security and rendering configuration.
*/
export const McpUiResourceMetaSchema = z.object({
/** @description Content Security Policy configuration. */
/** @description Content Security Policy configuration for UI resources. */
csp: McpUiResourceCspSchema.optional().describe(
"Content Security Policy configuration.",
"Content Security Policy configuration for UI resources.",
),
/** @description Sandbox permissions requested by the UI. */
/** @description Sandbox permissions requested by the UI resource. */
permissions: McpUiResourcePermissionsSchema.optional().describe(
"Sandbox permissions requested by the UI.",
"Sandbox permissions requested by the UI resource.",
),
/** @description Dedicated origin for view sandbox. */
domain: z.string().optional().describe("Dedicated origin for view sandbox."),
/** @description Visual boundary preference - true if UI prefers a visible border. */
/**
* @description Dedicated origin for view sandbox.
*
* Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.
*
* **Host-dependent:** The format and validation rules for this field are determined by each host. Servers MUST consult host-specific documentation for the expected domain format. Common patterns include:
* - Hash-based subdomains (e.g., `{hash}.claudemcpcontent.com`)
* - URL-derived subdomains (e.g., `www-example-com.oaiusercontent.com`)
*
* If omitted, host uses default sandbox origin (typically per-conversation).
*
* @example
* ```ts
* "a904794854a047f6.claudemcpcontent.com"
* ```
*
* @example
* ```ts
* "www-example-com.oaiusercontent.com"
* ```
*/
domain: z
.string()
.optional()
.describe(
"Dedicated origin for view sandbox.\n\nUseful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.\n\n**Host-dependent:** The format and validation rules for this field are determined by each host. Servers MUST consult host-specific documentation for the expected domain format. Common patterns include:\n- Hash-based subdomains (e.g., `{hash}.claudemcpcontent.com`)\n- URL-derived subdomains (e.g., `www-example-com.oaiusercontent.com`)\n\nIf omitted, host uses default sandbox origin (typically per-conversation).",
),
/**
* @description Visual boundary preference - true if view prefers a visible border.
*
* Boolean requesting whether a visible border and background is provided by the host. Specifying an explicit value for this is recommended because hosts' defaults may vary.
*
* - `true`: request visible border + background
* - `false`: request no visible border + background
* - omitted: host decides border
*/
prefersBorder: z
.boolean()
.optional()
.describe(
"Visual boundary preference - true if UI prefers a visible border.",
"Visual boundary preference - true if view prefers a visible border.\n\nBoolean requesting whether a visible border and background is provided by the host. Specifying an explicit value for this is recommended because hosts' defaults may vary.\n\n- `true`: request visible border + background\n- `false`: request no visible border + background\n- omitted: host decides border",
),
});
@ -551,7 +661,10 @@ export const McpUiToolMetaSchema = z.object({
* URI of the UI resource to display for this tool, if any.
* This is converted to `_meta["ui/resourceUri"]`.
*
* @example "ui://weather/view.html"
* @example
* ```ts
* "ui://weather/view.html"
* ```
*/
resourceUri: z.string().optional(),
/**

View file

@ -538,31 +538,98 @@ export interface McpUiInitializedNotification {
/**
* @description Content Security Policy configuration for UI resources.
*
* Servers declare which external origins their UI needs to access.
* Hosts use this to enforce appropriate CSP headers.
*
* > [!IMPORTANT]
* > MCP App HTML runs in a sandboxed iframe with no same-origin server.
* > **All** origins must be declared—including where your bundled JS/CSS is
* > served from (`localhost` in dev, your CDN in production).
*/
export interface McpUiResourceCsp {
/** @description Origins for network requests (fetch/XHR/WebSocket). */
/**
* @description Origins for network requests (fetch/XHR/WebSocket).
*
* - Maps to CSP `connect-src` directive
* - Empty or omitted → no external connections (secure default)
*
* @example
* ```ts
* ["https://api.weather.com", "wss://realtime.service.com"]
* ```
*/
connectDomains?: string[];
/** @description Origins for static resources (scripts, images, styles, fonts). */
/**
* @description Origins for static resources (images, scripts, stylesheets, fonts, media).
*
* - Maps to CSP `img-src`, `script-src`, `style-src`, `font-src`, `media-src` directives
* - Wildcard subdomains supported: `https://*.example.com`
* - Empty or omitted → no external resources (secure default)
*
* @example
* ```ts
* ["https://cdn.jsdelivr.net", "https://*.cloudflare.com"]
* ```
*/
resourceDomains?: string[];
/** @description Origins for nested iframes (frame-src directive). */
/**
* @description Origins for nested iframes.
*
* - Maps to CSP `frame-src` directive
* - Empty or omitted → no nested iframes allowed (`frame-src 'none'`)
*
* @example
* ```ts
* ["https://www.youtube.com", "https://player.vimeo.com"]
* ```
*/
frameDomains?: string[];
/** @description Allowed base URIs for the document (base-uri directive). */
/**
* @description Allowed base URIs for the document.
*
* - Maps to CSP `base-uri` directive
* - Empty or omitted → only same origin allowed (`base-uri 'self'`)
*
* @example
* ```ts
* ["https://cdn.example.com"]
* ```
*/
baseUriDomains?: string[];
}
/**
* @description Sandbox permissions requested by the UI resource.
*
* Servers declare which browser capabilities their UI needs.
* Hosts MAY honor these by setting appropriate iframe `allow` attributes.
* Apps SHOULD NOT assume permissions are granted; use JS feature detection as fallback.
*/
export interface McpUiResourcePermissions {
/** @description Request camera access (Permission Policy `camera` feature). */
/**
* @description Request camera access.
*
* Maps to Permission Policy `camera` feature.
*/
camera?: {};
/** @description Request microphone access (Permission Policy `microphone` feature). */
/**
* @description Request microphone access.
*
* Maps to Permission Policy `microphone` feature.
*/
microphone?: {};
/** @description Request geolocation access (Permission Policy `geolocation` feature). */
/**
* @description Request geolocation access.
*
* Maps to Permission Policy `geolocation` feature.
*/
geolocation?: {};
/** @description Request clipboard write access (Permission Policy `clipboard-write` feature). */
/**
* @description Request clipboard write access.
*
* Maps to Permission Policy `clipboard-write` feature.
*/
clipboardWrite?: {};
}
@ -570,13 +637,41 @@ export interface McpUiResourcePermissions {
* @description UI Resource metadata for security and rendering configuration.
*/
export interface McpUiResourceMeta {
/** @description Content Security Policy configuration. */
/** @description Content Security Policy configuration for UI resources. */
csp?: McpUiResourceCsp;
/** @description Sandbox permissions requested by the UI. */
/** @description Sandbox permissions requested by the UI resource. */
permissions?: McpUiResourcePermissions;
/** @description Dedicated origin for view sandbox. */
/**
* @description Dedicated origin for view sandbox.
*
* Useful when views need stable, dedicated origins for OAuth callbacks, CORS policies, or API key allowlists.
*
* **Host-dependent:** The format and validation rules for this field are determined by each host. Servers MUST consult host-specific documentation for the expected domain format. Common patterns include:
* - Hash-based subdomains (e.g., `{hash}.claudemcpcontent.com`)
* - URL-derived subdomains (e.g., `www-example-com.oaiusercontent.com`)
*
* If omitted, host uses default sandbox origin (typically per-conversation).
*
* @example
* ```ts
* "a904794854a047f6.claudemcpcontent.com"
* ```
*
* @example
* ```ts
* "www-example-com.oaiusercontent.com"
* ```
*/
domain?: string;
/** @description Visual boundary preference - true if UI prefers a visible border. */
/**
* @description Visual boundary preference - true if view prefers a visible border.
*
* Boolean requesting whether a visible border and background is provided by the host. Specifying an explicit value for this is recommended because hosts' defaults may vary.
*
* - `true`: request visible border + background
* - `false`: request no visible border + background
* - omitted: host decides border
*/
prefersBorder?: boolean;
}
@ -621,7 +716,10 @@ export interface McpUiToolMeta {
* URI of the UI resource to display for this tool, if any.
* This is converted to `_meta["ui/resourceUri"]`.
*
* @example "ui://weather/view.html"
* @example
* ```ts
* "ui://weather/view.html"
* ```
*/
resourceUri?: string;
/**