---
title: Tools
description: Defining external tools agents can use.
---

# Tools

Tools extend what agents can do. They're defined in the protocol and implemented in your backend.

## Tool Definition

```yaml
tools:
  get-user-account:
    description: Looking up your account information
    display: description
    parameters:
      userId:
        type: string
        description: The user ID to look up
```

### Tool Fields

| Field | Required | Description |
|-------|----------|-------------|
| `description` | Yes | What the tool does (shown to LLM and optionally user) |
| `display` | No | How to show in UI: `hidden`, `name`, `description`, `stream` |
| `parameters` | No | Input parameters the tool accepts |

### Display Modes

| Mode | Behavior |
|------|----------|
| `hidden` | Tool runs silently, user doesn't see it |
| `name` | Shows tool name while executing |
| `description` | Shows description while executing (default) |
| `stream` | Streams tool progress if available |

## Parameters

### Parameter Fields

| Field | Required | Description |
|-------|----------|-------------|
| `type` | Yes | Data type: `string`, `number`, `boolean`, `unknown` |
| `description` | No | Describes what this parameter is for |
| `optional` | No | If true, parameter is not required (default: false) |

### Optional Parameters

Parameters are **required by default**. Use `optional: true` to make a parameter optional:

```yaml
tools:
  search-products:
    description: Search the product catalog
    parameters:
      query:
        type: string
        description: Search query
      
      category:
        type: string
        description: Filter by category
        optional: true
      
      maxPrice:
        type: number
        description: Maximum price filter
        optional: true
      
      inStock:
        type: boolean
        description: Only show in-stock items
        optional: true
```

## Making Tools Available

Tools defined in `tools:` are available. To make them usable by the LLM, add them to `agent.tools`:

```yaml
tools:
  get-user-account:
    description: Look up user account
    parameters:
      userId: { type: string }
  
  create-support-ticket:
    description: Create a support ticket
    parameters:
      summary: { type: string }
      priority: { type: string }  # low, medium, high, urgent

agent:
  model: anthropic/claude-sonnet-4-5
  system: system
  tools:
    - get-user-account
    - create-support-ticket  # LLM can decide when to call these
  agentic: true
```

## Tool Invocation Modes

### LLM-Decided (Agentic)

The LLM decides when to call tools based on the conversation:

```yaml
agent:
  tools: [get-user-account, create-support-ticket]
  agentic: true  # Allow multiple tool calls
  maxSteps: 10   # Max tool call cycles
```

### Deterministic (Block-Based)

Force tool calls at specific points in the handler:

```yaml
handlers:
  request-human:
    # Always create a ticket when escalating
    Create support ticket:
      type: tool-call
      tool: create-support-ticket
      input:
        summary: SUMMARY  # From variable
        priority: medium  # Literal value
      output: TICKET      # Store result
```

## Tool Results

### In Prompts

Reference tool results in prompts:

```markdown
<!-- prompts/ticket-directive.md -->
A support ticket has been created:
- Ticket ID: {{TICKET.ticketId}}
- Estimated Response: {{TICKET.estimatedResponse}}

Let the user know their ticket has been created.
```

### In Variables

Store tool results for later use:

```yaml
handlers:
  request-human:
    Get account:
      type: tool-call
      tool: get-user-account
      input:
        userId: USER_ID
      output: ACCOUNT  # Result stored here
    
    Create ticket:
      type: tool-call
      tool: create-support-ticket
      input:
        summary: SUMMARY
        priority: medium
        # Can reference ACCOUNT here
        email: ACCOUNT.email
      output: TICKET
```

## Implementing Tools

Tools are implemented in your backend:

```typescript
const session = client.agentSessions.attach(sessionId, {
  tools: {
    'get-user-account': async (args) => {
      const userId = args.userId as string;
      const user = await db.users.findById(userId);
      
      return {
        name: user.name,
        email: user.email,
        plan: user.subscription.plan,
        createdAt: user.createdAt.toISOString(),
      };
    },
    
    'create-support-ticket': async (args) => {
      const ticket = await ticketService.create({
        summary: args.summary as string,
        priority: args.priority as string,
      });
      
      return {
        ticketId: ticket.id,
        estimatedResponse: getEstimatedTime(args.priority),
      };
    },
  },
});
```

## Tool Best Practices

### 1. Clear Descriptions

```yaml
tools:
  # Good - clear and specific
  get-user-account:
    description: >
      Retrieves the user's account information including name, email,
      subscription plan, and account creation date. Use this when the
      user asks about their account or you need to verify their identity.
  
  # Avoid - vague
  get-data:
    description: Gets some data
```

### 2. Document Constrained Values

```yaml
tools:
  create-support-ticket:
    parameters:
      priority:
        type: string
        description: Ticket priority level (low, medium, high, urgent)
```

