n8n-io/n8n · error · Error
MCP server name "${cfg.name}" is already registered
Error message
MCP server name "${cfg.name}" is already registered What it means
Thrown by the McpClient constructor when two McpServerConfig entries share the same name. The name is used as a tool-name prefix and as the connection key, so duplicates would collide in the surfaced tool namespace.
Source
Thrown at packages/@n8n/agents/src/sdk/mcp-client.ts:78
* @param configs - Server configurations. Each must have either `url` or `command`.
* Duplicate names within the list are rejected.
*/
constructor(configs: McpServerConfig[]) {
for (const cfg of configs) {
if (!cfg.url && !cfg.command) {
throw new Error(
`MCP server "${cfg.name}": exactly one of "url" or "command" must be provided`,
);
}
if (cfg.url && cfg.command) {
throw new Error(`MCP server "${cfg.name}": provide either "url" or "command", not both`);
}
}
const seen = new Set<string>();
for (const cfg of configs) {
if (seen.has(cfg.name)) {
throw new Error(`MCP server name "${cfg.name}" is already registered`);
}
seen.add(cfg.name);
}
this.configs = configs;
this.connections = configs.map((cfg) => new McpConnection(cfg));
}
/**
* Returns the names of all configured MCP servers. Does NOT require a
* network connection — safe to call before `listTools()` or `connect()`.
*/
get serverNames(): string[] {
return this.configs.map((cfg) => cfg.name);
}
/**
* Explicitly connect to all servers without listing tools.View on GitHub (pinned to 5ac6606e81)
Solutions
- Give each server a unique name (the name prefixes tool names, so pick something descriptive).
- De-duplicate configs by name before constructing McpClient.
- If you intended to replace a server, filter the older entry out before adding the new one.
Example fix
// before
new McpClient([
{ name: 'fs', command: 'npx', args: ['@anthropic/mcp-fs', '/a'] },
{ name: 'fs', command: 'npx', args: ['@anthropic/mcp-fs', '/b'] },
]);
// after
new McpClient([
{ name: 'fs-a', command: 'npx', args: ['@anthropic/mcp-fs', '/a'] },
{ name: 'fs-b', command: 'npx', args: ['@anthropic/mcp-fs', '/b'] },
]); Defensive patterns
Strategy: validation
Validate before calling
function assertUniqueNames(configs: { name: string }[]) {
const seen = new Set<string>();
for (const c of configs) {
if (seen.has(c.name)) throw new Error(`Duplicate MCP server name: ${c.name}`);
seen.add(c.name);
}
} Type guard
function mcpNamesUnique(configs: { name: string }[]): boolean {
return new Set(configs.map((c) => c.name)).size === configs.length;
} Prevention
- De-duplicate server configs by name before constructing McpClient.
- When merging config sources, namespace names by source to prevent collisions.
When it happens
Trigger: Passing an array with two entries whose .name is identical, e.g. [{ name: 'fs', ... }, { name: 'fs', ... }].
Common situations: Concatenating two config lists that both define a 'fs' server; loading MCP config from multiple sources without de-duplicating by name; copy-paste of a server block.
Related errors
- Duplicate deferred tool name "${tool.name}"
- MCP tool name collision — the following tool names resolve t
- MCP server "${cfg.name}": exactly one of "url" or "command"
- MCP server "${cfg.name}": provide either "url" or "command",
- Failed to parse ${label} at ${path}: ${msg}
AI-assisted analysis of n8n-io/n8n@5ac6606e81 (2026-08-12).
Data as JSON: /api/errors/0b83803ae300b58b.
Report an issue: GitHub.