> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cartesia.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Client tools

> Run functions in your application over the WebSocket API.

Client tools let an agent trigger actions in the connected application, such as opening a page or reading client-side state. They are available only over the [WebSocket API](/line/integrations/websocket-api).

When the model invokes a client tool, Cartesia sends a `client_tool_call` event. Your application runs the function and, when required, responds with `client_tool_result`.

## Define a client tool

```json theme={null}
{
  "type": "client",
  "name": "open_cart",
  "description": "Opens the shopping cart. Use it when the user wants to review or check out their cart.",
  "pre_tool_speech": "auto",
  "execution_mode": "async",
  "expects_response": false,
  "parameters": {
    "type": "object",
    "properties": {
      "cart_id": {
        "type": "string",
        "description": "Cart to open."
      }
    },
    "required": ["cart_id"]
  }
}
```

Create the tool with [`POST /v1/agents/tools`](/api-reference/agents/tools/create), then attach its ID through `config.tools`. See [Tools](/agents/tools#execution-settings) for the shared execution settings.

## Parameters

`parameters` must be a JSON Schema object. Properties may use `string`, `integer`, `number`, `boolean`, or an array of one of those scalar types. String properties may include an `enum`. Use `required` to identify values the model must supply.

## Response behavior

* `expects_response: true` makes the agent wait for a `client_tool_result` with the same `tool_call_id`. Use it when the result affects the conversation.
* `expects_response: false` completes the tool after dispatch. Use it for client-side actions that the agent does not need to confirm.

`response_timeout_secs` is available only when `expects_response` is `true`.

## Handle a tool call

```javascript theme={null}
// ws is the connection from the WebSocket API quick start.
async function runTool(name, parameters) {
  if (name === "open_cart") {
    // Open the cart in your interface.
    return { opened: true, cart_id: parameters.cart_id };
  }
  throw new Error(`Unknown tool: ${name}`);
}

ws.onmessage = async (message) => {
  const event = JSON.parse(message.data);
  if (event.type !== "client_tool_call") return;

  const result = await runTool(event.tool_name, event.parameters);

  if (event.expects_response) {
    ws.send(JSON.stringify({
      type: "client_tool_result",
      tool_call_id: event.tool_call_id,
      result: JSON.stringify(result),
      is_error: false,
    }));
  }
};
```

Results are strings up to 4 KiB. On failure, send `is_error: true` with a short result that the model can act on. See the [WebSocket event reference](/api-reference/agents/agent-websocket) for complete event schemas.
