Skip to content

Remote Workspaces

Workbench can connect to workspaces on another machine over an encrypted WebSocket connection. The local app discovers or connects to a remote server and displays remote repos, agents, and terminals alongside local ones.

Click Share this machine in the sidebar. The server starts automatically as a subprocess — no separate installation required. The server is embedded in the Workbench binary (gated behind the default-enabled server feature).

The Share this machine modal shows the new share’s connection string directly (and as a QR code, so you can pair the Workbench mobile app by scanning with your phone). The server’s own console output never prints tokens — it’s just a startup banner and an active-share count:

workbench-server v0.8.0 listening on wss://0.0.0.0:7683
Name: Work Laptop
Certificate fingerprint: 3f:9a:...
Hostname: work-laptop — 1 active share(s). Run `workbench-server share list` to print connection strings.
Ready for connections.

For headless machines without a GUI, the standalone server binary is still available:

Terminal window
# Build and install the standalone server binary
cargo install --path src-server
# Start it (generates a TLS certificate on first run)
workbench-server

The standalone binary has no GUI of its own to create a share from, but it reads and writes the same server.toml config as the Workbench desktop app. So the usual flow is: start workbench-server on the machine, then open the Workbench GUI on that same machine and click Share this machine to mint a share (workspace scope, label, collaborative or not). Once the share exists, print its connection string from the headless side with:

Terminal window
workbench-server share list

This works even after you close the GUI — the share lives in the config file, not in the GUI process.

If both machines are on the same network, the server appears automatically in the sidebar under Nearby. Click Connect and enter the pairing token when prompted.

Click + Add remote in the sidebar footer and paste the full connection string. Workbench authenticates, stores a session token, and reconnects automatically on future launches.

