---
product: "AG Studio"
title: "Tools Overview"
description: "Learn what a tool is, how it relates to the command underneath it, and the four ways to author one."
framework: angular
version: "3.0.0"
related:
    - title: "Built-in Tools"
      url: "https://www.ag-grid.com/studio/angular/ai-tools-builtin/"
    - title: "Custom Tools"
      url: "https://www.ag-grid.com/studio/angular/ai-custom-tools/"
    - title: "External Tools"
      url: "https://www.ag-grid.com/studio/angular/ai-tools-external/"
llms: "https://www.ag-grid.com/studio/llms.txt"
---

# Tools Overview

A tool is how an agent acts on a dashboard. It is a self-contained value: it advertises a JSON schema to the model, and when the model calls it, it runs against live state and reports back.

Tools need no chat panel, no harness, and no agent. `api.getAiTools()` returns values you can execute yourself, and everything else in this section builds on them.

The example below has no panel, no harness and no LLM. Each button drives Studio through tools and commands directly, and the console shows what each returns.

#### Tools Without a Harness

```ts
import '@angular/compiler';
import { provideHttpClient } from '@angular/common/http';
import { bootstrapApplication } from '@angular/platform-browser';

import { AppComponent } from './app.component.ts';

const app = bootstrapApplication(AppComponent, {
    providers: [provideHttpClient()],
});
```

