From 86b14add6e509e8085dba1fe2f61ff666c52921d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89der=20Costa?= Date: Tue, 23 Jun 2026 22:59:51 -0300 Subject: [PATCH] fix(claude): skip mcp__ tool-name cloak + guard missing connectionId (#4861) Integrated into release/v3.8.36 --- open-sse/services/claudeCodeToolRemapper.ts | 6 ++++++ src/sse/handlers/chat.ts | 2 +- tests/unit/claude-oauth-tool-cloak.test.ts | 8 ++++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/open-sse/services/claudeCodeToolRemapper.ts b/open-sse/services/claudeCodeToolRemapper.ts index 9ab697a100..754ecc978a 100644 --- a/open-sse/services/claudeCodeToolRemapper.ts +++ b/open-sse/services/claudeCodeToolRemapper.ts @@ -194,6 +194,12 @@ function toPascalCaseToolName(name: string): string { export function needsThirdPartyCloak(name: string): boolean { if (!name) return false; if (CLAUDE_BUILTIN_TOOL_NAMES.has(name)) return false; + // `mcp____` names are genuine Claude Code MCP tool names that + // Anthropic accepts natively. Cloaking them to PascalCase is unnecessary and, + // via round-trip asymmetry (a history tool_use keeping the original name while + // tools[] is cloaked), produces "Tool reference 'mcp__…' not found in available + // tools" 400s on the native claude OAuth path. Leave the MCP namespace alone. + if (name.startsWith("mcp__")) return false; return /[a-z]/.test(name.charAt(0)) || name.includes("_") || name.includes("-"); } diff --git a/src/sse/handlers/chat.ts b/src/sse/handlers/chat.ts index 58f732adc3..03ef7f5d05 100644 --- a/src/sse/handlers/chat.ts +++ b/src/sse/handlers/chat.ts @@ -1013,7 +1013,7 @@ async function handleSingleModelChat( ); preselectedCredentials = null; - if (!credentials || "allRateLimited" in credentials) { + if (!credentials || "allRateLimited" in credentials || !credentials.connectionId) { if (credentials?.allRateLimited) { const retryDecision = getCooldownAwareRetryDecision({ retryAfter: credentials.retryAfter, diff --git a/tests/unit/claude-oauth-tool-cloak.test.ts b/tests/unit/claude-oauth-tool-cloak.test.ts index 2fdb3c71b5..46bffc1d90 100644 --- a/tests/unit/claude-oauth-tool-cloak.test.ts +++ b/tests/unit/claude-oauth-tool-cloak.test.ts @@ -109,6 +109,14 @@ describe("cloakThirdPartyToolNames", () => { assert.equal(needsThirdPartyCloak("mixture_of_agents"), true); }); + it("needsThirdPartyCloak leaves mcp__ namespace untouched (#4861)", () => { + // Genuine Claude Code MCP names Anthropic accepts natively; cloaking them + // caused round-trip "Tool reference 'mcp__…' not found" 400s on claude OAuth. + assert.equal(needsThirdPartyCloak("mcp__filesystem__read_file"), false); + assert.equal(needsThirdPartyCloak("mcp__github__create_issue"), false); + assert.equal(needsThirdPartyCloak("mcp__server"), false); + }); + it("preserves the reserved name of a versioned Anthropic server tool", () => { const body: AnyRecord = { tools: [{ type: "web_search_20250305", name: "web_search", max_uses: 5 }],