---
title: "Self-host Amp orbs"
description: "Run Amp's orb provider on an exe.dev VM so each Amp orb thread gets a VM of its own, ready in seconds, with no exe.dev key on the provider."
url: https://exe-staging.dev/deploy/amp
category: "AI agents"
updated: 2026-11-07
---

# Self-host Amp orbs

Every Amp orb thread on its own exe.dev VM, ready in seconds.

- **Software:** Amp (https://ampcode.com)
- **License:** Proprietary (Amp's terms of service)
- **Time:** 10 minutes
- **Example VM name:** `my-amp` (yours will differ; on the VM, `hostname` prints it)
- **Machine-readable:** https://exe-staging.dev/deploy/amp/manifest.json
- **File:** https://exe-staging.dev/deploy/amp/dispatch.sh

## What you get

- The Amp CLI, and the dispatch program at `~/amp-orbs/dispatch.sh`
- The provider token in `~/amp-orbs/provider.env`, readable only by `exedev`
- The amp-orb-provider systemd service, enabled so it comes back after a reboot, with `Orb provider started` in its log

Running on the VM:

- **Amp orb provider**: `amp orb provider`, run by the amp-orb-provider systemd service, data in `~/amp-orbs`
- **dispatch.sh**: turns Amp's spawn, pause and delete jobs into exe.dev VMs, data in `~/amp-orbs/dispatch.sh`
- **The amp-orbs integration**: exe.dev's API, held by exe.dev and limited to VMs tagged amp-orb
- **Orb VMs**: one per thread, booted from Amp's orb image and named after the orb, data in `/home/user/workspace on each orb`

How it is reached:

- ampcode.com, the Amp apps, or amp -ox (private): where you start threads and pick this provider; Amp lets in only you
- ssh my-amp.exe.xyz (private): the provider VM, for its log and upkeep
- ssh amp-<orb id>.exe.xyz (private): a root shell in any orb

## Deploy with Shelley

Open https://exe-staging.dev/new?prompt=AMP_ORB_PROVIDER_TOKEN%3D%3Cfill-this-in%3E%0A%0ASet%20up%20Amp%20on%20this%20VM%20by%20following%20the%20exe.dev%20recipe%20at%20https%3A%2F%2Fexe-staging.dev%2Fdeploy%2Famp.md%20from%20top%20to%20bottom.%0A%0AThe%20values%20at%20the%20top%20of%20this%20message%20are%20mine%3A%0A-%20AMP_ORB_PROVIDER_TOKEN%3A%20the%20%60aop_live_%E2%80%A6%60%20token%20Amp%20showed%20once%20when%20you%20added%20the%20provider%20in%20Settings%20%E2%86%92%20Orbs%0AAsk%20me%20for%20any%20that%20still%20say%20%3Cfill-this-in%3E%20before%20you%20need%20them.%0A%0AThe%20recipe%27s%20example%20VM%20name%20is%20my-amp.%20This%20VM%27s%20name%20is%20the%20output%20of%20%60hostname%60%3A%20use%20it%20wherever%20the%20recipe%20writes%20my-amp.%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-%20The%20Amp%20CLI%2C%20and%20the%20dispatch%20program%20at%20%60~%2Famp-orbs%2Fdispatch.sh%60%0A-%20The%20provider%20token%20in%20%60~%2Famp-orbs%2Fprovider.env%60%2C%20readable%20only%20by%20%60exedev%60%0A-%20The%20amp-orb-provider%20systemd%20service%2C%20enabled%20so%20it%20comes%20back%20after%20a%20reboot%2C%20with%20%60Orb%20provider%20started%60%20in%20its%20log%0A%0ARun%20%22Set%20up%20the%20provider%20by%20hand%22%2C%20skipping%20VM%20creation%20and%20SSH.%0AAMP_ORB_PROVIDER_TOKEN%20is%20a%20secret%3A%20write%20it%20to%20~%2Famp-orbs%2Fprovider.env%0Awith%20%60printf%20%27AMP_ORB_PROVIDER_TOKEN%3D%25s%5Cn%27%20%22%24value%22%60%20under%20%60umask%20077%60%0Ainstead%20of%20the%20interactive%20read%2C%20and%20never%20print%20it.%20If%20the%20log%20says%0A%60Amp%20rejected%20the%20orb%20provider%20token%60%2C%20tell%20the%20owner%20the%20token%20is%20wrong%0Aor%20revoked.%20Never%20ask%20for%20an%20exe.dev%20API%20key%3A%20the%20integration%20in%20%22Let%0Athe%20provider%20make%20VMs%22%20is%20created%20by%20the%20owner%2C%20on%20their%20own%20computer.%0ADon%27t%20start%20a%20thread.%20Finish%20by%20giving%20the%20owner%20that%20integration%0Acommand%20with%20this%20VM%27s%20name%2C%20then%20pointing%20them%20to%20%22Start%20a%20thread%20on%0Ayour%20VMs%22.%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/amp/prompt.txt | ssh exe.dev new --prompt=/dev/stdin
```

Or follow the steps below by hand.

[Amp](https://ampcode.com) runs each of its cloud threads in an *orb*, a
machine of its own with your repository checked out, where the agent runs
commands, starts dev servers and tests its work while you're away. With
[self-hosted orbs](https://ampcode.com/docs/orbs/self-hosted), those
machines are yours: a small program, the orb provider, waits for Amp's
requests and hands each one to a dispatch program that creates, wakes or
deletes the machine.

This page makes the provider an exe.dev VM and every orb another one. Amp's
exe.dev example does this with an exe.dev SSH key on the provider; here an
exe.dev integration holds the key, and it can reach only the orbs. A new
orb VM boots from Amp's orb image in a few seconds, keeps its disk
between messages, and is a real VM you can SSH into. Everything connects
out to Amp, so nothing is open to the internet. You keep driving threads
from ampcode.com, the Amp apps, your editor or `amp -ox`.

## Before you start

- An [Amp](https://ampcode.com) account. Any plan works; self-hosted orbs
  are free except on Enterprise.
- For private repositories, GitHub connected in Amp's
  [integration settings](https://ampcode.com/settings/integrations). Amp
  clones and pushes from the orb with short-lived tokens of that
  connection, so no GitHub credentials go on your VMs.
- A provider and its token. In your personal
  [Settings → Orbs](https://ampcode.com/settings/orbs), click **Add
  Provider** and name it `exe-dev` (you pick it by this name later). Copy
  the `aop_live_…` token: Amp shows it only once. In a workspace, an admin
  can add one under the workspace's **Settings → Orbs** instead, and every
  member can use it.

## Set up the provider

Deploy sets it up on a new VM and asks for the provider token. To do it
yourself:

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

On your computer (any free name works for the VM):

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

### Install Amp and the dispatch program

On the VM, install the Amp CLI with Amp's installer, and fetch
[`dispatch.sh`](https://exe-staging.dev/deploy/amp/dispatch.sh), the program the
provider runs for every job:

```bash
curl -fsSL https://ampcode.com/install.sh | bash
mkdir -p ~/amp-orbs && cd ~/amp-orbs
curl -fsSLO https://exe-staging.dev/deploy/amp/dispatch.sh
chmod +x dispatch.sh
~/.local/bin/amp --version
```

The installer puts `amp` in `~/.local/bin`; the last line prints its
version. `dispatch.sh` is Amp's exe.dev example with two changes: it
calls exe.dev through the integration you add next instead of `ssh
exe.dev`, and it starts an orb's bootstrap over that integration too.

### Save the provider token

Paste the token at the prompt (it isn't shown):

```bash
(umask 077; read -rsp 'Provider token: ' t && printf 'AMP_ORB_PROVIDER_TOKEN=%s\n' "$t" > ~/amp-orbs/provider.env); echo
ls -l ~/amp-orbs/provider.env
```

Success is `-rw-------` for `provider.env`.

### Run the provider as a service

Amp wants exactly one provider per token, kept running by a service
manager:

```bash
sudo tee /etc/systemd/system/amp-orb-provider.service >/dev/null <<'EOF'
[Unit]
Description=Amp orb provider (self-hosted orbs on exe.dev VMs)
Wants=network-online.target
After=network-online.target

[Service]
User=exedev
WorkingDirectory=/home/exedev/amp-orbs
EnvironmentFile=/home/exedev/amp-orbs/provider.env
ExecStart=/home/exedev/.local/bin/amp orb provider /home/exedev/amp-orbs/dispatch.sh
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now amp-orb-provider
sleep 10; systemctl is-active amp-orb-provider
journalctl -u amp-orb-provider --no-pager -n 20
```

Success is `active`, and `info Orb provider started` in the log. `Amp
rejected the orb provider token` means the token is wrong or was revoked.
After a reboot, the provider first logs `Another amp orb provider is
connected for this token` and waits about a minute until Amp notices its
old connection is gone; that's expected.

</details>

## Let the provider make VMs

The provider VM makes orb VMs through exe.dev's API, by way of an
integration that holds the key, so no key is on any VM. On your computer:

```bash
ssh exe.dev integrations add exe-dev --name amp-orbs \
  --tag amp-orb --cmds ls,new,ssh,rm,pause,resume --attach vm:my-amp
```

The integration can list, make, reach, pause and delete VMs tagged
`amp-orb`, and nothing else; the VMs it makes get that tag. Only the
provider VM can use it, and `ssh exe.dev integrations remove amp-orbs`
revokes it. On the provider VM, check it:

```bash
curl -s -X POST https://amp-orbs.int.exe.xyz/exec -d ls
```

Expect `{"vms":[]}`.

## Start a thread on your VMs

On [ampcode.com](https://ampcode.com) or in the Amp app, click **New
Thread**, then **Orb**, open the type dropdown and choose `exe-dev` under
**Self-Hosted** (marked **Personal**). Pick a project, or **No Project**
for a clean orb, and give it a task:

> Build a tiny website for a sandwich critic with strong opinions, serve it, and show me a screenshot.

From a terminal, the same thing is:

```bash
amp -ox "Run the tests and fix any failures" --orb-provider exe-dev
```

It prints the thread's URL and returns; the agent keeps going. Amp sends
the provider a `spawn` job. The first orb takes about 40 seconds while
exe.dev pulls Amp's image; in our tests every orb after that was up and
connected about 3 seconds after Amp sent the job. Amp then clones the
repository, runs the project's `.agents/setup` and starts the agent. The
provider's log, and the thread's setup log, show `dispatch.sh`'s lines:

```
info Claimed job {"jobId":"spawn:amp-01a1b6e2-…","op":"spawn",…}
created VM amp-01a1b6e2-efed-7101-8974-5f86613e3a5e
started amp orb bootstrap in amp-01a1b6e2-efed-7101-8974-5f86613e3a5e
```

Close your laptop: the agent keeps working on the VM. When the thread goes
idle, or you archive it, Amp sends `pause` and `dispatch.sh` pauses the
VM within a few seconds (`paused VM amp-…`). Your next message sends
`spawn`, and the same VM is back in about 3 seconds (`resumed VM
amp-…`). Deleting the thread deletes its VM.

exe.dev's `pause` saves the VM's memory as well as its disk and frees
its CPU and memory, so a woken orb still has its dev servers, terminals
and desktop apps running: in our test, a web server the agent started
before the pause answered after it with the same process ID. (Amp's docs
say pausing needs exe.dev support to turn it on; it no longer does.)

## Look inside an orb

Each orb is an exe.dev VM named after it. On your computer:

```bash
ssh exe.dev ls 'amp-*'
ssh amp-<orb id>.exe.xyz
```

You're `root` there; the agent works as `user`, in
`/home/user/workspace`. The thread's **Terminal**, **Portals** and
**Desktop** tabs reach the orb through Amp's tunnel, as on Amp-hosted
orbs. Anything an orb
serves on a port from 3000 to 9999 is also at
`https://amp-<orb id>.exe.xyz:<port>/`, private to you behind exe.dev's
[HTTPS proxy](/docs/proxy).

- **Bigger orbs:** in the provider's **Edit** dialog in Amp, add an orb
  type named `large`. `dispatch.sh` gives it 4 CPUs and 16 GB; any other
  type gets exe.dev's default size. Pick it in the type dropdown, or with
  `--orb-size large`. Edit the `case` in `dispatch.sh` for more types.
- **Your own image:** set `ORB_IMAGE` in `~/amp-orbs/provider.env` and
  restart the service. Amp's
  [image requirements](https://ampcode.com/docs/orbs/self-hosted#bring-your-own-image)
  apply.

## Or: run threads on the VM itself

Amp's other way to use a machine you own is a
[runner](https://ampcode.com/docs/cli/runners): `amp --no-tui` serves the
directories on one machine, and every thread you send to it runs there,
with the tools and logins you set up. It suits a VM you treat as your dev
box. A runner run by a service signs in with an Amp access token: create
one in Amp's
[Settings → Security](https://ampcode.com/settings/security#access-token)
(it starts with `sgamp_`). It can do anything your Amp account can, so it
goes in a file only you can read. On the VM, paste it at the prompt, then
start the runner as a service under the VM's name:

```bash
(umask 077; read -rsp 'Amp access token: ' t && printf 'AMP_API_KEY=%s\n' "$t" > ~/amp-runner.env); echo
mkdir -p ~/code
sudo tee /etc/systemd/system/amp-runner.service >/dev/null <<'EOF'
[Unit]
Description=Amp runner
Wants=network-online.target
After=network-online.target

[Service]
User=exedev
WorkingDirectory=/home/exedev/code
EnvironmentFile=/home/exedev/amp-runner.env
ExecStart=/home/exedev/.local/bin/amp --no-tui --runner-id %H --discover-dirs
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now amp-runner
sleep 10; journalctl -u amp-runner --no-pager | grep Registered
```

Success is `Registered as <your email>. Create threads on
https://ampcode.com/ and they will run here.`

Clone repositories into `~/code`; the runner serves each checkout there and
picks up new ones as they appear. The VM shows up under **Runners** when
you start a thread, or from a terminal anywhere with
`amp -x "Run the tests" --executor runner:my-amp --runner-dir /home/exedev/code/<repo>`.
For private GitHub repositories,
[connect a GitHub repo](/docs/integrations-github) so the VM can clone and
push with no token on it. Add `--remote-control-terminal` to the
`ExecStart` line for a terminal from ampcode.com. A runner updates and
restarts itself when it's idle.

<details class="dp-details">
<summary>Update, back up and stop</summary>

### Update

The Amp CLI updates itself, and each orb gets the CLI from Amp's image
when it's created. To update the provider now:

```bash
~/.local/bin/amp update
sudo systemctl restart amp-orb-provider
```

To pick up a newer `dispatch.sh`, run the `curl -fsSLO` line again in
`~/amp-orbs`; the provider runs the file fresh for every job.

### Back up

The provider VM holds only `dispatch.sh` and the token; Amp keeps the
threads, and the orbs push their work to Git. If you lose the token, add a
new provider in Amp. Don't copy the provider VM with `ssh exe.dev cp`
while it runs: two providers on one token each take a share of the jobs.

### Stop

`sudo systemctl disable --now amp-orb-provider` stops new orbs; threads on
the provider wait until it's back. Delete the provider in Amp's Settings →
Orbs to revoke its token, `ssh exe.dev integrations remove amp-orbs` to
revoke the integration, and `ssh exe.dev rm amp-<orb id>` to delete any
orb VMs left over. For a runner, `sudo systemctl disable --now amp-runner`,
and delete its access token in Amp's Settings → Security.

</details>

## Troubleshooting

The provider's log is `journalctl -u amp-orb-provider`; each job's output
is there, and a spawn's output is in the thread's setup log too.

- **`Error: Amp rejected the orb provider token`.** The token is wrong or
  the provider was deleted. Add a new one and save it as above.
- **`exe.dev: integration not found or not attached to this VM`.** The
  `amp-orbs` integration doesn't exist or isn't attached to the provider
  VM. Run the `integrations add` command with this VM's name.
- **`exe.dev new amp-… failed`.** The JSON after it says why: often the
  VM limit of your plan, or an orb type bigger than your capacity.
- **The thread waits for an orb, and the log shows nothing.** Another
  provider is connected with the same token, such as a forgotten
  `amp orb provider` in a terminal; Amp sends it the jobs. Stop it.
- **`ORB_TOKEN was rejected by Amp`** in an orb's
  `/home/user/.amp-bootstrap.log`. That bootstrap was started with an
  old job's token, which lasts 15 minutes; send the thread another
  message to get a new spawn.

## Frequently asked questions

### Do I need an Amp workspace or a paid plan?

No. Since October 28 you can add a provider in your personal [Settings → Orbs](https://ampcode.com/settings/orbs), without a workspace. Self-hosted orbs are free on Amp's Hobby, Megawatt, Gigawatt and Teams tiers; Enterprise workspaces pay Amp's orb price for them. The agent's model usage is billed by Amp as usual, from your plan's included usage, credits, or your own keys and subscriptions in Amp's Model Routing.

### Can Amp use exe.dev's LLM gateway?

No. Amp runs the agent loop and calls the models from its own servers, not from the orb, and exe.dev's [LLM integration](/docs/integrations-llm) answers only requests from your VMs. Code that the agent writes and tests in an orb can call `https://llm.int.exe.xyz` without a key, like on any exe.dev VM.

### What leaves my VMs?

The orb runs the agent's tools: it reads and edits files and runs commands, and the repository, builds and disk stay on exe.dev. What the tools produce goes to Amp and is stored with the thread: the file contents the agent reads, command output, diffs, screenshots and attachments. The provider and the orbs only connect out to Amp; nothing on them listens to the internet.

### Self-hosted orbs or a runner?

An orb is a fresh VM per thread, created and cleaned up by Amp through your provider, so threads can't trip over each other. A [runner](#or-run-threads-on-the-vm-itself) is one machine that every thread shares, with whatever you installed and signed in to there. Use orbs for parallel tasks on one repository; use a runner for work that needs that one machine.

### Do macOS Satellites work with these orbs?

They should. A Satellite is a Mac in Amp's cloud that an orb starts and connects to over SSH, and Amp lists self-hosted orbs' access to it among the connections they make. Satellites are in beta behind a waitlist and billed by Amp at $2 to $4 an hour, so we haven't tried one. Nothing Mac-related runs on your VMs.

### How much does it cost on exe.dev?

The orb VMs are ordinary VMs on your plan. On [Personal](/docs/billing/personal) they share one pool of CPU and memory with your other VMs, up to 50 VMs, so idle orbs cost nothing extra but count toward the 50. Deleting threads you're done with deletes their VMs.

### Can new orbs skip `.agents/setup`?

Not with this dispatch program. Like Amp's own exe.dev example, it ignores project snapshots, so every new thread clones the repository and runs `.agents/setup`. A woken orb keeps its disk, so it runs only `.agents/resume`.


## Related

- [Run a Claude Code self-hosted runner](https://exe-staging.dev/deploy/claude-code-runner.md): Claude Code cloud sessions, running on a VM you control.
- [Run Codex remote control on a server](https://exe-staging.dev/deploy/codex-remote-control.md): Codex on an always-on VM, steered from the ChatGPT app on your phone.
- [Give any agent a sandbox over MCP](https://exe-staging.dev/deploy/exe-mcp.md): One URL gives your agent real VMs to run code on, host apps from, and hand work to.
- [Running Agents](https://exe-staging.dev/deploy/agents.md): Use exe.dev VMs as a sandbox
- [Run Claude Code on a remote server](https://exe-staging.dev/deploy/claude-code.md): A computer for Claude. A breather for your laptop.
- [Host OpenClaw](https://exe-staging.dev/deploy/openclaw.md): An AI sidekick with its own computer. Your laptop can take a nap.
