MCP tool design: why fewer, task-shaped tools win
Your agent doesn't read your API docs. It reads your tool list every turn, and it has to choose. Most MCP servers that disappoint in production aren’t broken. They’re hard to choose from. This guide covers how we design tools agents use correctly, and how we prove it.
Tools are a user interface, and the user is a model
Every tool’s name, description, and input schema goes into the model’s context on every turn. To act, the model has to read that list, decide which tool matches the user’s intent, and fill in arguments correctly. It’s a reading-comprehension task under a token budget, repeated constantly. Anything that makes the list longer, vaguer, or more repetitive makes the task harder.
The endpoint-mirroring trap
The fastest way to build an MCP server is to expose one tool per API endpoint. OpenAPI generators produce exactly that. It costs you three ways:
- Context. Dozens of tool definitions are loaded before the user says a word, crowding out the conversation and the data the agent actually needs.
- Ambiguity. Near-duplicates like
get_user,get_user_by_id, andsearch_usersforce the model to guess, and it guesses differently across clients and models. - Chains. A task that should be one call becomes five: look up the ID, fetch the record, fetch the comments, fetch the owner, then act. Every extra call is another chance to go wrong.
A generated server is a fine starting point. It’s a poor finish line.
Design around jobs, not resources
Start from what people will ask an agent to do, not from your data model. Write down the ten to twenty most common jobs (“find the open tickets for Acme”, “reply to this customer”, “escalate this to tier two”) and design one tool per job.
- Name tools verb-first after the job:
find_tickets,reply_to_customer,escalate_ticket. - Merge reads that always travel together. If every reply needs the ticket,
its history, and the customer, return them from one
get_ticket_contextcall. - Split tools by consequence. Keep reads and writes separate so they can carry different scopes and approval rules.
Names, descriptions, and schemas
The description is the tool’s only documentation the model will read. Say when to use the tool, what it returns, and what to call next. Then make the schema do as much of the work as possible:
- Enums instead of free text wherever the values are known.
- Sensible defaults, and as few required fields as the job allows.
- Accept the identifiers people actually use (an email, a company name) and resolve internal IDs on the server.
- A short example in the description where ambiguity is likely.
✗ name: "get_tickets" description: "GET /v2/tickets" ✓ name: "find_tickets" description: "Search support tickets by text, status, or assignee. Use before get_ticket_context. Returns ≤20 matches with ids."
Return what the next step needs
A tool result is input to the model’s next decision. Keep it concise and structured, and include the stable IDs the next call will need. Paginate with cursors and say clearly when more results are available. When a field is too large to return in full, truncate it and say so, so the agent doesn’t mistake a fragment for the whole. Where the client supports structured content, return it alongside the text.
Errors an agent can recover from
A stack trace or a bare 400 tells the model nothing. An error should say
what was wrong and what to do instead, for example status must be one of open, pending, closed. Mark
which errors are worth retrying. Good errors turn a failed call into a
corrected one, instead of a confused apology to the user.
Prove it with evals
Whether an agent “seems to get it” isn’t a quality bar. Write thirty to a hundred realistic scenarios drawn from the jobs list, run them against the clients and models your users actually have, and measure:
- Tool-selection accuracy: did it pick the right tool?
- Argument correctness: did it fill the inputs properly?
- Task success: did the job get done?
- Calls per task, and the token size of
tools/list.
Rerun the suite in CI on every tool change. Descriptions are code: a one-word edit can move selection accuracy, and you want to know before your users do.
A before and after
Illustrative- Tools
- 47 → 9
- Tool-selection accuracy
- 61% → 96%
- tools/list size
- 18.4k → 3.1k tokens
- Calls per task
- 7.2 → 2.4
Next, read Securing a remote MCP server. If you already have a server and want to know how it scores, that’s our MCP Audit & Eval.
Want this done for your product?
We design the tools, build the server, and hand you the eval suite.
Start an MCP project