Skip to content

fix: Declare widget csp/prefersBorder on the UI resource, not the tool - #1190

Open
jirispilka wants to merge 1 commit into
masterfrom
fix/widget-meta-placement
Open

fix: Declare widget csp/prefersBorder on the UI resource, not the tool#1190
jirispilka wants to merge 1 commit into
masterfrom
fix/widget-meta-placement

Conversation

@jirispilka

Copy link
Copy Markdown
Collaborator

Why

Closes #1188. Per MCP Apps spec (SEP-1865), csp/prefersBorder are UI-resource metadata (McpUiResourceMeta) — hosts read them from the resources/read content item (with the resources/list entry as fallback) — while the tool's _meta.ui (McpUiToolMeta) carries only resourceUri/visibility and types csp/permissions as never. Claude's host warns at runtime about our current placement and ignores the misplaced keys, so our declared CSP is dead weight on the wrong surface.

What changed

Before: one _meta.ui blob (resourceUri, visibility, csp, prefersBorder) served on every surface — tool descriptor, tool result, resources/list, resources/read.

Now: WidgetConfig carries meta (tool/result: resourceUri, visibility, plus the legacy ui/resourceUri alias that the ext-apps SDK's registerAppTool populates for older hosts) and resourceMeta (list/read: csp, prefersBorder). resource_service.ts serves resourceMeta on both resource surfaces. Widget-meta tests pin the per-surface placement.

Notes for reviewers (human-written)

Proof it works

mcpc probe against the built stdio server in apps mode: tools/list shows widget tools with _meta.ui = {visibility, resourceUri} + ui/resourceUri and no csp; resources/read ui://widget/search-actors.html returns _meta with openai/widgetCSP, openai/widgetDomain, and ui: {prefersBorder, csp}. Widgets verified rendering in Claude Desktop and MCP Jam alongside #1187 during the ext-apps#696 investigation (this change was bisected there and is behavior-neutral for current hosts — they ignore the misplaced keys either way; this aligns us with the spec surface hosts actually read).

🤖 Generated with Claude Code

Per MCP Apps spec (SEP-1865), csp/prefersBorder are UI-resource metadata
(McpUiResourceMeta); the tool's _meta.ui (McpUiToolMeta) carries only
resourceUri/visibility and types csp/permissions as never. Claude's host
warns at runtime about the current placement and ignores the misplaced
keys. Split the shared blob into per-surface variants, serve the resource
variant on resources/list and resources/read, and add the legacy
ui/resourceUri alias that registerAppTool populates for older hosts.

Closes #1188

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics. labels Jul 31, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

t-ai Issues owned by the AI team. tested Temporary label used only programatically for some analytics.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Widget _meta places csp/prefersBorder on the tool instead of the UI resource

2 participants