---
title: "Run OpenRig on a remote server"
description: "Run an OpenRig team of Claude Code and Codex agents on an exe.dev VM: no API keys, sessions that outlast your SSH connection, and a team that comes back after a reboot."
url: https://exe-staging.dev/deploy/openrig
category: "AI agents"
updated: 2026-10-31
---

# Run OpenRig on a remote server

A team of coding agents that keeps its seats when you log off.

- **Software:** OpenRig (https://openrig.dev)
- **Source:** https://github.com/mvschwarz/openrig
- **License:** Apache 2.0
- **Time:** 15 minutes
- **Example VM name:** `my-openrig` (yours will differ; on the VM, `hostname` prints it)
- **Machine-readable:** https://exe-staging.dev/deploy/openrig/manifest.json

## What you get

- OpenRig 0.7.6 with its daemon and kernel (operator, advisor and queue worker), started by systemd.
- Claude Code and Codex connected to exe.dev's LLM integration, with no API key on the VM.
- A two-agent team in `~/project`: a Claude Code builder and a Codex reviewer, each in its own tmux session.
- Teams that were running come back after a reboot and resume their conversations.

Running on the VM:

- **OpenRig daemon**: @openrig/cli 0.7.6 on Node.js 24, started by systemd; API on loopback only, port 7433, data in `~/.openrig`
- **Kernel**: OpenRig's operator, advisor and queue worker (Codex and Claude Code)
- **The pair team**: A Claude Code builder and a Codex reviewer, defined in ~/rigs/pair/rig.yaml, data in `~/project`
- **tmux**: One session per agent, so they keep working when you disconnect
- **Claude and GPT**: Through exe.dev's LLM integration

How it is reached:

- ssh my-openrig.exe.xyz (private): the OpenRig dashboard, every agent's terminal, and the `rig` CLI

## Deploy with Shelley

Open https://exe-staging.dev/new?prompt=Set%20up%20OpenRig%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Fopenrig.md%20from%20top%20to%20bottom.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-openrig.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-openrig.%20Skip%20the%20step%20that%20creates%20the%20VM%3B%20you%20are%20on%20it.%0A%0AYou%20are%20done%20when%20all%20of%20these%20are%20true.%20Check%20each%20one%20yourself%3A%0A-%20OpenRig%200.7.6%20with%20its%20daemon%20and%20kernel%20%28operator%2C%20advisor%20and%20queue%20worker%29%2C%20started%20by%20systemd.%0A-%20Claude%20Code%20and%20Codex%20connected%20to%20exe.dev%27s%20LLM%20integration%2C%20with%20no%20API%20key%20on%20the%20VM.%0A-%20A%20two-agent%20team%20in%20%60~%2Fproject%60%3A%20a%20Claude%20Code%20builder%20and%20a%20Codex%20reviewer%2C%20each%20in%20its%20own%20tmux%20session.%0A-%20Teams%20that%20were%20running%20come%20back%20after%20a%20reboot%20and%20resume%20their%20conversations.%0A%0ARead%20the%20whole%20recipe%2C%20including%20the%20closed%20details.%20For%20setup%2C%20follow%0A%22Install%20by%20hand%22%20only%2C%20skipping%20VM%20creation%3B%20the%20walkthrough%20above%20it%20is%0Afor%20the%20owner.%20Do%20not%20run%20the%20restore%2C%20update%20or%20Pi%20instructions.%0AInstall%20exactly%20%40openrig%2Fcli%400.7.6.%20Never%20attach%20to%20a%20tmux%20session%3B%20read%0Aagents%20with%20%60rig%20capture%60.%20Do%20not%20send%20the%20team%20work%2C%20and%20do%20not%20run%0A%60rig%20down%60.%20Keep%20the%20VM%20private%3A%20never%20run%20share%20set-public%20or%20bind%20the%0Adaemon%20beyond%20127.0.0.1.%20On%20an%20existing%20VM%2C%20ask%20before%20replacing%0A~%2F.openrig%2C%20~%2Frigs%2Fpair%20or%20~%2Fproject%2C%20or%20Claude%20Code%20or%20Codex%20settings%0Athat%20aren%27t%20exe.dev%27s.%0AVerify%3A%20%60rig%20doctor%60%20reports%20no%20failures%3B%20openrig.service%20is%20enabled%0Aand%20active%3B%20%60rig%20status%60%20says%20%60Kernel%3A%20ready%60%3B%20%60rig%20ps%20--nodes%20--rig%0Apair%60%20shows%20both%20seats%20%60run%60%2C%20each%20with%20a%20last%20observed%20model.%20Do%20not%0Areboot.%0AFinish%20with%20the%20two%20SSH%20commands%20from%20%22Meet%20your%20team%22%2C%20using%20this%20VM%27s%0Aname%2C%20and%20suggest%20the%20owner%20give%20the%20builder%20a%20first%20task.%0A%0AFinish%20with%20the%20URLs%20I%20should%20open.%0A to create a VM whose agent, Shelley, follows this recipe. From a terminal:

```sh
curl -fsSL https://exe-staging.dev/deploy/openrig/prompt.txt | ssh exe.dev new --prompt=/dev/stdin
```

Or follow the steps below by hand.

[OpenRig](https://openrig.dev) turns coding agents into a team. You
describe the team in YAML (who builds, who reviews, who they report to),
and OpenRig starts each agent in its own tmux session, gives it a role
and an address like `dev-build@pair`, and lets the agents message each
other and keep a shared queue of work. It's built for projects that
last weeks, so it wants a computer that doesn't sleep.

This page gives it one: a VM with Claude Code and Codex already
installed, connected to exe.dev's [LLM integration](/docs/integrations-llm)
with no API keys, and a two-agent team that starts again by itself after
a reboot.

## Meet your team

The team is called `pair`: a Claude Code builder, `dev-build@pair`, and a
Codex reviewer, `dev-review@pair`, both working in `~/project`. On your
computer, open the dashboard:

```bash
ssh -t my-openrig.exe.xyz tmux attach -t operator-human@kernel
```

Pick **pair** in the explorer on the left with the arrow keys and
**Enter**. Press **Ctrl-b**, then **d** to leave it running.

Now give the builder something to do, from a second terminal on your
computer:

```bash
ssh my-openrig.exe.xyz rig send dev-build@pair \
  "'Write hello.sh that prints Hello from the rig, and a test for it. Ask dev-review to check it, then commit it on a branch.'"
```

The builder records the task in OpenRig's queue, writes it, and sends it
to the reviewer. The dashboard shows both seats working and the queue
filling in:

<figure>
<img src="https://exe-staging.dev/deploy/openrig/dashboard.png" alt="The OpenRig dashboard in a terminal: the pair rig selected, its build and review seats both working, and the queue history below" width="1210" height="740" loading="lazy">
<figcaption>The pair team at work: the builder (cl, Claude Code) and the reviewer (cx, Codex).</figcaption>
</figure>

To watch or talk to one agent directly, attach to its session:

```bash
ssh -t my-openrig.exe.xyz tmux attach -t dev-build@pair
```

Type to it as you would in Claude Code. Detach with **Ctrl-b**, then
**d**; closing your laptop doesn't stop it.

## Ask the operator

OpenRig's kernel comes with an operator, a Codex agent that knows
OpenRig. Ask it to explain a stuck seat, design a bigger team, or start
one of OpenRig's own (`starter`, `factory`, `code-review`, `research`):

```bash
ssh -t my-openrig.exe.xyz tmux attach -t operator-agent@kernel
```

Teams it starts from OpenRig's library ask before running some commands.
When one waits, `rig ps --nodes -A` shows which seat; attach to it and
answer.

## Work on your own repository

Connect a repository with the [GitHub integration](/docs/integrations-github),
so the agents can clone and push without a token on the VM. On your
computer:

```bash
ssh exe.dev integrations add github --name app --repository you/app --attach vm:my-openrig
```

On the VM, clone it and give it a team of its own, named after it:

```bash
git clone https://github.int.exe.xyz/you/app.git ~/app
mkdir -p ~/rigs/app
sed -e 's/^name: pair/name: app/' -e 's|/home/exedev/project|/home/exedev/app|' \
  ~/rigs/pair/rig.yaml > ~/rigs/app/rig.yaml
printf '%s\n' /CLAUDE.md /AGENTS.md /.claude/ /.mcp.json /.openrig/ >> ~/app/.git/info/exclude
rig up ~/rigs/app/rig.yaml
```

The new seats are `dev-build@app` and `dev-review@app`. The `exclude`
line keeps the files OpenRig adds for its agents out of your commits.
Pushes appear as the exe.dev GitHub App unless the integration
[acts as you](/docs/integrations-github#acting-as-your-user---act-as-user).
Agents can open pull requests with `gh` once `GH_HOST=github.int.exe.xyz`
is set.

## Add a Pi agent

[Pi](/deploy/pi) seats keep their own settings, so give one the LLM
integration first, then add it to the running team. On the VM:

```bash
d="$HOME/.openrig/state/pi/dev-scout@pair/agent"
mkdir -p "$d"
cat > "$d/models.json" <<'EOF'
{
  "providers": {
    "exe": {
      "baseUrl": "https://llm.int.exe.xyz/anthropic",
      "api": "anthropic-messages",
      "apiKey": "exe-llm-integration",
      "models": [{ "id": "claude-sonnet-5-5" }]
    }
  }
}
EOF
rig grow pair scout --runtime pi --cwd /home/exedev/project
rig ps --nodes --rig pair
```

The API key is a placeholder; exe.dev supplies the real credentials
outside the VM. After a minute, `dev-scout@pair` shows a last observed
model of `exe/claude-sonnet-5-5`.

## Setup and upkeep

No need to read on unless you're curious, or doing it yourself.

<details id="create-the-vm" data-manual-setup class="dp-details">
<summary>Install by hand</summary>

On your computer (pick another name if `my-openrig` is taken):

```bash
ssh exe.dev new --name=my-openrig
ssh my-openrig.exe.xyz
```

All remaining commands run **on the VM**, as `exedev`.

### Install Node.js and OpenRig

OpenRig needs Node.js 22 or 24. Install Node.js 24 from NodeSource, and
OpenRig into `~/.local`, so updates need no sudo:

```bash
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs
npm config set prefix ~/.local
npm install -g @openrig/cli@0.7.6
rig --version
```

Expect `0.7.6`. npm warns that it skipped an install script; that's a
compatibility check, which `rig doctor` repeats below.

### Connect Claude Code and Codex

Point both at the LLM integration. OpenRig won't start Codex agents
unless `codex login status` says it's signed in, so give Codex a
placeholder key; the integration ignores it:

```bash
exeuntu configure claude
exeuntu configure codex
printf exe-llm-integration | codex login --with-api-key
claude -p "Reply with exactly: OK"
(cd /tmp && codex exec --skip-git-repo-check "Reply with exactly: OK")
```

Both should answer `OK`. On older VMs the first two commands are
`exeuntu claude configure` and `exeuntu codex configure`.

### Prepare OpenRig

`rig setup` checks both agents and adds mouse support and scrollback to
`~/.tmux.conf`. `--no-herdr` skips Herdr, a terminal workspace this
setup doesn't need, and `--router-line no` keeps an extra OpenRig line
out of your projects' `CLAUDE.md` and `AGENTS.md`:

```bash
rig setup --providers both --no-herdr --router-line no
rig doctor
```

The doctor should end with `No failures in the checks above`; a warning
that cmux isn't installed is fine.

### Start OpenRig with the VM

OpenRig starts its own daemon in the background. A systemd service runs
`rig start --last` at boot, which starts the daemon and the kernel and
brings back every team that was running, resuming their conversations.
It only starts and stops the daemon, so restarting it leaves the agents'
tmux sessions alone:

```bash
mkdir -p ~/.config/systemd/user
cat > ~/.config/systemd/user/openrig.service <<'EOF'
[Unit]
Description=OpenRig daemon, kernel, and the teams that were running
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
Environment=PATH=%h/.local/bin:/usr/local/bin:/usr/bin:/bin
WorkingDirectory=%h
ExecStart=%h/.local/bin/rig start --last
ExecStop=%h/.local/bin/rig daemon stop
KillMode=process
TimeoutStartSec=5min

[Install]
WantedBy=default.target
EOF
sudo loginctl enable-linger "$USER"
systemctl --user daemon-reload
systemctl --user enable --now openrig
rig status
```

The first start takes a minute while the kernel's agents start. Expect
`Daemon running on port 7433` and `Kernel: ready`. The daemon listens
on `127.0.0.1` only.

### Start the team

Make the project folder (skip the `git init` for a folder you already
have), and keep the files OpenRig adds for its agents out of git:

```bash
mkdir -p ~/project && cd ~/project
git rev-parse --git-dir >/dev/null 2>&1 || git init -b main
printf '%s\n' /CLAUDE.md /AGENTS.md /.claude/ /.mcp.json /.openrig/ >> .git/info/exclude
```

Describe the team. Its two agents come from OpenRig's library: an
implementer that builds and verifies, and a QA agent that checks the
exact change it's sent. The `yolo` policy lets them work without
permission prompts on this VM:

```bash
mkdir -p ~/rigs/pair
cat > ~/rigs/pair/rig.yaml <<'EOF'
version: "0.2"
name: pair
summary: A Claude Code builder and a Codex reviewer on their own exe.dev VM.
permission_policy: builtin:yolo
non_interruptive: true
pods:
  - id: dev
    label: Project
    members:
      - id: build
        agent_ref: "path:/home/exedev/.local/lib/node_modules/@openrig/cli/daemon/specs/agents/development/implementer"
        runtime: claude-code
        profile: default
        cwd: /home/exedev/project
      - id: review
        agent_ref: "path:/home/exedev/.local/lib/node_modules/@openrig/cli/daemon/specs/agents/development/qa"
        runtime: codex
        profile: default
        cwd: /home/exedev/project
    edges:
      - kind: delegates_to
        from: build
        to: review
edges: []
EOF
rig up ~/rigs/pair/rig.yaml
sleep 30
rig ps --nodes --rig pair
```

`rig up` reports `Status: completed`, then warnings that the seats run
with full bypass, as intended. Both seats should be `run`, with a last
observed model each (Claude for `build`, GPT for `review`).

</details>

<details id="back-up-and-restore" class="dp-details">
<summary>Back up and restore</summary>

The code is the agents' work: push their branches. Everything else lives
on the VM: OpenRig's database and queue in `~/.openrig`, the agents'
conversations in `~/.claude` and `~/.codex`, and the team files in
`~/rigs`. Copy the whole VM. On your computer:

```bash
ssh exe.dev cp my-openrig my-openrig-backup
```

The copy starts OpenRig and resumes the teams by itself, so use it
instead of the original, not beside it, or both teams work on the same
tasks. To keep a copy without running it, stop the copy's teams once
with `ssh my-openrig-backup.exe.xyz 'rig down pair'`.

</details>

<details id="update" class="dp-details">
<summary>Update</summary>

Read the [changelog](https://github.com/mvschwarz/openrig/blob/main/CHANGELOG.md)
first, and copy the VM as above. Then, on the VM, replacing `0.7.7` with
the version you want:

```bash
npm install -g @openrig/cli@0.7.7
systemctl --user restart openrig
rig --version
rig status
rig ps --nodes -A
```

The agents keep running through the restart; the new daemon picks them up.
Don't run `rig down` to update. For a big jump, ask Shelley to follow
OpenRig's
[upgrade skill](https://github.com/mvschwarz/openrig/blob/main/skills/_canonical/core/openrig-upgrade/SKILL.md).

</details>

<details id="troubleshooting" class="dp-details">
<summary>Something stuck?</summary>

Ask Shelley, or the operator. Or check on the VM:

```bash
rig status
rig ps --nodes -A
journalctl --user -u openrig -n 30 --no-pager
rig daemon logs | tail -n 40
rig doctor
```

- **A seat shows `needs input` or attention.** It's waiting at a
  prompt. `rig capture <seat>` shows it; attach with
  `tmux attach -t <seat>` and answer. If startup stopped there, run the
  `rig seat continue <seat>` that `rig ps` shows.
- **`codex_auth` fails in `rig doctor`.** Codex has no saved key: rerun
  the `codex login --with-api-key` line
  [above](#connect-claude-code-and-codex).
- **`Readiness timeout after 30s`.** The agent started slowly. Run
  `rig config set runtime.readiness_timeout_seconds 120`, then
  `rig up pair --existing`.
- **A team didn't come back after a reboot.** `rig start --last` leaves
  down a team you stopped with `rig down`. Bring it back with
  `rig up pair --existing`.
- **No model reply.** Run the two `OK` checks
  [above](#connect-claude-code-and-codex) and check your
  [LLM integration](/docs/integrations-llm).
- **`rig: command not found`.** Log in again, so `~/.local/bin` is on
  your PATH.

</details>

## Frequently asked questions

### What does it cost?

Your [VM plan](https://exe.dev/pricing) plus model usage, billed to your exe.dev account through the [LLM integration](/docs/integrations-llm). Agents waiting for work use no tokens, but every seat reads its instructions when it starts, and each task is paid for by the builder and the reviewer. The kernel's agents use tokens when you talk to the operator. The Claude Code seats use Claude Code's default model, which is Opus; type `/model` in a seat to pick a cheaper one.

### Why do the agents run without asking permission?

The team file attaches OpenRig's `builtin:yolo` policy, so a team that works for days doesn't stall on a prompt while you're away. The VM is their sandbox: keep it private, and keep unrelated secrets and integrations off it. OpenRig's own kernel runs Codex with full access by default anyway. For prompts, change the policy to `builtin:standard` in `~/rigs/pair/rig.yaml`, then start a new team with `rig down pair` and `rig up ~/rigs/pair/rig.yaml`.

### Can I use my Claude or ChatGPT subscription instead?

ChatGPT, yes, without touching the VM: point the OpenAI provider of your [LLM integration](/docs/integrations-llm) at your ChatGPT account. For a Claude subscription, remove the `apiKeyHelper` and `env.ANTHROPIC_BASE_URL` settings from `~/.claude/settings.json`, run `claude auth login` on the VM, then restart the team as above.

### Can my laptop's agent hand work to the team?

Yes. `ssh my-openrig.exe.xyz rig send dev-build@pair "'your task'"` works from any terminal or agent that can SSH to the VM (the inner quotes keep the task one argument on the VM), and `ssh my-openrig.exe.xyz rig ps --nodes --rig pair` shows what the team is doing.

### Where does Shelley fit in?

Shelley, exe.dev's agent, runs on every VM, at `https://my-openrig.shelley.exe.xyz/`. It can read `rig ps` and `rig capture`, set up another team, or debug a stuck one while the team keeps working.

### Is OpenRig stable?

It's young and moves fast: 0.7.3 to 0.7.6 shipped in four days. This page pins 0.7.6. Read the [changelog](https://github.com/mvschwarz/openrig/blob/main/CHANGELOG.md) and copy the VM before you [update](#update).


## Related

- [Run Claude Code on a remote server](https://exe-staging.dev/deploy/claude-code.md): A computer for Claude. A breather for your laptop.
- [Run Codex on a remote server](https://exe-staging.dev/deploy/codex.md): A computer for Codex. An early night for your laptop.
- [Run the Pi coding agent on a remote server](https://exe-staging.dev/deploy/pi.md): An agent that doesn't ask first, on a computer that can take it.
- [Self-hosted sandbox for Claude Managed Agents](https://exe-staging.dev/deploy/claude-managed-agents.md): Anthropic runs the agent. Each session's tools run on a VM of its own.
- [Host OpenClaw](https://exe-staging.dev/deploy/openclaw.md): An AI sidekick with its own computer. Your laptop can take a nap.
- [Run OpenCode on a remote server](https://exe-staging.dev/deploy/opencode.md): Every model, one VM, and an agent that works while your laptop sleeps.
