From 5b5f428ad9a61a8bf5d0dddb81bdd6dd9da1c46d Mon Sep 17 00:00:00 2001 From: Luis Pater Date: Wed, 12 Aug 2026 09:37:12 +0000 Subject: [PATCH] fix(claude): recover OAuth tool names with duplicated server alias prefixes - Handle reversed tool names starting with `mcp______` by resolving them against the exact alias map before regular matching. - Prevent failed reverse remapping for malformed/duplicated MCP alias patterns by short-circuiting to the direct alias match path. Closes: #4916 --- internal/runtime/executor/claude_executor_request.go | 7 +++++++ internal/runtime/executor/claude_executor_request_remap_test.go | 15 +++++++++++++++ 2 file(s) changed, 22 insertion(s)(+), 0 deletion(s)(-) diff --git a/internal/runtime/executor/claude_executor_request.go b/internal/runtime/executor/claude_executor_request.go --- a/internal/runtime/executor/claude_executor_request.go +++ b/internal/runtime/executor/claude_executor_request.go @@ -1586,6 +1586,13 @@ return "", false, nil } + repeatedServerPrefix := "mcp__" + server + "__" + server + "__" + if suffix, repeatedServer := strings.CutPrefix(name, repeatedServerPrefix); repeatedServer { + if original, exact := resolver.exact["mcp__"+server+"__"+suffix]; exact { + return original, true, nil + } + } + matchedOriginal := "" matchCount := 0 for _, entry := range resolver.aliases { diff --git a/internal/runtime/executor/claude_executor_request_remap_test.go b/internal/runtime/executor/claude_executor_request_remap_test.go --- a/internal/runtime/executor/claude_executor_request_remap_test.go +++ b/internal/runtime/executor/claude_executor_request_remap_test.go @@ -163,6 +163,21 @@ } } +func TestReverseRemapOAuthToolNamesRecoversRepeatedServerAlias(t *testing.T) { + const alias = "mcp__hmzqrngkulqv__xuo7jlxlpzee_Bash" + reverseMap := map[string]string{alias: "Bash"} + responseAlias := "mcp__hmzqrngkulqv__hmzqrngkulqv__xuo7jlxlpzee_Bash" + response := []byte(fmt.Sprintf(`{"content":[{"type":"tool_use","id":"toolu_1","name":%q,"input":{}}]}`, responseAlias)) + + restored, errReverse := reverseRemapOAuthToolNames(response, reverseMap) + if errReverse != nil { + t.Fatalf("reverseRemapOAuthToolNames() error = %v", errReverse) + } + if got := gjson.GetBytes(restored, "content.0.name").String(); got != "Bash" { + t.Fatalf("repeated server alias restored to %q, want Bash", got) + } +} + func TestReverseRemapOAuthToolNamesRejectsUnsafeMangledAliases(t *testing.T) { body := []byte(`{"tools":[{"name":"tool.name"},{"name":"tool/name"}]}`) remapped, reverseMap := remapOAuthToolNamesWithOptions(body, claudeMCPAliasOptions{secret: "ambiguous-alias-caller"}) -- tangled.sh