ax-check rule
AXC-D014: Duplicate name
Two entries share the same name or operationId, so a call by name is ambiguous.
ax-check is a checker being prepared for release. This page documents the rule ahead of that release; see all 50 rules.
| Severity | error |
| Kind | Conformance. A finding is a fact about the input. |
| Mode | ax-check lint |
| Applies to | MCP tool lists, OpenAPI, SKILL.md, CLI help |
| Pattern tags | selection, discovery |
| Fix in one line | Give every tool, operation, command or skill a unique, stable name. |
Two entries on the same surface share a name, so a call by that name is ambiguous. An agent picks a tool, operation, command or skill by its name, and the client routes the call by the same name. When two entries share it, at least one of them can never be reached reliably.
What it checks
Within one surface, ax-check compares the names of all selectable entries:
- MCP: the
nameof each tool in atools/listresult. - OpenAPI: the
operationIdof each operation. - Agent Skills: the
namein each SKILL.md frontmatter. - CLI help: the subcommand names listed in the root
--helpoutput.
Any name used by more than one entry is reported.
Why it matters
The name is the handle for everything else. A client looks a tool up by name, an agent writes the name into its call, and instructions files and skills mention it by name. If two tools are both called search_orders, the client may keep the first, keep the last or reject the list, and the agent cannot tell which description belongs to the tool it will actually reach.
The specifications treat names as identifiers. The OpenAPI 3.1 specification says an operationId “MUST be unique among all operations described in the API”. The MCP specification says tool names are case-sensitive. The Agent Skills specification requires a skill’s name to match its parent folder, which keeps names unique inside one skills folder.
How to fix
- Give every tool, operation, command or skill a unique, stable name.
- When two entries do similar jobs, name the difference (for example
search_ordersandsearch_archived_orders) and say in each description when to use the other. - If you rename an entry, update the instructions, skills and manifests that refer to the old name.
Example
Before
{
"tools": [
{ "name": "search_orders", "description": "Search open orders by customer email. Use this when a customer asks about a current order." },
{ "name": "search_orders", "description": "Search orders closed more than 90 days ago. Use this for refund history questions." }
]
}
After
{
"tools": [
{ "name": "search_orders", "description": "Search open orders by customer email. Use this when a customer asks about a current order. For orders closed more than 90 days ago, use search_archived_orders instead." },
{ "name": "search_archived_orders", "description": "Search orders closed more than 90 days ago. Use this for refund history questions. For current orders, use search_orders instead." }
]
}
How ax-check detects it
ax-check groups the entries by exact name. The comparison is case-sensitive and does no trimming or normalising, so getUser and getuser count as different names. It reports one finding for the second and each later entry that reuses a name, and the finding lists the location of every entry with that name.
Details per surface:
- OpenAPI operations with no
operationIdare named after their method and path (for exampleGET /orders), so they never collide with each other. - A skill with no frontmatter
nameis named after its folder or file path for this check. - For CLI help, the
helpsubcommand and command aliases are ignored. A command listed under two headings of the same help text (for example “Common commands” and “All commands”) is read once, from its first listing, so it is not reported.
Known false negatives: names that differ only in case or punctuation are not reported, although they can still confuse an agent.
If the finding does not apply, silence it with --disable AXC-D014.
Sources
- Specification: OpenAPI Specification v3.1.0, OpenAPI Initiative, 15 February 2021. https://spec.openapis.org/oas/v3.1.0. States that
operationId“MUST be unique among all operations described in the API”. - Specification: Model Context Protocol, Tools, revision 2026-07-28. https://modelcontextprotocol.io/specification/2026-07-28/server/tools. Tool names are case-sensitive identifiers of 1 to 128 characters.
- Specification: Agent Skills specification, agentskills.io, retrieved 2026-10-08. https://agentskills.io/specification. A skill’s
namemust match its parent directory name. - Guide: Write tool descriptions an agent can act on, agentexperience.tech, retrieved 2026-10-08. https://agentexperience.tech/insights/tool-descriptions/. Name the nearest neighbouring tool so an agent can tell similar tools apart.
- Related check: the agentexperience.tech
audit_agent_pathtool reports the same defect for MCP catalogues ascatalog.duplicate_tool_name.
Related evidence
Records in the AX evidence register that share a pattern tag with this rule. A shared tag means the record is about the same pattern, not that it tests this rule. Read the evidence class before the number.
- EV-0019: Skill selection precision collapses as the skill pool grows (Preprint). A preprint reports that as the pool of available skills grew from 5 to 100, the precision with which agents actually used the right skill fell from 29.6% to 3.3%.
- EV-0013: FAQ blocks and structured data showed no citation effect within a domain (Preprint). An observational study of about 2 million AI-engine citations (preprint) found that FAQ blocks, structured data and Core Web Vitals had positive effects on citation in pooled data that reversed or fell to zero once domain fixed effects were applied.
- EV-0020: Praise and list order move tool selection (Preprint). A preregistered preprint with two small OpenAI models found that stacked praise in a tool description raised its pick rate by about 43 percentage points, and that with identical listings the first-listed tool was picked about 72 points more often.
- EV-0021: Agents leave available tools unused: the adoption gap (Preprint). On OSWorld-MCP (preprint), a reasoning model given MCP tools called one on only 55 of 309 tasks, 23.9% of the tasks a tool could reach, and the same tools made a non-reasoning model 5.9 points worse.
- EV-0023: Hiding tools is not enforcing permissions (Preprint). Across 2,160 attempts with four frontier models (preprint), a server with only in-body permission checks exposed forbidden tools in 152 of 720 trials and permission-aware visibility cut that to 0 of 720, yet models named a hidden tool in up to 94% of settings when it was inferable from the prompt.
- EV-0027: A capable agent skipped the index and guessed the page (Preprint). A preregistered ablation on a 709-page Markdown wiki (preprint) found that a capable tool-using agent never loaded the compact catalogue index, inferring page paths from the question instead, while retrieval-based access kept answer quality non-inferior and cut cost by about a third to over half.
