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

# mutagent gateway

> Connect GitHub and Slack, link repositories, and configure the triggers and routines that start Helix runs.

<Note>
  **Early access.** GitHub and Slack runs start in a cloud sandbox operated by Mutagent, and cloud
  sandboxes are not open to every account yet: we are letting accounts in gradually while we test.
  There is nothing to host, and nobody has to be at a terminal.
</Note>

The gateway starts a Helix run when an event arrives or a schedule comes due. These commands connect
the providers, choose the repositories, and manage the triggers, routines and runs. See
[Gateway overview](/helix/gateway/overview) for the concepts.

## Before you start

1. [Install the CLI](/cli/installation) and [sign in](/cli/commands/login). A coding agent signs in
   with `MUTAGENT_API_KEY=<key> mutagent login --json`, or runs `mutagent login --browser --json`
   and shows the printed URL to the person.
2. Select the workspace: `mutagent workspaces use <workspace-name>`.
3. Run `mutagent gateway --json` and do what `next` says. Connecting GitHub or Slack needs a person
   at a browser who is signed in to Mutagent.

## JSON output and exit codes

Every command takes `--json` and prints one object:

* Success: `{ "success": true, "ok": true, "data": …, "next": [ … ] }`. `next` names the command to
  run next.
* Failure: `{ "success": false, "ok": false, "error", "code", "suggestedAction", "_agentGuidance" }`.
  Branch on `code`, not on the text. `_agentGuidance.fix` holds command lines to run; replace any
  `<placeholder>` in them first. `_agentGuidance.notes` is prose to read, not run. `_agentGuidance.escalate`
  is present when a person has to act, and says who.

The exit codes are the same as every other command: `0` success, `1` failure (usage errors
included), `2` key expired or invalid, `3` not signed in or no workspace. See [CLI errors](/cli/errors).
Never retry a failed command blind: run what `_agentGuidance.fix` says, or tell the person what
`escalate` says.

## mutagent gateway

With no arguments, print what is connected, what is missing, and the next command to run.

```bash theme={null}
mutagent gateway --json
```

## mutagent gateway status

Show the workspace's connections and configuration.

```bash theme={null}
mutagent gateway status --json
```

## mutagent gateway doctor

Run an end-to-end check and report each failure with the command that fixes it.

```bash theme={null}
mutagent gateway doctor --json
```

It checks that GitHub is connected, that the GitHub App reaches at least one repository, and that
every linked repository is still reachable. When a check fails, the command exits 1 with code
`GATEWAY_CHECKS_FAILED`; `data.checks` lists each check and `_agentGuidance.fix` lists the fixes in
order. An empty list of linked repositories with every check passing is healthy: you do not need to
link anything.

## mutagent gateway connect

Connect GitHub or Slack for your organization. Prints a sign-in URL and a consent URL; open the sign-in URL
first and the consent URL in that same browser. See
[Connecting GitHub and Slack](/helix/gateway/connect).

For a coding agent:

```bash theme={null}
mutagent gateway connect github --json
# The person opens data.signInUrl and signs in, then opens data.url in the same browser.
mutagent gateway connect github --wait --attempt <attempt-id> --json
```

The first command prints `data.signInUrl`, `data.url` and `data.attempt`, and exits 0. Show both URLs
to the person. The second waits for the attempt to finish. If GitHub or Slack is already connected,
`connect` exits 0 and does nothing, so it is safe to run again.

| Flag | What it does |
| - | - |
| `--wait` | Poll the attempt until it completes, fails or expires. If the wait runs out first, the command exits 1 with `CONNECT_PENDING`: nothing failed; finish the browser step and wait again. Without `--wait`, the command exits 0 once it has printed the URLs. |
| `--open` | Open the consent URL in a local browser. |
| `--attempt <id>` | Finish an attempt that was already started. |

## mutagent gateway reconnect

Start a re-authorization attempt for a provider. Finish it with
`connect <provider> --wait --attempt <id>`. It is also the fix for `RUN_PRINCIPAL_UNAVAILABLE`.

```bash theme={null}
mutagent gateway reconnect github
```

## mutagent gateway disconnect

Remove a provider connection.

```bash theme={null}
mutagent gateway disconnect slack --force
```

| Flag | What it does |
| - | - |
| `-f, --force` | Required. The CLI never prompts. `--yes` is another name for it. |

