What is tool calling?
Tool calling is the mechanism by which a model asks your program to run something. You describe the available functions in the request, the model replies with a structured call naming one of them and supplying arguments, your code executes it, and you send the result back as part of the next request. The model never executes anything itself, and vendors use the names tool calling, function calling and tool use for the same mechanism.
How tool calling works, step by step
You send the request with a list of tool definitions: each has a name, a description written for the model rather than for a developer, and a schema for its arguments. The model replies with either ordinary text or a structured tool call: the tool's name and a set of arguments that validate against your schema. Your code executes it, however you like, and appends the result to the conversation as a tool result message. Then you send the whole thing back, and the model continues with the result in hand.
Two details do most of the work in practice. The reply is structured rather than prose, so you are parsing a defined shape rather than guessing at intent from free text. And the round trip is explicit: there is a point in your own code between the model asking and anything happening, which is where validation, authorisation and approval belong.
The model does not run the tool
Worth stating plainly, because the phrase the model called a tool suggests otherwise. A model emits a request. Nothing runs unless your program chooses to run it. It has no network access of its own, no shell, no filesystem, and no way to reach a system you did not expose. Every capability an agent appears to have was granted by a tool definition someone wrote.
That also means the security boundary is entirely on your side. Argument schemas are a hint to the model, not a guarantee, so validate what arrives as you would validate anything from an untrusted client. Scope credentials to the smallest thing the tool needs. Keep destructive operations behind an explicit approval. And treat text that arrives from a tool result as data, since content fetched from a page or a ticket can contain instructions aimed at the model.
Designing tools a model uses correctly
Most tool-calling failures are description failures. The model picks between your tools using their names and descriptions, so write those for the caller: say what the tool does, when to use it, when not to, and what it returns. Prefer a few well-scoped tools over many overlapping ones, because two tools that could both plausibly apply is exactly how the wrong one gets chosen. Keep argument schemas small and required fields genuinely required.
Return errors as readable results rather than raising them, and include what to do next. A model handed {"error": "repo not found, try list_repos first"} will usually recover; a model handed a stack trace or nothing will loop. And remember that every tool definition occupies part of the context window on every request, so a wide tool surface is a permanent cost, not a one-off one.
MCP: the same idea, standardised
Once several harnesses each define tools their own way, the same integration gets rewritten repeatedly. The Model Context Protocol is an open specification for that boundary: a server exposes tools, resources and prompts over a defined protocol, and any compatible client can use them. It does not change how tool calling works at the model level, it standardises who describes the tools and how they are discovered, which is what makes an integration reusable across harnesses.
One tool call, both directions
you send:
tools = [{ name: "search_repo",
description: "Search the current repository for a literal
string. Use for code and config, not prose.",
input_schema: { query: string, path?: string } }]
messages = [{ role: "user", content: "where do we set OOM limits?" }]
model replies:
{ type: "tool_use", name: "search_repo",
input: { query: "OOMKilled", path: "deploy/" } }
your code runs the search, then sends:
{ type: "tool_result", content: "deploy/base.yaml:41 memory: 512Mi" }
model replies:
"OOM limits are set in deploy/base.yaml line 41 at 512Mi."
The gap between the second and third block is your program. Validation, authorisation and approval all live there, and nowhere else.
Common questions
Tool calling: frequently asked
Is function calling the same as tool calling?
Yes. They are vendor names for one mechanism: the model returns a structured request naming something you described, and your code decides whether to run it. OpenAI's documentation says function calling, Anthropic's says tool use, and the Model Context Protocol calls the exposed units tools. The request and reply shapes differ in detail, but the pattern and its implications are identical.
Can the model run code by itself?
No. It produces a request to run something. Nothing executes unless your program executes it, and it can only ask for tools you defined. Features that look like the model running code, such as a sandboxed interpreter, are tools the vendor implemented and exposed on your behalf, with the execution happening in their infrastructure rather than inside the model.
Why did the model call the wrong tool?
Almost always because two tools were plausible for the same job, or because a description explained the implementation instead of the decision. The model chooses on names and descriptions alone, so write them for the caller: what it does, when to use it, when not to. Narrowing the tool surface fixes more of these than any prompt change.
Do tool definitions cost tokens?
Yes, on every request, because the definitions are part of the input the model has to be given. A dozen verbose JSON schemas can take up more of the context window than the conversation itself, and unlike history you cannot summarise them away. Keeping the exposed tool set small and the schemas tight is one of the more reliable ways to cut cost per step.
Sources
Where these facts come from
- Anthropic docs: tool use overview: the tool_use and tool_result message shapes and the round trip they require
- OpenAI docs: function calling: the same mechanism under the function calling name, for cross-vendor comparison
- Model Context Protocol specification: the open standard for describing and discovering tools across harnesses