Quick answer: When two MCP servers expose a tool with the same name, an agent cannot reliably tell them apart by name alone, and it may call the wrong backend. The fix is to make the tool identity unique and meaningful: namespace the tools by server, give each a distinct description, and make the client surface which server will handle a call. If the servers are under your control, name the tools after the operation and domain rather than relying on generic labels.

Why a collision is dangerous

An agent selects a tool largely by matching the name and description to the user's intent. If two servers both expose something called search or create, the two entries look interchangeable at the moment of choice, even though they hit completely different systems. The result can be a read against the wrong database or, worse, a write to the wrong environment. Because the call succeeds from the agent's perspective, the error is not an exception; it is a quietly incorrect action.

SituationWhat the agent seesRisk
Unique tool namesOne clear match per intentLow
Same name, different serversTwo ambiguous entriesWrong backend selected
Same name, similar descriptionNearly indistinguishableEffectively a blind choice
Namespaced namesServer and operation both visibleDeterministic

A concrete collision

Imagine a team connects a billing MCP server and a support MCP server, and both expose a generic tool. The agent's tool list contains two entries with the same name but different identifiers behind the scenes.

// Server A: billing
{ "name": "get_record", "description": "Fetch an invoice" }

// Server B: support
{ "name": "get_record", "description": "Fetch a support ticket" }

// The agent must choose between two "get_record" tools
// with only the description to distinguish them.

If the descriptions are also terse, the agent's choice becomes a guess, and a request meant for the support system can land on the billing service.

Fixing it with namespacing

The reliable fix is to give each tool a name that carries its domain and operation, so the identity is unique without requiring the client to disambiguate. When a client supports server-scoped tool identifiers, use them so the server and the tool are both part of the reference.

// Clear, domain-specific names
{ "name": "billing_get_invoice", "description": "Fetch an invoice by ID" }
{ "name": "support_get_ticket", "description": "Fetch a support ticket by ID" }

Where the platform namespaces automatically, the client should display the server name alongside the tool and keep the fully qualified identifier internally, so the agent and the reviewer both see which system will be invoked.

Descriptions and the selection step

Even with unique names, the description is what the agent reads to map intent to a tool, so it should name the resource, the action, and the domain. A generic verb gives the model nothing to match against. At the point where a tool is chosen, a good client also shows the originating server in its confirmation, which gives a human a chance to catch a mismatch before a destructive call runs.

Generating tools from a spec

A spec-first workflow largely prevents the problem because tools are generated from operation IDs, and a well-formed OpenAPI document uses unique, operation-specific identifiers. When you generate multiple servers, enforce a naming convention that includes the domain and keep an operation ID lint rule in CI so two operations cannot collapse into the same generic name. Hand-written tool lists are where collisions quietly accumulate, especially as different teams add servers independently.

How an agent misreads it

An agent faced with a collision often picks the first matching entry and proceeds, or it may alternate between the two without explaining the choice. When reviewing a workflow, ask the agent to list every tool that matches the intent and identify the server for each before choosing. If the agent's response is simply to retry the same call, that solves nothing; the underlying ambiguity must be removed through naming and namespacing rather than hoped away.

Detecting collisions before they ship

Namespacing solves the problem, but you also want to catch it early. A short check that gathers every tool name across the connected servers and flags duplicates can run before a workflow is accepted, so a newly added server cannot silently reuse an existing name. When fully qualified identifiers are available, the check should compare the full server-and-tool reference rather than the short label alone, which distinguishes a genuine collision from two tools that merely share a generic verb in different namespaces.

import json

tools = json.load(open("tool-catalog.json"))
seen = {}
for tool in tools:
    key = tool["name"]
    if key in seen:
        print(f"collision: {key} on {seen[key]} and {tool['server']}")
    seen[key] = tool["server"]

Running this in CI is far cheaper than discovering the ambiguity after a wrong system was called. Treat a reported collision as a naming decision to resolve, not a warning to ignore, because each generic name is a place where the agent's choice becomes underdetermined.

Frequently asked questions

Why can't the agent just choose the best matching tool?

It can try, but when names and descriptions are nearly identical, the model has no reliable signal to distinguish two backends, so the choice becomes arbitrary and can hit the wrong system.

What is the cleanest fix?

Namespace tools by domain or server and give them operation-specific names, so each intent maps to a unique identifier rather than a generic label.

Do descriptions help if names collide?

They reduce the ambiguity, but they are not as reliable as a unique name; use both, and make the client show the server that will handle the call.

How does spec-first generation avoid this?

Tools derive from unique operation IDs, and a lint rule can enforce distinct, domain-specific identifiers, so two generic hand-written tools are far less likely to collide.

This is part of the Powerduck vs Cursor: API Contract Tools for AI Coding — start there for the full comparison of keeping agent tool calls accurate.