fix(mcp): narrow call tool results

This commit is contained in:
Aiden Cline
2026-06-13 19:27:38 -05:00
parent abd6e4e045
commit 17550f3871
2 changed files with 13 additions and 1 deletions
+5
View File
@@ -64,6 +64,7 @@ export function convertTool(mcpTool: MCPToolDef, client: Client, timeout?: numbe
timeout,
},
)
if (!isCallToolResult(result)) return result
if (result.isError) throw new Error(errorText(result))
if (result.structuredContent === undefined || result.structuredContent === null) return result
return {
@@ -74,6 +75,10 @@ export function convertTool(mcpTool: MCPToolDef, client: Client, timeout?: numbe
})
}
function isCallToolResult(result: Awaited<ReturnType<Client["callTool"]>>): result is CallToolResult {
return "content" in result && Array.isArray(result.content)
}
function errorText(result: CallToolResult) {
const content = result.content.flatMap((item) => {
if (item.type === "text") return [item.text]
+8 -1
View File
@@ -9,7 +9,7 @@ const definition = {
inputSchema: { type: "object" as const, properties: {} },
}
function tool(result: CallToolResult) {
function tool(result: CallToolResult | { toolResult: unknown }) {
const callTool = mock(async () => result)
const converted = convertTool(definition, { callTool } as unknown as Client)
if (!converted.execute) throw new Error("expected executable tool")
@@ -31,6 +31,13 @@ describe("mcp catalog", () => {
expect(converted.callTool).toHaveBeenCalledTimes(1)
})
test("returns task tool results", async () => {
const result = { toolResult: { taskId: "task-1" } }
const converted = tool(result)
await expect(converted.execute({}, { toolCallId: "call-1", messages: [] })).resolves.toBe(result)
})
test("throws MCP tool errors with text and structured diagnostics", async () => {
const converted = tool({
isError: true,