## mutagent gateway repos

List repositories. With no flag or `--available`, every repository the Mutagent GitHub App can
reach: the ones you gave it access to on GitHub. With `--linked`, the ones linked to this workspace,
whether by `repos link` or automatically by use (a web session, a trigger or routine created with
`--repo`, or a Slack mention), each with the number of triggers and routines that depend on it.

```bash theme={null}
mutagent gateway repos --json
mutagent gateway repos --linked --json
```

An empty list without `--linked`, with GitHub connected, means the app can reach no repository. Run
`mutagent gateway repos grant-more`.

| Flag | What it does |
| - | - |
| `--available` | Every reachable repository. Same as no flag. |
| `--linked` | Only repositories linked to this workspace, by hand or by use. |

## mutagent gateway repos link

Link one or more repositories to the workspace, up to 25 at a time, by `owner/name` or GitHub
repository id. This is optional: a repository the app can reach is linked automatically the first
time you use it. A repository the app cannot reach is refused, and none of the others are linked.

```bash theme={null}
mutagent gateway repos link owner/name owner/other
```

## mutagent gateway repos unlink

Unlink a repository. The triggers and routines that depend on it are paused, visibly, rather than
deleted, and the repository stays out of the ones a Slack mention chooses from.

```bash theme={null}
mutagent gateway repos unlink owner/name --force
```

| Flag | What it does |
| - | - |
| `-f, --force` | Required. `--yes` is another name for it. |

## mutagent gateway repos grant-more

Print the GitHub page where you change which repositories the Mutagent GitHub App can reach.

```bash theme={null}
mutagent gateway repos grant-more
```

## mutagent gateway triggers

List the workspace's triggers: yours first, then the built-in mention triggers, marked built-in.
Built-in triggers are always on and cannot be updated, enabled, disabled or deleted.

```bash theme={null}
mutagent gateway triggers
```

## mutagent gateway triggers create

