From bb634261cb9fedf4e61a78855b4af08231569352 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 28 Jul 2026 08:07:32 -0400 Subject: [PATCH] fix(mcp): keep resource-only servers available after unknown methods (#115169) --- src/agents/agent-bundle-mcp-runtime.test.ts | 72 +++++++++++++++++++-- src/agents/agent-bundle-mcp-runtime.ts | 2 +- 2 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/agents/agent-bundle-mcp-runtime.test.ts b/src/agents/agent-bundle-mcp-runtime.test.ts index a351e9f785fd..4ffd2decefa8 100644 --- a/src/agents/agent-bundle-mcp-runtime.test.ts +++ b/src/agents/agent-bundle-mcp-runtime.test.ts @@ -1728,15 +1728,35 @@ process.on("SIGINT", shutdown);`, } }); - it("keeps resource-only MCP servers available for utility tools", async () => { + it.each([ + { + name: "resource-only servers reporting method not found", + capabilities: { resources: { listChanged: true } }, + listToolsMethodNotFound: true, + listToolsJsonRpcErrorMessage: undefined, + }, + { + name: "resource-only servers reporting unknown method", + capabilities: { resources: { listChanged: true } }, + listToolsMethodNotFound: false, + listToolsJsonRpcErrorMessage: "Unknown method", + }, + { + name: "prompt-only servers reporting unknown method", + capabilities: { prompts: { listChanged: true } }, + listToolsMethodNotFound: false, + listToolsJsonRpcErrorMessage: "Unknown method", + }, + ])("keeps $name available for utility tools", async (testCase) => { const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "bundle-mcp-resource-only-")); const serverPath = path.join(tempDir, "resource-only.mjs"); const logPath = path.join(tempDir, "server.log"); await writeListToolsMcpServer({ filePath: serverPath, logPath, - capabilities: { resources: { listChanged: true } }, - listToolsMethodNotFound: true, + capabilities: testCase.capabilities, + listToolsMethodNotFound: testCase.listToolsMethodNotFound, + listToolsJsonRpcErrorMessage: testCase.listToolsJsonRpcErrorMessage, }); const runtime = await getOrCreateSessionMcpRuntime({ @@ -1762,8 +1782,9 @@ process.on("SIGINT", shutdown);`, expect(catalog.servers.notes).toMatchObject({ serverName: "notes", toolCount: 0, - resources: { listChanged: true }, + ...testCase.capabilities, }); + expect(catalog.diagnostics ?? []).toEqual([]); await waitForFileText(logPath, "recv initialize", LIST_TOOLS_SERVER_LOG_TIMEOUT_MS); } finally { await runtime.dispose(); @@ -1771,6 +1792,49 @@ process.on("SIGINT", shutdown);`, } }); + it("does not suppress unknown tools/list methods from tools-capable MCP servers", async () => { + const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "bundle-mcp-tools-unknown-method-")); + const serverPath = path.join(tempDir, "tools-unknown-method.mjs"); + const logPath = path.join(tempDir, "server.log"); + await writeListToolsMcpServer({ + filePath: serverPath, + logPath, + capabilities: { tools: {}, resources: { listChanged: true } }, + listToolsJsonRpcErrorMessage: "Unknown method", + }); + + const runtime = await getOrCreateSessionMcpRuntime({ + sessionId: "session-tools-unknown-method", + sessionKey: "agent:test:session-tools-unknown-method", + workspaceDir: "/workspace", + cfg: { + mcp: { + servers: { + notes: { + command: process.execPath, + args: [serverPath], + }, + }, + }, + }, + }); + + try { + const catalog = await runtime.getCatalog(); + + expect(catalog.servers).toEqual({}); + expect(catalog.tools).toEqual([]); + expect(catalog.diagnostics?.[0]).toMatchObject({ + serverName: "notes", + message: expect.stringContaining("Unknown method"), + }); + await waitForFileText(logPath, "recv tools/list", LIST_TOOLS_SERVER_LOG_TIMEOUT_MS); + } finally { + await runtime.dispose(); + await fs.rm(tempDir, { recursive: true, force: true }); + } + }); + it("does not pause MCP servers for normal tool error results", async () => { const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "bundle-mcp-error-backoff-")); const serverPath = path.join(tempDir, "error-backoff.mjs"); diff --git a/src/agents/agent-bundle-mcp-runtime.ts b/src/agents/agent-bundle-mcp-runtime.ts index e6077d44f2a8..ba922f691c19 100644 --- a/src/agents/agent-bundle-mcp-runtime.ts +++ b/src/agents/agent-bundle-mcp-runtime.ts @@ -183,7 +183,7 @@ function isMcpMethodNotFoundError(error: unknown): boolean { return true; } const message = String(error); - return message.includes("-32601") || /method not found/i.test(message); + return message.includes("-32601") || /\b(?:method not found|unknown method)\b/i.test(message); } async function listAllToolsBestEffort(params: {