Get your opencode server ready
Saffron OC talks to opencode's built-in server over your network. One command starts it; this guide makes sure it stays reachable after you close the laptop lid or the SSH session.
Start the server
On the machine where your code lives, pick a password and start opencode listening on the network:
OPENCODE_SERVER_PASSWORD="choose-a-password" \
opencode serve --hostname 0.0.0.0 --port 4096The password becomes the app's login. Saffron OC signs in with username opencode and whatever you set here, and keeps it in your iPhone's Keychain.
Find your machine's address
The app needs the server's address on your network. Ask the machine itself:
ipconfig getifaddr en0 # Wi-Fi (try en1 if this is empty)hostname -I | awk '{print $1}'In Saffron OC, add a server with that address, port 4096, username opencode and your password, then hit Test Connection. Green means go.
A quick sanity check from any other machine on the network, if you like proof before reaching for the phone:
curl -u opencode:choose-a-password http://192.168.1.42:4096/global/healthKeep it running when you walk away
If you start the server in an SSH session and the session ends, the server dies with it. Give it a terminal that survives you leaving.
With tmux
# start the server in a detached session named "opencode"
tmux new -s opencode -d \
'OPENCODE_SERVER_PASSWORD="choose-a-password" opencode serve --hostname 0.0.0.0 --port 4096'
tmux attach -t opencode # look in on it any time
# detach again with Ctrl-b then d, and it keeps runningWith screen
screen -dmS opencode \
bash -c 'OPENCODE_SERVER_PASSWORD="choose-a-password" opencode serve --hostname 0.0.0.0 --port 4096'
screen -r opencode # reattach
# detach again with Ctrl-a then dEither way the server now belongs to the session, not to you. Fly somewhere, reattach next week: still running.
Stop the machine from sleeping
A sleeping Mac answers nobody. If the server machine is a laptop or a desktop with sleep enabled, hold it awake while the server runs:
caffeinate -sim & # no sleep while on power; kill it when you're doneFor a machine that should serve around the clock, skip the terminal tricks and make it a service instead: launchd on macOS or a systemd user unit on Linux restarts the server after reboots too. A minimal systemd example:
[Unit]
Description=opencode server
[Service]
Environment=OPENCODE_SERVER_PASSWORD=choose-a-password
ExecStart=/usr/local/bin/opencode serve --hostname 0.0.0.0 --port 4096
Restart=on-failure
[Install]
WantedBy=default.targetsystemctl --user enable --now opencode
loginctl enable-linger $USER # keep it running while you're logged outStay on trusted networks
Reach it from anywhere
Away from home, your phone needs a private path back to the server. Two products do this well; both are free for personal use.
Tailscale (recommended)
A mesh VPN: every device you sign in gets a private address on the same network, wherever it is. Nothing about the server changes, traffic goes device to device, encrypted with WireGuard, and Tailscale's own servers only help the two ends find each other.
- Install Tailscale on the server machine from tailscale.com/download and run
tailscale up. - Install the Tailscale app on your iPhone and sign in to the same account.
- Ask the server for its Tailscale address, then bind opencode to it so nothing else can reach the port:
tailscale ip -4 # e.g. 100.101.102.103
OPENCODE_SERVER_PASSWORD="choose-a-password" \
opencode serve --hostname 100.101.102.103 --port 4096In Saffron OC, add a server with that 100.x address (or the machine's MagicDNS name) and port 4096. It works on the couch and on the train alike, as long as the Tailscale toggle on the phone is on.
Cloudflare Tunnel
If you would rather not run a VPN on the phone, Cloudflare Tunnel opens an outbound connection from the server to Cloudflare's edge and serves it at a hostname on a domain you own, over HTTPS, with no port opened on your router. The trade-off: Cloudflare terminates TLS, so your traffic passes through their network in the clear, and the hostname is reachable by anyone who can guess it. Put Cloudflare Access in front of it or, at minimum, keep a strong opencode password.
brew install cloudflared # or the package for your OS
cloudflared tunnel login
cloudflared tunnel create opencode
cloudflared tunnel route dns opencode oc.example.com
cloudflared tunnel run --url http://localhost:4096 opencodeIn Saffron OC, add the server as oc.example.com, port 443, with HTTPS switched on. The full walkthrough is in Cloudflare's docs.
Other routes
- Plain WireGuard or your router's VPN (UniFi, OPNsense, Fritz!Box): same idea as Tailscale, more setup, nothing in the middle.
- A reverse proxy with TLS (Caddy, nginx) in front of the server on a machine you already expose, with HTTPS turned on in the app. Saffron OC can pin a self-signed certificate the first time it sees one.
If the app can't connect
- Confirm the server is up and bound to the network:
--hostname 0.0.0.0, not the default loopback. - Phone and server on the same Wi-Fi or VPN? Guest networks often isolate devices.
- A firewall on the server machine may be eating port 4096. On macOS check System Settings → Network → Firewall; on Linux,
ufw allow 4096. - Run the
curlcheck above from another machine. If curl fails too, it's the server side; if curl works, re-check the address and password in the app.
Still stuck? Tell us what you tried and we'll dig in with you.