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

  1. Rename one of the colliding tools on its source server so the normalized forms differ.
  2. 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.
  3. 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

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


AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12). Data as JSON: /api/errors/8d78a1a4b60071dc. Report an issue: GitHub.