Documentation

Remote machines

Connect to remote toowld daemons over SSH or WebSocket. One config, three clients.

A remote is a toowld daemon running on another host. Define it once in ~/.config/toowl/remotes.toml and the same entry surfaces in the GUI Perch, the TUI picker, and the web client. Workspaces, panes, and scrollback live on the remote daemon — the client just renders.

Define a remote

Create ~/.config/toowl/remotes.toml with one [[remote]] table per machine:

# ~/.config/toowl/remotes.toml

[[remote]]
name = "idrl"
host = "idrl.example.com"
transport = "ssh"
port = 22
user = "ubuntu"

[[remote]]
name = "lan-box"
host = "192.168.1.20"
transport = "ws"
port = 7113

[[remote]]
name = "prod"
host = "api.example.com"
transport = "wss"
port = 7113
auth = { token_env = "TOOWL_PROD_TOKEN" }

Schema reference

FieldRequiredNotes
nameyesUnique identifier. Shown in the Perch, palette, and window-title badge. Must not collide with another remote.
hostyesHostname or IP. Must not start with - — that's an SSH option-injection guard.
transportyesssh, ws, or wss.
portnoDefaults to 22 for SSH and 7113 for ws / wss.
usernoSSH user. Must not start with -.
auth.token_envnoName of an env var holding the bearer token for wss. The token itself never lives in the config file.
remote_toowld_binnoOverride the toowld path on the SSH-side host. Whitelisted to filename-safe characters.

Transports

SSH stdio

The primary path today. toowl spawns ssh <host> [-l user] toowld --serve-stdio and tunnels JSON-RPC over the SSH connection. No port forwarding, no extra daemon config — if you can SSH into the box and it has toowld installed, you can use it as a remote.

  • Auth — whatever your SSH config does. Keys, agents, jump hosts all work.
  • Survives disconnect — the remote daemon was started with setsid(); it keeps running across SSH drops, so your workspaces survive.
  • Defense in depth — toowl rejects host and user values starting with - and constrains remote_toowld_bin to filename-safe characters so a hostile config can't smuggle SSH options.

WebSocket (ws)

Plain WebSocket. LAN-only — there's no transport-level encryption. Use this for a box on the same trusted network where SSH is overkill.

Secure WebSocket (wss)

TLS WebSocket with optional bearer-token auth. Set auth.token_env to the name of an environment variable holding the token; toowl reads it at connect time:

export TOOWL_PROD_TOKEN="…"
toowl

Heads up. wss and ws transports complete the TLS / WS handshake but the daemon's JSON-RPC endpoint is still landing. SSH is the primary path for now; ws and wss will light up automatically once the daemon adds /v1/rpc.

The Remotes Feather

The Feather is a one-tap switcher for the active window's daemon. Open the Perch with Cmd+B / Ctrl+B, find Remote Machines, and click a remote to rebind the current window. The window title picks up the @ host badge, panes you spawn from the palette land on the remote daemon, and the Workspaces Feather starts listing the remote's workspaces.

Click Local to drop back to your own machine.

Three clients, one config

ClientHow to open the picker
GUIClick Remote Machines on the Perch.
TUIType the prefix and mCtrl+B m by default.
WebNavigate to /remotes on the daemon's HTTP gateway. SSH remotes are hidden — browsers can't initiate SSH.

All three read the same ~/.config/toowl/remotes.toml. Edits are hot — the Feather watches the file and refreshes its list when you save.

Connecting from the command line

toowl up <workspace> --remote <name> opens a remote-backed workspace in a new window directly. The window's title shows @ <name> and the pane chrome dot turns yellow so you can tell at a glance the panes are remote.

Connection lost

If the underlying SSH session or WebSocket drops, the window title gains a (connection lost) suffix and the pane chrome dots flip to red. Run toowl up <workspace> --remote <name> again to reconnect — the daemon kept the panes alive, so you reattach to the same live state.

Setting up the remote box

Install the server-flavored build on the remote machine:

# On the remote host
bash scripts/install-server.sh

# Verify the daemon launches on demand
toowld doctor

See TUI client for the headless build flags and SSH-friendly install notes.

Security notes

  • Tokens live in env vars, not on disk. auth.token_env only names the env var; the token value never round-trips through the config file.
  • SSH option-injection guards. Hosts and users starting with - are rejected at config load, before they reach ssh.
  • Duplicate names are rejected. The loader refuses to start if two [[remote]] tables share a name.

Keep going

  • Workspaces — named windows you can open on local or remote daemons.
  • TUI client — run toowl over SSH on a server with no display.
  • Configuration — the rest of config.toml.

Edge case or feature request? File it on GitHub.