What is Claude Tool Use and Why It Matters
Claude tool use, also known as function calling, is the foundation of building reliable AI agents. Instead of Claude generating raw text responses, tool use enables Claude to request specific actions be taken on its behalf—calling APIs, executing functions, querying databases, or running system commands. This transforms Claude from a language model that *describes* what should happen into an agent that *makes things happen*.
The distinction is fundamental. When you ask Claude "What's the weather?" without tool use, it says "I don't know, I can't access real-time data." With tool use, Claude can request a weather API call, receive the response, and tell you the actual forecast. This is the difference between a chatbot and an agent.
Tool use is how Claude powers production systems. According to Anthropic's latest benchmarks, Claude models with tool use demonstrate a 40% improvement in task completion rates compared to text-only responses. For enterprise applications, this means the difference between aspirational AI and deployed AI that actually solves problems.
The real power emerges in agentic loops—where Claude uses a tool, analyzes the result, and decides whether to use another tool or finish. A financial advisor agent might retrieve account data (tool 1), analyze risk tolerance (reasoning), check market conditions (tool 2), and finally recommend a portfolio rebalance (final answer). All without human intervention.
Why Tool Use Matters Now
Three forces make tool use critical in 2026. First, Claude has become too capable at reasoning to waste on pure text generation. The model's 200K context window and extended thinking mean Claude can handle massive analytical tasks—but only if you give it access to data and actions. Second, enterprises demand accountability. Tool calls create an audit trail. You can see exactly which API Claude called, with what parameters, and what happened. This is impossible with text-only responses. Third, tool use is the pathway to reliability. Structured tool definitions with JSON schema prevent Claude from hallucinating API parameters or inventing fields.
How Tool Use Works: The Request/Response Cycle
Tool use follows a strict three-step cycle: definition, request, and execution. Understanding this cycle is essential to building systems that work at scale.
Step 1: Tool Definition
You begin by defining tools in your API call. A tool definition contains three required fields: name (what Claude calls it), description (when Claude should use it), and input_schema (what parameters it accepts). The schema uses JSON Schema format, which means Claude understands required fields, field types, constraints, and examples.
{
"name": "get_weather",
"description": "Fetches current weather for a specified city. Use this when the user asks about weather conditions, forecasts, or temperature.",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The city name (e.g., 'San Francisco', 'London')"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "Temperature unit preference. Defaults to fahrenheit."
}
},
"required": ["city"]
}
}
This definition tells Claude: "You have access to a tool called get_weather. It requires a city name and optionally accepts a units parameter. Use this when someone asks about the weather." Claude learns the tool's purpose from the description and its valid inputs from the schema.
Step 2: Claude Requests the Tool
When Claude decides a tool would help, it doesn't call the tool itself. Instead, it sends a tool_use content block in its response. This block specifies the tool name and the input parameters Claude wants to use. Here's what that looks like in the API response:
{
"type": "tool_use",
"id": "toolu_01234567890abcdef",
"name": "get_weather",
"input": {
"city": "San Francisco",
"units": "celsius"
}
}
The ID is crucial—it's how you'll link the tool result back to this specific request. Claude never executes the tool itself; it requests that you do.
Step 3: You Execute and Report Back
Your application receives Claude's tool_use request, executes the actual function or API call, and sends the result back to Claude in the conversation. You do this by adding a tool_result content block to the conversation history:
{
"type": "tool_result",
"tool_use_id": "toolu_01234567890abcdef",
"content": "{\"temperature\": 22, \"condition\": \"partly cloudy\", \"humidity\": 65}"
}
Claude then continues reasoning with this information. It might say "Based on the weather data, here's what I recommend..." or it might request another tool call if needed. This cycle repeats until Claude provides a final answer.
Defining Tools with JSON Schema
Tool definitions make or break agent reliability. A poorly defined tool leaves Claude guessing about parameters. A well-defined tool guides Claude toward correct inputs. JSON Schema is the standard for this, and mastering it is essential for production systems.
Schema Best Practices
Start with the complete picture. Don't define just the obvious parameters; include enum values for restricted choices, examples for complex types, and detailed descriptions for each field. When Claude can see that a "status" parameter only accepts "active", "inactive", or "pending", it won't invent new values.
{
"name": "query_database",
"description": "Execute a SELECT query against the company database. Use for retrieving customer data, order history, inventory levels, or sales metrics. Always specify filters to limit results.",
"input_schema": {
"type": "object",
"properties": {
"table": {
"type": "string",
"description": "Table name: 'customers', 'orders', 'inventory', or 'sales'",
"enum": ["customers", "orders", "inventory", "sales"]
},
"filters": {
"type": "object",
"description": "Column conditions. Example: {\"status\": \"paid\", \"date\": \">2026-01-01\"}",
"properties": {
"status": {
"type": "string",
"enum": ["pending", "paid", "refunded", "cancelled"]
},
"date": {
"type": "string",
"description": "ISO 8601 date format or comparison: '>2026-01-01', '<=2026-03-31'"
}
}
},
"columns": {
"type": "array",
"items": {"type": "string"},
"description": "Specific columns to return. Leave empty for all columns.",
"example": ["id", "email", "total_spent"]
},
"limit": {
"type": "integer",
"description": "Maximum rows to return. Default 100, max 10000.",
"default": 100
}
},
"required": ["table"]
}
}
Notice the enum constraints, examples, and default values. These dramatically improve Claude's accuracy. When the schema shows that "status" has four specific values, Claude picks one. Without that constraint, it might invent a fifth value like "waiting".
Description That Actually Helps
The description field is Claude's instruction for when to use a tool. A vague description like "Get information about a user" fails. A specific description works:
Poor: "Get user information"
Better: "Retrieve user profile data including email, account status, subscription tier, and payment methods. Use when the user asks about their account details or subscription information."
The better description tells Claude the exact scenario where this tool applies. It includes examples of user requests that should trigger this tool. Claude becomes more selective and accurate.
Tool Use Patterns: Single and Parallel Calls
Most developers assume Claude makes tool calls one at a time. In reality, Claude can request multiple tools simultaneously—a capability that transforms performance.
Single Tool Calls: The Sequential Pattern
A simple workflow calls tools in sequence. The user asks for current weather and current time. Claude requests the weather tool. You respond with weather data. Claude then requests the time tool. You respond with time. Finally, Claude provides the complete answer.
This pattern is correct but slower. You make three API round-trips: initial request, first tool result, second tool result. Each round-trip adds latency.
Parallel Tool Calls: The Performance Pattern
Claude can request multiple tools in a single response. Ask for current weather and current time, and Claude might return two tool_use blocks in the same response:
Message from Claude:
{
"content": [
{
"type": "text",
"text": "I'll get both the weather and current time for you."
},
{
"type": "tool_use",
"id": "toolu_001",
"name": "get_weather",
"input": {"city": "San Francisco"}
},
{
"type": "tool_use",
"id": "toolu_002",
"name": "get_current_time",
"input": {"timezone": "US/Pacific"}
}
]
}
Your application executes both tools (potentially in parallel threads) and returns both results in a single message. This reduces round-trips from three to two and makes multi-tool workflows dramatically faster. For enterprise agents handling dozens of tasks, parallel tool calls reduce execution time by 40-60%.
When to Use Each Pattern
Sequential tool calls make sense when the second tool depends on the first's output. For example: retrieve an order ID, then fetch order details using that ID. Parallel calls are for independent operations: fetch from three different APIs simultaneously.
Handling Tool Results and Error States
Real systems fail. APIs time out, databases return no results, permissions are denied. Your tool handling must be robust.
Reporting Success
When a tool succeeds, include the actual data. Claude needs this to continue reasoning. If your get_user tool returns user data, include the full JSON response:
{
"type": "tool_result",
"tool_use_id": "toolu_001",
"content": "{\"user_id\": 12345, \"name\": \"Alice Johnson\", \"email\": \"alice@company.com\", \"subscription\": \"enterprise\", \"active\": true}"
}
Reporting Errors
When a tool fails, communicate the error clearly. Set the is_error flag to true and include an explanation Claude can use to handle the error:
{
"type": "tool_result",
"tool_use_id": "toolu_001",
"content": "User not found. The user ID 99999 does not exist in the system.",
"is_error": true
}
Claude will read this error and respond appropriately. It might try an alternative approach, ask the user for clarification, or explain why the task cannot be completed. The key is clarity—avoid vague errors like "Request failed" that leave Claude confused.
Partial Results and Timeouts
Sometimes tools return partial results or hit timeouts. Be explicit about what succeeded and what didn't:
{
"type": "tool_result",
"tool_use_id": "toolu_002",
"content": "Fetched 47 of 150 customer records (timeout after 5 seconds). Partial data returned.",
"is_error": false
}
This tells Claude: "You got some data, but not all. Use what you have and note the limitation in your response." Claude will adapt its answer accordingly.
Building Agentic Loops: Multi-Step Reasoning
An agentic loop is where tool use becomes powerful. Claude makes a request, you provide a result, Claude analyzes that result and decides what to do next. This loop continues until the task is complete.
The Loop Pattern
Here's the fundamental structure:
- Send Claude a user request with available tools
- Claude responds with text and/or tool_use requests
- Execute the tool calls and collect results
- Add all tool results to the conversation
- Send the conversation back to Claude (without tools the second time)
- Claude responds again—either with a final answer or more tool requests
- Repeat until Claude provides a final answer (no more tool requests)
This is different from a single request-response. You maintain a conversation history and keep calling Claude in a loop until the task completes.
Example: Investment Research Agent
Consider an agent that researches investment opportunities. The user asks: "Should I invest in Tesla, and why?" Here's how the loop might work:
Loop 1: Claude sees the question and requests three tools: fetch current Tesla stock price, get financial statements, retrieve recent news. You execute all three tools. Claude receives all three results.
Loop 2: Claude analyzes the data. It calculates the P/E ratio and sees recent regulatory news. It requests two more tools: fetch analyst recommendations and get competitor data (Ford, GM). You execute both.
Loop 3: Claude now has price, financials, news, analyst views, and competitor data. It synthesizes everything and provides a complete investment recommendation. No more tool requests. The loop ends.
This multi-step reasoning is impossible with a single request. Claude needs feedback (tool results) to decide what to research next. The loop enables this iterative process.
Preventing Infinite Loops
Always set a maximum iteration limit (typically 10-20). If Claude reaches the limit without finishing, return an error and ask for clarification. Additionally, implement timeouts. If Claude keeps requesting the same tool, there's likely a problem.
Tool Use with Extended Thinking
Claude's extended thinking mode enables Claude to reason privately before selecting tools. This is transformative for complex problem-solving.
How Extended Thinking Changes Tool Selection
Without extended thinking, Claude makes quick tool decisions. With extended thinking enabled, Claude considers multiple strategies before committing to tool calls. For example, when debugging a system failure, Claude might think: "I could query the error logs, but I should first understand the system architecture. Let me check the documentation database, then request logs filtered for the relevant service."
This deliberate reasoning results in 25-35% more effective tool use, according to Anthropic's testing. Claude makes fewer unnecessary calls and asks for more relevant data on the first attempt.
Implementing Extended Thinking with Tools
Enable extended thinking in your API call by setting budget_tokens. Claude will use this budget for private reasoning:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-3-7-sonnet-20250219",
max_tokens=16000,
thinking={
"type": "enabled",
"budget_tokens": 10000
},
tools=[...], # your tool definitions
messages=[...]
)
Claude will spend up to 10,000 tokens reasoning internally, then proceed with tool calls. You won't see the thinking (it's in the response but typically filtered), but Claude's tool selections will be more deliberate.
Enterprise Patterns and Governance
Production systems require control. You can't let Claude make arbitrary API calls. Enterprise deployments add three critical layers: approval workflows, tool authorization, and audit logging.
Approval Workflows
For high-impact tools (charging a customer, deleting data, approving a loan), you might require human approval. Implement this by intercepting tool requests before execution:
if message.content[0].type == "tool_use":
tool_call = message.content[0]
# High-risk tools require approval
if tool_call.name in ["charge_customer", "delete_user", "approve_loan"]:
approval_task = create_approval_request(tool_call)
wait_for_approval(approval_task)
if not approval_granted:
result = {
"type": "tool_result",
"tool_use_id": tool_call.id,
"content": "This action requires human approval and was rejected.",
"is_error": True
}
else:
result = execute_tool(tool_call)
else:
result = execute_tool(tool_call)
This pattern lets Claude request sensitive actions, but requires human confirmation before execution. The approval decision is logged for compliance.
Tool Authorization
Different users should have access to different tools. A customer service agent shouldn't access billing APIs. Implement this by filtering which tools are available based on the user's role:
def get_authorized_tools(user_role):
base_tools = [
get_customer_info,
get_order_history,
get_product_catalog
]
if user_role == "support_agent":
return base_tools + [create_support_ticket, refund_order]
elif user_role == "finance_admin":
return base_tools + [process_payment, generate_invoice]
elif user_role == "manager":
return base_tools + [create_support_ticket, refund_order, process_payment]
return base_tools
Send only the authorized tools to Claude. Claude won't request tools it doesn't know about.
Audit Logging
Log every tool request and result. This creates accountability and enables compliance audits:
def log_tool_execution(user_id, tool_name, input_params, result, timestamp):
audit_entry = {
"timestamp": timestamp,
"user_id": user_id,
"tool": tool_name,
"inputs": input_params,
"result_summary": extract_summary(result),
"status": "success" if not result.is_error else "error"
}
database.insert("audit_log", audit_entry)
# For sensitive tools, also create an alert
if tool_name in SENSITIVE_TOOLS:
create_compliance_alert(audit_entry)
Every action is recorded with who did it, what they did, and what happened. This satisfies regulatory requirements and enables incident investigation.
MCP: The Standardized Tool Protocol
Manual tool definitions work, but they don't scale. MCP (Model Context Protocol) is Anthropic's open standard for tool integration. Instead of defining tools in your code, MCP servers expose tools that any Claude application can discover and use.
Why MCP Matters
Think of MCP like a plugin system. You install an MCP server (for Slack, GitHub, Salesforce, your custom API), and Claude automatically gains access to that tool. You don't rewrite tool definitions every project. You don't maintain tool schemas in multiple places. MCP standardizes this.
Anthropic has published MCP servers for:
- Google Drive (read/write files and folders)
- GitHub (access repos, issues, PRs)
- Slack (read/post messages, manage channels)
- SQLite (query and manage databases)
- Bash (execute shell commands safely)
You can also build custom MCP servers for your internal APIs. An MCP server for your company's invoicing system, CRM, or custom analytics platform. Your team uses the same MCP server across all Claude applications.
Getting Started with MCP
Connect an MCP server in Claude desktop or your application. The server exposes tools, which Claude immediately can use. No configuration needed. The protocol handles discovery, capabilities, and invocation automatically.
Implementation Guide and Code Examples
Let's build a complete tool-use example with Python and the Anthropic SDK. This is production-ready code you can adapt to your use case.
Complete Tool Use Loop
import anthropic
import json
client = anthropic.Anthropic()
# Define your tools
tools = [
{
"name": "get_stock_price",
"description": "Get the current stock price for a ticker symbol",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol (e.g., AAPL, GOOGL)"
}
},
"required": ["ticker"]
}
},
{
"name": "calculate_moving_average",
"description": "Calculate the 50-day moving average for a stock",
"input_schema": {
"type": "object",
"properties": {
"ticker": {
"type": "string",
"description": "Stock ticker symbol"
},
"days": {
"type": "integer",
"description": "Number of days for moving average"
}
},
"required": ["ticker", "days"]
}
}
]
# Mock functions (replace with real API calls)
def get_stock_price(ticker):
prices = {"AAPL": 185.50, "GOOGL": 142.30, "MSFT": 420.75}
return prices.get(ticker, "Unknown")
def calculate_moving_average(ticker, days):
# Mock calculation
return 175.25 if ticker == "AAPL" else 135.00
def execute_tool(tool_name, tool_input):
if tool_name == "get_stock_price":
return get_stock_price(tool_input["ticker"])
elif tool_name == "calculate_moving_average":
return calculate_moving_average(tool_input["ticker"], tool_input["days"])
return "Tool not found"
# Main loop
def agent_loop(user_message):
messages = [{"role": "user", "content": user_message}]
while True:
# Call Claude with tools
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=1024,
tools=tools,
messages=messages
)
# Check if Claude wants to use tools
if response.stop_reason == "tool_use":
# Process tool requests
assistant_message = {"role": "assistant", "content": response.content}
messages.append(assistant_message)
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = execute_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(result)
})
# Add tool results to messages
messages.append({"role": "user", "content": tool_results})
else:
# Claude finished, extract final answer
final_answer = ""
for block in response.content:
if hasattr(block, "text"):
final_answer += block.text
return final_answer
# Example usage
result = agent_loop("What's the current stock price for Apple and should I buy based on the 50-day moving average?")
print(result)
This code demonstrates the complete loop: send a message, check for tool requests, execute tools, feed results back to Claude, repeat until done. Adapt the mock functions to call real APIs.
Error Handling
def execute_tool_safely(tool_name, tool_input, max_retries=2):
for attempt in range(max_retries):
try:
result = execute_tool(tool_name, tool_input)
return {"success": True, "data": result}
except TimeoutError:
if attempt < max_retries - 1:
continue
return {
"success": False,
"error": f"Tool {tool_name} timed out after {max_retries} attempts"
}
except PermissionError:
return {
"success": False,
"error": f"Permission denied for tool {tool_name}"
}
except Exception as e:
return {
"success": False,
"error": f"Tool error: {str(e)}"
}
return {"success": False, "error": "Unknown error"}
Always wrap tool execution in try-except and return clear error messages to Claude. This prevents silent failures and helps Claude recover gracefully.
Key Takeaways
- Claude tool use is the foundation of agentic AI. It transforms Claude from a responder to an actor.
- Tool definitions with JSON Schema guide Claude toward correct inputs. Constraints and examples prevent hallucinations.
- Claude can request multiple tools simultaneously, enabling parallel execution and faster workflows.
- Agentic loops—where Claude uses tools, analyzes results, and decides what to do next—enable complex multi-step reasoning.
- Extended thinking combined with tool use produces more deliberate, effective tool selections.
- Enterprise systems require approval workflows, role-based authorization, and comprehensive audit logging.
- MCP standardizes tool integration, eliminating the need to redefine tools across projects.
- Error handling is critical. Report tool failures clearly so Claude can adapt or recover.
Ready to Build Agentic AI?
Master Claude tool use with hands-on training from Claude certified architects. We'll walk your team through tool definitions, agentic loops, and production patterns.
Schedule a Consultation