Machines
Run the agents, their dev servers and their databases on another computer, and keep driving them
from the board on your laptop. A server, a cloud VM, a dev box your team shares: if ssh gets you
in, kelpie can use it.
What a machine is
Section titled “What a machine is”Five feature branches, each with its own dev server, database and agent, is more than a laptop wants to carry. A machine moves that work somewhere bigger without changing how you work with it.
The machine runs its own kelpie board, headless. Your board reaches it over one ssh connection and
shows its sessions beside your local ones, each with a cloud chip. Chat, the diff, Start feature
and review all work the same. Every port your processes listen on over there is forwarded to the
same port on your laptop, so a feature’s URL is still localhost:3000, its annotation toolbar
still loads, and a phone you have paired with the board still opens its preview.
Any Linux box will do. Kelpie is tested on Ubuntu 24.04. Size it at about 4 GB of memory per feature you expect to run at once.
Before you start
Section titled “Before you start”On your laptop: a Claude subscription, and gh signed in (gh auth status), since the box gets
your GitHub sign-in from it. On Google Compute Engine, skip to
the one command that creates the VM too.
Adding one
Section titled “Adding one”There is one requirement: ssh <host> logs you in without asking anything. No password, no
passphrase, no host-key question. A key without a passphrase or a running ssh agent does it.
Check it first:
ssh -o BatchMode=yes me@box true && echo okThen add it:
kelpie machine add me@boxThe first time, kelpie runs claude setup-token for you and opens a browser tab: approve it and
the token lands in ~/.config/kelpie/claude-token, readable by you only, for this box and the next
one. Nothing to copy or paste. If no tab opens, kelpie prints the link instead; open it, and paste
the code the page shows into the terminal.
machine add does the rest over that one connection:
- Checks that ssh logs in by itself, and stops with ssh’s own reason if it does not.
- Installs git, gh, tmux, Docker, node, pnpm, bun and Claude Code. It uses sudo where there is one; on a box where you have none, it checks they are already there.
- Stores Claude’s token on the box, readable by you only. That token is good for a year and covers the model only: no Remote Control and no claude.ai connectors on the box.
- Signs the box’s
ghin with your GitHub token, and copies your git name and email, so its agents can push branches and open pull requests. - Sends it the kelpie you are running, into
~/.local/share/kelpie, so the box needs no access to kelpie’s repository, and starts its board as a user service that survives logout and reboots. - Adds the machine to your config. A running board picks it up within seconds.
Run it again at any time to update the box to the build you have. --name sets what the board calls it;
--token-file reads a token you already made from somewhere else.
kelpie machine remove <name> takes a machine off the board; on Google Compute Engine,
kelpie machine remove --gce <name> also deletes the VM and the Host that --gce wrote.
Providers
Section titled “Providers”Kelpie connects with nothing but ssh, so login, keys and host checks stay with OpenSSH, and a
provider plugs in by giving you an ssh Host. The one exception is --gce, which runs gcloud
to create the VM before it connects. Once ssh name works,
kelpie machine add name does too.
A server or VPS
Section titled “A server or VPS”Nothing to do beyond a key: kelpie machine add [email protected], or a Host you already have in
~/.ssh/config.
Google Compute Engine
Section titled “Google Compute Engine”You do not create the VM yourself. With gcloud signed in and a default project set:
kelpie machine add --gce my-boxThat creates an e2-standard-4 (16 GB, room for three features) running Ubuntu 24.04, reached
through IAP so it needs no public ssh port, writes a key for it to ~/.ssh/kelpie_machine, adds
a Host my-box to ~/.ssh/config, waits for ssh to answer, and then sets the box up as above.
Run with the same name again to update a box rather than create one.
Set PROJECT, ZONE or MACHINE in front of it to change where and how big:
PROJECT=my-project ZONE=europe-west1-b MACHINE=e2-standard-8 kelpie machine add --gce my-boxOnce per project, IAP needs a firewall rule letting it reach port 22 on the VMs kelpie tags
kelpie-sandbox. Your account also needs to create VMs and open IAP tunnels there; a project
owner or editor can do both.
gcloud compute firewall-rules create allow-iap-ssh-kelpie-sandbox \ --network default --allow tcp:22 --source-ranges 35.235.240.0/20 --target-tags kelpie-sandboxThe Host it writes looks like this, if you would rather make the VM yourself and run plain
kelpie machine add my-box:
Host my-box HostName my-box User me IdentityFile ~/.ssh/kelpie_machine IdentitiesOnly yes ProxyCommand gcloud compute start-iap-tunnel my-box 22 --listen-on-stdin --project my-project --zone us-central1-a --verbosity=errorAWS EC2
Section titled “AWS EC2”The same shape through Session Manager, as
AWS documents it:
a Host for the instance id whose ProxyCommand opens the session:
Host i-0123456789abcdef0 User ubuntu ProxyCommand sh -c "aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters 'portNumber=%p'"GitHub Codespaces and Coder
Section titled “GitHub Codespaces and Coder”Both write the Host for you: gh codespace ssh --config prints entries to add to
~/.ssh/config, and coder config-ssh adds them itself. Mind the provider’s own limits: a
codespace stops when it idles and is deleted after a while, and its agents stop with it.
boat.dev
Section titled “boat.dev”boat.dev’s own script, from Use an editor, writes a
Host named after the sandbox id into ~/.ssh/boat/; then kelpie machine add <id>. Create the
sandbox with boat new --no-auto-stop, or boat extend it, since an open ssh connection does not
keep it running. A sandbox resumed after more than a few minutes stopped comes back at a new
address with a new host key, so run the script again after every resume; until you do, the board
says the machine does not log in. Its sessions end when it stops.
Sandboxes with no ssh
Section titled “Sandboxes with no ssh”Some sandbox services offer only an exec command, not ssh. Kelpie does not support those yet: it needs ssh’s port forwarding for the board and for every dev server, and an exec pipe carries one stream, not ports.
Using it
Section titled “Using it”The New menu gets a machine picker once a machine is connected. It lists the same repos whichever machine you pick. On a machine, New, chat, Start feature and review use the repo’s checkout there, and clone it into the box’s home first if it has none. A session started on a machine is a chat you type into from the board, since the box has no screen to open a window on.
The first time you start something in a repo on a machine, kelpie copies that repo’s git-ignored
.env* files over, readable by you only, and never over a file the box already has. Secrets your
dev server needs arrive without a separate step.
From the terminal, and for agents that drive kelpie, --machine does the same as the picker:
kelpie chat --machine box --cwd ~/acme --ask "run the test suite"kelpie feature --machine box --cwd ~/acme fix-login --ask "the login form drops the email"A port already in use on your laptop is not forwarded, so a database running on the box never shadows the one running here.
Staying connected
Section titled “Staying connected”Your board connects with nobody at a terminal, so the login has to keep not asking. The usual way
it breaks is a sign-in that expires: a gcloud or aws session behind a ProxyCommand, or a key
that left the agent. Kelpie retries every few seconds, and a machine that stays unreachable shows
on the board within a few minutes as a setup problem, with ssh’s reason and the command to run
yourself:
gce-box is not connecting: ERROR: (gcloud.compute.start-iap-tunnel) ... Reauthentication failed. ssh gce-box trueSign in again in a terminal and it reconnects on its own. If ssh logs in but the board does not answer, the fix it names restarts the box’s board service instead.
The machine’s entry in ~/.config/kelpie/config.json is what machine add wrote:
"machines": [ { "name": "box", "ssh": "me@box" }]ssh can also be the argv of a command that opens ssh and accepts ssh options after it, such as
["gh", "codespace", "ssh", "-c", "name", "--"], and port is set when the box’s board is not on
4321.
What it does not protect
Section titled “What it does not protect”A machine keeps the agents off your laptop. It does not keep them apart from each other, or from your accounts: everything on the box runs as one user, with your Claude token, your GitHub sign-in and your repos’ secrets. Give each person a box of their own.
On a box several people share, each person’s board gets a port nobody else holds, and only your own dev servers are forwarded to you. But anyone on that box can reach your board on its loopback port, so share one only with people you would hand your Claude sign-in.
Questions
Section titled “Questions”Is a machine a sandbox?
Section titled “Is a machine a sandbox?”No, and kelpie does not call it one. It holds your repos, your Claude token and your GitHub sign-in. Treat it as your own dev box, not as a container for code you do not trust.
What happens to the agents when my laptop sleeps?
Section titled “What happens to the agents when my laptop sleeps?”They keep running. The box’s board owns them; your board only shows them, and catches up when the connection comes back.
Does it work with agents other than Claude Code?
Section titled “Does it work with agents other than Claude Code?”The box’s board shows whatever agents run there, the same as yours does. Setup signs in Claude Code only; sign the others in on the box yourself.
How do I remove one?
Section titled “How do I remove one?”Delete its entry from machines in your config. To stop its board too, run
ssh box 'bash -s -- remove' < docs/machine-setup.sh from the kelpie repository; repos, worktrees
and config on the box are left as they were.