From ba751d94334183ce29b65ce741dfec9c81fd854b Mon Sep 17 00:00:00 2001 From: Sameh Khamis Date: Thu, 1 Oct 2026 23:03:41 -0700 Subject: [PATCH] fix: also name a tool's UI resource with the flat ui/resourceUri key Some MCP Apps hosts read the earlier flat _meta key; the MCP Apps SDK sends it alongside _meta.ui.resourceUri, and so does the adapter now. --- src/tools/mcp/mcp.test.mjs | 1 + src/tools/mcp/protocol.js | 9 ++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/tools/mcp/mcp.test.mjs b/src/tools/mcp/mcp.test.mjs index ff94659f0..0df9bb955 100644 --- a/src/tools/mcp/mcp.test.mjs +++ b/src/tools/mcp/mcp.test.mjs @@ -233,6 +233,7 @@ test('resources are listed and read, and tools name their UI resource', async () }); assert.deepEqual((await call('tools/list')).tools[0]._meta, { ui: { resourceUri: 'ui://fixture/view' }, + 'ui/resourceUri': 'ui://fixture/view', }); assert.deepEqual((await call('resources/list')).resources, [ { diff --git a/src/tools/mcp/protocol.js b/src/tools/mcp/protocol.js index 67858833e..446d01869 100644 --- a/src/tools/mcp/protocol.js +++ b/src/tools/mcp/protocol.js @@ -40,7 +40,14 @@ export function toMcpTools(catalog, { descriptions = {}, decorate } = {}) { inputSchema: tool.inputSchema, annotations: { title, ...tool.annotations }, ...(tool.ui - ? { _meta: { ui: { resourceUri: tool.ui.resourceUri } } } + ? { + // The flat key is the earlier form of the same field, which some + // hosts still read; the MCP Apps SDK sends both. + _meta: { + ui: { resourceUri: tool.ui.resourceUri }, + 'ui/resourceUri': tool.ui.resourceUri, + }, + } : {}), }; return decorate