Overview
Tool use lets a model emit a structured call that your code executes and answers with a result. Reliable tool use is a schema-and-description problem: the model picks the right tool with valid arguments when the tool is named, typed, and described well. The rules below hold across providers, with Claude API specifics marked; for MCP servers see mcp-tool-design, and for the loop around tools see agent-architecture-patterns.
Write long, specific descriptions
Anthropic calls the description the most important factor in tool performance. Say what the tool does, when to use it and when not to, what each parameter means, what it returns, and what it does not return. Aim for at least three or four sentences; name units and formats. Weak: “Gets the stock price for a ticker.” Strong: it adds the exchanges supported, that it returns the latest trade price in USD, and that it provides nothing else about the company.
On the Claude API, add input_examples (schema-validated example inputs) for tools with nested or format-sensitive arguments. They cost roughly 20 to 50 tokens each for simple inputs and 100 to 200 for nested ones, and they are not supported on server tools.
Shape tools around workflows
Fewer, more capable tools reduce selection ambiguity: a schedule_event tool that checks availability and books beats three endpoint wrappers. Prefix names with the service (github_list_prs) when a library spans several. Keep destructive operations separate from reads so confirmation and permission rules can target them. Overlapping tools make the model guess; keep each tool’s job distinct.
Type every argument and use strict mode
Declare JSON Schema types, mark only the inputs the tool cannot default as required, use enums for closed sets, and add format hints. Claude tool names must match ^[a-zA-Z0-9_-]{1,128}$. Set strict: true on a tool definition to guarantee schema-valid inputs; it removes missing parameters and type mismatches. The discipline is the same as structured-output.
Validate inputs before executing
Strict mode checks shape, not truth. Validate against business rules before the call touches a system: the model can supply a plausible ID that does not exist or a value in range but wrong. Validation is also the first defense when arguments derive from untrusted text; see prompt-injection-defense.
Return errors the model can act on
Return a failed call as the tool result with is_error: true and a message that says what went wrong and what to try next: “order_id not found; call search_orders first” or “Rate limit exceeded. Retry after 60 seconds.” A bare “Error 500” makes the model retry blindly. Claude retries an invalid call two or three times before giving up, so cheap, clear errors pay for themselves.
Follow the Claude API rules for tool_choice and results
tool_choiceisauto(default),any,tool, ornone. On Claude Opus 5.5, Sonnet 5.5, and Fable 5.1,anyandtoolreturn a 400 error; manual extended thinking also rejects them. Useautowithstrict: true, or structured outputs when you need a fixed JSON shape. Changingtool_choiceinvalidates cached message blocks.- A
tool_resultmessage must immediately follow itstool_usemessage, andtool_resultblocks must come first in the content array, before any text. Otherwise the API returns 400. - Treat tool results as untrusted: they can carry instructions from web pages, email, or third-party APIs.
Keep the tool surface minimal and measured
Expose the fewest tools that solve the task, gate destructive actions behind confirmation, sandbox side effects, and rate-limit per session. Tool definitions are context, so prune tools the logs show are unused, and evaluate with realistic tasks that need several calls. See reliable-agents-in-production and tool-use.