Tool catalog & naming
Controls: Which tools exist in a session, and what they are named.
Blind to: Whether the schema of a chosen tool is well designed.
Get it wrong: Near-identical tools crowd the list, and the model guesses between them.
Six surfaces, 24 named design rules, and five ways a tool interface fails. The tools and the context an agent works through are the product surface. Most complaints that an agent is unreliable trace back to the interface.
An agent sees your system differently from a person. It sees a list of tool names and a schema for each tool. It sees the context assembled ahead of it and the result of each call. A person made every one of those design decisions, on purpose or by default. A system that looks unreliable often has an interface that nobody designed.
These rules apply to any protocol and any framework. MCPMCP is an open standard for connecting LLM applications to tools and data sources. standardizes how a tool call crosses a process boundary. It says nothing about how many tools to expose, what to name them, or what a good response looks like. You make those decisions on every surface below. This is true for MCP and for a plain function call in your own codebase.
Each surface controls one part of the interface and cannot see the rest. A correct surface does not fix the others.
Controls: Which tools exist in a session, and what they are named.
Blind to: Whether the schema of a chosen tool is well designed.
Get it wrong: Near-identical tools crowd the list, and the model guesses between them.
Controls: The shape of the inputs to one tool.
Blind to: Whether the result that comes back is any good.
Get it wrong: A loose schema lets the model invent a plausible argument instead of supplying a real one.
Controls: What the model reads when a call returns.
Blind to: Whether the call was the right one to make.
Get it wrong: A response built for a human in a debugger buries or drops the one thing the model needed.
Controls: What occupies the token budget at each step: tool definitions, retrieved content, history, and the task.
Blind to: Whether any piece placed in context is trustworthy.
Get it wrong: The task is the first thing truncated, because it was assembled last with no reserved share.
Controls: What a tool call may do once it executes.
Blind to: Whether the call needed to happen, or whether its name and scope make sense.
Get it wrong: A shared, broad credential gives every bad call the reach of the most dangerous tool in the session.
Controls: How a tool call crosses a process or team boundary, and whether anyone can reconstruct what happened afterward.
Blind to: Whether the tool on the other side of that boundary is well designed inside.
Get it wrong: A protocol ships with no operations story. Nobody can say who called what, or trust the version they pinned.
Filter by applicability (read-only, writes, autonomous), then copy the visible list as a Markdown checklist.
Showing all 24 rules
Every tool definition sits in context on every turn. The model reads it whether or not that turn needs it. A session with forty tools pays for forty schemas before the model reasons about anything. The catalog layer decides which tools exist and what they are called. It also decides how many a session loads. This is the first place a token budget disappears. Get the count and the names right, and tool selection improves with little extra effort. Get them wrong, and no later context engineeringContext engineering decides what occupies a model's context window at every step, and in what order. helps a model that cannot tell two tools apart.
The schema is the only briefing the model gets before it calls a tool. It has no comments and no onboarding doc. It has field names and types, plus the constraints the schema author chose to encode. If the schema is loose, the model fills the gap with a plausible guess, whether or not a real value exists. Tool callingTool calling lets a model request a structured action instead of only generating text. is only as reliable as this contract. You fix a hallucinated argument here, with an enum or a validated pattern. A better prompt does not fix it.
A tool response becomes the model's whole picture of what just happened. The model has no side channel to learn that a call failed. The response format must carry that signal. A raw database dump or a wall of UUIDs suits a human at a debugger. So does an HTTP 200 that wraps an error string. Each suits a model badly, because it reasons about the result on the next turn within a fixed token budget. A high-signal response lets the model notice a failure. A poor one lets the model report missing data as a fact.
Tool definitions and retrieved documents compete with prior turns for one fixed context window. Nothing makes that competition favor the task. Without management, the stable material (system instructions and tool schemas) drifts to the front. There, one reordered field breaks prompt caching. The volatile material, such as this turn's question, gets buried or evicted first. A team should set the context budget once, on purpose. A truncation strategy improvised on the day the window fills is a poor substitute.
A tool call that can write or delete carries a different risk from one that only reads. If you treat them the same, you get one flat credential and one shared identity. The catalog then makes no distinction between them. Every prompt injectionPrompt injection is untrusted input crafted to override a model's system prompt or task. and hallucinated argument inherits the blast radius of the most dangerous tool in the session. This layer cannot stop a bad call from being attempted. It decides how far a bad call can reach before a human or a rollback steps in.
A tool call that crosses a process boundary stops being a function call. The boundary can be a team's API or a vendor's MCP server. The call becomes a contract with an operations story. That story says who may call it and what happens when its shape changes. It also says how anyone reconstructs the events afterward. MCP standardizes the wire format for the crossing. It does not standardize the governance around it. Most failures at this layer come from an org that shipped the protocol and skipped the operations.
No rules match that combination. Clear a filter to see more.
One tool definition, first wrong and then right, in the shape a model reads.
A vague catalog entry and a narrow one, side by side. Only the right pane survives a session with forty other tools in it.
{
"name": "search",
"description": "Searches for stuff.",
"parameters": {
"type": "object",
"properties": {
"options": { "type": "object" }
}
}
} A free-form name, a free-form options bag, no enum, and no cap on how many results come back.
{
"name": "search_kb_by_tag",
"description": "Finds KB articles by tag. Not for fuzzy search.",
"parameters": {
"type": "object",
"properties": {
"tag": {
"type": "string",
"enum": ["billing", "auth", "deploy"]
},
"max_results": {
"type": "integer",
"default": 10,
"maximum": 50
}
},
"required": ["tag"]
},
"response_shape": {
"results": [
{ "id": "string", "title": "string" }
],
"truncated": "boolean"
}
} A narrow name, an enum for the one filter that matters, a bounded max_results, and a declared response shape.
Each failure has a cause on one of the surfaces above. Each has a named symptom that this site documents elsewhere.
Looks like: Two or three tools in one session do nearly the same thing under slightly different names. The model picks the one it saw most often in training. The task may have needed another.
Guardrail: Audit the catalog for near-duplicates before you add a tool. Merge or retire the older one. Do not ship a fourth way to make the same call.
Failure mode: Tool argument hallucinationLooks like: Tool definitions and retrieved results together fill most of the window before the model reaches the question. When something must give, the task is the first thing truncated.
Guardrail: Budget context per slice: instructions, tool definitions, retrieved content, and task. Alarm when a slice crosses its share. Do not discover the dropped task after the fact.
Failure mode: Context overflow drops the taskLooks like: A tool call returns HTTP 200 with an empty or malformed body. The model reports the missing data as a fact. It does not flag a failure.
Guardrail: Give every response a typed status field that the model can branch on: ok, empty, or error. A failure must then appear as a failure. The model does not infer it from a blank body.
Failure mode: Silent tool failureLooks like: A write tool call times out and retries automatically. The mutation then happens twice, or the retry itself burns the budget.
Guardrail: Put an idempotencyAn idempotent operation produces the same result no matter how many times it runs. key on every write call, so a retried request is provably a no-op. Cap retries explicitly. Never leave the ceiling unbounded.
Failure mode: Retry-amplified spendLooks like: A tool response includes retrieved text that reads like an instruction. The model has no structural way to tell data from command, so it follows the text.
Guardrail: Treat everything a tool returns as data. Scope every tool to least privilege, so a followed instruction has nowhere dangerous to go.
Failure mode: Injection via retrieved contentThis page cites no benchmark numbers and no client names. It cites only what this site documents.
The specification text our tool-design and catalogue rules are checked against. Retrieved 2026-08-24.
The schema specification a tool description must satisfy under our rule bank. Retrieved 2026-08-24.
A Ship Audit checks the tool interface your agent runs against: catalog, contract, permissions, and the rest. It tells you which surface is the live risk.
What teams ask us before they scope a tool catalog.
No fixed number applies. The failure mode is near-identical tools crowding the model's choice. Audit for overlap before you add a tool. Cap what loads per session to what the task needs.
Link to this answer: How many tools is too many?Stay in-process until a tool crosses a team or product boundary. MCP costs a server, a transport layer, and an auth story. That cost pays off once another team or product needs to call the same tool. Earlier, it adds operational surface with no boundary to justify it.
Link to this answer: Do we need MCP, or is in-process enough?Start with read-only by default, and add a typed status field to every response. Together they close the two failure modes with the most early damage. One is an over-scoped credential. The other is a silent failure that the model reports as fact.
Link to this answer: Which rule should we start with?The Eval Stack tells you whether the system works. This page covers the interface the agent works through. A contract check on /evals/ scores a tool contract built to the rules above. The two complement each other.
Link to this answer: How does this relate to the Eval Stack?No. Prompt engineering shapes what you ask the model. This page covers the surface the model acts through once it decides to act. A well-designed tool catalog survives a mediocre prompt. A great prompt on a badly designed tool interface still fails at the tool call.
Link to this answer: Is this just prompt engineering?Context engineering decides what occupies the token window at every step, and in what order. That includes tool definitions, retrieved content, history, and the task itself. Prompt engineering is one input to it. See the context surface above.
Link to this answer: What is context engineering, and how does it differ from prompt engineering?Source: https://customlabs.io/tool-design/