Skip to content

Commit dc6d654

Browse files
Alexey Panfilovclaude
andcommitted
feat: always prefix MCP tool names with server name (server__tool)
Prevents tool name conflicts between MCP servers (e.g. sql_query existing in both finance and health-dashboard). Tool names sent to LLM are prefixed (finance__sql_query), but the original name is used when calling the MCP server. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 5049e0c commit dc6d654

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

internal/mcp/client.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,8 @@ func (c *Client) Initialize(ctx context.Context) {
116116
continue
117117
}
118118
t.ServerName = name
119+
// Always prefix tool names with server name to avoid conflicts.
120+
t.Name = name + "__" + t.Name
119121
c.tools = append(c.tools, t)
120122
c.toolServers[t.Name] = name
121123
allowed++
@@ -287,7 +289,12 @@ func (c *Client) CallTool(ctx context.Context, name string, argsJSON string) (st
287289
return "", fmt.Errorf("unknown tool: %s", name)
288290
}
289291
srv := c.servers[serverName]
290-
result, err := srv.callTool(ctx, name, json.RawMessage(argsJSON))
292+
// Strip server prefix: "server__tool_name" → "tool_name"
293+
originalName := name
294+
if idx := strings.Index(name, "__"); idx >= 0 {
295+
originalName = name[idx+2:]
296+
}
297+
result, err := srv.callTool(ctx, originalName, json.RawMessage(argsJSON))
291298
if err == nil {
292299
return result, nil
293300
}
@@ -300,7 +307,7 @@ func (c *Client) CallTool(ctx context.Context, name string, argsJSON string) (st
300307
c.logger.Warn("mcp reconnect failed", "server", serverName, "err", reinitErr)
301308
return "", err // return original error
302309
}
303-
result, err = srv.callTool(ctx, name, json.RawMessage(argsJSON))
310+
result, err = srv.callTool(ctx, originalName, json.RawMessage(argsJSON))
304311
}
305312
return result, err
306313
}

0 commit comments

Comments
 (0)