Skip to main content
By default Mains is a single desktop app: the UI and all execution — git, terminals, agent CLIs, the local database — run in the same process on the same machine. Relay adds a second mode. The UI can point at a Mains backend running on a different machine, while the interface stays local. Two sides of the same feature:
SideWhat it does
Share this machineExpose the running app so a phone, a LAN device, or another Mains can drive it
Connect to a backendPoint this app at a remote backend over an SSH tunnel or a direct WebSocket URL
Local mode is the zero-config default. Relay is opt-in, and only one backend is active at a time — switching is instant and never touches your local data.

How It Works

Every call in Mains — queries, run events, terminal streams, tool approvals — already flows through one uniform seam (window.api). Relay swaps the transport behind that seam from in-process IPC to a WebSocket, so the entire app surface works against a remote backend with no feature loss.
Local mode    UI ──IPC──▶ backend (same machine)
Remote mode   UI ──WS───▶ backend (other machine)
When a remote backend is active, everything runs on that machine:
Runs on the backendStays local
Provider CLIs (claude, codex, copilot, cursor) and their login stateThe renderer / UI
Git, worktrees, and the workspace filesThe browser panel and inputs
Terminals (node-pty)Settings UI
The SQLite database and encrypted connection secrets
Because agents run on the backend, the provider CLIs must be installed and authenticated on the remote machine (claude login, codex auth login, etc.) — not on the laptop you watch from.

Connection Status

The active backend shows a live status dot:
StatusMeaning
connectedThe WebSocket is open and the UI is live
connectingFirst connection in progress
reconnectingLink dropped — backing off and retrying
offlineNo connection (local mode is always connected)
Durable state lives in the backend’s database, so a reconnect simply refetches it — runs, diffs, and history come back automatically. Only in-flight streaming events emitted during a disconnect are lost.

Web Client

A backend that exposes itself can also be opened in a plain browser — a phone or tablet loads the same Mains UI over the network. See Share This Machine for enabling it. In the web client, you’re already connected to the backend that served the page; adding or switching backends is a desktop-app concern.

Where To Start

1

Watch a remote dev box from your laptop

Use an SSH tunnel — the secure, zero-infrastructure path. Nothing is exposed on the network.
2

Reach your desktop from a phone or another device

Share this machine over LAN or Tailscale HTTPS, then open the web URL or connect directly.

Security Model

  • SSH tunnel — traffic is encrypted and authenticated by SSH; the backend only listens on 127.0.0.1. No ports on the network.
  • Direct / LAN / Tailscale — guarded by a pairing token. Never expose a tokenless backend on a routable interface.
  • Local-only controls — the toggles that expose a machine are registered on local IPC only, so a connected remote client can’t change the exposure it’s riding on.