fix(mcp): serialize raw plugin tool results

This commit is contained in:
Vincent Koc
2026-04-28 21:23:34 -07:00
parent 24adf2c8e6
commit e4b09e1bf3
2 changed files with 40 additions and 3 deletions

View File

@@ -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 {

View File

@@ -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",