Claude API Development

Claude Tool Use Guide: Function Calling & Agent Architecture

📅 Published March 2026 · 12 min read

Table of Contents

  1. What is Claude Tool Use and Why It Matters
  2. How Tool Use Works: The Request/Response Cycle
  3. Defining Tools with JSON Schema
  4. Tool Use Patterns: Single and Parallel Calls
  5. Handling Tool Results and Error States
  6. Building Agentic Loops: Multi-Step Reasoning
  7. Tool Use with Extended Thinking
  8. Enterprise Patterns and Governance
  9. MCP: The Standardized Tool Protocol
  10. Implementation Guide and Code Examples

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.

Example: Weather Tool Definition
{ "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:

Claude's Tool Use Request
{ "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:

Reporting Tool Results
{ "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.

Complete Schema Example: Database Query Tool
{ "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:

Parallel Tool Requests
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:

Successful Tool Result
{ "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:

Tool Error Response
{ "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:

Partial Results
{ "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:

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:

Extended Thinking in API Call
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:

Approval Workflow Pattern
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:

Role-Based Tool Authorization
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:

Audit Logging Pattern
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:

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

Python: Complete Tool Use Implementation
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

Robust 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

Get the Latest Claude Updates

New Claude tools, API updates, and deployment patterns delivered to your inbox.

📚

Claude Implementation Team

Claude Certified Architects & AI Strategy Experts

We're the specialists in Claude deployment. From enterprise API integration to agentic AI architectures, we help organizations unlock Claude's full potential. Our team has trained hundreds of developers on tool use, prompt engineering, and production AI systems.