Workspace-scoped shares are built for collaboration: you pick which workspaces a guest can see. When the remote machine is your own — a workstation you drive from a laptop while traveling, or a second desktop you sit down at — you want the opposite: everything, including things a share can’t grant. That’s an owner credential. Because both sides run the full desktop app, you can start work on one machine, walk away, and pick up the same conversation on the other — agent sessions, chat history, terminals, and all:

  • Full access: every repository and workspace on the machine, creating and archiving workspaces, and repo terminals for trunk-workflow repositories. The terminal panel spawns shells on the server in the workspace’s worktree — the first tab auto-opens, + adds more, and shells survive workspace switches by re-attaching to the server-side PTY. The diff viewer’s Changes tab is fully interactive too: stage, unstage, and discard operate on the server-side worktree exactly as they do locally (guest shares see the file list read-only). For trunk-workflow repositories, the ship banner and Sync with main also work over an owner connection — the merge, archive, and progress updates all run on the server, with live status streamed back to the laptop. The sidebar’s main-branch push/pull arrows and ahead/behind badge appear on the remote repo’s header too: push, fast-forward pull, and the Smart Pull flow for diverged branches (merge/rebase choice, conflict detection, abort) all operate on the server’s primary checkout, exactly as they do locally. Checkpoints and forking work too: the per-turn rollback controls, Clear conversation, and Fork from here all operate on the server’s database and worktree, and the agent keeps its memory of the surviving turns exactly as it does locally. Composer attachments work too: paste, drag-drop, or pick files on the laptop and they upload to the server with your message, subject to the same per-type size limits as a local send — and attachment bodies load back on demand, so PDF thumbnails, the lightbox, and downloads work for remote history. The attach menu also offers “From workspace…” to browse and attach files directly from the server worktree, and “Upload to workspace…” to pick files on your local machine, upload them to the server, and insert an @-mention into the message (25 MB per-file size limit). The rest of the composer is at parity as well: steering a message into a running turn (Cmd/Ctrl+Enter) injects mid-turn on the server exactly as it does locally — including attachments, @-mentions, and the pre-steer checkpoint — so BTW asides work over remote too; /clear clears the server-side conversation; and !shell runs the command in the remote workspace’s terminal on the serving machine (the shell chip and placeholder say so explicitly). The Files tab is fully editable as well: create files and folders, rename, drag-to-move, and delete all run against the server’s worktree. OS-file drag-and-drop from your local machine onto a remote worktree uploads the files into the drop target directory (25 MB per-file size limit; single files only — dropped folders are reported as unsupported), and every drop ends with a toast reporting what was uploaded or why it failed. Delete moves the file to the server machine’s trash (never a permanent delete), and the undo shortcut restores it from there. Workspace lifecycle is at parity too: the sidebar context menu on a remote workspace offers rename (double-click the name also works), archive, delete (with the same confirmation dialog as local), and Sync with main; goal editing in the Context tab, re-running the repo’s setup script, and workspace-name generation all run on the server. Renames and deletes push live to every connected client, so sidebars update everywhere at once. Terminal tabs are first-class as well: creating, renaming, closing, and reordering tabs persist to the server’s database, so the same tab set greets you when you sit back down at the host machine. The connection’s sidebar group also shows a compact Token Usage section reading the server machine’s Claude subscription quota (5-hour, 7-day, and per-model bars), so you can watch the workstation’s burn from the laptop. While remote focus is active, the sidebar’s footer Token Usage widget switches to that same server-side quota and appends the server’s name to its headline (e.g. “Token Usage — ceo/laptop”), so the footer never silently reports the local machine while the window is showing a remote one; Codex bars are hidden in this mode since the server keeps no Codex rate-limit cache. Click Back to local and the footer returns to your local machine’s own quota. Items that act on your local machine — Open Folder, Reveal in File Manager, Copy absolute Path, and dragging files in from your OS file manager — stay hidden for remote workspaces, since those paths only exist on the server. (Guest shares see none of these — they are owner-only.)
  • Durable terminals: remote terminal shells are server-side resources the client merely views. Closing the laptop lid, losing the network, or reloading the frontend never kills the shell or whatever it is running — the server keeps buffering output (256 KiB of scrollback per terminal), and when the client comes back each pane re-attaches to its own shell and replays what happened while nobody was watching. While the connection is down the pane shows a reattach overlay and blocks input, so keystrokes can never reach a shell whose output you can’t see; if the shell exited in the meantime, the pane says so. Shells nobody re-attaches to are reaped after a grace period (48 hours by default; tune with WORKBENCH_PTY_ORPHAN_GRACE_HOURS on the server, 0 disables reaping).
  • Panel stays put: as the server’s owner, the terminal panel of a remote workspace is yours to open and close. Joining a chat session, switching sessions, or reconnecting never opens it for you — only guests of a collaborative share see the panel open when the host shares a terminal.
  • Local clipboard: copying from a remote terminal pane — by mouse selection plus Ctrl+Shift+C / ⌘C, the right-click menu, or a program on the server using the OSC 52 escape (Claude Code’s “press c to copy the login URL”) — lands on the clipboard of the machine running the frontend, not the server. See Copy and Paste.
  • Host-local minting: mint an owner credential from a terminal on the server machine (workbench-server owner mint --label laptop, over SSH is fine), or — for the desktop app’s own embedded server — from the app itself: open Share this machine → New share, choose Owner share, optionally give it a label, and confirm the full-machine-access warning. Minting boots the embedded server on first share if it isn’t already running. Both paths create the config file and TLS certificate if needed and produce one connection string — workbench://<host>:<port>/<token>#fp=<fingerprint> — ready to paste into the other machine’s + Add remote flow. There is deliberately no way to mint or escalate an owner credential over the network: minting is strictly host-local whether it comes from the CLI or the GUI (ADR-0044) — the desktop app’s mint action is a Tauri command only, never exposed over WSS. Owner shares minted via the CLI also show their full connection string in the GUI’s share list.
  • Hardened pairing: the printed string ends in #fp=<fingerprint> — the server certificate’s SHA-256 — so the client verifies it is talking to that exact server before sending anything (no trust-on-first-use window). Pairing itself is an HMAC challenge-response: the raw token never crosses the wire, and there is no approval-code prompt (a headless server has nowhere to show one; the pinned certificate plus proof of token possession are the credential).
  • Remote focus mode: when the laptop connects with an owner credential, the window switches to showing only that server’s world, with a persistent accent-tinted badge naming the server. Back to local returns to your own repos; clicking the connection header re-enters. The badge is the standing reminder that files and terminals live on the remote machine.
  • Owner ≠ host: owner sessions can edit the server’s app settings through the Settings target picker and its agent-backend configuration and secrets, but still cannot manage its shares, mint or revoke owner credentials, or stop the server without its local control token; collaboration shares are completely unaffected — their pairing flow, approval codes, and workspace scoping are unchanged.

Revoke with workbench-server owner revoke <id> (or --all), or click Stop on the entry in the GUI’s share list — either path immediately disconnects every session the credential issued and permanently invalidates its connection string, and the laptop shows Re-pair required. share list (CLI) and the GUI’s share list both mark owner entries.

When focused on a remote server with an owner credential, the Add repository modal (sidebar + button) operates on the server’s filesystem instead of the local machine. All three tabs work:

  • Open existing — type or autocomplete a path on the server to register a git repository that already exists there.
  • Create new — pick a parent directory on the server and a project name; Workbench runs git init on the server and registers the result.
  • Clone — enter an SSH URL, directory name, and a parent directory on the server; the clone runs on the server with progress streamed back to the modal in real time.

In each case, after the repository is registered a workspace is automatically created so you can start working immediately. Path fields use autocomplete against the server’s filesystem (no local file-picker dialog, since the paths live on the remote machine).

Right-click a repository inside a connection’s group and choose Remove Repository…, or open the repository’s Settings page and use Remove repository in its Danger Zone. The confirmation dialog is the same one used for local repositories: the repository is unregistered from the server’s database and every workspace under it (active and archived) has its worktree removed on the server, but the repository itself stays on the server’s disk. This is owner-only; guest shares never see the entry.