Create a trigger: an event kind, a repository (or none) and an instruction. See
[Trigger kinds](/helix/gateway/triggers-and-routines#trigger-kinds).

```bash theme={null}
mutagent gateway triggers create --on github.issue.opened --repo owner/name --instruction "Triage it"
```

| Flag | What it does |
| - | - |
| `--on <kind>` | Required. `github.issue.opened`, `github.ci-failed`, `slack.mention`, `webhook`, `trace.threshold`, or `emit:<kind>`. `github.mention` is refused: mentions of the app are always answered by the built-in trigger. |
| `--repo <owner/name>` | The repository the run checks out: any repository the app can reach, linked for you if it is not yet. Without it, the CLI uses this directory's GitHub remote, linked or not, and prints which one (`data.repoSource` is `cwd-remote`). A directory with no GitHub remote is refused with `REPOSITORY_REQUIRED`. A repository the app cannot reach is refused with `REPOSITORY_INACCESSIBLE`: run `mutagent gateway repos grant-more`. |
| `--no-repo` | No repository: the run starts without a checkout. `webhook`, `emit:<kind>` and `trace.threshold` only. |
| `--instruction <text>` | The instruction Helix runs. |
| `--instruction-file <path>` | Read the instruction from a file. |
| `--name <name>` | A name. Defaults to one derived from the kind and repository. |
| `--key <key>` | Idempotency key. A retry with the same key returns the same trigger. |
| `--channel <id...>` | Required with `slack.mention`. The Slack channel IDs this trigger answers in. A channel another enabled trigger already holds is refused. |
| `--threshold <n>` | `trace.threshold` only. Fire at or above this many traces, 1 to 1,000,000. |
| `--window <duration>` | `trace.threshold` only. The counting window, such as `60m`, `24h` or `7d`. |
| `--service <name>` | `trace.threshold` only. Limit to this service name. |
| `--session <id>` | `trace.threshold` only. Limit to this session id. |
| `--subject <kind:names>` | `trace.threshold` only. Count only the traces of these agents, skills or services, for example `agent:support-bot`. |
| `--stage <stage>` | `evaluate`, `diagnose` or `optimize`: labels which Helix step the trigger serves. It does not change the instruction: to run that stage, start the instruction with its command, such as `/diagnose`. |
| `--env <name>` | A workspace [Environment](/cli/commands/env) every run loads. An unknown name is refused with `ENVIRONMENT_NOT_FOUND`. |

A retry with the same `--key` or `--name` and the same request returns the same trigger. A different
request under the same key or name is refused with `KEY_CONFLICT` or `NAME_TAKEN`. With `--json`,
`data` is the trigger with `repo` and `repoSource`. Next, check it with `triggers test`.

## mutagent gateway triggers show

Show one trigger.

```bash theme={null}
mutagent gateway triggers show <id>
```

## mutagent gateway triggers update

Change a trigger. Only the flags you pass change; everything else stays as it is. The kind and the
repository cannot be changed: create a new trigger for those, then delete this one.

```bash theme={null}
mutagent gateway triggers update <id> --instruction "Label, estimate, and link duplicates"
```

| Flag | What it does |
| - | - |
| `--instruction <text>` | New instruction. |
| `--instruction-file <path>` | Read the new instruction from a file. |
| `--name <name>` | New name. |
| `--channel <id...>` | `slack.mention` only. Replaces the full channel list. |
| `--threshold <n>` | `trace.threshold` only. New trace count, together with `--window`. |
| `--window <duration>` | `trace.threshold` only. New counting window, together with `--threshold`. |
| `--service <name>` | `trace.threshold` only. Limit to this service name. |
| `--session <id>` | `trace.threshold` only. Limit to this session id. |
| `--subject <kind:names>` | `trace.threshold` only. New subject selector, or `none` to clear it. |
| `--stage <stage>` | New stage, or `none` to clear it. |
| `--env <name>` | New Environment every run loads. `--env ""` clears it. |

## mutagent gateway triggers enable

Enable a disabled trigger.

```bash theme={null}
mutagent gateway triggers enable <id>
```

## mutagent gateway triggers disable

Stop a trigger firing without deleting it.

```bash theme={null}
mutagent gateway triggers disable <id>
```

## mutagent gateway triggers delete

Delete a trigger.

```bash theme={null}
mutagent gateway triggers delete <id> --force
```

| Flag | What it does |
| - | - |
| `-f, --force` | Required. `--yes` is another name for it. |

## mutagent gateway triggers test

Report whether a sample event would match the trigger, and why not if it would not. No side effects,
and no run is started.

```bash theme={null}
mutagent gateway triggers test <id> --event @sample.json --json
```

`sample.json` looks like `{ "source": "github", "kind": "github.issues.opened", "repositoryId": "123" }`.
With `--json`, `data.matches` and `data.wouldRun` give the answer, and `data.checks` lists each check
with `passed` and `detail`.

## mutagent gateway routines

List the workspace's routines with their next fire times.

```bash theme={null}
mutagent gateway routines
```

## mutagent gateway routines create

Create a routine: a schedule, a timezone, a repository (or none) and an instruction. Give exactly one of
`--every` or `--cron`.

```bash theme={null}
mutagent gateway routines create --every "weekdays 09:00" --tz Europe/Berlin --repo owner/name --instruction "…"
```

| Flag | What it does |
| - | - |
| `--every <schedule>` | A plain-language schedule: `every N minutes` (N is 1, 2, 3, 4, 5, 6, 10, 12, 15, 20 or 30), `every N hours` (N is 1, 2, 3, 4, 6, 8 or 12), `hourly`, `daily HH:MM`, `weekdays HH:MM`, `weekends HH:MM`, or days such as `mon,wed,fri HH:MM`. |
| `--cron <expression>` | A cron expression, such as `"0 9 * * 1-5"`. |
| `--tz <IANA timezone>` | Required. For example `Europe/Berlin`. Omitting it is refused locally with `TIMEZONE_REQUIRED`, before any request. |
| `--repo <owner/name>` | The repository the run checks out: any repository the app can reach, linked for you if it is not yet. Without it, the CLI uses this directory's GitHub remote, linked or not, and prints which one (`data.repoSource` is `cwd-remote`). A directory with no GitHub remote is refused with `REPOSITORY_REQUIRED`. A repository the app cannot reach is refused with `REPOSITORY_INACCESSIBLE`: run `mutagent gateway repos grant-more`. |
| `--no-repo` | No repository: the run starts without a checkout. |
| `--instruction <text>` | The instruction Helix runs. |
| `--instruction-file <path>` | Read the instruction from a file. |
| `--name <name>` | A name for the routine. The default is derived from the schedule and repository. |
| `--key <key>` | Idempotency key. A retry with the same key returns the same routine. |
| `--stage <stage>` | `evaluate`, `diagnose` or `optimize`: labels which Helix step the routine serves. |
| `--env <name>` | A workspace [Environment](/cli/commands/env) every run loads. |

The output shows the normalized cron, the timezone and the next three fire times. With `--json`,
read them from `data.schedule`.

## mutagent gateway routines show

Show one routine, including why it is paused if it is.

```bash theme={null}
mutagent gateway routines show <id>
```

## mutagent gateway routines update

Change a routine. Only the flags you pass change. The repository cannot be changed: create a new
routine for that, then delete this one.

```bash theme={null}
mutagent gateway routines update <id> --every "weekdays 10:00" --tz Europe/Berlin
```

| Flag | What it does |
| - | - |
| `--every <schedule>` | New plain-language schedule, together with `--tz`. |
| `--cron <expression>` | New cron expression, together with `--tz`. |
| `--tz <IANA timezone>` | Required with `--every` or `--cron`. On its own, moves the current schedule to that timezone. |
| `--instruction <text>` | New instruction. |
| `--instruction-file <path>` | Read the new instruction from a file. |
| `--name <name>` | New name. |
| `--stage <stage>` | New stage, or `none` to clear it. |
| `--env <name>` | New Environment every run loads. `--env ""` clears it. |

## mutagent gateway routines pause

Stop a routine firing without deleting it.

```bash theme={null}
mutagent gateway routines pause <id>
```

## mutagent gateway routines resume

Start a paused routine again.

```bash theme={null}
mutagent gateway routines resume <id>
```

## mutagent gateway routines run-now

Run a routine once, now, outside its schedule.

```bash theme={null}
mutagent gateway routines run-now <id> --wait
```

| Flag | What it does |
| - | - |
| `--wait` | Poll the run until it finishes. |
| `--key <key>` | Idempotency key. The same key is one run. Without it, each call gets a fresh key. |

Without `--wait`, `--json` returns `data.eventId`. `data.created` is `false` when this key already ran;
the event ID is then that run's. Follow the run with `mutagent gateway runs show <event-id> --json`.

## mutagent gateway routines delete

Delete a routine.

```bash theme={null}
mutagent gateway routines delete <id> --force
```

| Flag | What it does |
| - | - |
| `-f, --force` | Required. `--yes` is another name for it. |

## mutagent gateway test-run

Start a real run of the built-in test agent on a repository to prove the whole path works.

```bash theme={null}
mutagent gateway test-run --repo <owner/name> --wait --json
```

Success: exit code `0`, with the run's status in `data`. A run that ends in the `failed` phase fails
the command (exit 1): read `code`, `error` and `_agentGuidance`. Without `--wait`, the command returns
`data.eventId` at once; follow it with `mutagent gateway runs show <event-id> --json`.

| Flag | What it does |
| - | - |
| `--repo <owner/name>` | Required. The repository to run on. |
| `--wait` | Poll until the run settles instead of returning the event id immediately. |
| `--key <key>` | Idempotency key. The same key is one run. Without it, each call gets a fresh key. |

## mutagent gateway runs

List runs from triggers, routines, test runs and `emit`.

```bash theme={null}
mutagent gateway runs --since 24h
```

| Flag | What it does |
| - | - |
| `--status <states>` | Comma-separated states to filter to. |
| `--since <when>` | An ISO-8601 timestamp, or a duration such as `30m`, `24h` or `7d`. |
| `--trigger <id>` | Only runs from this trigger. |
| `--routine <id>` | Only runs from this routine. |

The states are `queued`, `allocating`, `checkout_ready`, `grant_ready`, `running`, `succeeded`,
`failed`, `cancelled` and `unknown`.

## mutagent gateway runs show

Show one run, by run id (from `runs`) or event id (from `test-run`, `emit` or `events list`).

```bash theme={null}
mutagent gateway runs show <id> --json
```

An event ID returns `data.phase`; a run ID returns `data.state`. Branch on whichever is present. An
event that started no run has phase `no-match`, and `data.error` says why. `filed_as_triage` is not a
failure: a Slack mention filed a triage item instead of starting a run.

## mutagent gateway runs logs

Read a run's logs, by run id or event id.

```bash theme={null}
mutagent gateway runs logs <id> --follow
```

| Flag | What it does |
| - | - |
| `--follow` | Keep printing as the run produces more output. |

## mutagent gateway runs cancel

Stop a run that is still going, and its Helix session.

```bash theme={null}
mutagent gateway runs cancel <runId> --force
```

| Flag | What it does |
| - | - |
| `-f, --force` | Required. `--yes` is another name for it. |
| `--reason <text>` | Why. Kept in the server log only, never stored on the run or shown back. |

A run that already finished is refused with `RUN_NOT_ACTIVE`. A run that is still starting has no
session to stop yet and is refused with `RUN_STARTING`: run the same cancel again in a few seconds.
Cancelling a run that is already cancelled succeeds.

## mutagent gateway emit

Send an event of your own kind. An `emit:<kind>` trigger fires on it.

```bash theme={null}
mutagent gateway emit deploy.finished --payload @event.json --wait
```

| Flag | What it does |
| - | - |
| `--key <key>` | Idempotency key. A retry with the same key is one event. Without it, each call gets a fresh key and is a new event. |
| `--payload <@file>` | The JSON payload, as `@file.json`. |
| `--wait` | Poll every resulting run to a terminal phase before returning. |

The payload is always a file reference (`@file.json`), never inline JSON. With `--json`, `data.eventIds`
lists the events created; it can be empty when no `emit:<kind>` trigger matches, which is not an error.
The kinds `routine.*`, `onboarding.*`, `trace.threshold` and `github.ci-failed` are reserved and
refused. To run a routine now, use `routines run-now`.

## mutagent gateway events list

Every event that reached the workspace, newest first, with its outcome.

```bash theme={null}
mutagent gateway events list --since 24h
```

| Flag | What it does |
| - | - |
| `--since <when>` | An ISO-8601 timestamp, or a duration such as `30m`, `24h` or `7d`. |
| `--limit <n>` | Page size, 1 to 100. |
| `--cursor <cursor>` | `nextCursor` from the previous page. |
| `--follow` | Stay connected and print each event as it settles. Ctrl-C stops it. |

## mutagent gateway notices list

Each time a Slack or GitHub mention of the app started no run: why, and the reply the gateway sent.

```bash theme={null}
mutagent gateway notices list
```

| Flag | What it does |
| - | - |
| `--limit <n>` | Page size, 1 to 100. |
| `--cursor <cursor>` | `nextCursor` from the previous page. |

## If it fails

| Code | Fix |
| - | - |
| `AUTH_REQUIRED`, `WORKSPACE_REQUIRED` (exit 3) | [Sign in](/cli/commands/login), then `mutagent workspaces use <workspace-name>`. |
| `AUTH_EXPIRED`, `INVALID_API_KEY` (exit 2) | Sign in again, or set a valid `MUTAGENT_API_KEY`. |
| `GITHUB_NOT_CONNECTED` | Run `mutagent gateway connect github --json` and have the person finish the browser steps. |
| `CONNECT_PENDING` | The browser step is not done yet. Finish it, then run `connect <provider> --wait --attempt <attempt-id>` again. |
| `REPOSITORY_REQUIRED` | Pass `--repo <owner/name>` (any repository in `mutagent gateway repos --json`) or `--no-repo`. |
| `REPOSITORY_INACCESSIBLE` | The GitHub App cannot reach the repository. Run `mutagent gateway repos grant-more` and have the person grant access on GitHub. |
| `RUN_PRINCIPAL_UNAVAILABLE` | Run `mutagent gateway reconnect <provider>` and finish it with `connect --wait --attempt`. |
| `TIMEZONE_REQUIRED` | Add `--tz <IANA timezone>` to the routine command. |
| `TRIGGER_CONFLICT` | Another enabled `slack.mention` trigger holds the channel. Update or delete that trigger first. |
| `TRIGGER_KIND_BUILTIN_ONLY` | `--on github.mention` is built in. Use `github.issue.opened`, or a `slack.mention` trigger on a dedicated channel. |
| `BUILTIN_TRIGGER_READ_ONLY` | Built-in triggers cannot be changed. |
| `CONFIRMATION_REQUIRED` | The command needs `--force`. Confirm with the person first. |

All of these exit 1 unless the table says otherwise.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.