Docs
Remote access
How your phone and laptop reach mobd on the office computer: on the office network, or from anywhere. Set the route up once, then pair each device with mobd link.
Choose a method
| Same network | Tailscale Serve | Cloudflare Tunnel | Tailscale Funnel | |
|---|---|---|---|---|
| Works from | office network only | anywhere | anywhere | anywhere |
| App on the phone | none | Tailscale | none | none |
| You need | nothing | a Tailscale account | a Cloudflare account and a domain | a Tailscale account |
| Who can reach mobd | your network | only your devices | anyone, pairing required | anyone, pairing required |
| Who can read traffic | your network (plain HTTP) | only you | you and Cloudflare | only you |
| Live view | WebRTC | WebRTC | WebSocket | WebSocket |
| Speed | fastest | fast when direct | good | slower (relayed) |
- Start with the same network. It needs no setup and is the fastest.
- To use Mob from anywhere, choose Tailscale Serve if you're happy to run the Tailscale app on your phone: only your devices can reach mobd. Otherwise choose Cloudflare Tunnel.
- Funnel is for occasional use without a domain; it's slower than the others.
Whatever you choose, every device must pair: an address alone gives nobody access to mobd.
Same network (LAN)
For devices on the office Wi-Fi. On the office computer:
mobd link
Without remote access set up, it prints the office computer's network address with a QR code: http://<name>.local:8080 on a Mac, the computer's network IP on Linux, such as http://192.168.1.20:8080. Scan it in Mob (Settings → Machines → Add machine). Once remote access is set up, mobd link uses that address instead; mobd link --lan always gives the network one.
- mobd must listen on the network.
mobd initsets"listen": "0.0.0.0:8080". If yours is127.0.0.1:8080,mobd linksays so instead of printing a code that cannot work. - It is plain HTTP. Use it on a network you trust, never forward port 8080 to the internet.
- Firewall: on macOS, if the firewall asks, allow mobd to accept incoming connections. On Linux, open port 8080 and UDP 9527 to your network (how).
Tailscale Serve
Your devices join a private network (a tailnet) with the office computer. mobd gets an HTTPS address that only they can reach, and the live view keeps WebRTC.
What you need
- Tailscale on the office computer and on each device, signed in to the same account. On Linux:
curl -fsSL https://tailscale.com/install.sh | sh, thensudo tailscale up. - In the admin console → DNS: MagicDNS and HTTPS Certificates turned on.
Set it up
mobd remote setup --tailscale
It checks Tailscale is installed and signed in and that HTTPS is on, shows the tailscale serve command and asks before running it, then checks the new address reaches this mobd and saves it. Then pair each device with Tailscale switched on:
mobd link
By hand
sudo tailscale serve --bg --https=443 http://127.0.0.1:8080 tailscale serve status
The status shows the address, such as https://office.your-tailnet.ts.net. Pair with it, without :8080: mobd link --url https://office.your-tailnet.ts.net. With the Tailscale app on macOS, sudo is not needed. On Linux, sudo tailscale set --operator=$USER once lets your user run it without sudo.
Check it is direct
tailscale ping your-phone
via direct or via an address and port means the device talks to the office computer directly. via DERP(…) means it goes through a Tailscale relay: it works, but requests can take seconds when the relay is far away. Give it a minute, or try another network.
Only your devices (access control)
In access controls, allow only your devices to reach TCP 443 and UDP 9527 on the office computer: 443 carries conversations and pairing, 9527 the live view over WebRTC. With 443 only, the live view uses WebSocket.
Turn it off
mobd remote off, or by hand sudo tailscale serve --https=443 off. Paired devices stay paired.
Cloudflare Tunnel
Your devices reach mobd at an HTTPS address on your own domain, with no app besides Mob. The office computer runs cloudflared, which connects out to Cloudflare, so it needs no public IP or open port. The tunnel carries no UDP, so the live view uses the WebSocket stream.
What you need
- A Cloudflare account and a domain whose DNS is on Cloudflare; below,
mob.example.com. - In the Cloudflare dashboard, Zero Trust → Networks → Tunnels: create a Cloudflared tunnel, environment macOS or Debian, and copy the token from the install command it shows.
- On the tunnel, add a public hostname:
mob.example.com, service type HTTP, URL127.0.0.1:8080. HTTP, not HTTPS: Cloudflare provides the certificate.
Set it up
mobd remote setup --cloudflare --hostname mob.example.com
It asks for the token without showing it, installs cloudflared if needed (Homebrew on macOS, Cloudflare's apt repository on Debian and Ubuntu), installs it as a service that starts at boot (asking before each command), waits for the tunnel, checks https://mob.example.com reaches this mobd and saves it. Then pair each device:
mobd link
By hand
Install cloudflared: on macOS brew install cloudflared; on Debian and Ubuntu from Cloudflare's apt repository; elsewhere from Cloudflare's downloads. Then:
sudo cloudflared service install YOUR_TUNNEL_TOKEN mobd link --url https://mob.example.com
The tunnel shows Healthy in the dashboard once cloudflared is connected.
If devices only use the tunnel, set listen to 127.0.0.1:8080 and run mobd restart, so the unencrypted port isn't open on your network. Keep the tunnel token secret; regenerate it in the dashboard if it leaks.
Turn it off
mobd remote off removes the service from the office computer (by hand: sudo cloudflared service uninstall). The tunnel and hostname stay in your Cloudflare account until you delete them there. Paired devices stay paired.
Tailscale Funnel
A public HTTPS address from Tailscale for devices without the Tailscale app, with no domain needed. Traffic always goes through Tailscale's relays, so requests can take seconds when they are far away. mobd remote doesn't set it up; by hand:
sudo tailscale funnel --bg --https=443 http://127.0.0.1:8080 sudo tailscale funnel status mobd link --url https://office.your-tailnet.ts.net
Serve and Funnel cannot share a port. To move to Serve once your devices have Tailscale, run sudo tailscale funnel --https=443 off, then the Serve setup; the address stays the same, so devices stay paired. See Tailscale Funnel.
At the office and away
An office computer can have more than one address: the fast network address at the office and a remote one for elsewhere. Scan a code for each:
mobd link --lan # scan: the office network address mobd link # scan: the remote address
The second code for the same computer adds its address to its row in Settings → Machines, labelled LAN or Remote; there is still one row, with the same conversations. The row shows which route is in use and whether it answers. To switch, long-press the computer in the list (on the desktop app, click the route next to its name), or tap the route under the chat title. When the route in use doesn't answer, Mob shows LAN not reachable · Use Remote; it never switches by itself. Each address is paired on its own, so the device credential only goes to addresses it was paired on.
With Tailscale or Cloudflare the remote address also works at the office, so one address is often enough. The LAN address mainly makes the live view faster at your desk.
Security
- Every request needs a paired device. Without its credential, mobd answers nothing but the pairing request, whatever the route.
- Pairing is closed unless you open it.
mobd linkcreates one invitation: 256-bit, one use, valid for 10 minutes, and only on the office computer. With no open invitation, mobd refuses every pairing attempt and logs it. Runmobd link --closeonce your device is added. - A public address (Cloudflare Tunnel, Funnel) is reachable by anyone but useless without pairing. Keep mobd up to date. For Cloudflare, you can add a rate-limiting rule for
/pairunder Security → WAF. - Who can read the traffic: on the office network it is plain HTTP. Tailscale encrypts end to end. Cloudflare ends TLS on its servers, so invitations, credentials, conversations and the live view pass through it decrypted; if that isn't acceptable, use Tailscale Serve.
- A lost device:
mobd clients list, thenmobd clients revoke CLIENT_ID. It is cut off on every route at once. - Don't put Cloudflare Access in front of mobd for now: Mob can't sign in to it yet.
Problems
Start with this on the office computer. It shows the remote address and checks it reaches this mobd:
mobd remote
Mob says “Cannot reach mobd” or “mobd did not answer in time”
- On the office computer,
mobd statusandmobd logs: is mobd running? - LAN address: is the device on the office network? Guest Wi-Fi often keeps devices apart. On Linux, check the firewall.
- Tailscale: is Tailscale on and connected on the device? iPhone and iPad run one VPN at a time.
tailscale pingshould show a direct path. - Away from the office on the LAN address: Mob shows LAN not reachable · Use Remote; switch to the remote address.
HTTP 502
The route works but mobd doesn't answer behind it: mobd isn't running, or Serve or the tunnel's hostname points at a port other than mobd's (http://127.0.0.1:8080).
Cloudflare error 1033
cloudflared isn't running or can't reach Cloudflare. Check the tunnel's status in the dashboard, and the service on the office computer: sudo launchctl list | grep cloudflared on macOS, systemctl status cloudflared on Linux.
“Answers, but not as this mobd”
mobd remote reached the address, but another program answered: often something else on port 8080 of the office computer. lsof -nP -iTCP:8080 -sTCP:LISTEN (macOS) or sudo ss -ltnp 'sport = :8080' (Linux) lists what listens there; move that program to another port.
Chat works, but the live view is slow
Over Cloudflare Tunnel and Funnel the live view always uses the WebSocket stream. Over Tailscale it uses WebRTC on UDP 9527; if your access control or a firewall blocks UDP, it falls back to WebSocket too.
The pairing link is “invalid, expired or already used”
Invitations last 10 minutes and work once. Run mobd link again and scan the new code.
Still stuck? See FAQ & help, or report a problem.