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

# Client-Side Tools

> Register tools that run in the user's browser

Client-side tools execute in the browser instead of on a server. You register handlers via `window.argide('registerTools', {...})`, and the agent calls them like any other tool — but the work happens client-side.

## When to Use

Use client-side tools for browser-only actions:

* CSV / file downloads
* Page navigation
* DOM manipulation
* Accessing client-side state (stores, localStorage)

<Note>
  Use server-side tools (OpenAPI / MCP) for API calls, database queries, and anything that requires backend access.
</Note>

## Setup

### 1. Register Handlers

In your app code, register functions the widget can call:

```js theme={null}
window.argide('registerTools', {
  exportListToCSV: async ({ fileName }) => {
    // ... build CSV from app state
    downloadCsv(data, fileName || 'export');
    return { status: 'success', rows_exported: data.length };
  }
});
```

### 2. Upload Tool Definitions

On the [Actions](https://dashboard.argide.ai/dashboard/tools/client-tools) page, upload a JSON definition so the agent knows the tool exists:

```json theme={null}
[{
  "name": "exportListToCSV",
  "description": "Export the current list to a CSV file. Downloads directly to the user's device.",
  "parameters": {
    "type": "object",
    "properties": {
      "fileName": { "type": "string", "description": "Name for the CSV file" }
    },
    "required": []
  }
}]
```

<Tip>
  Good descriptions help the agent decide when to use the tool.
</Tip>

## Handler Contract

Each handler receives an `args` object matching the tool's parameters schema and must return an object.

| Outcome | Return value                            |
| ------- | --------------------------------------- |
| Success | `{ status: "success", ...data }`        |
| Failure | `{ status: "error", error: "message" }` |

The returned object is sent back to the agent so it can incorporate the result into its response.

## Showing a Loading State

For tools that take a few seconds, call `setToolStatus` to show a spinning indicator with a status message inside the widget. Clear it when done.

```js theme={null}
window.argide('registerTools', {
  createAndPopulateList: async ({ listName }) => {
    window.argide('setToolStatus', 'Creating list...');
    await createList(listName);
    window.argide('setToolStatus', 'Adding leads...');
    await addLeads();
    window.argide('setToolStatus', ''); // clear
    return { status: 'success' };
  }
});
```

The status appears above the input box with a spinner while non-empty, and disappears when set to `''`.

## How It Works

```mermaid theme={null}
sequenceDiagram
    participant User
    participant ArgideCopilot
    participant ArgideBackend as Argide Backend

    User->>ArgideCopilot: "Export this list as CSV"
    ArgideCopilot->>ArgideBackend: POST /chat/message
    ArgideBackend-->>ArgideCopilot: SSE tool_call (exportListToCSV)
    ArgideCopilot->>ArgideCopilot: Runs registered handler in browser
    ArgideCopilot->>ArgideBackend: Tool result
    ArgideBackend-->>ArgideCopilot: SSE assistant message
    ArgideCopilot->>User: "Done — exported 142 rows"
```

1. **User asks** — The message is sent to the agent
2. **Agent picks the tool** — Based on the tool definition
3. **Widget runs the handler** — Executes your registered function client-side
4. **Result flows back** — The agent sees the return value and responds

<CardGroup cols={2}>
  <Card title="Tool Renderers" icon="paintbrush" href="/integration/tool-renderers">
    Render custom UI for tool results
  </Card>

  <Card title="Embed Widget" icon="code" href="/setup/embed-widget">
    Full installation guide
  </Card>
</CardGroup>
