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

# Tools

> Built-in tools for file operations, shell commands, web access, skills, and integrations — with workspace sandboxing.

Tools are what your agents can *do*. Each tool gives an agent a real-world capability — reading files, running commands, searching the web, and more. You enable tools per agent when you deploy or edit it in Desktop.

## File tools

<Tabs>
  <Tab title="read">
    Read the contents of a file and return it as text.

    | Parameter | Type     | Required | Description       |
    | --------- | -------- | -------- | ----------------- |
    | `path`    | `string` | yes      | File path to read |

    Paths are resolved relative to the workspace when configured. Path traversal outside the workspace is blocked.
  </Tab>

  <Tab title="write">
    Create a new file or overwrite an existing file.

    | Parameter | Type     | Required | Description        |
    | --------- | -------- | -------- | ------------------ |
    | `path`    | `string` | yes      | File path to write |
    | `content` | `string` | yes      | Content to write   |

    Paths are resolved relative to the workspace when configured.
  </Tab>

  <Tab title="edit">
    Make targeted changes to an existing file (find-and-replace).

    | Parameter    | Type     | Required | Description       |
    | ------------ | -------- | -------- | ----------------- |
    | `path`       | `string` | yes      | File path to edit |
    | `old_string` | `string` | yes      | Text to find      |
    | `new_string` | `string` | yes      | Replacement text  |

    Paths are resolved relative to the workspace when configured.
  </Tab>

  <Tab title="ls">
    List files and directories at a given path.

    | Parameter | Type     | Required | Description            |
    | --------- | -------- | -------- | ---------------------- |
    | `path`    | `string` | yes      | Directory path to list |

    Paths are resolved relative to the workspace when configured.
  </Tab>

  <Tab title="find">
    Find files by name or pattern (e.g. `**/*.ts`).

    | Parameter | Type     | Required | Description                        |
    | --------- | -------- | -------- | ---------------------------------- |
    | `pattern` | `string` | yes      | File name or glob pattern to match |

    Searches within the workspace when configured.
  </Tab>

  <Tab title="grep">
    Search for text or patterns inside files.

    | Parameter | Type     | Required | Description                 |
    | --------- | -------- | -------- | --------------------------- |
    | `pattern` | `string` | yes      | Text or regex to search for |

    Searches within the workspace when configured.
  </Tab>
</Tabs>

## Shell

<Tabs>
  <Tab title="bash">
    Execute a shell command and return its output.

    | Parameter | Type     | Required | Description                  |
    | --------- | -------- | -------- | ---------------------------- |
    | `command` | `string` | yes      | The shell command to execute |

    **Limits:**

    * **Timeout**: 30 seconds — commands that exceed this are killed
    * **Output size**: 100 KB — output beyond this limit is truncated

    When a workspace is configured, `bash` sets its working directory (`cwd`) to the workspace path. Commands still have access to the full system; the workspace only sets the starting directory.
  </Tab>
</Tabs>

## Web

<Tabs>
  <Tab title="web_search">
    Search the internet for information and return results.

    | Parameter | Type     | Required | Description  |
    | --------- | -------- | -------- | ------------ |
    | `query`   | `string` | yes      | Search query |

    Not affected by workspace sandboxing.
  </Tab>

  <Tab title="web_fetch">
    Download content from a URL and return it as text.

    | Parameter | Type     | Required | Description  |
    | --------- | -------- | -------- | ------------ |
    | `url`     | `string` | yes      | URL to fetch |

    Not affected by workspace sandboxing.
  </Tab>
</Tabs>

## Skills

Loading a skill is automatic — whenever skills are available, the agent can pull a skill's full instructions on demand, so there's no tool to enable for that. The tools below are the ones you opt into to let an agent *manage* its own skills. See [Skills](/skills) for the full picture.

