What you will be able to do
- Sort a tool into user-defined client, Anthropic-schema client, or server-executed, and say what your application has to do for each
- Contrast client-side and server-side tools: who runs the code, who drives the loop, and what comes back (tool_use and tool_result vs. server_tool_use, pause_turn, mixed turns)
- Write a tool definition with name, description, input_schema, and optionally input_examples and strict
- Write tool descriptions that steer Claude toward the right tool
- Apply Anthropic's guidance on tool set construction: consolidation, namespacing, and high-signal responses
- Configure tool_choice and server tool entries correctly, including the restrictions on forced tool use
Key concept
Tool use as a contract — You declare which operations exist and what shape their inputs take. Claude decides when to call them and sends back a structured request. Claude never runs code itself: your application or Anthropic's servers carry out the call and return the result.
1.Where a tool runs decides what you build
Tool use (also called function calling) lets Claude call functions that you define or that Anthropic provides. Before writing any schema, decide where the tool's code will run. The docs treat this as the main way tools differ, and it fixes what your application is responsible for. There are three buckets. User-defined client tools carry most tool-use traffic: you write the schema, run the code, and return the result. Anthropic-schema client tools (memory, bash, text_editor, computer, browser) work the same way, except Anthropic publishes the schema. Server-executed tools (web_search, web_fetch, code_execution, tool_search) run on Anthropic's infrastructure, so you never build a tool_result for them.
| Approach | When to use it | What you handle |
|---|---|---|
| User-defined client tools | Custom business logic, internal APIs, proprietary data | Execution and the agentic loop |
| Anthropic-schema client tools | Standard dev operations (bash, file editing, desktop and browser control) | Execution; Claude calls the tool reliably because the schema is trained-in |
| Server-executed tools | Web search, code sandbox, web fetch | Nothing to execute; you read the results |
Why use Anthropic's bash schema when you could write your own shell tool? Claude has been optimized on many successful trajectories that use those exact signatures. As a result it calls them more reliably and recovers from errors better than it would with a custom equivalent.
The three buckets collapse into a two-way split: client-side vs. server-side tools. Client-side tools (user-defined and Anthropic-schema) run in your application. Claude answers with stop_reason: "tool_use" and one or more tool_use blocks, your code runs each call, and you send back a tool_result block. Because the model can't run your code, every call is a round trip, and your application drives a while loop that continues as long as stop_reason is tool_use. If a client tool fails, you report it with is_error: true. Server-side tools run on Anthropic's infrastructure inside their own loop. The response contains server_tool_use blocks showing what ran and what came back, you never construct a tool_result, and you don't handle is_error for them. Two cases need your attention. If the server loop hits its iteration limit, the response has stop_reason: "pause_turn", and you re-send the conversation, including the paused response and the same tools, to let Claude continue. If Claude calls a server tool and a client tool in the same group of parallel calls, the API does not run the server tool yet: the response has stop_reason: "tool_use" and a server_tool_use block with no result block. You return the client tool_result blocks, keep the same tools array, and the API then runs the deferred server tool.
Checkpoint 1 of 8· Check yourself
A response has stop_reason "tool_use" and contains a server_tool_use block with no result block, plus a client tool_use block. What do you do?
In a mixed turn the API holds the server tool until you return the client tool results. Unlike pause_turn, you continue with tool_result blocks rather than re-sending the response.
“Claude can call a server tool and a client tool in the same group of parallel tool calls”Source: platform.claude.com
Checkpoint 2 of 8· Check yourself
Your agent needs a shell tool. Your application will run the commands either way. Why prefer Anthropic's bash tool over a custom run_shell tool?
Anthropic-schema tools are still executed by your application and still need a tool_result. What you gain is a schema Claude was trained on.
“The reason to use an Anthropic-schema tool instead of defining your own equivalent is that these schemas are trained-in.”Source: platform.claude.com
2.Anatomy of a tool definition
You declare client tools in the top-level tools parameter of the request. A user-defined tool has a name, which must match ^[a-zA-Z0-9_-]{1,128}$. It also has a plaintext description and an input_schema, which is a JSON Schema object for the parameters. Behind the scenes, the API turns these definitions into a special system prompt, so everything you write in them becomes context for Claude.
{
"name": "get_weather",
"description": "Get the current weather in a given location",
"input_schema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The unit of temperature, either 'celsius' or 'fahrenheit'"
}
},
"required": ["location"]
}
}Two optional fields make tool calls more dependable. input_examples is an array of sample inputs, which helps most with nested objects and format-sensitive parameters. Every example has to validate against input_schema, otherwise the request returns a 400. Examples also cost prompt tokens, and they don't work on server tools or on the computer use and browser use toolsets. strict: true turns on grammar-constrained sampling. That guarantees the inputs match your schema, so you get passengers: 2 and never the string "two".
Checkpoint 3 of 8· Check yourself
A booking function crashes because Claude sometimes sends passengers as a string instead of an integer. Which change guarantees correctly typed arguments?
Strict mode limits sampling to outputs that fit the schema. Examples and descriptions make good calls more likely, but they don't guarantee them.
“Setting strict: true on a tool definition guarantees Claude's tool inputs match your JSON Schema”Source: platform.claude.com
3.Writing descriptions that drive tool selection
Claude decides whether to call a tool based on the user's request and the tool's description. A good description says four things: what the tool does, when to use it and when not to, what each parameter means, and its limits, such as what it doesn't return. Anthropic recommends at least 3–4 sentences per tool, and more for complex ones. Compare this description with the weak alternative, "Gets the stock price for a ticker."
{
"name": "get_stock_price",
"description": "Retrieves the current stock price for a given ticker symbol. The ticker symbol must be a valid symbol for a publicly traded company on a major US stock exchange like NYSE or NASDAQ. The tool will return the latest trade price in USD. It should be used when the user asks about the current or most recent price of a specific stock. It will not provide any other information about the stock or company.",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
}
},
"required": ["ticker"]
}
}Checkpoint 4 of 8· Exam question
An application must guarantee that Claude calls the `submit_refund` tool on every turn of a specific workflow step, and that no other tool is used in its place. Which `tool_choice` configuration achieves this?
Correct answer: A — `{"type": "tool", "name": "submit_refund"}`
- A. Correct. Setting `tool_choice` to the `tool` type with the specific tool name forces Claude to always use that particular tool, which is the only option that guarantees `submit_refund` specifically rather than any tool.
- B. `any` forces Claude to use one of the provided tools but does not force a particular tool, so Claude could call a different tool in the set instead of `submit_refund`.
- C. `auto` lets Claude decide whether to call any tool at all; a prompt instruction can steer behavior but provides no guarantee, unlike a forced `tool_choice`.
- D. `none` prevents Claude from using any tools at all, and array position has no effect on tool selection, so this configuration guarantees the opposite of the desired outcome.
Checkpoint 5 of 8· Check yourself
Which item does Anthropic's guidance NOT list as something a tool description should cover?
Claude only sees the schema and the result, never your implementation. A description should explain behavior, scope, parameters, and limits.
“Claude never sees your implementation; it only sees the schema you provided and the result you returned.”Source: platform.claude.com
4.Building a tool set that scales
Good individual tools can still add up to a confusing set. Anthropic gives three construction rules. Consolidate: one tool with an action parameter beats separate create_pr, review_pr, and merge_pr tools, because fewer tools leave less room for picking the wrong one. Namespace: when tools span services, prefix names with the service, as in github_list_prs and slack_send_message. This matters most when you use tool search. Return high-signal results: send back stable, meaningful identifiers such as slugs or UUIDs, and only the fields Claude needs for its next step. Bloated responses waste context.
Also check that a task needs a tool in the first place. Tools fit side effects, fresh or external data, outputs that must have a fixed shape, and calls into existing systems. They don't fit summarization, one-shot Q&A, or trivial work where the extra round trip would dominate. Anthropic's rule of thumb: if you're writing a regex to extract a decision from model output, that decision should have been a tool call.
Checkpoint 6 of 8· Exam question
A custom `fetch_invoice` client tool calls a downstream billing API. During a load spike the API begins returning HTTP 503 responses. The engineering team wants Claude to recognize the failure, explain it to the user, and avoid treating the 503 body as valid invoice data. How should the tool result be constructed for this call?
Correct answer: A — Return a `tool_result` block with `tool_use_id` set to the original call's id, `content` describing the 503 and suggesting a retry window, and `is_error` set to `true`
- A. Correct. Setting `is_error: true` explicitly marks the call as failed rather than letting Claude parse ambiguous data, and an instructive message (what failed, what to try next) gives Claude the context needed to inform the user or retry appropriately.
- B. Omitting `is_error` forces Claude to guess whether the returned content is valid invoice data or an error body, risking the 503 payload being treated as real data instead of being surfaced as a failure.
- C. Every `tool_use` block must be immediately followed by a matching `tool_result`; omitting it produces a malformed message sequence and the API will reject the request.
- D. Marking a failed call as `is_error: false` with empty content misrepresents the outcome, and Claude has no signal that the billing API call did not succeed.
Checkpoint 7 of 8· Match them up
Match each tool-set problem to the guideline that addresses it
Tap a term, then the definition that fits it.
Each rule targets one failure: consolidation reduces selection ambiguity, namespacing removes collisions, lean results save context, and schemas replace parsing.
“Fewer, more capable tools reduce selection ambiguity and make your tool surface easier for Claude to navigate.”Source: platform.claude.com
5.Configuring requests for external systems: tool_choice and server tools
The request also controls *whether* Claude calls tools. With the default tool_choice of auto, Claude decides on each turn. You can push it with the system prompt: "Use the tools to investigate before responding." increases tool use. To require a call rather than rely on prompting, set tool_choice. Adding disable_parallel_tool_use: true limits Claude to at most one tool call per turn.
| tool_choice | Behavior |
|---|---|
| auto | Claude decides whether to call a tool (default when tools are provided) |
| any | Claude must use one of the provided tools, but not a particular one |
| tool | Claude must use the named tool |
| none | Claude cannot use tools (default when no tools are provided) |
Forcing a tool has costs. With any or tool, the API prefills the assistant turn, so Claude writes no explanation before its tool_use blocks. Forced tool use also isn't supported everywhere. Manual extended thinking rejects any and tool. On Claude Opus 5.5, Claude Sonnet 5.5, Claude Fable 5.1, and Claude Mythos 5.1, any and tool return a 400 error. On those models, use auto with strict tool use, or use structured outputs. Server tools need very little setup: you enable them with a date-versioned type. For remote MCP servers, the MCP connector connects from the Messages API without a separate MCP client.
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
tools=[{"type": "web_search_20260209", "name": "web_search"}],
messages=[{"role": "user", "content": "What's the latest on the Mars rover?"}],
)
print(response.content)Checkpoint 8 of 8· Check yourself
On Claude Opus 5.5 you send tool_choice: {"type": "tool", "name": "get_weather"}. What happens?
Opus 5.5 and the other models in that group reject forced tool use. The documented alternative is auto plus strict tool use.
“any and tool return a 400 error”Source: platform.claude.com
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Server-side tools need the same handling as client-side tools: build a tool_result and set is_error on failures.Why is that wrong?
Only client tools need your tool_result and is_error handling. Server tools run in Anthropic's own loop and show up as server_tool_use blocks. The exceptions to watch for are pause_turn and a turn that mixes server and client tools.
Covered in Where a tool runs decides what you build
2.If Claude picks the wrong tool or calls it out of scope, turn on strict mode or add parameters.Why is that wrong?
Strict mode only guarantees the shape of the input. Which tool Claude picks, and when, depends on the description, so rewrite it to state scope, when not to use the tool, and what it returns.
3.tool_choice: tool is always the way to force a specific tool call.Why is that wrong?
Some models reject it with a 400, including Opus 5.5, Sonnet 5.5, Fable 5.1, and Mythos 5.1, and so does manual extended thinking. On those, use auto with strict tool use or structured outputs.
Covered in Configuring requests for external systems: tool_choice and server tools
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“The primary axis along which tools differ is where the code executes.”
↩︎ Where a tool runs decides what you build“For web_search, web_fetch, code_execution, and tool_search, Anthropic runs the code.”
↩︎ Where a tool runs decides what you build“Client-executed tools (both user-defined and Anthropic-schema) require your application to drive a loop.”
↩︎ Where a tool runs decides what you build“You never construct a tool_result block for these tools.”
↩︎ Where a tool runs decides what you build“if you're writing a regex to extract a decision from model output, that decision should have been a tool call.”
↩︎ Building a tool set that scales“Tool use is a contract between your application and the model.”
↩︎ Key concept“The reason to use an Anthropic-schema tool instead of defining your own equivalent is that these schemas are trained-in.”
↩︎ Checkpoint“Claude never sees your implementation; it only sees the schema you provided and the result you returned.”
↩︎ Checkpoint - 2.
“Claude can call a server tool and a client tool in the same group of parallel tool calls”
↩︎ Where a tool runs decides what you build - 3.
“The name of the tool. Must match the regex ^[a-zA-Z0-9_-]{1,128}$.”
↩︎ Anatomy of a tool definition“Invalid examples return a 400 error”
↩︎ Anatomy of a tool definition“Aim for at least 3–4 sentences for each tool description, more if the tool is complex.”
↩︎ Writing descriptions that drive tool selection“Bloated responses waste context and make it harder for Claude to extract what matters.”
↩︎ Building a tool set that scales“the models will not emit a natural language response or explanation before tool_use content blocks”
↩︎ Configuring requests for external systems: tool_choice and server tools“Provide extremely detailed descriptions. This is by far the most important factor in tool performance.”
↩︎ Exam trap 2“auto with strict tool use to guarantee schema-valid tool inputs, or structured outputs when you need a response in a fixed JSON shape”
↩︎ Exam trap 3“Provide extremely detailed descriptions. This is by far the most important factor in tool performance.”
↩︎ Prediction“Fewer, more capable tools reduce selection ambiguity and make your tool surface easier for Claude to navigate.”
↩︎ Checkpoint“any and tool return a 400 error”
↩︎ Checkpoint - 4.
“Setting strict: true on a tool definition guarantees Claude's tool inputs match your JSON Schema”
↩︎ Anatomy of a tool definition - 5.
“Claude determines when to call a tool based on the user's request and the tool's description.”
↩︎ Writing descriptions that drive tool selection“Connect to remote MCP servers from the Messages API without a separate MCP client.”
↩︎ Configuring requests for external systems: tool_choice and server tools
Also cited
“Unlike client tools, you do not need to handle is_error results for server tools.”
↩︎ Exam trap 1