# Tools

> Built-in tools, background tasks and human-in-the-loop input.

A tool is a typed definition (`ToolDef`) that the model can call. This page lists the built-in tools and shows how to rename them, run shell commands in the background and ask a human for input. [MCP servers](https://zidane.si/docs/mcp.md) add more tools.

## Built-in tools

The `basic` preset (`zidane/presets`) has:

| Tool | Behavior |
| - | - |
| `shell` | Combined stdout and stderr, capped at 32 KiB. Past the cap, commands that only read, search, list or run read-only git, in every stage of a pipe, keep the start and the end of the output. Other commands keep the end, with a `…(N bytes truncated from head)…` marker. `maxOutputBytes: 0` turns off the cap. |
| `shell_kill`, `wait_task` | Stop a [background task](#background-tasks), or wait for it to exit. The agent registers them only when background tasks are on. |
| `read_file` | Line range, default 2000 lines, 256 KiB cap. Paging footer, binary marker. |
| `write_file` | Returns `Created`, `Updated` or `No change needed: …`. |
| `edit` | `old_string` to `new_string`. Errors on non-unique or missing matches, with a nearest-match preview. |
| `multi_edit` | Several edits to one file, in order. A failed edit does not stop the others. The file is written when at least one edit applied, and the result lists each edit as applied or failed. |
| `list_files` | Directory listing. |
| `spawn` | Sub-agent delegation ([Sub-agents](https://zidane.si/docs/sub-agents.md)). The `basic` preset sets `persist: true`. |

`basicTools` is the same set without `spawn`:

```ts
import { basicTools, definePreset } from 'zidane/presets'

createAgent({ ...definePreset({ name: 'researcher', tools: basicTools }), provider })
```

Opt-in tools:

| Tool | Import | Notes |
| - | - | - |
| `glob` | `zidane` | Matches through the execution context (process, Docker, sandbox). It skips git-ignored files by default and returns 1000 results at most. |
| `grep` | `zidane` | ripgrep, with a fallback when `rg` is missing. The input follows Claude Code's Grep and adds `patterns`, `paths`, `globs` and `exclude`. A `!` glob skips files (`!*.lock`). A missing root among several is skipped with a note. `head_limit` defaults to 250 lines. |
| `createInteractionTool` | `zidane` | Human-in-the-loop factory ([below](#interaction-tool)). |
| `todowrite` / `todoread` | `createTodoTools` from `zidane/chat` | Task checkpoints that persist across prompts. |
| `skills_use`, `skills_read`, `skills_run_script` | added for you | Injected once the skills catalog is non-empty ([Skills](https://zidane.si/docs/skills.md)). |
| `web_search`, `fetch_url` | `zidane/tools/web-search`, `zidane/tools/fetch-url` | Search the web and read a page. `behavior.fetchUrlAllowHosts` limits the hosts. |
| `createGenerateImageTool` | `zidane` | Generates images with the run's image models and saves them in the workspace ([Images](https://zidane.si/docs/images.md)). |
| `record_artifact` | `recordArtifact` from `zidane/tools` | The model marks a deliverable (a PR, a branch, a deployment) so it shows as a session artifact. |
| `codemode` | `behavior.codemode: true` | The model writes one short script that calls the other tools. The script runs in a sandbox ([reference](https://zidane.si/docs/reference/codemode.md)). |

## Tools the apps add

In the terminal and desktop apps, each session gets the tools of its agent profile. The Build and Codemode profiles have the `basic` tools plus `glob`, `grep`, `web_search` and `fetch_url`. The Plan profile has only `read_file`, `list_files`, `glob`, `grep`, `web_search` and `fetch_url`. Plan shares Build's agent: the request keeps Build's tool list, and a gate refuses the tools Plan does not have ([profiles](https://zidane.si/docs/extensions.md#agent-profiles)). The apps then add these tools:

| Tool | When the agent has it |
| - | - |
| `todowrite`, `todoread` | In the Build and Codemode profiles |
| `present_plan`, `ask_user` | Unless the setting Interaction mode is Disable tools ([approvals](https://zidane.si/docs/approvals.md#plans-and-questions)) |
| `read_chat_turns` | Always. It reads only the chats that the current prompt mentions with `#`. |
| `record_artifact` | The setting Artifacts is on (the default) |
| `model_search` | The setting Allow subagents to use different models is on and the profile has a `spawn` tool ([sub-agents](https://zidane.si/docs/sub-agents.md)) |
| `generate_image` | The setting Image generation is on (the default) and a connected provider can generate images ([Images](https://zidane.si/docs/images.md)) |
| `tool_search`, `call_tool` | MCP tools load on demand ([MCP](https://zidane.si/docs/mcp.md)). `call_tool` only while the setting Stable tool list (call_tool) is on, the default. |
| `codemode` | The setting Codemode is on |
| `browser_*` | Desktop app, while the settings Browser tab and Agent can use the browser are on |
| `terminal_list`, `terminal_read`, `terminal_write` | Desktop app, while the settings Terminals and Agent can use your terminals are on and a window shows terminals. Needs the [daemon](https://zidane.si/docs/daemon.md). |
| `sessions` | The [Main session](https://zidane.si/docs/daemon.md#main-session) only, with the setting Main session on |

A `/side` session gets only the Plan tools and `read_parent_session`. The apps add none of the tools above to it.

## Aliasing and descriptions

`toolAliases` changes the name the model sees:

```ts
createAgent({ provider, tools: { shell }, toolAliases: { shell: 'Bash' } })
```

`toolDescriptions` overrides any description, native or MCP, with a string or a function of the current one:

```ts
createAgent({
  provider,
  toolDescriptions: {
    shell: cur => `${cur}\nNever invoke sudo.`,
    mcp_github_create_pull_request: 'Open a PR. Always target `develop`.',
  },
})
```

## Background tasks

With `run_in_background: true`, `shell` returns a `bash_<n>` handle at once. Output goes to a log file that the model reads with `read_file`. `shell_kill` stops the task. `wait_task` blocks until the task exits. When a task finishes, the next turn gets a `<task-notification>` block, so the model does not have to poll.

Set a log directory to turn it on:

```ts
import { createAgent, resolveTasksDir } from 'zidane'

const tasksDir = resolveTasksDir({ userDir: '/var/lib/my-agent', sessionId: session.id })
const agent = createAgent({
  provider,
  session,
  behavior: { tasksDir }, // required
})
```

The built-in `shell` hides `run_in_background` from the model, and the agent does not register `shell_kill` and `wait_task`, in each of these cases:

- `behavior.tasksDir` is unset.
- `behavior.disableBackgroundTasks` is `true`.
- `behavior.disableBackgroundTasks` is `'non-durable'` and the detached tasks of the context are not durable.
- The context cannot detach tasks.

The full lifecycle is in [`docs/RUN_IN_BACKGROUND.md`](https://github.com/Tahul/zidane/blob/main/docs/RUN_IN_BACKGROUND.md).

`agent.destroy()` sends SIGTERM to each task's process group and flushes its log before tearing down the execution handle.

## Interaction tool

`createInteractionTool` pauses the agent until `onRequest` returns the structured input of a human. It takes `schema`, `onRequest` and an optional `name` and `description`. No preset includes it. The apps have their own `ask_user` and `present_plan` ([approvals](https://zidane.si/docs/approvals.md#plans-and-questions)).

```ts
import { createInteractionTool } from 'zidane'

const askUser = createInteractionTool({
  name: 'ask_user',
  schema: { type: 'object', properties: { question: { type: 'string' } }, required: ['question'] },
  onRequest: async ({ question }) => ({ answer: await promptUser(question) }),
})

createAgent({ provider, tools: { ...basicTools, ask_user: askUser } })
```

## Calls a crash cut off

`ToolDef.replay` says what a durable run does with a call of the tool that a process death left unfinished. `'safe'` runs it again, for reads with no side effect. `'unsafe'` (the default) reports it to the model as interrupted. See [safe and unsafe tools](https://zidane.si/docs/durability.md#safe-and-unsafe-tools).

## Related

| Topic | Page |
| - | - |
| `steer`, `followUp`, `abort`, `cancelTool` | [Agents](https://zidane.si/docs/agents.md) |
| Concurrency, `dedupTools`, `toolBudgets`, `repeatGuard` | [Hooks](https://zidane.si/docs/hooks.md#tool-dispatch) |
| Gate, rewrite and observe tool calls | [Hooks](https://zidane.si/docs/hooks.md) |

## Reference

- [`zidane/tools`](https://zidane.si/docs/reference/tools.md)
- [`zidane/tools/web-search`](https://zidane.si/docs/reference/tools-web-search.md)
- [`zidane/tools/fetch-url`](https://zidane.si/docs/reference/tools-fetch-url.md)
- [`zidane/tools/prompts`](https://zidane.si/docs/reference/tools-prompts.md)
- [`zidane/codemode`](https://zidane.si/docs/reference/codemode.md)
