Room 42, home

Tool Calling Explained with Real Examples

What tool calling is, how the request, decide, run and return loop works, and what makes a good tool, with real examples and no API boilerplate.

Codingbeginner7 min readUpdated 12 Jun 2026

In short

  1. 01Tool calling lets a model reach outside its context to do real work, but the model only asks: your system runs the tool and returns the result.
  2. 02Every tool interaction follows the same loop: the model requests, your app runs it, the result is injected, and the model reasons on.
  3. 03Because the model only asks, you control which tools exist, and every call is auditable and can be blocked or logged before it runs.
  4. 04Good tools are single-purpose, clearly named, and tightly scoped, since vague descriptions cause wrong calls that compound across steps.
Contents · 10 sections
  1. 1The key insight: the model only asks
  2. 2How does tool calling work?
  3. 3Concrete examples
  4. 4What the model sees at each stage
  5. 5What makes a good tool?
  6. 6The tool-calling loop in Claude Code
  7. 7How does tool calling power agents?
  8. 8How does MCP extend tool calling?
  9. 9Common mistakes
  10. 10What to learn next

Tool calling is how an AI model reaches outside its own context window to do real work. You have probably heard it called "function calling" too. Same thing. Here is the part people miss: the model does not run your tools. It asks to. Your system runs them and hands the results back. Get that one distinction and the rest follows.

The key insight: the model only asks

When Claude decides it needs to search the web or read a file, it does not reach out and do it. It emits a structured request, something like:

{
  "tool": "web_search",
  "input": { "query": "current Node.js LTS version" }
}

Your application receives that request, calls the real tool, and returns the result. The model never had network access. It asked, you fetched, you told it what you found. From there it carries on.

Why does this matter? A few things fall out of it:

  • You control exactly what tools exist and what they can do.
  • Every tool call is auditable. You see the request before it runs.
  • You can block, log, or rewrite any call before it executes.
  • The model can plan whole sequences of calls without ever running one itself.

How does tool calling work?

Every tool interaction follows the same four-step cycle, regardless of what the tool does.

One round is rarely enough. A model working on a hard task might call four tools in sequence, each result feeding the next call, before it produces a final answer. In Claude Code you watch every step scroll past as it happens.

Concrete examples

The same loop drives every kind of tool. Here are four categories, with what the model asks for and what comes back.

The model wants current information it was not trained on. It asks:

{ "tool": "web_search", "input": { "query": "Next.js 15 breaking changes" } }

Your app calls the search API, grabs the top results, and returns the titles, snippets, and URLs as plain text. The model reads that text. Then it decides: fetch a specific page, answer directly, or search again with a sharper query.

Reading a file

The model needs to understand code before editing it. It asks:

{ "tool": "read_file", "input": { "path": "src/auth/session.ts" } }

Your app opens the file and returns its contents as a string. The model reads it, sees the structure, and makes a targeted edit instead of guessing.

Querying a database

An agent doing data analysis might ask:

{
  "tool": "run_sql",
  "input": { "query": "SELECT user_id, COUNT(*) FROM events GROUP BY user_id LIMIT 20" }
}

Your app executes that query against your actual database (with whatever access controls you have wired in) and returns the rows as JSON. The model interprets the data and continues.Common gotchaBecause the model only asks and your app runs, it is tempting to hand a model-written SQL string straight to your database. That string carries the model's full DB privileges, so a confused or prompt-injected model can issue a DELETE or read a table it should never see.Give the runner a read-only role scoped to the rows the task needs, and validate the call before it executes, rather than trusting the request just because the model emitted it.

Hitting an API

A support agent might ask:

{
  "tool": "get_order",
  "input": { "order_id": "ORD-88421" }
}

Your app calls your internal order service and returns the order object. Now the model answers the customer from real data, with no invented order details.

What the model sees at each stage

It helps to watch the context grow over a multi-step task. Picture the model's view as a conversation that keeps stacking up results.

TurnAdded to context
1User prompt: "What changed in Next.js 15?"
2Model tool call: web_search("Next.js 15 changelog")
3Tool result: search snippets injected
4Model tool call: fetch_url("https://nextjs.org/blog/next-15")
5Tool result: full article text injected
6Model final answer synthesised from both results

The model reasons over real information it asked for and received.Common gotchaEach result stays in context for the rest of the task, so a tool that returns a whole file or thousands of rows can fill the window and bury the signal the model needs.Trim results to the fields that matter and paginate large lists rather than returning everything at once.

