Claude API

Tool use (function calling) in LLMs, explained with code

An LLM cannot check the weather, query your database or send an email. It can ask you to. Tool use (also called function calling) is that conversation: you describe functions, the model requests one, you run it, and you hand the result back.

The loop#

Send messages +tool listyour appModel asks for atoolname + argumentsRun it, returnthe resultyour appuntil the modelanswers
Your code does the doing. The model does the deciding.

Step 1: describe the tool#

A tool is a name, a description the model reads to decide when to use it, and a JSON schema for the inputs.

ts
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const tools: Anthropic.Tool[] = [
  {
    name: "get_order_status",
    description:
      "Look up the status of a customer order by its ID. Use when the user asks where their order is.",
    input_schema: {
      type: "object",
      properties: {
        order_id: { type: "string", description: "The order ID, e.g. A-1042" },
      },
      required: ["order_id"],
    },
  },
];

The description is the most important line. It is how the model chooses.

Step 2: run the loop#

ts
async function getOrderStatus(orderId: string) {
  // your real code: DB query, API call...
  return { order_id: orderId, status: "shipped", eta: "2026-10-12" };
}

const messages: Anthropic.MessageParam[] = [
  { role: "user", content: "Where is order A-1042?" },
];

while (true) {
  const response = await client.messages.create({
    model: "claude-opus-5-5",
    max_tokens: 4096,
    tools,
    messages,
  });

  messages.push({ role: "assistant", content: response.content });

  if (response.stop_reason !== "tool_use") {
    for (const block of response.content) {
      if (block.type === "text") console.log(block.text);
    }
    break;
  }

  const results: Anthropic.ToolResultBlockParam[] = [];
  for (const block of response.content) {
    if (block.type !== "tool_use") continue;
    try {
      const input = block.input as { order_id: string };
      const data = await getOrderStatus(input.order_id);
      results.push({ type: "tool_result", tool_use_id: block.id, content: JSON.stringify(data) });
    } catch (err) {
      results.push({
        type: "tool_result",
        tool_use_id: block.id,
        content: `Error: ${(err as Error).message}`,
        is_error: true,
      });
    }
  }

  messages.push({ role: "user", content: results });
}

What happens: the model returns a tool_use block with name and input; stop_reason is "tool_use". You run the function and return a matching tool_result (same tool_use_id). The model reads it and answers.

Rules that save you hours#

  1. Return all results in one user message. If the model made several tool calls at once, send one message with every tool_result.
  2. Report errors, do not throw. is_error: true lets the model recover or explain.
  3. Parse inputs, never trust them. The arguments are model output. Validate them, and never build file paths, SQL or shell commands from them without checks. See MCP security.
  4. Write descriptions for a stranger. Say what it does, when to use it, what it returns.
  5. Keep results small. Big tool output fills the context. See context engineering.
  6. Prefer strict: true on tools when you need arguments to match the schema exactly.

You rarely need to hand-write the loop#

The SDK has a tool runner helper that runs this loop for you from typed tool functions. Write the manual loop once so you understand it, then use the helper.

Tool use, agents and MCP#

A loop with tools is the core of every agent. MCP is how you avoid re-describing the same tools in every app: a server exposes them, any client lists and calls them. Same idea, standardized.

Frequently asked questions

What is tool use or function calling in an LLM?

It is a protocol where you describe functions to the model, the model replies with a request to call one with specific arguments, your code runs it, and you return the result so the model can continue.

Does the LLM execute the function itself?

No. For tools you define, your application executes the function. The model only decides which tool to call and with what arguments.

What is an agent loop?

A loop that sends the conversation to the model, runs any tools it requests, appends the results and calls the model again until it stops asking for tools.

How do tool use and MCP relate?

Tool use is the model capability of calling functions. MCP is a protocol that lets many apps discover and call tools hosted on servers, so you do not hand-write the tool wiring for each one.

How should I handle a tool error?

Return a tool_result with is_error set to true and a short message, so the model can adapt or tell the user, instead of throwing and ending the loop.