From ae00f009e64c40510aaa783f1246658c75b8af40 Mon Sep 17 00:00:00 2001 From: Sameh Khamis Date: Fri, 2 Oct 2026 18:16:05 -0700 Subject: [PATCH] Log why a tool call failed in the stdio server's log A failed call's reason went only to the client, so client logs showed a failure without its cause. --- server/mcp/stdio.js | 6 +++++- src/tools/localServer.test.mjs | 27 +++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/server/mcp/stdio.js b/server/mcp/stdio.js index 563ef30ce..c89407be3 100644 --- a/server/mcp/stdio.js +++ b/server/mcp/stdio.js @@ -54,7 +54,11 @@ async function respond(server, line, log) { } const described = describeRequest(message); if (described) log(described); - return server.handle(message); + const response = await server.handle(message); + // A failed tool call answers the client, not the log; say why here too. + if (response?.result?.isError) + log(` ${described} failed: ${response.result.content?.[0]?.text}`); + return response; } /** Read `--api-base ` from command-line arguments. */ diff --git a/src/tools/localServer.test.mjs b/src/tools/localServer.test.mjs index 61aa5c024..c9b901bf0 100644 --- a/src/tools/localServer.test.mjs +++ b/src/tools/localServer.test.mjs @@ -104,3 +104,30 @@ test('the stdio log names methods, tools and resources but never arguments', asy ); assert.equal(describeRequest({ result: {} }), null); }); + +test('a failed tool call is logged with its reason', async () => { + const server = { + handle: async (message) => ({ + jsonrpc: '2.0', + id: message.id, + result: { isError: true, content: [{ type: 'text', text: 'bad area' }] }, + }), + }; + const input = new PassThrough(); + const output = new PassThrough(); + output.resume(); + const logged = []; + const served = serveStdio(server, { + input, + output, + log: (line) => logged.push(line), + }); + input.end( + '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"show_in_gods_eye_view"}}\n', + ); + await served; + assert.deepEqual(logged, [ + 'tools/call show_in_gods_eye_view', + ' tools/call show_in_gods_eye_view failed: bad area', + ]); +});