Tool Use
Teaching Claude to Call Functions
What Is Tool Use?
Tool use (also called function calling) lets Claude call functions you define. Instead of guessing or hallucinating, Claude can read real data, check actual schedules, and perform concrete actions.
Here's the flow:
tool_use content blocktool_result message backDefining a Tool
Each tool needs a name, description, and an input schema:
{
"name": "read_emails",
"description": "Read and filter the user's emails by status, sender, or date",
"input_schema": {
"type": "object",
"properties": {
"status": { "type": "string", "enum": ["unread", "read", "all"] },
"from": { "type": "string", "description": "Filter by sender" }
}
}
}The description is critical — Claude uses it to decide which tool to call. Vague descriptions lead to wrong tool selection.
The Tool Use Response
When Claude wants to call a function, the response looks different:
| Normal Response | Tool Use Response |
|---|---|
| `type: "text"` content block | `type: "tool_use"` content block |
| Contains Claude's text reply | Contains tool name + input arguments |
| `stop_reason: "end_turn"` | `stop_reason: "tool_use"` |
You detect stop_reason === "tool_use", extract the tool name and arguments, execute your function, and send the result back.
Returning Results
After executing the function, you send a tool_result message:
messages.push({
role: "user",
content: [{
type: "tool_result",
tool_use_id: toolUseBlock.id,
content: JSON.stringify(result),
}],
});Claude then uses this real data to write a natural language response.
Multi-Tool Conversations
Claude can call multiple tools in sequence. For example:
> User: "Do I have any meetings with people who emailed me today?"
Claude might:
read_emails to get today's emails and extract sender namescheck_calendar to get today's meetings and check attendeesYou handle this by looping: keep sending tool results back until Claude returns a text response instead of another tool call.
Tool Design Best Practices
| Practice | Why |
|---|---|
| Clear, specific descriptions | Claude uses descriptions to pick the right tool |
| Use enums for fixed choices | Prevents invalid arguments |
| Keep input schemas simple | Complex schemas increase error rates |
| Return structured data | Claude processes JSON better than prose |
| Include error cases | Return `{"error": "..."}` instead of crashing |
When Claude Calls the Wrong Tool
If Claude picks the wrong tool, the problem is almost always in the descriptions. Two common fixes:
Key Takeaways
stop_reason === "tool_use" and loop until Claude gives a text response.This is chapter 2 of Build Your AI Assistant with Claude.
Get the full hands-on course — free during early access. Build the complete system. Your projects become your portfolio.
View course details