<Tabs>
  <Tab title="create_skill">
    Create a reusable skill that persists across conversations.

    | Parameter     | Type       | Required | Description                                                   |
    | ------------- | ---------- | -------- | ------------------------------------------------------------- |
    | `name`        | `string`   | yes      | Skill name (lowercase alphanumeric and hyphens, max 64 chars) |
    | `description` | `string`   | yes      | When to use this skill — powers automatic discovery           |
    | `content`     | `string`   | yes      | Full skill instructions as markdown                           |
    | `trigger`     | `string`   | no       | Trigger keyword or phrase for automatic activation            |
    | `tools`       | `string[]` | no       | Tool names this skill uses                                    |
    | `tags`        | `string[]` | no       | Tags for categorization                                       |

    The agent creates skills when the user asks it to remember a process, save a workflow, or build reusable instructions. Skills are persisted to the managed skills directory and available in future conversations.
  </Tab>

  <Tab title="install_skill">
    Install a text-only skill from the public ecosystem.

    | Parameter | Type     | Required | Description                                                                     |
    | --------- | -------- | -------- | ------------------------------------------------------------------------------- |
    | `source`  | `string` | yes      | `git:owner/repo[/subpath][@ref]`, an https URL to a `SKILL.md`, or a local path |
    | `name`    | `string` | no       | Override the installed skill's name                                             |

    Bundled scripts are stripped (skills are text-only), and every install passes a security scan that refuses prompt-injection, secret-exfiltration, or destructive instructions. See [Skills](/skills) for details.
  </Tab>

  <Tab title="remove_skill">
    Uninstall a managed, installed, or agent-created skill.

    | Parameter | Type     | Required | Description              |
    | --------- | -------- | -------- | ------------------------ |
    | `name`    | `string` | yes      | The skill name to remove |

    Bundled skills are read-only and cannot be removed.
  </Tab>
</Tabs>

## Memory

Reading and writing memory is automatic — whenever memory is on for an agent, it gets the three tools below without any per-agent tool selection, the same way `load_skill` is always available. See [Memory](/memory) for the full picture.

<Tabs>
  <Tab title="save_memory">
    Save or update one memory that should persist across conversations.

    | Parameter     | Type     | Required | Description                                                                                                                                        |
    | ------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `name`        | `string` | yes      | Stable slug for this fact (lowercase letters, digits, hyphens, max 64 chars). Reusing an existing name updates it instead of creating a duplicate. |
    | `description` | `string` | yes      | One line shown in the memory index — written so a later turn can tell whether to recall it                                                         |
    | `type`        | `string` | yes      | `user`, `feedback`, `project`, or `reference`                                                                                                      |
    | `content`     | `string` | yes      | The fact itself, as markdown, up to 2 KB                                                                                                           |

    Never available to sub-agents or swarm workers — they inherit the parent agent's memory read-only.
  </Tab>

  <Tab title="recall_memory">
    Read the full content of one memory from the index by name.

    | Parameter | Type     | Required | Description                    |
    | --------- | -------- | -------- | ------------------------------ |
    | `name`    | `string` | yes      | The memory name from the index |

    Not available to sub-agents or swarm workers either — they see the memory index and whatever is automatically recalled for their brief, but cannot look up additional memories on demand.
  </Tab>

  <Tab title="forget_memory">
    Delete one memory by name when it is wrong or no longer applies.

    | Parameter | Type     | Required | Description               |
    | --------- | -------- | -------- | ------------------------- |
    | `name`    | `string` | yes      | The memory name to remove |

    Never available to sub-agents or swarm workers — they inherit the parent agent's memory read-only.
  </Tab>
</Tabs>

## Integrations

<Tabs>
  <Tab title="mcp">
    Connect to external services and tools via the Model Context Protocol (MCP).

    MCP lets agents access third-party tools and data sources through a standardized interface. When enabled, the agent can discover and call tools provided by MCP servers.

    Not affected by workspace sandboxing.
  </Tab>

  <Tab title="connector management">
    Let an agent manage its own MCP connectors over chat: `mcp_add_server`, `mcp_list_servers`, and `mcp_remove_server` add, list, and remove external tool servers. Enable these only for agents you trust to wire up their own integrations.

    Not affected by workspace sandboxing.
  </Tab>
</Tabs>

## Projects

Task-tracking tools for the [Projects](/projects) board in Desktop. Every agent has these automatically — they are not part of the per-agent tool selection.

| Tool                    | What it does                                                                                          |
| ----------------------- | ----------------------------------------------------------------------------------------------------- |
| `projects_list`         | List projects, optionally filtered by status                                                          |
| `projects_read`         | Read one project by id or key, with task counts per status                                            |
| `projects_create`       | Create a project (name, uppercase key, optional description)                                          |
| `issues_list`           | List tasks with filters: project, status, sub-status, assignee, creator, parent task, agents involved |
| `issues_read`           | Read one task in full — description, comments, timeline, subtasks, linked sessions                    |
| `issues_create`         | Create a task; can place it in a project or under a parent task (one level)                           |
| `issues_update`         | Update a task's title, description, status, sub-status, assignee, or project                          |
| `issues_comment`        | Post a markdown comment on a task                                                                     |
| `issues_comment_edit`   | Edit a comment the agent posted earlier                                                               |
| `issues_comment_delete` | Soft-delete a comment (shown as "deleted" in the timeline)                                            |

