Skip to main content
Lesson 12 of 16 · Responses API: Primary Endpoint

Combining Server and Client Tools

Lesson 12 of 16 Updated July 30, 2026 Developer
On this page
  1. Hybrid Workflows
  2. Combining Server Tools and Functions
  3. The Hybrid Execution Flow
  4. Common Combination Patterns
  5. max_turns and Hybrid Tools
  6. Multi-turn Context with Storage
  7. Key Takeaways

Hybrid Workflows

The true power of the Responses API emerges when you combine server tools (executed automatically by xAI) and client tools (your custom functions) in a single request. The model orchestrates these tools autonomously, creating complex workflows in just a few lines of code.

Combining Server Tools and Functions

response = client.responses.create(
    model="grok-4.20-0309-reasoning",
    input="Search for the latest Ligue 1 soccer results and send a summary to my team.",
    tools=[
        {"type": "web_search"},
        {
            "type": "function",
            "name": "send_team_message",
            "description": "Sends a message to the team via Slack",
            "parameters": {
                "type": "object",
                "properties": {
                    "channel": {"type": "string"},
                    "message": {"type": "string"}
                },
                "required": ["channel", "message"]
            }
        }
    ]
)

In this scenario, the model:

  1. Triggers web_search automatically (server-side) to find the results
  2. Incorporates the data into a summary
  3. Calls send_team_message (client-side) so your code sends the Slack message

The Hybrid Execution Flow

The flow differs depending on the tool type:

Server Tools Only

Request → [model → web_search → result → model] → Final response

Everything happens on the xAI side. You receive the final response directly with the results integrated.

Client Tools Only

Request → [model → function_call] → PAUSE
Your code executes the function
Result → [model] → Final response

The model pauses, your code executes, then you send the result back.

Hybrid Flow

Request → [model → web_search → result → model → function_call] → PAUSE
Your code executes the function
Result → [model] → Final response

The model uses server tools first (automatically), then calls your function when it needs your infrastructure.

Common Combination Patterns

Search + Action

Combine web_search or x_search with an action function:

tools = [
    {"type": "web_search"},
    {"type": "x_search"},
    {
        "type": "function",
        "name": "create_report",
        "description": "Creates a report in the CRM",
        "parameters": {
            "type": "object",
            "properties": {
                "title": {"type": "string"},
                "content": {"type": "string"},
                "tags": {"type": "array", "items": {"type": "string"}}
            },
            "required": ["title", "content"]
        }
    }
]

Calculation + Notification

Combine code_interpreter with a notification function:

tools = [
    {"type": "code_interpreter"},
    {
        "type": "function",
        "name": "send_alert",
        "description": "Sends an alert if a threshold is exceeded",
        "parameters": {
            "type": "object",
            "properties": {
                "metric": {"type": "string"},
                "value": {"type": "number"},
                "threshold": {"type": "number"}
            },
            "required": ["metric", "value"]
        }
    }
]

max_turns and Hybrid Tools

max_turns behavior is important in a hybrid context:

  • max_turns limits server-side turns within a single request
  • When the model calls a client function and your code returns the result, a new allocation of max_turns begins

In practice, this means client calls do not exhaust your server turn budget. The model can perform 3 web searches, call your function, then perform 3 additional searches after receiving the result.

Multi-turn Context with Storage

For complex workflows that span multiple interactions, combine storage and chaining:

# Turn 1: initial search
r1 = client.responses.create(
    model="grok-4.20-0309-reasoning",
    input="Analyze AI market trends.",
    tools=[{"type": "web_search"}, {"type": "code_interpreter"}],
    store=True,
    max_turns=5
)

# Turn 2: deepen with your internal data
r2 = client.responses.create(
    model="grok-4.20-0309-reasoning",
    input="Compare with our internal data.",
    tools=[{
        "type": "function",
        "name": "query_internal_db",
        "description": "Queries the internal database",
        "parameters": {"type": "object", "properties": {"query": {"type": "string"}}}
    }],
    previous_response_id=r1.id,
    store=True
)

Key Takeaways

  • Combine server tools and client functions in a single request for hybrid workflows
  • Server tools execute automatically; client functions pause generation
  • max_turns resets after each client round-trip
  • Common patterns: search + action, calculation + notification, multi-source aggregation
  • Use store: true and previous_response_id for multi-turn workflows