Remote Daemons
boss --host points boss at a bossd running on another machine, over an
SSH-forwarded unix socket. The TUI, the CLI, sessions, repos, cron jobs — every
command works the same way it does locally, apart from the handful noted in
Commands that stay local that act on the machine
boss runs on.
TUI against the daemon on workstation:
- Chat
- CLI
- MCP
No equivalent — this command runs locally
boss --host workstation
No equivalent — this command runs locally
One-shot CLI against a remote daemon:
- Chat
- CLI
- MCP
No equivalent — this command runs locally
boss --host deploy@bastion repo ls
No equivalent — this command runs locally
Typical uses: driving a beefy build box from a laptop, or reaching a daemon running inside a VM or on a cloud instance you already reach over SSH.
Prerequisites
On your local machine, you need only ssh. boss --host does not
require tmux locally — pane attach happens on the remote host (see
Attaching to a chat pane).
On the remote host, you need:
- A running
bossd.--hostnever starts a local daemon for you, and it will not start a remote one either — bring the daemon up on that host first (ssh <destination> boss daemon install, or however you already manage it). - SSH access as the user that runs
bossd. The socket, its directory, and the auth token beside it are all owner-only, so another user's login cannot reach the daemon even when everything else works. Discovery reports it asno bossd is reachable on <destination>; with--host-socketyou getcould not read the bossd token at … on …instead. bossreachable on the non-interactive SSHPATH, so socket discovery works — or a known socket path you can pass to--host-socketinstead. See When discovery fails.tmux, if you want to attach to chat panes. The pane is atmuxsession on the remote machine.- A
terminfoentry for yourTERM, again only for pane attach — and only if you want your own terminal type rather than thexterm-256colorfallback. See Terminfo on the remote host.
Connect for the first time
-
Check plain SSH works.
--hosthands your destination straight tossh, so if this fails, nothing else will:ssh workstation true -
Check the remote
bossis on the non-interactivePATH. This is the exact commandbossuses to discover the remote socket, run the same non-interactive way:ssh workstation boss env --jsonIf that prints JSON reporting
"reachable": trueunderdaemon, discovery will work. If it reports"reachable": false, nobossdis running for that user on that host — start it there first. If the remote shell reports thatbosswas not found (bash: boss: command not found,zsh: command not found: boss), runboss env --jsonfrom a login shell on that host, note its.daemon.socketvalue, and pass that to--host-socket(below). -
Verify with a one-shot command before reaching for the TUI. A CLI command gives you a plain error message instead of a full-screen failure, and
repo lsis the cheapest end-to-end check: it dials the tunnel, discovers the socket, and round-trips a request through the remote daemon. If it lists the repos configured on that host — not the ones configured locally — the connection is good.- Chat
- CLI
- MCP
No equivalent — this command runs locally
boss --host workstation repo lsNo equivalent — this command runs locally
-
Launch the TUI.
- Chat
- CLI
- MCP
No equivalent — this command runs locally
boss --host workstationNo equivalent — this command runs locally
SSH destinations and your ~/.ssh/config
--host takes a standard SSH destination — user@host, a bare host, or a
Host alias from your ~/.ssh/config — and hands that string to ssh
unparsed. Nothing is split, substituted, or rewritten, so User, Port,
IdentityFile, ProxyJump, and HostName from your SSH config all keep
working exactly as they do when you type ssh <destination> yourself.
That means a jump host, a non-standard port, or a per-host key needs no
Bossanova-specific configuration at all — configure it in ~/.ssh/config as
usual and pass the alias. build-box here is a Host build-box … ProxyJump bastion … alias in ~/.ssh/config:
- Chat
- CLI
- MCP
No equivalent — this command runs locally
boss --host build-box
No equivalent — this command runs locally
When discovery fails: --host-socket
--host-socket is the escape hatch when discovery fails. boss finds the
remote socket by running boss env --json over SSH, and a non-interactive SSH
login gets a reduced PATH — if remote boss is not on it, pass the socket
path directly. The path must be absolute on the remote host, not this one — a
local ~ expands to the wrong home:
- Chat
- CLI
- MCP
No equivalent — this command runs locally
boss --host deploy@workstation --host-socket /home/deploy/.config/bossanova/bossd.sock
No equivalent — this command runs locally
--host vs --remote
--host and --remote cannot be combined. They select different daemons — an
SSH tunnel to another machine's bossd versus the cloud orchestrator — so
boss refuses rather than silently preferring one.
| Flag | Talks to | Transport |
|---|---|---|
| (neither) | the bossd on this machine | local unix socket |
--host <dest> | a bossd on another machine you own | SSH-forwarded unix socket |
--remote <url> | the hosted Bossanova cloud orchestrator | HTTPS to the orchestrator |
--host also never starts a local daemon. You asked for the daemon on that
host; booting one here would drive the wrong machine and hide the real failure.
Attaching to a chat pane
Attaching to a chat pane works over --host. The pane is a tmux session
on the remote machine, so boss attaches with
ssh -t <destination> 'exec "$SHELL" -lc '\''tmux -u attach -t <session>'\'''
rather than driving the local tmux. That is the trimmed form — the live attach
also passes -e none and ssh keepalives, none of which change which machine the
pane runs on. The remote tmux runs through that host's login shell for the
same reason --host-socket exists: a non-interactive SSH login gets a reduced
PATH, and a tmux installed outside it (Homebrew's /opt/homebrew/bin,
exported from a ~/.zprofile that zsh does not read non-interactively) would
otherwise fail every attach with tmux: command not found. Because the attach
runs remotely, boss --host does not require tmux on your local machine —
only ssh.
Ctrl+X detaches back to the local TUI as usual. If the connection drops
mid-pane you are ejected back to the local TUI — the remote tmux session
survives, so attaching again returns you to the same pane, and
boss fix-terminal restores a terminal left in a strange state by the drop.
Running boss --host inside a local tmux
Running boss --host inside tmux makes the prefix key ambiguous. You end
up with two tmux clients in one terminal — your local one and the remote one
inside the pane — and both answer to the same prefix (Ctrl+B by default). The
outer tmux wins, so the remote one needs the prefix pressed twice (Ctrl+B
Ctrl+B, then the command). boss does not rebind your prefix to work around
this; if you attach over --host often, set a distinct prefix in the outer
session's own ~/.tmux.conf.
Terminfo on the remote host
The remote host is the one that needs a terminfo entry for your TERM.
The tmux client runs on that machine and reads its terminfo database, so
under --host boss probes the remote host for your TERM and, when the
entry is missing, falls back to xterm-256color rather than failing. That is a
silent downgrade: the pane works, but colours and key handling may not match
your terminal. If an attach does fail with a missing-terminal error, the error
screen names the host to install on and shows the reproduction command. Install
the entry with:
infocmp -x $TERM | ssh <destination> tic -x -
Pasting screenshots into a remote chat
Pasting screenshots works under boss --host, and cannot work over plain ssh.
The difference is which machine the TUI runs on, and it decides whether boss can
reach the file at all.
Your terminal never pastes an image. When you press cmd/ctrl+V with a
screenshot on the clipboard, the emulator writes the image to a temporary file on
the machine you are sitting at and pastes that file's path as text —
something like /tmp/cmux-drop-383cd973-4bab-42c5-a2f5-20497d580fa2.png. All boss
ever sees is that path.
-
Under
boss --host <destination>the TUI runs on your local machine, which is the machine the file is on. Boss recognises the pasted path, copies the file to a per-chat temporary directory on the host the agent runs on, and inserts that path into the composer instead. The agent opens a file it can actually read, and the temporary directory is removed when you detach. -
Under a plain
sshlogin — you SSH to the box and runbossthere — the TUI runs on the remote machine and the screenshot is on your laptop. There is no reverse channel from the remote process back to your local filesystem, so boss cannot fetch the file. The path is passed through to the agent exactly as you pasted it, and the agent reports it cannot open it.
Boss says so rather than failing silently: a paste of an absolute image path that
does not exist on the machine running the TUI is recorded in boss.log, and
briefly flashes a one-line
[boss] no such image on this machine: … · use boss --host on the bottom row
(the file name is shortened so the line always fits one row). The log is the
durable record and the flash is
easy to miss — boss forwards the paste to the agent immediately afterwards, and
the agent's next frame redraws over that row — so check the log if you did not
catch it:
grep 'image path not claimed' "${XDG_STATE_HOME:-$HOME/.local/state}/bossanova/logs/boss.log"
Your keystrokes are never altered — the text still reaches the agent exactly as typed.
To paste screenshots into a remote chat, attach with boss --host from your own
machine rather than running boss inside an SSH session:
boss --host <destination>
If you must work inside an SSH session, copy the file over yourself and paste the
remote path — for example with scp ~/Desktop/shot.png <destination>:/tmp/.
Commands that stay local
A few commands act on the machine boss runs on, so they are refused or hidden
under --host rather than silently doing the wrong thing:
-
boss account addis refused, except for a pasted claude token. Registration normally mints a credential by running the agent's own CLI as a local subprocess, which resolves against this machine'sPATHand this machine's browser rather than the remote host's. The one shape with no local subprocess in it is allowed through:boss --host <dest> account add claude --token-stdinreads a token you already hold (mint one withclaude setup-token) and stores it on the daemon you asked for, so the credential lands on the remote machine. Keep--hoston that command — without it the token is registered on your local daemon instead. Every other shape — codex in any form, and claude's interactive walkthrough — is refused with the command that does work; run it in a shell on that host instead. Under--host, the TUI's add-account flow makes the same split: choosing codex is refused up front, and choosing claude skips the walkthrough and asks you to paste a token.Known gap: this split is
--hostonly. Under--remote <url>the TUI is not gated at all, so Settings → Accounts →[a]still spawns a localclaude setup-token/codex loginon the machine you are sitting at while the credential goes to the remote daemon. Useboss account addin a shell on the remote host until that is closed. -
The
boss daemonsubcommands are refused. They install, start, stop, and uninstall this machine'sbossdthrough local subprocesses, so they would manage the wrong daemon. Runssh <destination> boss daemon ...instead. -
The
[t]erminalaction is hidden. It opens a session's worktree in a new local terminal tab, and under--hostthat path is on the other machine. Chat titles are likewise not backfilled locally — the remote daemon does that job itself.
When the tunnel drops
A dropped tunnel does not kill boss. The connection is supervised and
redialled with backoff, so a blip only fails the in-flight request. While it is
down the TUI says Reconnecting to <destination> and points at the SSH checks
for that host, and the session resumes on its own once SSH is back — no user
action, and no local daemon to restart.
Read that banner, though. If the supervisor itself has stopped, nothing is
redialling, and the TUI says so instead: Disconnected from <destination>,
followed by Restart boss to reconnect. Waiting will not help in that state —
only Reconnecting to … promises an automatic recovery.
Flag reference
See the CLI Reference for the --host /
--host-socket flag table.