[Live example: Tools Without a Harness](https://www.ag-grid.com/studio/examples/ai-tools/ai-tools-direct-example/angular/)

## Anatomy

| Property | Type | Default | Description |
| --- | --- | --- | --- |
| `name` | `string` |  | The name the LLM calls it by. |
| `description` | `string` |  | What the tool does, as the LLM reads it. |
| `kind` | `AgAiToolKind` |  | Where the tool runs. See AgAiToolKind. |
| `schema` | `Function` |  | The current LLM-facing schema, or `undefined` when uncallable. |
| `execute` | `Function` |  | Carries out one call against current state. Present only on a `client` tool: a `server` or `provided` tool is declared here and run elsewhere, so guard this rather than assuming it. |

Three parts of that shape are worth calling out.

**`schema()` is a function, not a value.** It is called every turn, and it reads live state. A tool whose parameters include a widget-id enum reports the widgets that exist *now*.

**A tool can be uncallable.** When `schema()` returns `undefined`, the tool is withheld from that turn entirely - not advertised, not callable. That happens to `configure_widget` on a page with no widgets: rather than offering the model a choice with no valid values, the tool drops out until there is something to configure.

**`execute` is optional.** A `client` tool runs here. A `server` or `provided` tool is declared here and run elsewhere - see [External Tools](https://www.ag-grid.com/studio/angular/ai-tools-external/).

## Commands: the Layer Below

Most tools that change something are built on a **command**, and the split matters when you author your own.

A command is an *action*: an input shape plus an `execute`. It validates its arguments against the shape, applies the change, and returns a discriminated result. It has no name, no description and no idea an LLM exists.

A tool is the *LLM-facing wrapper*: the name and description the model sees, and the formatting that turns what the command returned into a response the model can read.

```ts
// The command: schema + action.
const setTheme = api.defineAiCommand((s) => ({
    input: s.object({ theme: s.enum(['light', 'dark']) }),
    execute: ({ theme }) => {
        applyTheme(theme);
        return { success: true, value: theme };
    },
}));

// The tool: what the model sees.
const setThemeTool = api.defineAiTool({
    name: 'set_theme',
    description: 'Switch the dashboard between light and dark.',
    command: setTheme,
    result: (theme) => ({ response: `Theme is now ${theme}.` }),
});
```

The command's input shape *is* the tool's schema, with nothing wrapped around it. Splitting them this way lets the validated action be reused: the same command can back a tool, a button in your own UI, and a scripted migration.

## Results

A tool returns a discriminated result, never a thrown error:

```ts
execute: (args, ctx) => {
    if (!isAllowed(args)) {
        return ctx.error('That region is not available to this user.');
    }
    return ctx.success(`Found ${rows.length} rows.`, { rows });
},
```

`response` is the string the model reads. `data` is an optional structured payload, serialised to the model *and* handed to the tool's [component](https://www.ag-grid.com/studio/angular/ai-tool-components/) for rendering. Failures carry messages the model sees, so it can correct itself and try again.

## The Four Authoring Paths

| You want | Use | Page |
| --- | --- | --- |
| A tool Studio already ships | `api.getAiTools()` | [Built-in Tools](https://www.ag-grid.com/studio/angular/ai-tools-builtin/) |
| Your own action, validated | `api.defineAiTool({ command, result })` | [Custom Tools](https://www.ag-grid.com/studio/angular/ai-custom-tools/) |
| Studio's action, your wrapper | `api.defineAiCommand({ type: 'AgX' })` then wrap it | [Custom Tools](https://www.ag-grid.com/studio/angular/ai-custom-tools/#wrap-a-built-in-command) |
| A tool run by a server or the provider | `api.defineAiTool({ kind: 'server' \| 'provided' })` | [External Tools](https://www.ag-grid.com/studio/angular/ai-tools-external/) |

## Descriptions Are Prompts

A tool's description is prompt text, and it is the cheapest lever you have over behaviour. There are two ways to change it without touching the tool:

- Per listing, for one agent: `studio.addWidget({ description: '...' })`
- Globally: the `aiText` property, keyed `tools.<name>.description`

Both work for tools you define yourself, under the name the tool advertises. `aiText` holds prompt text rather than reader-facing wording, so it is not translated - see [Localisation](https://www.ag-grid.com/studio/angular/ai-chat-ui/#localisation).

## Without a Harness

A harness is only needed to manage a conversation. The tools work on their own, driven by an automated process, an agent of your own, or something else entirely. [WebMCP](https://www.ag-grid.com/studio/angular/ai-webmcp/) publishes them to the browser's own agent.

The AI module must still be registered, because it carries the tools, the context service and the licence. Tool schemas read live state, so build them per turn rather than once.

### Running a Tool

A tool takes an invocation and a per-call context, and hands back a discriminated result:

```ts
const studio = api.getAiTools();
const tool = studio.executeQuery();

const result = await tool.execute!({ toolCallId: 'call-1', name: tool.name, args: { query } }, createAiToolContext());
```

An invocation carries the call id, the tool name, and `args` as a decoded object. If you are relaying a call from a model, parse its arguments first - the tool validates them against its own shape, so a bad payload comes back as issues rather than an exception.

`createAiToolContext` builds what a harness would normally supply. Pass a `signal` to make the call cancellable, and a `run` if a tool needs to scope a resource per conversation.

`execute` is optional on `AgAiTool`, because [external tools](https://www.ag-grid.com/studio/angular/ai-tools-external/) declare a schema without one. Every tool from `api.getAiTools()` has one, hence the assertion above; guard it instead when the tool could be external.

### Running a Command

For an automated process with no LLM anywhere, use a **command** rather than a tool. It validates its input and returns a result:

```ts
const addWidget = api.defineAiCommand({ type: 'AgAddWidgetCommand' });

const result = await addWidget.apply({
    widgetId: 'sales',
    type: 'bar-chart-grouped',
    xTrack: 0,
    yTrack: 0,
    xSpan: 6,
    ySpan: 4,
});

if (!result.success) {
    console.error(result.error.message);
}
```

[Custom Tools](https://www.ag-grid.com/studio/angular/ai-custom-tools/#from-a-command) covers writing commands of your own.

## Next

- [Built-in Tools](https://www.ag-grid.com/studio/angular/ai-tools-builtin/) - the catalogue
- [Custom Tools](https://www.ag-grid.com/studio/angular/ai-custom-tools/) - authoring
- [Tool Components](https://www.ag-grid.com/studio/angular/ai-tool-components/) - rendering a call in the panel