Right-click a repository inside a connection’s group and choose Add to Favorites to pin it to the top of that group, under a Favorites header. Favorites are stored on the serving machine, so each host keeps its own set — one server’s stars never appear under another’s, and the same server shows the same favorites to every machine you drive it from. See repo sidebar organization for the full behavior.

Terminal window
# Print paste-able workbench:// connection strings for every active share
# (owner entries are marked; uses Tailscale-aware hostname when available)
workbench-server share list
# Mint / revoke an owner credential (host-local only — this CLI command,
# or the desktop app's Share modal for its own embedded server)
workbench-server owner mint --label laptop
workbench-server owner revoke <share-id>
workbench-server owner revoke --all
# Bind to a specific interface or port
workbench-server --bind 192.168.1.50 --port 9000
# Disable mDNS advertisement
workbench-server --no-mdns

To revoke a collaboration share, close it from the Workbench GUI (Share this machine > close the share). Owner credentials are revoked from the terminal as above (the GUI can also stop them from the share list).

All traffic is encrypted with TLS. The local app pins the server’s certificate fingerprint on first connection (trust-on-first-use), similar to SSH’s known_hosts. This means:

  • The first connection requires manual verification of the pairing token
  • Subsequent connections are authenticated automatically via the pinned certificate
  • If the server’s certificate changes, you’ll be prompted to re-verify

Owner connection strings go one step further: they embed the certificate fingerprint (#fp=…), so even the first connection verifies the server before any credential material is sent, and the owner pairing token itself never crosses the wire (HMAC challenge-response).

Workbench treats a remote connection as something that survives laptop lids and network changes:

  • The client sends a WebSocket keepalive ping after ~25 seconds of idle. If the server doesn’t answer within 10 seconds, the connection is declared dead — so half-open connections after sleep or a network switch are detected without you running anything.
  • Connections with auto-connect enabled reconnect automatically and indefinitely, backing off up to 30 seconds between attempts. Opening the laptop lid or joining a new network triggers an immediate retry.
  • While offline, your last-known remote repositories and workspaces stay visible (dimmed) in the sidebar. A successful reconnect replaces them with a fresh snapshot from the server — unread and attention badges catch you up on what happened while you were away. Joined remote terminal sessions re-attach automatically after reconnect.
  • Auth or certificate failures stop automatic retries and mark the connection Re-pair required; reconnecting silently is never attempted in that state. A TLS fingerprint change is never retried through the trust prompt. Error messages show only 8-character fingerprint prefixes so full fingerprints never reach logs or the console. Fix the cause (or re-pair) and click Connect.
  • Manually disconnecting a connection sticks — window focus and network events will not silently reconnect it. The connection waits for you to click Connect again (or remove and re-add it).
  • Sequenced event replay: When a remote client reconnects after a disconnection, the server replays any room events the client missed since its last seen sequence number. This means in-flight agent responses, turn state changes, and collaboration events are recovered automatically — not just persisted messages.
  • Session continuity (owner shares): connecting to your own machine from another desktop or laptop picks up the existing chat conversation automatically. The server resumes the running Claude CLI session, and both sides detect when the other advanced the conversation and respawn with the current transcript — so you can start work on one machine, walk away, and continue from the other without losing context. No action is required: continuity is implicit for owner shares.

A common roaming setup: a headless server on an always-on machine, reached from a laptop over Tailscale from anywhere.

  1. Mint the credential on the machine (SSH is fine — no GUI needed). For your own always-on box, use an owner credential:

    Terminal window
    workbench-server owner mint --label laptop
    # → workbench://your-machine:7683/<token>#fp=<fingerprint>

    Then add the connection on the laptop with + Add remote, pasting the full string. Pairing completes without a code prompt. (For a machine you share with others, mint a workspace-scoped share from the GUI instead — see Sharing from the Desktop App.)

    mDNS discovery does not cross networks, so the Nearby list won’t show the server remotely — the manual connection string is the way in. TLS uses fingerprint pinning (embedded in the owner string), so the tailnet hostname works fine.

  2. Keep the server alive across reboots with a systemd user unit at ~/.config/systemd/user/workbench-server.service:

    [Unit]
    Description=Workbench remote server
    After=network-online.target
    [Service]
    ExecStart=%h/.cargo/bin/workbench-server
    Restart=on-failure
    [Install]
    WantedBy=default.target
    Terminal window
    systemctl --user enable --now workbench-server
    loginctl enable-linger "$USER" # keep it running while logged out

    Session tokens and the TLS certificate persist across restarts, so a reboot at home never forces a re-pair from the road.

  3. Back home, either keep using the headless server (connect the desktop GUI to localhost as a remote) or stop it and launch the GUI natively — both use the same database, so workspaces and history are already there.


Original source: utensils.io/claudette