Claude Tool Use Documentation: A Practical Guide
If you're searching for "claude tool use documentation," you're probably trying to implement function calling with Claude and want a clear map of what the official docs actually cover — the JSON schema format, the request/response shape, and how streaming or multi-step tool calls fit together. This article walks through the documentation structure and gives you working examples you can adapt immediately.
Tool use (also called function calling) lets Claude call external functions you define — a weather lookup, a database query, a calculator — instead of trying to answer from memory. Claude decides when a tool is needed, tells you which tool and with what arguments, and you run the actual code and send the result back. The documentation for this feature is split across a few concerns: defining tools, handling the model's tool call, and returning results in the right format.
What the Documentation Covers
Claude's tool use documentation is organized around three core pieces:
- Tool definitions — a JSON schema describing each tool's name, description, and input parameters.
- The request/response cycle — how Claude signals it wants to call a tool (
stop_reason: "tool_use") and how you send results back as atool_resultcontent block. - Edge cases — parallel tool calls, forced tool choice, streaming with tools, and error handling when a tool fails.
Understanding these three pieces is enough to build a working integration. The rest is refinement: better descriptions, tighter schemas, and handling multi-turn conversations where Claude might call several tools in sequence.
Defining a Tool
Every tool definition needs a name, a description, and an input_schema using standard JSON Schema. The description matters more than most developers expect — Claude uses it to decide when to call the tool, not just how.
{
"name": "get_stock_price",
"description": "Get the current price of a stock by ticker symbol",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol, e.g. AAPL"
}
},
"required": ["ticker"]
}
}
A vague description ("get price data") leads to inconsistent tool selection. A specific one ("get the current price of a stock by ticker symbol") gives the model enough context to trigger the call reliably and fill in the right argument.
The Request/Response Cycle
Once tools are defined, you send them alongside your messages. If Claude decides to use one, the response's stop_reason will be tool_use, and the content block will include the tool name and generated input:
{
"type": "tool_use",
"id": "toolu_01A09q90qw90lq917835lq9",
"name": "get_stock_price",
"input": { "ticker": "AAPL" }
}
You then run the actual function on your side, and send the result back in a new message as a tool_result block referencing the same id:
{
"type": "tool_result",
"tool_use_id": "toolu_01A09q90qw90lq917835lq9",
"content": "192.53"
}
Claude then continues the conversation using that result — often producing a final natural-language answer, or calling another tool if the task requires it.
A Minimal Working Example
Here's what a full round trip looks like end to end using a generic HTTPS client:
const tools = [{
name: "get_stock_price",
description: "Get the current price of a stock by ticker symbol",
input_schema: {
type: "object",
properties: { ticker: { type: "string" } },
required: ["ticker"]
}
}];
const response = await client.messages.create({
model: "claude-sonnet-4",
max_tokens: 1024,
tools,
messages: [{ role: "user", content: "What's AAPL trading at?" }]
});
if (response.stop_reason === "tool_use") {
const toolCall = response.content.find(c => c.type === "tool_use");
const price = await getStockPrice(toolCall.input.ticker);
const followUp = await client.messages.create({
model: "claude-sonnet-4",
max_tokens: 1024,
tools,
messages: [
{ role: "user", content: "What's AAPL trading at?" },
{ role: "assistant", content: response.content },
{
role: "user",
content: [{
type: "tool_result",
tool_use_id: toolCall.id,
content: price.toString()
}]
}
]
});
console.log(followUp.content);
}
This pattern — send tools, check stop_reason, run the function, send tool_result — is the core loop documented across every tool use example you'll find, regardless of which client library you use.
Common Gaps in Understanding
A few things trip people up when reading through tool use documentation for the first time:
- Forced tool choice: you can require Claude to use a specific tool (or any tool) instead of leaving the decision to the model, useful for structured extraction tasks.
- Parallel tool calls: Claude can request multiple tools in a single turn — your code needs to handle an array of
tool_useblocks, not just one. - Streaming: tool use works with streaming responses, but the tool call arguments arrive incrementally as JSON deltas, which requires buffering before you can parse them.
- Error results: if your function fails, you can still send a
tool_resultwith an error message — Claude will often retry or adjust rather than crashing the conversation.
If you're routing Claude through a proxy or wrapper API rather than calling Anthropic directly, check that tool use is passed through unmodified — some layers strip or reformat tool schemas, which breaks the whole flow silently.
Where SubToAPI Fits
If you already have Claude access and want to expose it as a straightforward HTTPS API for your own apps — without managing separate API billing — SubToAPI turns your existing access into sub_live_... application keys with full support for tool use, streaming, and usage metadata. The request and response format follows the same tool use structure covered above, so existing integration code ports over with minimal changes. See the tool use docs and the quickstart for setup, or check pricing if you're evaluating it for a team.
questions
Where is the official documentation for Claude tool use? Anthropic publishes it as part of the Messages API reference, covering tool definitions, the tool_use/tool_result cycle, and streaming behavior. Third-party API layers, including SubToAPI, document the same request shape at /docs/tools.
Do I need a specific SDK to use tool use documentation examples? No — the request/response format is plain JSON over HTTPS, so any HTTP client or language works. SDKs just wrap the same structure with convenience methods.
Why does Claude sometimes not call my tool even though it's defined? Usually the tool's description is too vague or the user's request doesn't clearly map to it. Rewriting the description to state exactly what the tool does and when it's useful almost always fixes inconsistent tool selection.