n8n-io/n8n · warning · McpToolNameValidationError
MCP tool "${name}" from ${options.source} conflicts with "${
Error message
MCP tool "${name}" from ${options.source} conflicts with "${claimedBy}" What it means
Thrown by addSafeMcpTools when a tool's normalized name (NFKC → lowercase → strip non-alphanumerics) already exists in the claimedToolNames map, i.e. another tool from this or an earlier source already claimed that normalized slot. The error reports both the conflicting tool and who claimed the slot. Note: inside addSafeMcpTools this error is caught and routed to the warn callback (the tool is skipped), so it surfaces as a warning unless the caller re-throws.
Source
Thrown at packages/@n8n/instance-ai/src/agent/mcp-tool-name-validation.ts:69
}
return claimed;
}
export function addSafeMcpTools(
target: McpToolRegistry,
sourceTools: McpToolRegistry,
options: {
source: string;
claimedToolNames: Map<string, string>;
warn?: (error: McpToolNameValidationError) => void;
},
): void {
for (const [name, tool] of sourceTools) {
try {
const normalizedName = validateMcpToolName(name, options.source);
const claimedBy = options.claimedToolNames.get(normalizedName);
if (claimedBy) {
throw new McpToolNameValidationError(
`MCP tool "${name}" from ${options.source} conflicts with "${claimedBy}"`,
name,
options.source,
);
}
options.claimedToolNames.set(normalizedName, name);
target.set(name, tool);
} catch (error) {
if (error instanceof McpToolNameValidationError) {
options.warn?.(error);
continue;
}
throw error;
}
}
}
View on GitHub (pinned to 5ac6606e81)
Solutions
- Rename one of the colliding tools on its source server so the normalized forms differ.
- If you control the registry load order, load the higher-priority server first so its claim wins and the collision is reported (and skipped) for the lower-priority one.
- Inspect the warn callback output to see which tools were skipped due to conflicts.
Example fix
// before — two servers expose tools that normalize to 'searchitems'
serverA: { name: 'search.items' }
serverB: { name: 'searchItems' }
// after — rename one so normalized forms differ
serverA: { name: 'search.items' } // -> 'searchitems'
serverB: { name: 'searchItemsV2' } // -> 'searchitemsv2' Defensive patterns
Strategy: validation
Validate before calling
import { normalizeMcpToolName, createClaimedToolNames } from './mcp-tool-name-validation';
function detectCollisions(sources: { source: string; names: string[] }[]): { source: string; name: string; claimedBy: string }[] {
const claimed = createClaimedToolNames([]);
const collisions: { source: string; name: string; claimedBy: string }[] = [];
for (const s of sources) {
for (const name of s.names) {
const norm = normalizeMcpToolName(name);
const claimedBy = claimed.get(norm);
if (claimedBy) collisions.push({ source: s.source, name, claimedBy });
else claimed.set(norm, name);
}
}
return collisions;
}
const collisions = detectCollisions(allSources);
if (collisions.length) throw new Error(`collisions: ${JSON.stringify(collisions)}`); Type guard
import { McpToolNameValidationError } from './mcp-tool-name-validation';
function isMcpToolConflictError(e: unknown): e is McpToolNameValidationError {
return e instanceof McpToolNameValidationError && /conflicts with/.test(e.message);
} Try / catch
import { addSafeMcpTools } from './mcp-tool-name-validation';
const warnings: string[] = [];
addSafeMcpTools(target, sourceTools, {
source,
claimedToolNames,
warn: (e) => warnings.push(`${e.source}: ${e.toolName} conflicts; skipped`),
});
if (warnings.length) logger.warn(`MCP tool conflicts: \n${warnings.join('\n')}`); Prevention
- Use addSafeMcpTools with a warn callback so conflicts are logged, not fatal.
- Load higher-priority servers first so their claims win.
- Namespace tool names per server to avoid cross-server collisions.
When it happens
Trigger: Two MCP servers expose tools whose names collide after normalization (e.g. 'search.items' and 'searchItems', or 'foo-bar' and 'foo_bar'); the same server is registered twice; a built-in tool name collides with an MCP tool.
Common situations: Loading multiple MCP servers with overlapping tool vocabularies; a server using punctuation that normalizes away to match another server's tool; a tool name that lowercases to a built-in.
Related errors
- MCP tool "${name}" from ${source} has an invalid name
- Deferred tool name "${tool.name}" is reserved
- Duplicate deferred tool name "${tool.name}"
- Invalid delegate sub-agent tool name "${name}": must start w
- Sub-agent task name must contain at least one alphanumeric c
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/8d78a1a4b60071dc.
Report an issue: GitHub.