Designing Tools for Agents vs Designing APIs for Developers
One endpoint, one tool is the obvious mapping and the wrong one. APIs assume a consumer who reads docs once and writes a loop — an agent re-decides everything from a paragraph, every call.
Wrapping an existing API as agent tools looks like a mapping exercise: one endpoint, one tool. The result usually underperforms, because APIs are designed for a consumer with properties an agent doesn't have.
A developer reads documentation once, writes a loop, handles errors deliberately, and keeps a mental model of the whole system. An agent re-decides everything on every call, from whatever is in its context. Design for that consumer and several conventions invert.
Where the two diverge
Composition. A developer chains calls: fetch the order, fetch the customer, fetch the plan, combine. Each round trip is cheap and the logic is written once. For an agent, each is a turn — a full context re-send and a model call.
→ Tools should be coarser than endpoints. One get_order_context(order_id) returning the order, the customer's tier, and the return-window status beats three calls the agent must sequence. What's normalized in an API should be denormalized in a tool.
Discovery. A developer explores an API, reads reference docs, and learns what's available. An agent knows only what's in the descriptions, right now. Anything requiring "you'd know this from the guide" isn't available to it.
Error handling. A developer maps status codes to behavior once. An agent reads the error as text and decides afresh, so the error must say what to do — retryable or terminal, and what the alternative is.
Pagination and defaults. A developer writes the cursor loop deliberately. An agent re-decides whether to continue and is easily satisfied by a plausible first page. Tools want generous limits and loud incompleteness.
Idempotency. A developer knows which operations are safe to retry. An agent may repeat a call after a summarization step drops the earlier result. Write tools need idempotency keys much more than their API equivalents do.
The shape that works
Design tools around tasks, not around resources.
An API exposes resources because that's a good organizing principle for a general-purpose interface. A tool surface should expose the things an agent needs to do — which is a smaller, more specific set, shaped by your actual use cases.
API: GET /orders/{id}
GET /customers/{id}
GET /plans/{id}
GET /orders/{id}/returns
Tools: get_order_context(order_id) # everything needed to reason about one order
find_orders(filter...) # merged search
issue_refund(approval_id) # one privileged action, proof-gated
Fewer tools, each answering a question someone actually asks. ⚠️ The temptation with a large existing API is to expose all of it — that maximizes the tool list, degrades selection accuracy, and consumes context on tools that are never called.
The wrapper is where the work goes
Between the API and the agent sits a layer that does what a developer would have done in their client code:
- Denormalizes — joins what the agent will need together.
- Filters fields — returns what's relevant, not the full object.
- Normalizes units and formats — explicit currencies, ISO timestamps.
- Translates errors into actionable instructions.
- Enforces policy — permission checks with the end user's identity, not the service account's.
- Adds idempotency to writes.
- Handles pagination internally where a bounded "all" is feasible.
This layer is the actual product. Treating tools as a thin proxy over an API leaves all of that undone, and every one of the resulting failures shows up as "the model got it wrong."
✅ A quick audit of an existing tool surface
For each tool:
- Does using it require knowledge that isn't in its description?
- Does the agent typically call it together with another? → Merge them.
- Does its result need a follow-up call to be usable? → Include that data.
- Are its errors actionable as text?
- If it writes, is it safe to call twice?
- Would a competent person, seeing only the description and schema, use it correctly?
That last question is the whole test, and it's the one that catches wrapped-API tools most reliably.
The takeaway
An API optimizes for a consumer who reads docs once and writes a loop. A tool surface optimizes for one that re-decides everything, every call, from a paragraph. So: coarser tools shaped around tasks, denormalized results, explicit units, actionable errors, idempotent writes, and a curated list rather than complete coverage. The wrapper layer isn't plumbing — it's where most of the reliability comes from.