> ## 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.

# Connecting GitHub and Slack

> Connect each provider once for your organization, choose the repositories the gateway works on, and know why signing in with GitHub is not enough.

<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>

GitHub and Slack are connected once for your organization. Each connection is a browser step. Start
it in the web app under **Configuration › Integrations** (click **Connect** on the card), or from the
CLI, which prints the URL and waits, or exits so you can open it yourself. GitHub can also be
connected at the **Connect GitHub** step when you sign up in the web app; that step can be skipped.

## Before you start

* You are signed in to the `mutagent` CLI and a workspace is selected. See
  [Sign in](/cli/commands/login).
* A person who can install apps on the GitHub organization (or Slack workspace) has a browser. The
  browser step cannot be done by the CLI.
* Run `mutagent gateway --json` first. It shows what is connected and, in `next`, the one command to
  run next. A coding agent runs what `next` says.

## Signing in with GitHub is not connecting GitHub

These are two different things, and doing the first does not do the second.

* **Signing in** with GitHub uses an OAuth app. It proves who you are to Mutagent. That is all it does.
* **Connecting** the gateway installs the **Mutagent GitHub App** into the account or organization that owns your
  repos. The App is what receives events and reaches your code.

So connecting is always a second, explicit step, even for an account that signed in with GitHub. There
is no way to skip it, and nothing about your sign-in grants the App anything.

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

## Connect GitHub

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

`connect github` starts an attempt, prints two URLs and the attempt id, and exits 0:

| Field | What it is |
| - | - |
| `data.signInUrl` | Sign in to Mutagent here **first**. |
| `data.url` | Then install the App and pick repositories, in that same browser. |
| `data.attempt` | The attempt id, for `--wait --attempt`. |

The order and the browser both matter. The provider callback checks your signed-in Mutagent session,
so the App must be installed from a browser already signed in as you. Opening `data.url` in a browser
that is not signed in fails with `state_user_mismatch`.

Once the person has finished in the browser, wait for the attempt to complete:

```bash theme={null}
mutagent gateway connect github --wait --attempt <attempt-id> --json
```

If the wait runs out first, the command fails with `CONNECT_PENDING` (exit 1). Nothing failed: finish
the browser step and run the same command again. If GitHub 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, instead of returning right away. |
| `--open` | Open `data.url` in a local browser. For a person at a desktop. |
| `--attempt <id>` | Finish an attempt that was already started. |

## Connect Slack

Slack follows the same pattern, in the same browser:

```bash theme={null}
mutagent gateway connect slack
```

Then invite the app to the channels you want it to answer in. A `slack.mention` trigger of your own
answers in the channels you name with `--channel <id...>`; the built-in mention trigger answers
everywhere else.

## Reconnect and disconnect

`reconnect` starts a re-authorization attempt — use it when a connection's access has been revoked or
its permissions have changed, or when a run fails with `RUN_PRINCIPAL_UNAVAILABLE`. It exits 0 and
points you at the same `--wait --attempt` command to finish:

```bash theme={null}
mutagent gateway reconnect github
mutagent gateway connect github --wait --attempt <id>
```

`disconnect` removes a connection and requires `--force` (or `--yes`). Without it, the command exits 1
with `CONFIRMATION_REQUIRED` and sends nothing:

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

## Repositories

The repositories you can use are the ones you give the Mutagent GitHub App access to on GitHub.
When you install the app, GitHub asks whether it gets **All repositories** or **Only select
repositories**. That choice is the list; there is nothing to set up again in Mutagent.

```bash theme={null}
mutagent gateway repos            # every repository the app can reach
mutagent gateway repos --linked   # the ones linked to this workspace, by hand or by use
```

`repos` and `repos --available` are the same list.

A repository is linked to your workspace automatically the first time you use it:

* you start a session on it in the web app,
* you create a trigger or routine for it with `--repo`, or
* a Slack mention runs on it, because the message named it or someone picked it from the buttons.

A repository the app cannot reach is refused with `REPOSITORY_INACCESSIBLE`, and the fix is
`mutagent gateway repos grant-more`: give the app access to it on GitHub first.

