Begin with one clear user intent
A good tool has a recognizable job and a crisp boundary. It is neither a mechanical copy of one internal endpoint nor a vague mega-tool that can do anything.
Weak
customer_api_action
“Performs an action on a customer.” The model cannot tell when to use it, what it changes, or how it differs from other tools.
Improved
prepare_customer_refund
“Validate refund eligibility and return a reviewable proposal. Does not move money. Use before issue_refund.”
What every definition should communicate
| Field | Design question | Good practice |
|---|---|---|
| Name | Can the model distinguish it quickly? | Stable, action-oriented, specific, meaningfully namespaced where aggregated hosts may see collisions. |
| Title | Can a person recognize the action? | Short human-readable label for approvals and interfaces. |
| Description | When should—and should not—the tool be used? | State intent, prerequisites, limits, side effects, and distinction from nearby tools. |
| Input schema | Can invalid or ambiguous calls be prevented? | Explicit required fields, descriptions, enums, formats, bounds, and no model-guessed IDs. |
| Output schema | Can a host or model reuse the result reliably? | Predictable structured fields, stable IDs, source references, and explicit status. |
| Annotations | What risk does the tool claim? | Accurate read-only, destructive, idempotent, and open-world hints; never a substitute for enforcement. |
| Authorization | Who may call it on which records? | Validate identity, tenant, role, resource, and scope inside every handler. |
Write descriptions for selection
The description should make a tool easy to retrieve and hard to confuse. State:
- What outcome it produces.
- When it is the correct tool.
- When another tool should be used instead.
- Any prerequisite identifier or prior step.
- Whether it reads, prepares, writes, sends, publishes, or deletes.
- Important limits: date range, result count, supported record type, or required role.
Keep the critical distinction near the beginning. Progressive tool-search systems often rely on server and tool summaries to decide what full definitions to load.
Make inputs constrained and explicit
Loose schema
{
"query": "string",
"options": "object"
}
Focused schema
{
"customer_id": "cus_...",
"status": ["open", "past_due"],
"created_after": "2026-01-01",
"limit": 25
}
Use actual JSON Schema types, formats, required fields, enums, bounds, and descriptions in the implementation. The example is simplified for readability.
Return compact, composable results
Prefer structured content that another tool call can reuse without parsing prose. Return stable IDs, display labels, timestamps, status, provenance, pagination cursors, and the fields needed for the next decision. Omit secrets, internal diagnostics, and large irrelevant payloads.
If a result may be large, design filtering and pagination at the tool boundary. A model should not receive 10,000 rows just to count five exceptions.
Separate risk boundaries
Read and write behavior should generally be separate. Preparation and execution should also be separate when a person needs to inspect the effect.
get_invoiceread
prepare_creditcalculate + preview
issue_creditapproved write
Design for retries and partial failure
Make safe retries explicit. Use idempotency keys for consequential writes, stable proposal or job handles, and result fields that distinguish accepted, completed, partially completed, and failed work. If a call commits one side effect before another fails, report the committed effect clearly.
Return errors the model can act on
A tool execution error should explain the correctable issue without leaking internals: missing account ID, ambiguous record, expired proposal, unsupported date range, permission denied, or temporary downstream unavailability. Reserve protocol-level errors for malformed or unknown protocol requests.
Avoid these two extremes
Hundreds of micro-tools
The API directory
Near-duplicate operations crowd context and make selection ambiguous. Consolidate only where the user intent, permission, and side effect remain clear.
One mega-tool
The hidden application
A generic action parameter hides capability, risk, and approval meaning. Split materially different jobs and authority boundaries.
Evaluate discovery separately from execution
For each tool, test whether the host finds it for direct and indirect requests, ignores it for negative cases, distinguishes it from neighbors, supplies valid arguments, handles empty and error results, and shows the right approval. A perfectly implemented handler is useless if the model never finds it—or finds it for the wrong job.
Design review checklist
Could a new teammate choose this tool correctly from its metadata alone?
If not, the model will struggle too. Improve the user intent, boundary, description, schema, or neighboring tools before adding more prompt instructions.
Primary references: OpenAI’s official tool-planning guide, the MCP tool specification, and Anthropic’s tool implementation guidance.