Skip to content

Commit

Permalink
Errors invoking tools should be erroneous tool results, not McpErrors
Browse files Browse the repository at this point in the history
  • Loading branch information
jspahrsummers committed Jan 7, 2025
1 parent ff22f25 commit aac1959
Show file tree
Hide file tree
Showing 2 changed files with 82 additions and 4 deletions.
58 changes: 56 additions & 2 deletions src/server/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -860,16 +860,70 @@ describe("Server.tool", () => {
server.connect(serverTransport),
]);

const result = await client.request(
{
method: "tools/call",
params: {
name: "error-test",
},
},
CallToolResultSchema,
);

expect(result.isError).toBe(true);
expect(result.content).toEqual([
{
type: "text",
text: "Tool execution failed",
},
]);
});

test("should throw McpError for invalid tool name", async () => {
const server = new Server({
name: "test server",
version: "1.0",
});

const client = new Client(
{
name: "test client",
version: "1.0",
},
{
capabilities: {
tools: {},
},
},
);

server.tool("test-tool", async () => ({
content: [
{
type: "text",
text: "Test response",
},
],
}));

const [clientTransport, serverTransport] =
InMemoryTransport.createLinkedPair();

await Promise.all([
client.connect(clientTransport),
server.connect(serverTransport),
]);

await expect(
client.request(
{
method: "tools/call",
params: {
name: "error-test",
name: "nonexistent-tool",
},
},
CallToolResultSchema,
),
).rejects.toThrow("Tool execution failed");
).rejects.toThrow(/Tool nonexistent-tool not found/);
});
});
28 changes: 26 additions & 2 deletions src/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -405,10 +405,34 @@ export class Server<

const args = parseResult.data;
const cb = tool.callback as ToolCallback<ZodRawShape>;
return await Promise.resolve(cb(args, extra));
try {
return await Promise.resolve(cb(args, extra));
} catch (error) {
return {
content: [
{
type: "text",
text: error instanceof Error ? error.message : String(error),
},
],
isError: true,
};
}
} else {
const cb = tool.callback as ToolCallback<undefined>;
return await Promise.resolve(cb(extra));
try {
return await Promise.resolve(cb(extra));
} catch (error) {
return {
content: [
{
type: "text",
text: error instanceof Error ? error.message : String(error),
},
],
isError: true,
};
}
}
},
);
Expand Down

0 comments on commit aac1959

Please sign in to comment.