Mastering Claude Tool Calls: Turn Claude into a Real‑Time Assistant

This tutorial explains how to extend Claude's static knowledge by using tool calls, covering the full workflow from initial requests to final responses, building Python tool functions, defining JSON Schemas, handling multi‑block messages, managing multi‑tool interactions, fine‑grained streaming, and using built‑in text‑editor and web‑search tools.

Java One
Java One
Java One
Mastering Claude Tool Calls: Turn Claude into a Real‑Time Assistant

Why Tool Calls Are Needed

Claude can only answer from its training data and fails on real‑time queries such as "What’s the weather in San Francisco now?". Tool calls let Claude request external data, turning it from a static knowledge base into a dynamic assistant.

Tool Call Workflow

The process follows a five‑step round‑trip:

Initial request – the user asks a question and hints at needed external data.

Tool request – Claude decides a tool is required and sends a tool_use block.

Data fetch – your server runs the specified function (e.g., an API call).

Result block – you return a tool_result block containing the fetched data.

Final response – Claude combines the result with the original query and replies to the user.

Concrete Example: Weather Query

When a user asks for the current weather, Claude sends a tool_use block for a get_current_weather function. Your server calls a weather API, returns the JSON result, and Claude replies with a real‑time forecast.

Core Advantages

Real‑time information – access data that Claude never saw during training.

External system integration – call any API, database, or service.

Dynamic responses – answers are based on the latest available data.

Structured interaction – Claude knows exactly which parameters to request.

Project Overview: Reminder System

The tutorial builds a reminder assistant that needs three tools:

Get current date‑time.

Add a duration to a date‑time.

Set a reminder.

Tool Functions and Schemas

Each tool is a normal Python function paired with a JSON Schema that tells Claude how to call it.

def get_current_datetime(date_format="%Y-%m-%d %H:%M:%S"):
    if not date_format:
        raise ValueError("date_format cannot be empty")
    return datetime.now().strftime(date_format)

The corresponding schema (simplified) is:

get_current_datetime_schema = {
    "name": "get_current_datetime",
    "description": "Return the current date and time formatted with the given strftime pattern.",
    "input_schema": {
        "type": "object",
        "properties": {
            "date_format": {"type": "string", "default": "%Y-%m-%d %H:%M:%S"}
        },
        "required": []
    }
}

Similar functions and schemas are provided for add_duration_to_datetime and set_reminder.

Calling the API with Tools

When sending a request, include the schemas in the tools array:

response = client.messages.create(
    model=model,
    max_tokens=1000,
    messages=messages,
    tools=[get_current_datetime_schema, add_duration_to_datetime_schema, set_reminder_schema]
)

Claude’s reply may contain a ToolUseBlock and an optional TextBlock. Example response excerpt:

Message(id='msg_1',
        content=[
            TextBlock(text='I will fetch the current time for you.'),
            ToolUseBlock(id='call_123', name='get_current_datetime', input={'date_format': '%H:%M:%S'})
        ],
        stop_reason='tool_use')

Processing Tool Use Blocks

Extract all tool_use blocks, map the name to the actual Python function, call it with the supplied input, and build a result block:

tool_use_blocks = [b for b in response.content if b.type == "tool_use"]
results = []
for block in tool_use_blocks:
    fn = tool_functions.get(block.name)
    if fn:
        result = fn(**block.input)
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": str(result),
            "is_error": False
        })

Append the result blocks as a new user message and continue the conversation loop until response.stop_reason != "tool_use".

Multi‑Tool Scenarios

Claude can request several tools in a single response. Each request has a unique id. The same extraction logic works; just ensure each result block matches the corresponding tool_use_id.

Conversation Loop Example

def run_conversation(messages):
    while True:
        response = client.messages.create(
            model=model,
            max_tokens=1000,
            messages=messages,
            tools=[get_current_datetime_schema, add_duration_to_datetime_schema, set_reminder_schema]
        )
        messages.append({"role": "assistant", "content": response.content})
        if response.stop_reason != "tool_use":
            break
        tool_results = run_tools(response)
        messages.append({"role": "user", "content": tool_results})
    return messages

Fine‑Grained Streaming

When streaming, Claude emits InputJsonEvent objects that contain partial_json (a fragment) and snapshot (the cumulative JSON so far). This allows you to show live parameter generation. By default the API validates each top‑level key before sending; you can disable validation for lower latency:

run_conversation(messages, tools=[save_article_schema], fine_grained=True)

Built‑In Text Editor Tool

Claude ships with a text‑editor tool that can read, write, and modify files. You still need to implement the actual file‑system operations, but the schema is provided by Claude. Example schema selector:

def get_text_edit_schema(model):
    if model.startswith("claude-3-7-sonnet"):
        return {"type": "text_editor_20250124", "name": "str_replace_editor"}
    elif model.startswith("claude-3-5-sonnet"):
        return {"type": "text_editor_20241022", "name": "str_replace_editor"}

With this schema, Claude can request actions such as "open ./main.py and replace the placeholder with a pi‑calculation function" or "create ./test.py with unit tests".

Built‑In Web Search Tool

Claude can also perform web searches. Define a simple schema:

web_search_schema = {
    "type": "web_search_20250305",
    "name": "web_search",
    "max_uses": 5
}

You may restrict the search to trusted domains with allowed_domains (e.g., ["nih.gov"]) to ensure authoritative sources. The response contains a mixture of text blocks, ServerToolUseBlock (the query), WebSearchToolResultBlock (raw results), and citation blocks that UI can render as a source list.

Quiz – Test Your Understanding

The article ends with a short quiz covering stop reasons, message structures, schema purpose, batch tool calls, workflow order, and the role of tool calls in providing real‑time information.

No tools scenario
No tools scenario
Tool call workflow
Tool call workflow
Weather query example
Weather query example
Tool result block
Tool result block
Multi‑block message structure
Multi‑block message structure
Key‑value pair validation process
Key‑value pair validation process
Fine‑grained tool calls
Fine‑grained tool calls
Text editor tool overview
Text editor tool overview
Text editor schema versions
Text editor schema versions
Web search tool
Web search tool
Search response structure
Search response structure
Search result rendering
Search result rendering
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Java One
Written by

Java One

Sharing common backend development knowledge.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.