Cloud agents
Last updated: 2026-06-01
What it is
Run shells, edit files, and use Claude Code or Codex on a VPS — all from inside the same harnx window you use locally. Pick a project, attach it to a remote, and any terminal pane you open in that project spawns on the VPS instead of your laptop.
Two ways to keep local and remote in sync:
- Git mode — the agent clones your repo. You sync with fetch / pull / push. Best when your project is already in a git remote.
- Files mode — push local files directly to the agent and pull its changes back. For projects without git.
What you need
- A Linux VPS (DigitalOcean, Fly, Hetzner, your own box — anything) with SSH access.
- No need to install Node.js first — the installer auto-installs Node 20 via NodeSource (apt / dnf) or apk (Alpine) if it's missing. Pass
--no-install-nodeif you manage Node via nvm / fnm and want the installer to leave it alone. - No need to open any new ports on the VPS — harnx tunnels in over your existing SSH connection.
Install the agent
SSH into your VPS, then run:
curl -fsSL https://harnx.dev/install-agent.sh | sudo bashThe installer sets up the agent as a systemd service, generates a bearer token, and installs Claude Code + Codex. It takes about a minute. At the end you'll see something like:
Installation complete.
Connect from the harnx desktop:
1. Open an SSH tunnel from your laptop:
ssh -L 6767:127.0.0.1:6767 [email protected]
2. In harnx, click 'Add remote' and enter:
URL: ws://127.0.0.1:6767/
Bearer: <64 hex chars>
AI CLIs installed for the 'harnx' user:
✓ claude — log in with: sudo -u harnx -i claude /login
✓ codex — log in with: sudo -u harnx -i codex loginCopy the bearer — you'll paste it into harnx in a minute. Ignore step 1 from the install output; harnx opens the SSH tunnel for you.
Optional flags
--port 6868— use a different agent port.--workspace /path— put the workspace somewhere other than/srv/harnx-workspace.--rotate-bearer— generate a fresh bearer (e.g. if you think it leaked).--no-claude/--no-codex— skip installing either AI CLI.--no-install-node— skip the Node 20 auto-install (if you manage Node via nvm / fnm).--sandbox— run every terminal inside a per-workspace, kernel-isolated container, so a misbehaving AI agent can't read host files (~/.ssh), reach cloud metadata, or exhaust the box. Off by default; slightly slower on VPSes without hardware virtualization.--uninstall— remove everything (add--purgeto also delete the workspace).
Sign in to Claude Code / Codex
One-time setup. SSH into the VPS again and run these commands. Each opens a browser-OAuth flow (paste the URL into your laptop browser, paste the resulting code back into the terminal).
sudo -u harnx -i claude /login
sudo -u harnx -i codex loginAfter that, claude and codex work in any cloud terminal pane.
Connect from harnx
Open the right panel and switch to the cloud tab. Click + Add remote in the left rail.
Pick SSH tunnel (recommended) and fill in:
- Name — any label (
fly-iad-1,home-vps, etc.). - SSH user — the user you SSH in as (NOT
harnx). - SSH host — your VPS hostname or an alias from
~/.ssh/config. - SSH port — usually
22. - Agent port —
6767unless you changed it. - Bearer — paste what the installer printed.
Click Add remote, then Connect. Status dot turns green when ready.
Attach a project
Open a local project, switch to the cloud tab. You'll see an attach form.
Git mode
Pick Git, choose the remote, paste your repo URL, set a target directory name, click Clone & attach.
If you're using an SSH clone URL ([email protected]:...), you need an SSH key on the agent first. Click the remote in the left rail, expand Git SSH key on the agent, click Generate ed25519 key, copy the public key, and paste it into your git host (e.g. GitHub → Settings → SSH and GPG keys).
Files mode
Pick Files, choose the remote, leave "Run initial push immediately" checked, click Attach. Your local files get uploaded to the agent.
Day-to-day
Cloud terminal panes
Once a project is on a remote, any terminal pane in that project spawns on the agent. You'll see a ☁ <remote-name> chip next to the pane label so you can tell at a glance. Run claude, codex, or anything else you'd normally type in a shell.
Git mode
The cloud tab shows current branch, ahead/behind, and dirty files. Three buttons:
- Fetch — pulls down refs without modifying your working tree.
- Pull — fast-forward only. Resolve any conflicts manually.
- Push — pushes current branch to origin.
Files mode
Two buttons:
- Push — uploads files you changed locally to the agent.
- Pull — downloads files the agent changed (e.g. from a cloud terminal) to your laptop.
If the same file changed on both sides, you'll see a conflict panel after the push/pull. Click local or remote for each file, then push or pull again. Files mode never deletes anything automatically.
Browse + edit files
The files tab shows the agent's workspace when the project is remote, with the same M/A/D/U markers as a local project. Open a file → harnx reads it from the agent. Edit + save → harnx writes it back to the agent.
Checkpoints
The checkpoint tab lets you snapshot the agent's working tree, restore it later, and view diffs. Enter a short reason, click snapshot. Restore reapplies the captured state on top of whatever's in the working tree now.
Security
A connected agent is a privileged shell on your VPS. Treat the bearer like a password.
- SSH tunnel is the default — the agent isn't reachable from the internet. You need SSH access to the VPS to connect.
- Bearer is stored owner-only on both your laptop and the VPS. harnx never sends it over a URL — only in an HTTP header.
- The agent runs as a dedicated
harnxuser with no shell login. Its filesystem access is constrained to the workspace directory. - To rotate the bearer, SSH into the VPS and run:
Then remove + re-add the remote in harnx with the new bearer.sudo bash install-agent.sh --rotate-bearer - If you suspect the bearer leaked, rotate it immediately and check
journalctl -u harnx-agentfor unexpected connections.
For team use, point a domain at the VPS and put Caddy or nginx in front of the agent to serve wss:// over TLS. Edit /etc/harnx-agent/config.env to set HARNX_BIND_HOST=0.0.0.0 and HARNX_INSECURE=1 (the flag acknowledges the agent itself is no longer on loopback), then restart with systemctl restart harnx-agent.
Troubleshooting
"Connection refused" on connect
The agent isn't running. On the VPS:
sudo systemctl status harnx-agent
sudo journalctl -u harnx-agent -n 50The journalctl output usually tells you the exact problem. Re-running the installer fixes most native-build issues.
"Auth failed" on connect
Bearer mismatch. Check the bearer in harnx matches:
sudo cat /etc/harnx-agent/bearer.envRemove + re-add the remote in harnx with the correct bearer.
SSH tunnel won't open
Test the bare SSH command from your laptop terminal:
ssh -L 6767:127.0.0.1:6767 [email protected] -NWhatever error you see there is what harnx is hitting. Usual fixes: add your key to ssh-agent, fix the Host stanza in ~/.ssh/config, or check the hostname.
Git push: "Permission denied (publickey)"
The agent doesn't have an SSH key set up for your git host. Click the remote in the cloud tab's left rail, generate the key, copy the public half, add it to your git host.
Files-mode shows a file as conflict
The file changed on both sides since the last sync. Pick a side (local or remote) in the conflict picker, then push or pull again.
Uninstall
To remove the agent from a VPS:
sudo bash install-agent.sh --uninstallStops the service, removes everything in /opt/harnx-agent and /etc/harnx-agent, removes the harnx user (including its home with Claude / Codex auth state). The workspace is preserved unless you add --purge.
In the harnx app, click the remote in the left rail, then Remove.