fix(claude): skip mcp__ tool-name cloak + guard missing connectionId (#4861)

Integrated into release/v3.8.36
This commit is contained in:
Éder Costa
2026-06-23 22:59:51 -03:00
committed by GitHub
parent 108e93e14b
commit 86b14add6e
3 changed files with 15 additions and 1 deletions

View File

@@ -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__<server>__<tool>` 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("-");
}

View File

@@ -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,

View File

@@ -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 }],