diff --git a/packages/client-runtime/src/mcpApps/host.test.ts b/packages/client-runtime/src/mcpApps/host.test.ts index 898588737c31f..76f6574f5012f 100644 --- a/packages/client-runtime/src/mcpApps/host.test.ts +++ b/packages/client-runtime/src/mcpApps/host.test.ts @@ -203,8 +203,10 @@ describe("makeMcpAppHost", () => { }); it("proxies tools/call and reports a refusal as a JSON-RPC error", async () => { + const calls: Array = []; const { host, sent } = setup({ callTool: async (input) => { + calls.push(input.arguments); if (input.name === "delete_everything") throw new McpAppHostRefusal({ message: "Declined by the user." }); return { content: [], structuredContent: { ok: true } }; @@ -217,7 +219,14 @@ describe("makeMcpAppHost", () => { method: "tools/call", params: { name: "delete_everything", arguments: {} }, }); + host.receive({ + jsonrpc: "2.0", + id: 9, + method: "tools/call", + params: { name: "refresh", arguments: { since: undefined, limit: 5 } }, + }); await flush(); + expect(calls.at(-1)).toStrictEqual({ limit: 5 }); expect(sent).toContainEqual({ jsonrpc: "2.0", id: 7, diff --git a/packages/client-runtime/src/mcpApps/host.ts b/packages/client-runtime/src/mcpApps/host.ts index 847771fb09dbd..42938a6d7f005 100644 --- a/packages/client-runtime/src/mcpApps/host.ts +++ b/packages/client-runtime/src/mcpApps/host.ts @@ -247,10 +247,16 @@ export function makeMcpAppHost(options: McpAppHostOptions): McpAppHost { fail(id, -32602, "tools/call needs a tool name and object arguments."); return; } + let jsonArgs: Record; + try { + // postMessage keeps undefined and other non-JSON values the RPC encoding rejects. + jsonArgs = JSON.parse(JSON.stringify(args)); + } catch { + fail(id, -32602, "tools/call arguments must be JSON."); + return; + } answer(id, () => - options - .callTool({ name, arguments: args as Record }) - .then(normalizeMcpAppToolResult), + options.callTool({ name, arguments: jsonArgs }).then(normalizeMcpAppToolResult), ); return; }