Intermediate

Tool Use & Function Calling

Tool use lets Claude call external functions during a conversation — databases, APIs, code execution, file systems, web search, or any custom function you define. This page covers the tool definition schema, how Claude decides whether to call a tool, result handling, parallel calls, and error recovery.

Tool Definition Schema

Each tool is defined as a JSON object with three required fields:

{
  "name": "get_weather",
  "description": "Get the current weather for a specific city. Returns temperature in Celsius and a condition description.",
  "input_schema": {
    "type": "object",
    "properties": {
      "city": {
        "type": "string",
        "description": "The city name, e.g. 'London' or 'New York'"
      },
      "units": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "Temperature units"
      }
    },
    "required": ["city"]
  }
}

The description field is the most important — Claude reads it to decide when to call the tool. Write descriptions that clearly explain what the tool does, what inputs it expects, and what it returns. Claude uses this description, not the input schema, to decide whether to call the tool.

User Message
Claude Evaluates
Needs tool?
Tool Call
name + input JSON
Tool Result
Append to messages
Final Response
stop_reason: end_turn

Tool call round-trip — Claude drives the loop

How Claude Decides Whether to Call a Tool

Claude decides whether to call a tool based on:

  • Whether the task requires information or actions the tool provides
  • The tool's description — a good description prevents both over-calling and under-calling
  • The tool_choice parameter in the API request, which can force or prevent tool use:
    • auto (default) — Claude decides whether to call a tool
    • any — Claude must call at least one tool
    • tool — Claude must call a specific tool by name
    • none — Claude may not call any tools

Receiving and Processing a Tool Call

When Claude decides to call a tool, it returns a response with stop_reason: "tool_use" and one or more tool_use content blocks:

# Claude's response when calling a tool:
{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01A2B3C4",
      "name": "get_weather",
      "input": { "city": "London", "units": "celsius" }
    }
  ]
}

# Send the result back:
{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01A2B3C4",
      "content": "{ \"temperature\": 18, \"condition\": \"Partly cloudy\" }"
    }
  ]
}

The tool_use_id in the result must match the id from Claude's tool call — this is how Claude links results to calls.

Parallel Tool Calls

Claude can request multiple tool calls in a single response when they are independent. The response will contain multiple tool_use blocks:

# Claude requests two tools in one response:
"content": [
  { "type": "tool_use", "id": "toolu_01", "name": "get_weather", "input": {"city": "London"} },
  { "type": "tool_use", "id": "toolu_02", "name": "get_weather", "input": {"city": "Paris"} }
]

# Execute both in parallel, then send both results:
"content": [
  { "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." },
  { "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." }
]

Always send results for all requested tool calls in a single user message — Claude expects all results before continuing.

Error Handling: When a Tool Call Fails

If a tool call fails (network error, invalid input, permission denied), return a tool result with is_error: true:

{
  "type": "tool_result",
  "tool_use_id": "toolu_01",
  "content": "Error: City 'Lndon' not found. Check spelling.",
  "is_error": true
}

Claude will read the error message and adapt — it may try a different input, use an alternative approach, or inform the user of the failure. Provide descriptive error messages; generic "error occurred" messages leave Claude without useful information for recovery.

Checklist: Do You Understand This?

  • Tool definition: name + description (most important) + input_schema (JSON Schema)
  • Claude decides whether to call based on the description — write descriptions clearly about what the tool does and returns
  • Tool call response has stop_reason: "tool_use" — always send results back before continuing
  • Parallel tool calls: Claude can request multiple tools in one response — execute in parallel, return all results together
  • Error handling: return is_error: true with a descriptive message — Claude will adapt based on the error content

Page built: 01 Jun 2026