Guides
Phone relay & remote
vmux relay speaks the community
Cmux Remote HTTP and WebSocket protocol. Point
that iPhone app at your Tailscale IP and the relay port (default 4399, configurable) and
you can drive vmux workspaces and panes from your phone.
iPhone (Cmux Remote) ── Tailscale ──► vmux relay :port ── Unix socket ──► vmux daemon
(default 4399)
This is a compatibility layer, not an official Manaflow product. Official cmux Mobile Connect is a different stack and will not work with it. Protocol drift in the App Store app may require relay updates.
The relay is on by default. On vmux attach, a managed relay starts if it is
not already running (bind: Tailscale IP when available, otherwise localhost). Starting or stopping the
relay does not change how attach, the CLI, or the daemon behave beyond that process.
The port is not fixed
The historical Cmux Remote default is 4399, and vmux uses that out of the box — but the port is not hard-wired.
| How | Example |
|---|---|
| Config (managed relay / attach auto-start) | vmux config set relay.port 4400 |
| CLI override | vmux relay serve --listen 100.x.y.z:4400 |
relay.json listen | "listen": "127.0.0.1:4400" |
Whatever you choose, the phone app (and paste-page URLs) must use the same port.
The managed phone relay is machine-global, not per vmux --session. Session
default and session dev share the same config port and the same process — a
second attach sees "already running" and reuses it. That is intentional: the phone app points at one
host:port.
Settings
In vmux attach, open ⚙ set and find the mobile relay section:
| Setting | Meaning |
|---|---|
| mobile relay | on / off (default on) |
| relay bind | auto (Tailscale if online, else localhost), tailscale, or local |
| relay port | TCP port (default 4399) |
| relay localhost | Allow device registration from 127.0.0.1, for dev |
| paste page | Serve /paste for screenshot paste |
| phone-fit resize | Leased view-size overrides (relay.allow_view_resize) |
Changing relay port / bind / toggles stays pending until you move to another row or
close Settings — config is then saved once and the managed relay restarted once, no multi-second lag
while cycling ports. There is deliberately no "all interfaces" option: the relay refuses to bind
0.0.0.0 or ::.
vmux config set relay.enabled true # default
vmux config set relay.bind auto # auto | tailscale | local
vmux config set relay.port 4399
vmux config set relay.allow_localhost false
vmux config set relay.allow_paste true
vmux config set relay.allow_view_resize false
Running it by hand
vmux relay serve
vmux relay serve --listen 127.0.0.1:4400
vmux relay serve --allow-localhost --listen 127.0.0.1:4399
vmux relay status
vmux relay devices list
vmux relay devices revoke <device_id>
Pairing a phone
- Install Cmux Remote, or another client that speaks the same wire protocol.
- Run Tailscale on the phone and on the host, on the same tailnet.
- On the host, run
vmux relay serve(or attach withrelay.enabled). - In the app, set host to your
tailscale ip -4address and the relay port. - Pair, list workspaces, open a surface.
PORT=4399
curl -s http://$(tailscale ip -4):${PORT}/v1/health
# {"ok":true,"version":"…","backend":"vmux",…}
Phone-fit pane sizing
Off by default — a phone glancing at a pane must not resize it under whoever is at the desk.
vmux config set relay.allow_view_resize true
Once enabled, the PTY runs at min(desktop layout, phone view) per axis — tmux's "smallest
client wins", scoped to the one pane being viewed. The lease re-signs on every poll cycle and expires
~10s after the phone vanishes, so the pane always returns to its desktop size by itself. The desktop
attach UI dims the pane's unused margin with a "sized by phone" note while an override is active.
Pasting screenshots over SSH
Claude Code's Ctrl+V image paste reads the clipboard of the machine it runs on. When you SSH into a box running vmux, your screenshot is on your laptop — vmux bridges that two ways.
The paste page — nothing to install. With the relay running, open
http://<host>:<port>/paste in any browser on your tailnet and press
Cmd+V/Ctrl+V (or drop an image file). The relay saves the image on the host and
types its path into the active pane. Works from a phone too, photo picker included.
vmux send-image — for the terminal, pipes image bytes over SSH:
# macOS (brew install pngpaste)
pngpaste - | ssh yourbox vmux send-image -
# Linux: wl-paste --type image/png (Wayland) or
# xclip -selection clipboard -t image/png -o (X11)
ssh yourbox vmux send-image - < ~/Desktop/Screen*.png
For both, --pane pane-2 / ?pane=pane-2 targets a specific pane and
--enter / ?enter=1 submits immediately. Uploads land in
~/Downloads/vmux-remote/, capped at 16 MiB.
Turn the paste page off entirely (/paste and /v1/paste then 404):
vmux config set relay.allow_paste false