diff --git a/src/mcp/plugin-tools-handlers.ts b/src/mcp/plugin-tools-handlers.ts index 99db6fa5b87..5cf7a3e4670 100644 --- a/src/mcp/plugin-tools-handlers.ts +++ b/src/mcp/plugin-tools-handlers.ts @@ -52,10 +52,14 @@ export function createPluginToolsMcpHandlers(tools: AnyAgentTool[]) { } try { const result = await tool.execute(`mcp-${Date.now()}`, params.arguments ?? {}); + const rawContent = + result && typeof result === "object" && "content" in result + ? (result as { content?: unknown }).content + : result; return { - content: Array.isArray(result.content) - ? result.content - : [{ type: "text", text: coerceChatContentText(result.content) }], + content: Array.isArray(rawContent) + ? rawContent + : [{ type: "text", text: coerceChatContentText(rawContent) }], }; } catch (err) { return { diff --git a/src/mcp/plugin-tools-serve.test.ts b/src/mcp/plugin-tools-serve.test.ts index cea3e50cb3b..8e0622e5361 100644 --- a/src/mcp/plugin-tools-serve.test.ts +++ b/src/mcp/plugin-tools-serve.test.ts @@ -65,6 +65,39 @@ describe("plugin tools MCP server", () => { expect(result.content).toEqual([{ type: "text", text: "Stored." }]); }); + it("serializes plugin tool results that do not use the MCP content envelope", async () => { + const execute = vi.fn().mockResolvedValue({ + provider: "kitchen-sink-search", + results: [{ title: "Kitchen Sink image fixture" }], + }); + const tool = { + name: "kitchen_sink_search", + description: "Search Kitchen Sink fixture content", + parameters: { + type: "object", + properties: { + query: { type: "string" }, + }, + }, + execute, + } as unknown as AnyAgentTool; + + const handlers = createPluginToolsMcpHandlers([tool]); + const result = await handlers.callTool({ + name: "kitchen_sink_search", + arguments: { query: "kitchen sink" }, + }); + expect(result.content).toEqual([ + { + type: "text", + text: JSON.stringify({ + provider: "kitchen-sink-search", + results: [{ title: "Kitchen Sink image fixture" }], + }), + }, + ]); + }); + it("returns MCP errors for unknown tools and thrown tool errors", async () => { const failingTool = { name: "memory_forget",