Back to guides
2
4 min

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:

  • You define tools — JSON schemas describing available functions
  • You send them with the API call — Claude sees what's available
  • Claude decides to call one — it returns a tool_use content block
  • You execute the function — run the actual code
  • You return the result — send a tool_result message back
  • Claude responds naturally — using the real data from your function
  • Defining 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 ResponseTool Use Response
    `type: "text"` content block`type: "tool_use"` content block
    Contains Claude's text replyContains 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:

  • Call read_emails to get today's emails and extract sender names
  • Call check_calendar to get today's meetings and check attendees
  • Cross-reference the two results and answer the question
  • You handle this by looping: keep sending tool results back until Claude returns a text response instead of another tool call.

    Tool Design Best Practices

    PracticeWhy
    Clear, specific descriptionsClaude uses descriptions to pick the right tool
    Use enums for fixed choicesPrevents invalid arguments
    Keep input schemas simpleComplex schemas increase error rates
    Return structured dataClaude processes JSON better than prose
    Include error casesReturn `{"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:

  • Make descriptions more specific ("Read the user's email inbox" vs. "Read data")
  • Add negative descriptions ("This tool does NOT modify data, only reads it")
  • Key Takeaways

  • Tool use follows a loop: define → Claude calls → you execute → return result → Claude responds.
  • Tool descriptions are the most important part — Claude reads them to decide which tool to use.
  • Always check for stop_reason === "tool_use" and loop until Claude gives a text response.
  • Return structured JSON from tools. Include error handling for missing data or invalid queries.
  • 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