Why this page exists
A model that can only emit text is an advisor. A model that can call your functions is a worker. Tool use is the one API feature that turns "Claude tells you the SQL" into "Claude runs the query, reads the result, and writes the summary". Every skill, every MCP server, every agent framework you will ever touch is this loop underneath.
The tool loop 14 min core
Three roles, strictly separated: you define tools, Claude decides, you execute. Claude never runs anything - it asks, you act, you report back.
CoreWhat tool use actually is4 min▶
You pass a list of function descriptions with your request. Claude reads the user's question, and if a tool would help, it stops generating text and instead emits a structured request: "call get_weather with {"city": "Auckland"}". Your code executes the real function and sends the result back as a new message. Claude reads it and either answers or asks for another tool call.
- You define the tools: name, description, input schema. Claude only ever sees these descriptions - it has no idea what your code does beyond what you wrote.
- Claude decides whether to call a tool at all, which one, and with what arguments. This decision is the intelligence you are renting.
- You execute. The API never touches your database, your filesystem, or your network. Every side effect goes through code you wrote, which is exactly where you enforce permissions and limits.
That request-execute-report cycle, repeated until Claude has what it needs, is the agent loop. Claude Code, Cowork, and every MCP integration are this loop with a bigger toolbox.
CoreDefining a tool: name, description, JSON Schema4 min▶
A tool is a dict with three keys. The input_schema is standard JSON Schema - the same vocabulary you know from API specs.
The description carries almost all the weight. Claude uses it to decide WHEN to call the tool - which is the exact same lesson as skill descriptions in Session 3: vague description, tool never fires (or fires when it shouldn't). Say what it does, when to use it, what it returns, and what it is NOT for.
- Name: verb_noun, snake_case, unambiguous.
query_ordersbeatshelper2. - Schema descriptions matter too: per-property descriptions steer the arguments Claude fills in. Include an example value.
- Fewer, sharper tools beat many overlapping ones. If two tools could both plausibly handle a request, Claude has to guess - and so would a human reading your descriptions.
CoreThe loop mechanics: stop_reason, tool_use, tool_result6 min▶
When Claude wants a tool, the response comes back with stop_reason == "tool_use" and one or more content blocks of type tool_use, each carrying an id, the tool name, and the parsed input. You execute, then append TWO messages: the assistant turn exactly as received, and a user turn containing tool_result blocks that echo each tool_use_id. Then you call the API again. Here is the whole thing, runnable:
Things that bite people the first time:
- Echo the assistant message untouched. The
tool_useblocks must be in the history or thetool_resulthas nothing to attach to - the API will reject the request. - tool_result goes in a USER message. You are reporting back, so it is your turn. All results for one response go in one user message.
- Errors are results too. If your function throws, catch it and return the error text with
"is_error": Trueon the tool_result block. Claude will read the error and usually retry sensibly or explain the failure. - Cap the loop. A
for _ in range(10)guard beats an infinite while loop the day a tool starts returning garbage.
Multiple tools and structured data 8 min core
One tool is a feature. Several tools plus Claude's judgment about which to call is a system.
CoreMulti-turn with multiple tools: Claude routes4 min▶
Pass several tools and Claude picks per request - no if/else router needed on your side. A data-team trio:
- The descriptions do the routing. "Prefer this over running a fresh query" is an instruction Claude follows. You are programming the router in English.
- Parallel calls: one response can contain SEVERAL
tool_useblocks when the calls are independent (weather in two cities, three metrics at once). Your loop already handles this - it iterates over all blocks and returns all results in one user message. Execute them concurrently if the functions are slow. - Multi-turn chains: Claude can call
query_database, read the result, decide it needs a second query, and call again - that is just the while loop going around twice. You wrote an agent and it took no extra code.
A four-person data team wrapped exactly this trio around their warehouse as a Slack bot. Stakeholder questions that used to become Jira tickets ("how many active users in Germany last month?") now get answered in 20 seconds, and only the genuinely-new requests reach the team. The entire bot is the loop from Part 1 plus these three definitions - about 120 lines.
CoreTools for structured data: the forced-call trick4 min▶
In 6.1 you extracted JSON by prompting "reply with only JSON" and hoping. The robust version: define a tool whose input schema IS your desired output shape, then force Claude to call it with tool_choice. The tool never executes anything - you just harvest block.input, which the API guarantees matches your schema.
- No markdown fences, no "here is the JSON:", no parse errors. The schema is enforced, enums included.
- tool_choice modes:
{"type": "auto"}(default - Claude decides),{"type": "any"}(must call some tool),{"type": "tool", "name": ...}(must call this one). Forced extraction uses the last. - This is the "structured data with tools" and "flexible tool extraction" lesson from the Bedrock/Vertex courses - same trick, any platform.
Server-side tools and batch processing 8 min core
Some tools you never have to implement - Anthropic executes them server-side. And when the job is high-volume and not urgent, there is a cheaper lane entirely.
AdvancedServer-side tools: web search and the text editor4 min▶
Client tools (everything above) follow the loop: Claude asks, YOU execute. Server tools invert it: you enable them in the request and ANTHROPIC executes them mid-response - no loop on your side for the execution.
| Tool | Who executes | What it gives you |
|---|---|---|
| Your functions (client tools) | You, in your code | Anything: your DB, your APIs, your files. Full control, full responsibility. |
| Web search (server tool) | Anthropic | Live web results with citations, mid-response. You just enable it and set a max_uses cap. |
| Text editor (client tool, Anthropic-defined) | You | A standardized view/create/str_replace file-editing interface Claude is trained on. You implement the file operations; the schema and Claude's fluency with it come free. |
The text editor tool sits in between: Anthropic defines the schema (commands like view, create, str_replace) and Claude has been trained to use it well, but the file operations run in YOUR code - which is why it is safe. This is the exact mechanism Claude Code uses to edit your repo. Note the platform delta: web search is a direct-API feature; on Bedrock and Vertex you cover the same ground with your own search tool.
AdvancedBatch processing: the Message Batches API4 min▶
Everything so far was real-time: one request, seconds of latency, full price. The Message Batches API takes up to thousands of requests in one submission, processes them asynchronously (most finish well within an hour, guaranteed within 24), and costs 50% less per token. Tools, system prompts, forced extraction - everything above works inside a batch.
- When batch beats real-time: nightly scoring, backfills, bulk classification, eval runs from 6.2 - anywhere nobody is watching a spinner. Half price for changing a cron schedule is the easiest cost win in this whole track.
- When it doesn't: anything interactive, and client-tool loops that need YOUR code between turns (each batch request must be self-contained - forced extraction is fine, a multi-turn query loop is not).
- custom_id is your join key - results can arrive in any order.
Try it yourself ◐ 3 exercises
1 · Calculator loop. Define a calculate tool (one string property: expression) whose implementation evaluates basic arithmetic safely. Wire it into the Part 1 loop and ask: "What is 17.5% of 2,340, minus 89?" Print every tool_use block so you can watch Claude decompose the question. Then break it on purpose: return an error string with is_error and see how Claude recovers.
2 · Warehouse read-only query tool. Build query_database against a local SQLite or DuckDB file. In YOUR implementation, reject anything that is not a single SELECT (no INSERT/UPDATE/DELETE/DROP, no semicolon chaining) and only allow tables from an explicit allowlist. Note where the safety lives: in your executor, not in the prompt. Ask three analytics questions and check the SQL Claude wrote.
3 · Forced extraction. Take 5 messy real texts (emails, ticket comments) and run the record_extraction pattern with an enum field and a required field that is sometimes missing from the text. Inspect what Claude does with missing data, then tighten the property descriptions until all 5 come back right. Bonus: resubmit all 5 as one Message Batch.
Official courses covered
This page teaches the Tool Use module that all three 8-hour engineering courses share, plus the Bedrock/Vertex-specific tool lessons.