`mutagent gateway repos` with GitHub connected but an empty list means the app has no repository
access yet. That is fixed on GitHub too.

### Linking by hand

Linking by hand is optional. It links a repository before you first use it:

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

`link` takes up to 25 repositories at a time. Linking does not grant access; the app's access on
GitHub already decides what the gateway can reach. `repos --linked` shows each linked repository with
its state, whether it is private, and **how many triggers and routines depend on it**, which makes an
unlink's effect visible before you run it.

### Unlinking

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

Unlinking pauses the triggers and routines that depend on that repository, visibly — they are not
deleted, and `routines show` gives the reason they are paused. Linking the repository again, by hand
or by use, does not resume them on its own: resume each one with `mutagent gateway triggers enable`
or `mutagent gateway routines resume`.

An unlinked repository also stays out of the repositories a Slack mention chooses from, even though
the app can still reach it. Unlinking is how a workspace narrows that set (see
[Which repository a Slack mention runs on](/integrations/slack#which-repository-a-mention-runs-on)).

### Choosing the repository

There is no default repository. Each trigger and routine chooses its repository when you create it,
and a test run names one with `--repo`:

* `--repo owner/name` picks that repository. Any repository the app can reach works; one not linked
  yet is linked when you create the trigger or routine.
* Without `--repo`, the CLI uses the GitHub remote of the directory you run it in, linked or not, and
  prints which one it chose. With `--json`, `data.repoSource` is `cwd-remote` in that case.
* `--no-repo` means no repository: the run starts without any code. Routines and `webhook`,
  `emit:<kind>` and `trace.threshold` triggers allow it.

Otherwise (no `--repo`, and no GitHub remote in the directory) the command is refused with
`REPOSITORY_REQUIRED`, and the error lists your linked repositories. The repository cannot be changed later: create a new trigger or routine instead.

### Changing which repositories the app can reach

If a repository you want is not in `repos`, the app cannot reach it yet. You change that on GitHub,
not in Mutagent:

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

This prints the GitHub page for the app's repository access. Open it, add or remove repositories
there, then run `mutagent gateway repos` again.

## Check the whole path

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

`doctor` runs an end-to-end check: GitHub is connected, the app reaches at least one repository, and
every linked repository is still reachable. It exits 0 when every check passes. When one fails, it
exits 1 with `GATEWAY_CHECKS_FAILED`; with `--json`, `data.checks` lists each check and
`_agentGuidance.fix` lists the command that fixes each failure, in order. No linked repositories with
every check passing is healthy: there is nothing to link.

To prove the whole path, including a Helix run in a sandbox, run the built-in test agent on a
repository:

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

It exits 0 when the run succeeds and 1 when it fails; read `code`, `error` and `_agentGuidance` for
the next step.

While cloud runs are in early access, a run for an account that is not enabled yet stops before it
starts. The run, the GitHub issue reply and the Slack thread all say: "Cloud runs aren't enabled for
this account yet, so nothing ran. Ask the Mutagent team to enable cloud access."

## If it fails

Gateway commands use the CLI's exit codes: 0 success, 1 failure (usage errors included), 2 your
Mutagent API key expired or is invalid, 3 not signed in or no workspace. With `--json`, branch on
`code`, run what `_agentGuidance.fix` names (replace any `<placeholder>` first), and when
`_agentGuidance.escalate` is present, stop and tell the person: that step is theirs. See
[Errors and exit codes](/cli/errors).

| Code or error | Fix |
| - | - |
| `state_user_mismatch` | `data.url` was opened in a browser not signed in to Mutagent. Open `data.signInUrl` first, then `data.url` in the same browser. |
| `CONNECT_PENDING` | The browser step is not finished. Finish it and run `connect <provider> --wait --attempt <attempt-id>` again. |
| `REPOSITORY_INACCESSIBLE` | `mutagent gateway repos grant-more`, then give the app access on GitHub. |
| `REPOSITORY_REQUIRED` | Pass `--repo <owner/name>`, or `--no-repo` where it is allowed. |
| `CONFIRMATION_REQUIRED` | Confirm with the user, then run the command again with `--force`. |


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