spring-projects/spring-ai · warning
Tool name '<toolName>' already exists. Using unique tool nam
Error message
Tool name '<toolName>' already exists. Using unique tool name '<uniqueToolName>'
What it means
DefaultMcpToolNamePrefixGenerator.prefixedToolName() detected a tool name collision: after prefixing with connection info, the generated name was already used by another registered MCP tool. The generator appends an "alt_<counter>_" prefix to create a unique name and warns which original name was remapped, so callers referencing the old name will no longer resolve.
Source
Thrown at mcp/common/src/main/java/org/springframework/ai/mcp/DefaultMcpToolNamePrefixGenerator.java:73
private final Set<ConnectionId> existingConnections = ConcurrentHashMap.newKeySet();
private final Set<String> allUsedToolNames = ConcurrentHashMap.newKeySet();
private final AtomicInteger counter = new AtomicInteger(1);
@Override
public String prefixedToolName(McpConnectionInfo mcpConnectionInfo, McpSchema.Tool tool) {
String uniqueToolName = McpToolUtils.format(tool.name());
if (this.existingConnections
.add(new ConnectionId(mcpConnectionInfo.clientInfo(), (mcpConnectionInfo.initializeResult() != null)
? mcpConnectionInfo.initializeResult().serverInfo() : null, tool))) {
if (!this.allUsedToolNames.add(uniqueToolName)) {
uniqueToolName = "alt_" + this.counter.getAndIncrement() + "_" + uniqueToolName;
this.allUsedToolNames.add(uniqueToolName);
if (logger.isWarnEnabled()) {
logger.warn("Tool name '" + tool.name() + "' already exists. Using unique tool name '"
+ uniqueToolName + "'");
}
}
}
return uniqueToolName;
}
private record ConnectionId(@Nullable Implementation clientInfo, @Nullable Implementation serverInfo, Tool tool) {
}
}
View on GitHub (pinned to 98a7beda4f)
Solutions
- Look up tools by the renamed unique name ('alt_<n>_<name>') reported in the warning when invoking them.
- Provide a custom ToolNamePrefixGenerator (or configure distinct connection ids) that yields stable, collision-free names.
- Rename tools on the conflicting MCP servers so their exposed names differ.
- Recreate the tool-name generator/registry when the set of MCP connections changes to keep mappings deterministic.
Example fix
// before: assuming prefixed name equals tool name String name = prefixGenerator.prefixedToolName(connectionInfo, tool); // 'server1_search' client.call(name, args); // may hit remapped tool // after: keep the returned (possibly renamed) name String name = prefixGenerator.prefixedToolName(connectionInfo, tool); toolRegistry.put(name, tool); // always use the returned unique name
Defensive patterns
Strategy: validation
Validate before calling
Set<String> seen = new HashSet<>();
for (var conn : connections) {
for (var tool : conn.listTools()) {
String name = prefixGenerator.prefixedToolName(conn.info(), tool);
if (!seen.add(name)) {
logger.warn("collision on " + name + " — configure a custom prefix generator");
}
}
} Type guard
boolean isRemapped(String expectedName, String actualName) {
return actualName.startsWith("alt_") && !actualName.equals(expectedName);
} Try / catch
// renamed tools won't throw; detect by absence
var tool = toolRegistry.get(name);
if (tool == null) {
// name may have been remapped (alt_N_...); resolve from registry log/lookup
} Prevention
- Use a custom ToolNamePrefixGenerator with stable, distinct prefixes per MCP connection.
- Avoid generic tool names across aggregated MCP servers.
- Persist the name mapping generated at registration time and invoke tools only via it.
- Rebuild the tool registry when connection topology changes.
When it happens
Trigger: Registering tools from multiple MCP connections/servers that expose identically named tools (e.g. two servers both exposing a 'search' tool) such that the prefix generator produces the same prefixed name twice within the same generator instance.
Common situations: Aggregating several MCP servers where tools share generic names; a server reconnecting/re-registering tools without a fresh name-prefix generator; similarly-named tools on the same server after prefix normalization.
Related errors
- Tool call arguments are null or empty for MCP tool: <toolNam
- Tool call arguments are null or empty for MCP tool: <toolNam
- Tool name '${toolName}' may not be compatible with some LLMs
- Failed to read stdio connection resource
- SSE connection '<connectionName>' requires a 'url' property.
AI-assisted analysis of spring-projects/spring-ai@98a7beda4f (2026-09-11).
Data as JSON: /api/errors/47668341fb43b9e9.
Report an issue: GitHub.