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
| Field | Required | Notes |
|---|---|---|
name | yes | Unique identifier. Shown in the Perch, palette, and window-title badge. Must not collide with another remote. |
host | yes | Hostname or IP. Must not start with - — that's an SSH option-injection guard. |
transport | yes | ssh, ws, or wss. |
port | no | Defaults to 22 for SSH and 7113 for ws / wss. |
user | no | SSH user. Must not start with -. |
auth.token_env | no | Name of an env var holding the bearer token for wss. The token itself never lives in the config file. |
remote_toowld_bin | no | Override 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 constrainsremote_toowld_binto 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
| Client | How to open the picker |
|---|---|
| GUI | Click Remote Machines on the Perch. |
| TUI | Type the prefix and m — Ctrl+B m by default. |
| Web | Navigate 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_envonly 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 reachssh. - Duplicate names are rejected. The loader refuses to start if two
[[remote]]tables share aname.
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.