Claude Tool Use Explained: Give Claude the Ability to Act

Out of the box, Claude can read, reason, and write — but it cannot do. It cannot check the current weather, query your database, look up a live stock price, or send a Slack message. Its knowledge has a training cutoff, and it has no way to take action in external systems.
Tool use changes that. By defining tools — functions that Claude can choose to call — you give Claude the ability to reach outside its own knowledge and take real actions in the world. This is the capability that turns Claude from a conversational AI into a productive agent.
Tool use is the foundation of everything in Module 4 of this series. Whether you want Claude to browse the web, analyse images, or orchestrate multi-step workflows, tool use is the underlying mechanism.
How Tool Use Works: The Core Loop
Tool use in Claude is not Claude autonomously running code. The loop works like this:
- You define tools: You send Claude a list of available tools as part of your API request, each with a name, description, and input schema
- Claude decides whether to call a tool: Based on the user's message and the available tools, Claude decides if it needs to call a tool to answer correctly
- Claude returns a tool_use block: Instead of a text response, Claude returns a structured tool call with the tool name and arguments
- Your code runs the tool: You extract the tool call, execute the actual function in your code, and get the result
- You send the result back to Claude: You add the tool result to the conversation and call the API again
- Claude generates the final response: Claude uses the tool result to produce its final answer to the user
Your code always controls execution. Claude requests tools; your code runs them. This design is intentional — it keeps humans in control of side effects.
Claude Never Executes Code Directly
In standard tool use, Claude produces a tool call request — a structured JSON object with a function name and arguments. Your application code receives that request and executes the actual function. Claude has no direct access to your systems, databases, or APIs — it can only request that your code run them on its behalf. This is the fundamental safety boundary in tool use.
Defining a Tool
Tools are defined using JSON Schema syntax. Each tool needs three things: a name, a description, and an input_schema.
The description is critical — Claude reads it to decide when to use the tool. A clear, accurate description is more important than anything else in your tool definition.
1import anthropic
2
3client = anthropic.Anthropic()
4
5# Define a tool for getting current weather
6weather_tool = {
7 "name": "get_weather",
8 "description": "Retrieves the current weather conditions for a specified city. Use this whenever the user asks about current weather, temperature, rain chance, or similar conditions.",
9 "input_schema": {
10 "type": "object",
11 "properties": {
12 "city": {
13 "type": "string",
14 "description": "The city name to get weather for, e.g. 'London' or 'New York'"
15 },
16 "units": {
17 "type": "string",
18 "enum": ["celsius", "fahrenheit"],
19 "description": "Temperature units to use in the response",
20 "default": "celsius"
21 }
22 },
23 "required": ["city"]
24 }
25}A Complete Tool Use Example
Here is a full working example of the tool use loop from start to finish.
1import anthropic
2import json
3
4client = anthropic.Anthropic()
5
6# Step 1: Define your tools
7tools = [
8 {
9 "name": "get_weather",
10 "description": "Gets current weather for a city",
11 "input_schema": {
12 "type": "object",
13 "properties": {
14 "city": {"type": "string", "description": "City name"}
15 },
16 "required": ["city"]
17 }
18 }
19]
20
21# Step 2: The actual function (your code, not Claude)
22def get_weather(city: str) -> dict:
23 # In production this would call a real weather API
24 return {
25 "city": city,
26 "temperature_celsius": 14,
27 "condition": "Partly cloudy",
28 "humidity_percent": 72
29 }
30
31# Step 3: Initial API call with tools
32messages = [{"role": "user", "content": "What is the weather like in Edinburgh right now?"}]
33
34response = client.messages.create(
35 model="claude-sonnet-4-6",
36 max_tokens=1024,
37 tools=tools,
38 messages=messages
39)
40
41# Step 4: Handle tool calls in the response
42while response.stop_reason == "tool_use":
43 tool_results = []
44
45 for block in response.content:
46 if block.type == "tool_use":
47 # Execute the function
48 if block.name == "get_weather":
49 result = get_weather(**block.input)
50
51 tool_results.append({
52 "type": "tool_result",
53 "tool_use_id": block.id,
54 "content": json.dumps(result)
55 })
56
57 # Step 5: Add assistant response and tool results, call API again
58 messages.append({"role": "assistant", "content": response.content})
59 messages.append({"role": "user", "content": tool_results})
60
61 response = client.messages.create(
62 model="claude-sonnet-4-6",
63 max_tokens=1024,
64 tools=tools,
65 messages=messages
66 )
67
68# Step 6: Extract final text response
69print(response.content[0].text)
70# "The current weather in Edinburgh is partly cloudy with a temperature of 14°C and 72% humidity."Controlling Tool Choice
By default, Claude decides whether to use a tool. You can override this behaviour:
- tool_choice: auto: Claude decides whether to use a tool (default)
- tool_choice: any: Claude must use at least one of the provided tools
- tool_choice: tool (with name): Claude must use the specific named tool — useful for structured output extraction
- tool_choice: none: Claude must not use any tools, even if provided
1# Force Claude to use the weather tool specifically
2response = client.messages.create(
3 model="claude-sonnet-4-6",
4 max_tokens=1024,
5 tools=tools,
6 tool_choice={"type": "tool", "name": "get_weather"},
7 messages=messages
8)Parallel Tool Calls
Claude can call multiple tools in a single response when it needs information from several sources to answer a question. For example, if a user asks to compare the weather in London and Paris, Claude might call get_weather twice in parallel. Your implementation must handle lists of tool_use blocks, not just a single one. Always iterate over all blocks in the content array.
Defining Good Tool Descriptions
The quality of your tool description directly determines when and how Claude uses your tool. Follow these practices:
- Explain when to use it: "Use this when the user asks about current stock prices or market data" is more helpful than "Gets stock prices"
- Describe parameter constraints: If a city name must be in English, say so in the parameter description
- Describe the return value: Tell Claude what data comes back so it knows how to use the result in its response
- Note limitations: "Only returns data for major cities with populations over 100,000" prevents Claude from calling the tool for inputs that will fail
Multi-Tool Applications
Real applications typically provide Claude with several tools. The principles remain the same:
1tools = [
2 search_database_tool,
3 send_email_tool,
4 create_ticket_tool,
5 lookup_customer_tool
6]
7
8response = client.messages.create(
9 model="claude-sonnet-4-6",
10 max_tokens=4096,
11 tools=tools,
12 messages=messages
13)Claude will select the appropriate tool based on the task at hand. For complex requests, it may call multiple tools in sequence — using the result of one to inform the next.
Start with One Tool, Add More Gradually
When building a tool-using application for the first time, start with a single, well-defined tool and make it work end-to-end before adding more. The most common mistake is defining five tools at once and struggling to debug which tool is causing unexpected behaviour. One tool at a time lets you verify each integration in isolation.
Error Handling in Tool Use
When a tool call fails — network error, invalid input, service unavailable — you should return the error to Claude as a tool result rather than crashing.
1tool_results.append({
2 "type": "tool_result",
3 "tool_use_id": block.id,
4 "content": "Error: Weather service is unavailable. Please try again later.",
5 "is_error": True
6})Claude will incorporate the error into its response and either attempt a different approach or inform the user gracefully.
Summary
Tool use is the capability that turns Claude from a conversational model into an active participant in your application's workflows. The core pattern is always the same: define tools with clear descriptions and schemas, pass them to the API, handle tool_use blocks by executing your functions, return the results, and let Claude compose the final response.
Everything in the rest of Module 4 — web search, vision, computer use, and the Files API — builds directly on this tool use foundation. Next up: Claude Web Search Tool: Real-Time Data in Your AI App.
This post is part of the Anthropic AI Tutorial Series. Previous post: Prompt Engineering Refresher: 10 Techniques Every Developer Should Know.
