← Blog

Claude Tool Use: Multiple Tools Example That Works

2026-11-03 · 4 min read · SubToAPI Team

When you give Claude more than one tool, two things change compared to a single-tool setup: Claude has to decide which tool (or tools) to call based on the user's message, and in some cases it will request several tool calls in a single turn. This article walks through a real multi-tool example — a weather tool and a calculator tool — showing the request, Claude's response, how to execute both calls, and how to send the results back correctly.

The short answer to "how do I use multiple tools with Claude" is: define each tool as a separate object in the tools array with its own name, description, and input_schema, send them all in the same request, then check stop_reason: "tool_use" and loop over every block in content with type: "tool_use" — not just the first one — because Claude can return more than one tool call per response.

Defining multiple tools in one request

Each tool is an independent schema. Claude reads the descriptions to decide which tool (if any) applies to the user's message.

{
  "model": "claude-sonnet-4-5",
  "max_tokens": 1024,
  "tools": [
    {
      "name": "get_weather",
      "description": "Get the current weather for a given city",
      "input_schema": {
        "type": "object",
        "properties": {
          "city": { "type": "string", "description": "City name" }
        },
        "required": ["city"]
      }
    },
    {
      "name": "calculate",
      "description": "Evaluate a basic arithmetic expression",
      "input_schema": {
        "type": "object",
        "properties": {
          "expression": { "type": "string", "description": "e.g. 12 * 7" }
        },
        "required": ["expression"]
      }
    }
  ],
  "messages": [
    {
      "role": "user",
      "content": "What's the weather in Lisbon, and what is 340 * 12?"
    }
  ]
}

Because the user's question needs both tools, Claude typically returns two tool_use blocks in one response rather than asking you to go back and forth twice.

What Claude's response looks like

{
  "id": "msg_01abc",
  "role": "assistant",
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "text",
      "text": "I'll check the weather and do the math."
    },
    {
      "type": "tool_use",
      "id": "toolu_01weather",
      "name": "get_weather",
      "input": { "city": "Lisbon" }
    },
    {
      "type": "tool_use",
      "id": "toolu_02calc",
      "name": "calculate",
      "input": { "expression": "340 * 12" }
    }
  ]
}

Notice there's an optional text block before the tool calls, and then two distinct tool_use blocks each with their own id and name. Your code needs to handle both, in the order they appear, and keep track of each id — it's what links the result back to the specific call.

Executing the calls and sending results back

For each tool_use block, run your own matching function and return a tool_result with the same tool_use_id. If there are multiple tool calls, you send multiple tool_result blocks in a single follow-up user message — not separate requests.

const toolHandlers = {
  get_weather: (input) => `18°C, partly cloudy in ${input.city}`,
  calculate: (input) => String(eval(input.expression)) // demo only, don't eval in prod
};

const toolResults = response.content
  .filter((block) => block.type === "tool_use")
  .map((block) => ({
    type: "tool_result",
    tool_use_id: block.id,
    content: toolHandlers[block.name](block.input)
  }));

const followUp = await fetch("https://api.anthropic.com/v1/messages", {
  method: "POST",
  headers: {
    "x-api-key": process.env.ANTHROPIC_API_KEY,
    "anthropic-version": "2023-06-01",
    "content-type": "application/json"
  },
  body: JSON.stringify({
    model: "claude-sonnet-4-5",
    max_tokens: 1024,
    tools: [...], // same tools array as before
    messages: [
      { role: "user", content: "What's the weather in Lisbon, and what is 340 * 12?" },
      { role: "assistant", content: response.content },
      { role: "user", content: toolResults }
    ]
  })
});

Claude then reads both results and produces a final natural-language answer combining them, something like: "It's 18°C and partly cloudy in Lisbon. 340 × 12 is 4,080."

Common mistakes with multiple tools

Running this through SubToAPI

If you're calling Claude from a product rather than a script, this exact flow — multiple tools, parallel tool_use blocks, result matching — works unchanged against SubToAPI's /v1/messages endpoint. You get a sub_live_... key, usage metadata per request, and team seats for sharing access, without managing Anthropic billing directly. See the tool use docs for the full schema reference, quickstart to get a key, or pricing for plan details.

questions

Can Claude call more than two tools in one response? Yes. There's no hard limit on how many tool_use blocks can appear in one response — it depends on how many distinct actions the model determines it needs to answer the request.

Does the order of tool calls in content matter? The order reflects the sequence Claude reasoned through them, but you can execute and return results in any order as long as each tool_result has the correct tool_use_id.

What if one of my tools doesn't apply to the user's message? Claude simply won't call it. Having extra tools defined doesn't force usage — it only picks the ones relevant to the current input based on the descriptions you provide.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →