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

# Tools

> Declare the tool servers an agent's sessions can call: auto's platform tools, brokered GitHub access, hosted provider connections, and raw remote MCP servers.

Every capability an agent has beyond its sandbox filesystem comes from the `tools:` map in its agent file. Each entry wires one MCP server into the agent's sessions — the platform's own coordination tools, a brokered GitHub server, a hosted provider like Notion or Sentry, or any remote MCP server you point at. This page covers every tool kind field by field; read it when you are deciding what an agent should be able to touch.

## The tools map

`tools:` is a map from an alias to a tool spec. The alias must be a valid resource name (1–128 characters of `A-Za-z0-9_.-`), and the alias `workspace` is rejected — it is reserved by Claude Code.

```yaml .auto/agents/pr-review.yaml theme={null}
name: pr-review
harness: claude-code
environment: agent-runtime
mounts:
  - kind: git
    repository: acme/platform
    mountPath: /workspace/platform
    auth:
      kind: githubApp
tools:
  auto:
    kind: local
    implementation: auto
  chat:
    kind: local
    implementation: chat
    auth:
      kind: connection
      provider: slack
      connection: slack
  github:
    kind: github
  notion:
    kind: connection
    provider: notion
    connection: notion
```

Four kinds exist, discriminated on `kind`:

| Kind         | What it wires in                                                                 | Credentials                                                                   |
| ------------ | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `local`      | auto's bundled platform tools: `auto.*` coordination, `chat.*` messaging, `ping` | None needed; served by the platform per session                               |
| `github`     | A brokered GitHub MCP server scoped by the agent's [mounts](/reference/mounts)   | Minted per call from the session's GitHub App mounts; never enter the sandbox |
| `connection` | A built-in hosted MCP provider (Notion, Sentry, Stripe, …)                       | A provider connection you authorize once; tokens refreshed server-side        |
| `mcp_remote` | Any Streamable HTTP MCP server by URL                                            | `none` or a named MCP OAuth connection                                        |

When a session is created, auto snapshots the agent's tools into it. The snapshot is immutable: editing the agent later changes future sessions, never a running one.

### How the agent sees tool names

The harness namespaces each server's tools. Claude Code renders `mcp__<server>__<tool>` with dots flattened to underscores; Codex uses `<server>.<tool>`.

The server name depends on the kind:

* `connection` and `mcp_remote` tools use **your alias** as the server name — alias `notion` yields `mcp__notion__*`.
* All `local` tools are served from one bundled server named **`auto`** regardless of their aliases — `chat.send` appears as `mcp__auto__chat_send`.
* `github` tools are served from a server named **`github`** — `mcp__github__create_pull_request`, the names models already know.

If one of your own `mcp_remote` or `connection` aliases claims `auto` or `github`, your alias wins and the reserved server shifts to `auto2` / `github2`.

## Fields on every kind

<ParamField path="tools.<alias>.kind" type="enum" required>
  One of `local`, `github`, `connection`, `mcp_remote`.
</ParamField>

<ParamField path="tools.<alias>.description" type="string">
  Optional human-readable description (trimmed, non-empty). Documents intent in the YAML; it is not delivered to the sandbox.
</ParamField>

<ParamField path="tools.<alias>.disabled" type="boolean">
  When `true`, the tool is dropped from session tool snapshots entirely — the agent never sees it. Useful for switching a tool off without deleting its config, or for suppressing a tool inherited from an [import](/reference/imports-and-fragments).
</ParamField>

<ParamField path="tools.<alias>.optional" type="boolean">
  On `kind: connection` tool specs: when `true`, apply silently skips the tool instead of failing when the referenced connection has no active grant. The skipped tool is omitted from the applied agent and re-activates on the next apply or sync once the connection exists. Absent preserves the blocking behavior. Chat and `mcp_oauth` tools carry the same flag on their auth object instead (`auth.optional`).
</ParamField>

`optional: true` is how shared fragments and [managed templates](/reference/managed-templates) declare tools that light up only in projects that have connected the provider. A multi-connection chat tool is all-or-nothing: either every listed connection resolves or the whole tool is skipped.

## `kind: local` — auto's platform tools

Local tools are implementations bundled with the platform, discriminated on `implementation`: `auto`, `chat`, or `ping`. They all share the session-scoped platform MCP server; the catalog of what each exposes lives in [auto tools](/runtime/auto-tools) and [chat tools](/runtime/chat-tools).

### `implementation: auto`

The platform coordination surface: spawning and messaging sessions, bindings, connections, secrets, webhook endpoints, resource dry runs, and introspection of other sessions. Most agents should carry it.

```yaml theme={null}
tools:
  auto:
    kind: local
    implementation: auto
```

<ParamField path="capabilities.billing" type="enum" default="none">
  `none`, `read`, or `write`. Gates the billing-related tools and API scopes; `write` implies `read`. The default `none` means agents that never declared the capability cannot see billing state.
</ParamField>

<ParamField path="auth" type="object" default="{ kind: &#x22;none&#x22; }">
  Only `{ kind: "none" }` is valid; the platform authenticates the session itself.
</ParamField>

### `implementation: chat`

Unified messaging (`chat.send`, `chat.history`, `chat.search`, reactions, issue reads and updates) across the chat providers the agent is connected to. Supported providers are `slack`, `linear`, `telegram`, and `discord`.

Unlike the other local implementations, `auth` is **required** — the chat tool must name the provider connection(s) it speaks through:

```yaml theme={null}
tools:
  chat:
    kind: local
    implementation: chat
    auth:
      kind: connections
      connections:
        - provider: slack
          connection: slack
        - provider: linear
          connection: linear
```

<ParamField path="auth.kind" type="enum" required>
  `connection` for a single provider (`provider` + `connection` inline), or `connections` for several (an array of `{ provider, connection }`, minimum one).
</ParamField>

<ParamField path="auth.optional" type="boolean">
  Skip the tool at apply time when a referenced connection has no grant. With `kind: connections`, all connections must resolve or the tool is skipped as a whole.
</ParamField>

### `implementation: ping`

A single `ping` tool that echoes a message back. A connectivity smoke test for the platform MCP endpoint; omit it from production agents.

<Note>
  GitHub check-run tools (`checks.list`, `checks.begin`, `checks.success`, `checks.failure`) are not declared in `tools:` at all — they register automatically for sessions whose spawning [trigger declares `checks:`](/reference/triggers).
</Note>

## `kind: github` — brokered GitHub access

The GitHub tool wires in auto's GitHub MCP proxy, which fronts a pinned `github/github-mcp-server` v1.3.0 deployment. There is no `auth` field by design: the proxy mints a down-scoped GitHub App installation token per call from the session's `githubApp` [mounts](/reference/mounts), so repository credentials never enter the sandbox. Declaring a `github` tool in an agent that has no `githubApp` mount is a silent no-op rather than a session failure.

```yaml theme={null}
tools:
  github:
    kind: github
```

<ParamField path="tools" type="string[]">
  Optional explicit tool selection (minimum one name), validated against the pinned server's catalog of 41 upstream tools plus 6 proxy-implemented tools. **Naming any tools replaces the default allowlist entirely** — list everything the agent needs.
</ParamField>

Omitting `tools` applies the curated default allowlist of 24 tools: the pull-request lifecycle (`create_pull_request`, `pull_request_read`, `update_pull_request`, `update_pull_request_branch`, `pull_request_review_write`, `add_comment_to_pending_review`, `add_reply_to_pull_request_comment`), issue and comment surface (`add_issue_comment`, `delete_issue_comment`, `upsert_issue_comment`, `download_comment_attachment`, `issue_read`, `issue_write`), search (`search_pull_requests`, `search_issues`, `search_code`), repository content (`get_file_contents`, `list_commits`, `create_branch`, `create_or_update_file`, `push_files`), and Actions reads (`actions_get`, `actions_list`, `get_job_logs`).

Deliberately excluded from the default — opt in by naming them: `merge_pull_request`, `create_repository`, `fork_repository`, `delete_file`, `actions_run_trigger`, `list_repository_collaborators`, `sub_issue_write`, release/tag/label reads, `search_repositories`, and `search_commits`.

Two tool families are additionally gated by mount capabilities and stay invisible and uncallable even when named explicitly:

* **Merge tools** (`merge_pull_request`, `enable_pull_request_auto_merge`) require a mount with `merge: write` on the target repository.
* **Secrets tools** (`actions_secret_list` needs `secrets: read` or better; `actions_secret_write` needs `secrets: write`).

A real example — an agent that copies most of the default allowlist and adds merging, paired with the mount capability that un-gates it:

```yaml .auto/agents/staff-engineer.yaml theme={null}
mounts:
  - kind: git
    repository: fractal-works/auto
    mountPath: /workspace/auto
    ref: main
    auth:
      kind: githubApp
      capabilities:
        contents: write
        pullRequests: write
        merge: write
tools:
  github:
    kind: github
    tools:
      - create_pull_request
      - pull_request_read
      - update_pull_request
      - update_pull_request_branch
      - pull_request_review_write
      - add_reply_to_pull_request_comment
      - upsert_issue_comment
      - search_pull_requests
      - get_file_contents
      - list_commits
      - actions_list
      - actions_get
      - get_job_logs
      - merge_pull_request
```

The full catalog, capability model, and per-repository scoping rules are on [GitHub MCP](/runtime/github-mcp).

## `kind: connection` — built-in hosted MCP providers

Connection-backed tools name a provider from auto's built-in catalog of hosted MCP servers. auto owns the server URL and OAuth mechanics; you authorize the provider once as a [connection](/concepts/connections-and-identities), then reference the grant by name. At runtime the session's calls are proxied through auto so the OAuth token is resolved and refreshed per request — the sandbox never holds the provider credential.

<ParamField path="provider" type="string" required>
  The built-in provider slug (1–64 characters).
</ParamField>

<ParamField path="connection" type="string" required>
  The name of the installed provider connection to use.
</ParamField>

The built-in hosted MCP providers:

| Provider slug                                             | Service            |
| --------------------------------------------------------- | ------------------ |
| `asana`                                                   | Asana              |
| `atlassian`                                               | Atlassian Rovo     |
| `attio`                                                   | Attio              |
| `azure-devops`                                            | Azure DevOps       |
| `cloudflare`                                              | Cloudflare         |
| `datadog-us1`, `datadog-us3`, `datadog-us5`, `datadog-eu` | Datadog (per site) |
| `github-mcp`                                              | GitHub MCP         |
| `gitlab`                                                  | GitLab             |
| `gmail`                                                   | Gmail              |
| `google-drive`                                            | Google Drive       |
| `linear-mcp`                                              | Linear             |
| `mobbin`                                                  | Mobbin             |
| `neon`                                                    | Neon               |
| `notion`                                                  | Notion             |
| `planetscale`                                             | PlanetScale        |
| `posthog`                                                 | PostHog            |
| `sentry`                                                  | Sentry             |
| `stripe`                                                  | Stripe             |
| `supabase`                                                | Supabase           |
| `vercel`                                                  | Vercel             |

Setup is three steps:

<Steps>
  <Step title="Discover providers">
    The Connections page in the web app lists every provider the deployment can start; from a session, `auto.connections.providers.list` returns the same catalog.
  </Step>

  <Step title="Connect one">
    From the Connections page, run the provider's consent flow and allow the connection into the project. A session can also start this flow itself with the `auto.connections.start` tool.
  </Step>

  <Step title="Reference it from the agent">
    ```yaml theme={null}
    tools:
      notion:
        kind: connection
        provider: notion
        connection: notion
        description: Notion pages, databases, and workspace search.
    ```
  </Step>
</Steps>

## `kind: mcp_remote` — raw remote MCP servers

The escape hatch for servers outside the built-in catalog: any HTTPS Streamable HTTP MCP endpoint, including tenant-owned servers.

<ParamField path="url" type="string" required>
  The server URL. Must be `https:`; `http:` is rejected outside explicit local-development parsing.
</ParamField>

<ParamField path="transport" type="enum" default="streamable_http">
  `streamable_http` is the only supported transport.
</ParamField>

<ParamField path="auth.kind" type="enum" default="none">
  `none` or `mcp_oauth`. Two further kinds (`bearer`, `provider_oauth`) exist in the schema but are refused by apply today — see the warning below.
</ParamField>

### `auth.kind: none`

For unauthenticated servers. The sandbox connects directly to the URL — no proxy in the path:

```yaml theme={null}
tools:
  docs:
    kind: mcp_remote
    url: https://docs.example.com/mcp
    transport: streamable_http
    auth:
      kind: none
```

### `auth.kind: mcp_oauth`

For servers that implement MCP OAuth. auto completes the OAuth flow once, stores the tokens encrypted (with the same envelope scheme as [secrets](/reference/secrets)), and proxies the session's calls so tokens are refreshed server-side. The agent is never asked to authenticate.

<ParamField path="auth.connection" type="string" required>
  The name of the project-scoped MCP OAuth credential to create or reuse. The stored credential is bound to the exact server URL it was connected for; changing the URL requires reconnecting.
</ParamField>

<ParamField path="auth.optional" type="boolean">
  Skip the tool at apply time when the named credential does not exist yet.
</ParamField>

```yaml theme={null}
tools:
  datadog:
    kind: mcp_remote
    description: Datadog logs, metrics, monitors, incidents, and dashboards.
    url: https://mcp.us5.datadoghq.com/api/unstable/mcp-server/mcp?toolsets=all
    transport: streamable_http
    auth:
      kind: mcp_oauth
      connection: datadog-prod
```

Create or refresh the credential from a running session with its `auto.agent_tools.connect` tool: it reports an existing live connection, or returns the authorization URL for a human to open — the outcome is delivered back to the session automatically once the flow completes.

<Warning>
  `auth.kind: bearer` (a static token via `{ token: { $secret: <name> } }`) and `auth.kind: provider_oauth` parse in the schema but are rejected when you apply the agent: session runtime support currently covers `none` and `mcp_oauth` only. The apply error suggests the connection-backed equivalent when your URL matches a built-in provider. A tool using an unsupported auth kind can only exist with `disabled: true`.
</Warning>

## Removing inherited tools

Tools merge by alias across [imports](/reference/imports-and-fragments): an importing document deep-merges over an imported tool with the same alias, and new aliases append. To drop a tool an import gave you, use the `remove` control field:

```yaml .auto/agents/quiet-agent.yaml theme={null}
name: quiet-agent
imports:
  - ../fragments/base-toolkit.yaml
remove:
  tools:
    - notion
```

`remove.tools` deletes by alias from the merged import result before your own fields merge on top. Setting `disabled: true` on the alias works too and keeps the config visible in the file.

## Complete example

A digest agent that reads GitHub through the default allowlist, posts to Slack, reads Linear through the hosted provider, and queries a tenant-owned observability server:

```yaml .auto/agents/ship-digest.yaml theme={null}
name: ship-digest
harness: claude-code
environment: agent-runtime
mounts:
  - kind: git
    repository: acme/platform
    mountPath: /workspace/platform
    ref: main
    auth:
      kind: githubApp
tools:
  auto:
    kind: local
    implementation: auto
  chat:
    kind: local
    implementation: chat
    auth:
      kind: connection
      provider: slack
      connection: slack
  github:
    kind: github
  linear:
    kind: connection
    provider: linear-mcp
    connection: linear-mcp
    optional: true
  observability:
    kind: mcp_remote
    description: Tenant-owned observability MCP server.
    url: https://mcp.example.com/mcp
    transport: streamable_http
    auth:
      kind: mcp_oauth
      connection: observability-prod
triggers:
  - kind: heartbeat
    cron: "0 17 * * 1-5"
    timezone: America/New_York
    message: Compile today's ship digest and post it to Slack.
    routing:
      kind: spawn
```

The session sees four servers: `auto` (platform + chat tools), `github`, `linear`, and `observability` — with `linear` silently absent in projects that have not connected the provider yet.
