Claude Tool Use Cheatsheet
A one-page reference for the Messages API tool-use loop: request shape, response blocks, stop_reason, tool_choice, schema rules, server tools, and common gotchas.
Minimal Request
client.messages.create(
model="claude-opus-4-7",
max_tokens=1024,
tools=[{"name":"...","description":"...",
"input_schema":{...}}],
tool_choice={"type":"auto"}, # optional
messages=[{"role":"user","content":"..."}])
Response (Message object)
{
"id": "msg_01ABC...",
"type": "message",
"role": "assistant",
"model": "claude-opus-4-7",
"stop_reason": "tool_use", // see table below
"stop_sequence": null,
"content": [
{"type":"text","text":"I'll check the weather."},
{"type":"tool_use",
"id":"toolu_01A09q90qw90lq917835lq9",
"name":"get_weather",
"input":{"location":"San Francisco, CA"}}
],
"usage": {
"input_tokens": 472,
"output_tokens": 89,
"cache_read_input_tokens": 0,
"cache_creation_input_tokens": 0
}
}
Access in SDK: resp.content (list of blocks), resp.stop_reason, resp.usage.input_tokens. Iterate blocks and check b.type == "tool_use" to find calls; use b.id, b.name, b.input.
tool_choice
| Value | Use when |
|---|---|
{"type":"auto"} | Default; tool optional |
{"type":"any"} | Must call some tool |
{"type":"tool","name":"X"} | Must call this tool |
{"type":"none"} | Disable tools this turn |
⚠ any / tool block text preamble and are incompatible with extended thinking.
stop_reason → Action
| Value | Action |
|---|---|
end_turn | Done |
tool_use | Run tool, send tool_result, loop |
max_tokens | Raise cap |
pause_turn | Re-send to continue server-tool loop |
refusal | Surface to user |
Content Blocks
| Assistant (response) | User (request) |
|---|---|
text | text |
thinking / redacted_thinking | image |
tool_use (id, name, input) | document |
server_tool_use | tool_result (tool_use_id, content, is_error?) |
web_search_tool_result | |
code_execution_tool_result |
Order: tool_result must come before any text in a user message, and immediately after the assistant's tool_use turn.
The Loop (6 lines)
while True:
resp = client.messages.create(model, tools=tools,
messages=messages, max_tokens=1024)
messages.append({"role":"assistant","content":resp.content})
if resp.stop_reason != "tool_use": break
results = [{"type":"tool_result","tool_use_id":b.id,
"content": run(b.name, b.input)}
for b in resp.content if b.type=="tool_use"]
messages.append({"role":"user","content":results})
input_schema Keywords (supported)
| Keyword | Where | Example |
|---|---|---|
type | any | string, integer, number, boolean, null, array, object |
description | any | "Stock ticker" |
enum / const | scalars | ["celsius","fahrenheit"] |
default | any | "celsius" |
format | string | date, date-time, email, uri, uuid, ipv4 |
items | array | {"type":"string"} |
properties, required | object | — |
additionalProperties | object | false (strict mode) |
minItems | array | 0 or 1 only |
pattern | string | "^[A-Z]{1,5}$" |
anyOf / allOf | any | composition |
NOT supported (strict): minimum, maximum, minLength, maxLength, maxItems, uniqueItems, oneOf, not, recursion, regex lookaheads / backrefs. Put these in description.
Full Tool Schema Example
{
"name": "search_products",
"description": (
"Search the product catalog by keyword and filters. "
"Returns up to 20 matching products with id, name, price, "
"and stock. Use when the user asks to find/browse products. "
"Does NOT place orders, use place_order for that."
),
"strict": true,
"input_schema": {
"type": "object",
"additionalProperties": false,
"required": ["query"],
"properties": {
"query": {
"type": "string",
"description": "Search keywords, e.g. 'wireless headphones'.",
"pattern": "^.{1,200}$"
},
"category": {
"type": "string",
"enum": ["electronics","apparel","home","books","other"],
"default": "other",
"description": "Category filter."
},
"max_price": {
"type": "number",
"description": "Upper price bound in USD (must be > 0)."
},
"in_stock_only": {
"type": "boolean",
"default": true,
"description": "If true, exclude out-of-stock items."
},
"tags": {
"type": "array",
"description": "Tag filters; products must match ALL.",
"items": {"type": "string"},
"minItems": 0
},
"sort": {
"type": "object",
"description": "Sort config.",
"additionalProperties": false,
"required": ["by"],
"properties": {
"by": {"type":"string","enum":["price","rating","newest"]},
"desc": {"type":"boolean","default": false}
}
},
"released_after": {
"type": "string",
"format": "date",
"description": "ISO date, e.g. '2026-01-01'."
},
"contact_email": {
"type": ["string","null"],
"format": "email",
"description": "Optional email for saved-search alerts."
},
"id_or_sku": {
"description": "Either a UUID (id) or SKU string.",
"anyOf": [
{"type":"string","format":"uuid"},
{"type":"string","pattern":"^SKU-[A-Z0-9]{6}$"}
]
}
}
}
}
Covers: type, description, enum, default, format, pattern, nested object, array + items, minItems, anyOf, nullable union, required, additionalProperties:false, strict:true.
tool_result Shapes
// Success, string
{"type":"tool_result","tool_use_id":"toolu_01",
"content":"15°C"}
// Success, multi-block
{"type":"tool_result","tool_use_id":"toolu_01","content":[
{"type":"text","text":"15°C"},
{"type":"image","source":{"type":"base64",
"media_type":"image/jpeg","data":"..."}}]}
// Error
{"type":"tool_result","tool_use_id":"toolu_01",
"content":"Rate limit. Retry after 60s.",
"is_error":true}
Where Tools Run
| Kind | Who runs | Examples |
|---|---|---|
| User-defined client | Your app | get_weather, query_db |
| Anthropic-schema client | Your app | bash, text_editor, computer, memory |
| Server | Anthropic | web_search, web_fetch, code_execution, computer use (beta), bash (beta), tool_search, memory, mcp connector |
Server Tools (run by Anthropic)
| Tool | type / name | Purpose |
|---|---|---|
| Web search | web_search_20250305 / web_search | Query the live web; returns web_search_tool_result with citations. |
| Web fetch | web_fetch_20250910 / web_fetch | Fetch a specific URL (HTML/PDF) as context. Beta header required. |
| Code execution | code_execution_20250825 / code_execution | Python sandbox with numpy, pandas, matplotlib. Files via Files API. Returns code_execution_tool_result. |
| Computer use | computer_20250124 / computer | Screenshot plus mouse/keyboard on a VM. Beta. |
| Bash (server) | bash_20250124 / bash | Shell in the code-exec sandbox. Pairs with code_execution. |
| Text editor | text_editor_20250728 / str_replace_based_edit_tool | View / create / edit files in sandbox. No undo_edit in latest. |
| Memory | memory_20250818 / memory | Persistent file-backed memory across turns / sessions. |
| Tool search | tool_search_tool_regex_20251119 (regex) or ..._20250916 (semantic) | Lazy-load tool defs from a large registry. Cuts prompt cost. |
| MCP connector | mcp_servers (top-level, not in tools) | Attach remote MCP servers; Claude calls their tools via server. |
Usage: declare as {"type":"<versioned>","name":"<name>"} in tools (no input_schema). Many require a beta header (e.g. anthropic-beta: computer-use-2025-01-24, web-fetch-2025-09-10, code-execution-2025-08-25).
Response blocks: server tools emit server_tool_use plus a matching *_tool_result block (e.g. web_search_tool_result). You do not send tool_result back. Expect stop_reason: "pause_turn" on long server-tool loops; re-send the message to continue.
Definition Best Practices
- Descriptions: 3 to 4 or more sentences. What, when, parameter meaning, limitations.
- Namespace:
github_list_prs, not baresearch. - Consolidate: one
manage_prwith anactionparam beats three tools. - High-signal responses: stable IDs, no raw payload dumps.
- Strict mode:
"strict":trueplus"additionalProperties":falsegives a guaranteed schema match. - Combine
tool_choice:anyplusstrict:truefor guaranteed valid calls.
Cost Overhead
| Model | auto / none | any / tool |
|---|---|---|
| Opus 4.7 / Sonnet 4.6 / Haiku 4.5 | 346 tok | 313 tok |
| Haiku 3.5 | 264 tok | 340 tok |
Plus tokens for the tools array, tool_use, and tool_result. Server tools add per-call fees.
Gotchas
- Changing
tool_choicemid-conversation invalidates prompt cache. any/toolplus extended thinking returns a 400 error.tool_resultmust immediately follow the matchingtool_useturn.- Write instructive error messages so Claude can recover.
- No PHI in schema
enum/const/pattern/ property names (cached separately).