Every read, create, update, or comment automatically links the agent's current chat session to the task, so the task page shows which conversations touched it. When an agent sets a task's sub-status to `waiting_on_human`, the task appears in your Inbox under **Waiting on you**.

Not affected by workspace sandboxing — task data lives in the HQ's local database.

## Sub-agents

An agent can hand a self-contained task to a **sub-agent**: a child agent with its own context, its own tool set, and its own transcript. The child never sees the parent's conversation — it gets only the prompt it is given — and it answers with one final report the parent reads and relays to you.

Sub-agents are **on by default** for every agent. The `agent` and `send_message` tools appear automatically; they are not part of the per-agent tool selection. See [Configuration → Sub-agents](/configuration#sub-agents) to turn them off, cap them, or change how eagerly an agent delegates.

<Tabs>
  <Tab title="agent">
    Launch a sub-agent to handle one task.

    | Parameter           | Type      | Required | Description                                                                                                                                                                                               |
    | ------------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
    | `prompt`            | `string`  | yes      | The task, written to stand alone — the sub-agent does not see the conversation                                                                                                                            |
    | `description`       | `string`  | yes      | A short (3-5 word) description, shown on the row in chat                                                                                                                                                  |
    | `subagent_type`     | `string`  | no       | Which agent type to launch (default: `general-purpose`)                                                                                                                                                   |
    | `model`             | `string`  | no       | Model override: a `provider/model` id, or `inherit` to use the parent's model. Short alias names are accepted but resolve to nothing in this release — see [Troubleshooting](/troubleshooting#sub-agents) |
    | `name`              | `string`  | no       | A name to address the agent by later with `send_message` — up to 64 characters, starting with a letter or digit, then letters, digits, `_` or `-`                                                         |
    | `run_in_background` | `boolean` | no       | Run it detached and be notified on completion (default: `false`)                                                                                                                                          |
    | `isolation`         | `string`  | no       | `worktree` — give the agent its own git worktree of the workspace                                                                                                                                         |

    Fails with an error result when a cap is reached, when the type is unknown (the message lists the valid types), when the requested model isn't allowed, when the definition would leave the agent with no tools at all, or when `isolation: worktree` is asked for in a workspace that isn't a git repository.
  </Tab>

  <Tab title="send_message">
    Continue one of this conversation's sub-agents, by name or by id.

    | Parameter | Type     | Required | Description                                        |
    | --------- | -------- | -------- | -------------------------------------------------- |
    | `to`      | `string` | yes      | The name or id of a sub-agent in this conversation |
    | `message` | `string` | yes      | The message to deliver                             |

    Returns immediately. A **running** agent receives the message after its current turn finishes, not between its tool calls — unless it is **paused on an `ask_orchestrator` question**, in which case the message arrives at once as the answer and does not count against the message cap. A **finished** agent is resumed with its context intact and picks up from where it stopped. Either way, its next completion comes back as a notification.

    Refuses an unknown name, a message past the per-agent steer cap, and a **new task** for a one-shot type (`Explore`, `Plan`). Answering a one-shot sub-agent that is paused on an `ask_orchestrator` question is not a new task and goes through — the same exemption the reply box on its row and the legacy `send_to_worker` use.
  </Tab>

  <Tab title="ask_orchestrator">
    Every sub-agent gets this one tool of its own: ask the parent a question and **pause** until it answers.

    | Parameter  | Type     | Required | Description                                      |
    | ---------- | -------- | -------- | ------------------------------------------------ |
    | `question` | `string` | yes      | The blocker or decision to send up to the parent |

    The sub-agent shows as **waiting for input** until it is answered or the request times out.

    Three things can answer it, whatever the type: the parent's own `send_message`, the reply box on the sub-agent's row, and the legacy [`send_to_worker`](#legacy-swarm-tools). That includes the one-shot `Explore` and `Plan` — being one-shot refuses a new task, not an answer.

    **A question lives only as long as the turn that launched the sub-agent.** When that turn ends the question is dropped, the sub-agent's `ask_orchestrator` call comes back aborted, and it carries on without an answer. A foreground `agent` call holds its turn open until the child finishes, so there is time to answer; a **background** sub-agent that is still waiting when its launching turn ends is no longer waiting for anyone.
  </Tab>
</Tabs>

**Foreground or background.** By default `agent` waits: the parent blocks until the child finishes and the child's report comes back as the tool result. With `run_in_background: true` the call returns straight away with `Agent <name> launched in the background. You will be notified when it completes.`, the child keeps running after the parent's turn ends, and its completion arrives later as a notification (below).

**Several at once.** An agent can call `agent` more than once in a single turn; those children run concurrently. Cancelling the turn cancels its foreground children and leaves background ones running.

**Built-in agent types.**

| Type              | What it's for                                                       | Tools                                                                                                                                                                                                                                                                                                                          |
| ----------------- | ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `general-purpose` | Researching complex questions, searching for code, multi-step tasks | Everything the parent has, except the skill-management, connector-management and Projects tools, which are never passed down. The four legacy swarm tools are not passed down either — a sub-agent that is still allowed to spawn gets `agent` and `send_message` instead, and one already at the nesting ceiling gets neither |
| `Explore`         | Broad read-only searches where you only want the conclusion         | `read`, `grep`, `find`, `ls`, `web_fetch`, `web_search`, `load_skill`                                                                                                                                                                                                                                                          |
| `Plan`            | Designing a step-by-step implementation plan                        | The same read-only set                                                                                                                                                                                                                                                                                                         |

`Explore` and `Plan` are **one-shot**: they are read-only and cannot be given a new task, so `send_message` refuses one. Answering a question is not a new task — `send_message`, the reply box on the row and the legacy `send_to_worker` all get through to a paused one-shot. Your own types and plugin types are never one-shot; the one exception is a definition that deliberately **shadows** `Explore` or `Plan` by name, which replaces the built-in in that workspace and is resumable like any other type.

**Your own agent types.** Drop a markdown file with Claude Code frontmatter into `.dash/agents/` (or `.claude/agents/`) in the agent's workspace and it becomes a launchable type — the frontmatter sets its name, description, tool list, model, and preloaded skills, and the body is its system prompt. Plugins ship types too. See [Configuration → Sub-agent types](/configuration#sub-agent-types) for the file format, where the files can live, and which one wins. Whatever a definition asks for, **a sub-agent can never hold a tool or an MCP server its parent doesn't have.**

**Nesting.** A sub-agent can launch sub-agents of its own, down to the configured depth (`subagents.maxDepth`, default `3`). In chat, one level of nesting is shown: expanding a child shows its transcript, and a grandchild's row appears there but doesn't open.

**Notifications.** When a background agent finishes — or a resumed one, or one you sent a message to — its parent is told in a new turn that starts on its own. In chat that arrives as a compact notification row followed by the agent's response to it. Nothing is lost while the parent is busy: notifications queue and are delivered together when its current turn ends.

### What you see

Each sub-agent draws a **collapsed row** where it was launched: status, type, the description it was given, and how many tools it has used with elapsed time. Click or tap the row to expand it and watch the child's own transcript live, with a box at the bottom to type into that child directly. When several start together they are grouped under one summary line.

There's also a list of everything running in the conversation:

* **Web** — a **Tasks** button in the top bar (with a live count) opens a tasks panel; each row has **Stop** and **Resume**.
* **iOS** — a **Tasks** toolbar button opens a sheet, plus a strip above the composer while anything is live.
* **Desktop** — the people icon in the chat header opens the **Sub-agents** panel, with **Stop**, **Resume**, and the child's transcript in place. The icon appears once the conversation has sub-agents (or when the agent's Swarm card is ticked).

Sub-agent rows are a chat-app feature. Over Telegram or WhatsApp you get the agent's final answer only.

## Legacy swarm tools

`spawn_worker`, `wait_workers`, `send_to_worker`, and `check_workers` are the earlier **swarm** tools. They still work, and they appear alongside `agent` and `send_message` whenever [sub-agents](#sub-agents) are enabled — but they are now **thin wrappers** over the same machinery, kept so prompts written against them keep working. **Write new agents against `agent` and `send_message`.**

What that means in practice:

* `spawn_worker` is an `agent` call with `subagent_type: general-purpose` and `run_in_background: true`. The `role` becomes the child's description (and its name, when the role is a legal name).
* `send_to_worker` does what `send_message` does, which means it now **resumes a worker that has already finished** instead of refusing. The two differ only in **shape**: `send_to_worker` reports a refusal as a not-ok result, where `send_message` raises an error the agent sees as a failed tool call.
* `wait_workers` and `check_workers` read the same children the sub-agent tools do.
* Workers and sub-agents **share one set of caps** — there is one coordinator behind both.
* A worker's **read-only default is unchanged**: with no `tools` argument it gets `read`, `grep`, `find`, and `ls`, intersected with what the parent holds.
* Two consequences worth knowing: an agent whose `subagents.allowedTypes` excludes `general-purpose` now refuses `spawn_worker`, and a worker can launch sub-agents of its own.

**Caps.** Spawning is bounded by the agent's caps (concurrent children, total per turn, messages per child, and a wall-clock limit) plus an HQ-wide ceiling — see [Configuration → Sub-agents](/configuration#sub-agents). A call that would exceed a cap **fails with an error result** (rendered as an error tool block in chat) rather than silently doing nothing, so the agent can adapt.

The four tools:

<Tabs>
  <Tab title="spawn_worker">
    Spawn a parallel worker with a role and a self-contained brief.

    | Parameter | Type       | Required | Description                                                                                                                      |
    | --------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
    | `role`    | `string`   | yes      | Short role/name for the worker (e.g. `researcher`) — shown in the panel and status events                                        |
    | `brief`   | `string`   | yes      | A self-contained brief: the goal, relevant files/paths, and exactly what to report back (the worker never sees the conversation) |
    | `tools`   | `string[]` | no       | Subset of the orchestrator's tools to grant the worker. Defaults to read-only tools                                              |
    | `model`   | `string`   | no       | Model id for the worker. Must be an allowed model; defaults to the orchestrator's model                                          |

    Fails with an error result when a cap is reached (too many at once, too many per turn, or the global ceiling), when the model isn't allowed, or when a requested tool isn't one the orchestrator has.
  </Tab>

  <Tab title="wait_workers">
    Block until the referenced workers finish or need input, then return each one's status and report.

    | Parameter        | Type       | Required | Description                                                               |
    | ---------------- | ---------- | -------- | ------------------------------------------------------------------------- |
    | `workerIds`      | `string[]` | no       | Which workers to wait on. Omit to wait on all workers in the run          |
    | `timeoutSeconds` | `number`   | no       | Max seconds to block before returning the current status (default: `300`) |

    Respects the wall-clock cap and returns early when a worker is waiting on the orchestrator's input. This is the collection step of the loop.
  </Tab>

  <Tab title="send_to_worker">
    Answer a worker that's waiting on the orchestrator, or steer a running worker with an extra instruction.

    | Parameter  | Type     | Required | Description                                     |
    | ---------- | -------- | -------- | ----------------------------------------------- |
    | `workerId` | `string` | yes      | The worker to steer or answer                   |
    | `message`  | `string` | yes      | The answer or additional instruction to deliver |

    Messages are capped per worker. A worker that has already finished is **resumed** by this call rather than refused. A one-shot type is refused — as a not-ok result rather than an error — **unless it is paused on a question, in which case this call answers it.**
  </Tab>

  <Tab title="check_workers">
    Return a non-blocking snapshot of every worker in the run — id, role, status, and latest report or question. Use it to poll progress without blocking (unlike `wait_workers`).

    Takes no parameters. Returns an empty roster before anything has been spawned.
  </Tab>
</Tabs>

A worker is a sub-agent, so it gets [`ask_orchestrator`](#sub-agents) like any other child, and it draws the same row in chat. Watch and steer one from the tasks panel, the tasks sheet, or Desktop's **Sub-agents** panel — see [Architecture → Sub-agents](/architecture#sub-agents).

## Workspace sandboxing

Each agent's **working directory** sets where its tools operate. It defaults to `~/.dash/workspaces/<agent-id>` and you can set a custom path when you deploy or edit the agent. The directory is created automatically if it doesn't exist.

**How sandboxing works per tool:**

| Tool         | Behavior                                                                                                                                                                      |
| ------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `bash`       | Workspace is set as the working directory (`cwd`). The command itself is not sandboxed — it can still access other paths if given absolute paths.                             |
| `read`       | Paths are resolved relative to the workspace. Uses `realpath()` to verify the final resolved path stays within the workspace. Symlinks that escape the workspace are blocked. |
| `write`      | Paths are resolved relative to the workspace. Path traversal outside the workspace is blocked.                                                                                |
| `edit`       | Paths are resolved relative to the workspace. Path traversal outside the workspace is blocked.                                                                                |
| `ls`         | Paths are resolved relative to the workspace.                                                                                                                                 |
| `find`       | Searches within the workspace directory.                                                                                                                                      |
| `grep`       | Searches within the workspace directory.                                                                                                                                      |
| `web_search` | Not affected — operates independently of the workspace.                                                                                                                       |
| `web_fetch`  | Not affected — operates independently of the workspace.                                                                                                                       |
| `mcp`        | Not affected — operates independently of the workspace.                                                                                                                       |

<Note>
  If no workspace is configured, file tools operate without path restrictions and `bash` runs in the default directory.
</Note>