What makes a good tool?

The quality of your tools sets the ceiling on the model's work. Poorly defined tools lead to wrong calls, missed steps, and invented parameters. Good tools share these properties:

PropertyWhat it means in practice
Single purposeDoes exactly one thing. A get_user tool should not also update the user.
Clear nameReads like a verb phrase. search_products, not do_stuff.
Typed inputsEvery parameter has a name, a type, and a description the model can read.
Predictable outputReturns consistent structure. The model learns your schema from one call.
Tight scopeReturns only what is needed. A paginated list beats dumping 10,000 rows.
Safe defaultsDestructive operations (delete, send, pay) should require explicit confirmation or an extra parameter.

The model reads your tool's name and description every time it weighs up calling it. Write those descriptions for a reader who has never seen your system. A vague description means the model guesses, and guesses compound across multi-step tasks.

The tool-calling loop in Claude Code

In Claude Code you never write the loop. The CLI ships with a built-in toolbox (Read, Edit, Bash, WebSearch, WebFetch, and more), and you extend it with MCPModel Context Protocol: the open standard that lets Claude Code connect to external servers that expose tools, resources, and prompts. servers. The agent runs the request-decide-run-return cycle on its own, for every tool call a task needs.

You interact with it through the CLI:

# See every MCP server and the tools it exposes
claude mcp list
claude mcp get <server-name>
 
# Add a new server (and its tools) to the agent's toolbox
claude mcp add github -- npx -y @modelcontextprotocol/server-github
 
# Ask the agent something that needs a tool
claude "What are the open PRs on this repo assigned to me?"

That last command will trigger at least one tool call to the GitHub MCP server, inject the result, and give you a real answer from your actual repo.

How does tool calling power agents?

One tool call is useful. A chain of them is an agent. Let the model loop, calling tools until it has what a task needs, and you get autonomous behaviour without hard-coding a workflow.

Every arrow in that diagram is a tool call the model chose to make off the back of the previous result. No script decides the order; the model makes the decisions. Your tools feed it real information at each step, which is what keeps those decisions grounded.

This is also why tool quality compounds. A poorly described tool causes one bad decision. That decision changes the context for the next call, which skews the one after it. Errors stack. Good tools keep the model on track across the whole chain.

How does MCP extend tool calling?

MCPModel Context Protocol: the open standard that lets Claude Code connect to external servers that expose tools, resources, and prompts. is the standard that lets you add new tools without touching the model. An MCP server is a program that registers named tools the model can call. Connect one, and its tools show up next to the built-ins. The model treats them the same.

The pattern is:

  1. Write or install an MCP server that wraps your API, database, or service.
  2. Connect it with claude mcp add.
  3. The model discovers the tools at startup and can call them in any task.

You can commit a .mcp.json file to a repo so every contributor gets the same tools without manual setup. The full configuration format is covered in MCP Configuration.

{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres", "${DATABASE_URL}"],
      "type": "stdio"
    }
  }
}

With that in place, Claude Code can query your database mid-task, and you wrote no query code at all. You wrote the configuration. MCP and the tool-calling loop do the rest.

Common mistakes

Assuming the model runs the tool itself. It does not. The model asks. You run. If your tool runner is not connected, the call fails silently or the model reports it cannot reach the tool. Always verify a new MCP server is registered with claude mcp list before expecting it to work.

Vague tool descriptions. The model reads your description every time it decides whether to call a tool. "Does things with orders" tells it nothing. "Returns full order details including line items and status for a given order ID" tells it exactly when to reach for this tool.

Tools with too wide a scope. A tool that can read, update, and delete records is harder for the model to use correctly than three separate ones. It will sometimes call the wrong operation. Narrow tools produce reliable behaviour.

No pagination on list tools. If a list_products tool returns every product in your catalogue, the model's context fills up fast. Cap results and let the model ask for the next page when it needs more.

Confusing tool calling with tool use in Claude Code. In Claude Code you are configuring tools and writing prompts, not wiring the request loop. The loop is already built in. The guides Tool Use and Function Calling and MCP Fundamentals cover the Claude Code-specific configuration in detail.

What to learn next

Once the request-decide-run-return loop is clear, the natural next step is understanding how multiple agents share tools and hand tasks to each other. See Multi-Agent Architectures for that. For the mechanics of connecting real MCP servers to Claude Code, see MCP Fundamentals and MCP Configuration.