Pick a network path so your phone can reach OpenCode.
KKCode can connect through a local address, a private VPN, an HTTPS tunnel, a reverse proxy, or the built-in QR tunnel. The app needs an OpenCode API base URL — it does not require a specific tunnel provider.
Connection requirements
Every method supplies the same three values:
- Server URL — origin plus any required API path prefix (for example
https://dev.example.com/api). - Username — the value of
OPENCODE_SERVER_USERNAME. - Password — the value of
OPENCODE_SERVER_PASSWORD.
Missing protocol is normalised, configured path prefixes are preserved, optional HTTP Basic authentication is added, and session, file, and event requests are scoped to the selected project.
Method 1 — trusted local network
Use this when the phone and the OpenCode machine are on the same private Wi-Fi or LAN.
export OPENCODE_SERVER_USERNAME=your-user
export OPENCODE_SERVER_PASSWORD='use-a-strong-password'
opencode serve --hostname 0.0.0.0 --port 4096
Find the machine's private address, then enter a URL such as http://192.168.1.20:4096 in KKCode. Allow TCP port 4096 only on the private-network firewall profile. Do not forward this port through your router, and never use this approach on an untrusted network.
Method 2 — Tailscale
Tailscale keeps the OpenCode process bound to loopback while providing a private HTTPS address inside your tailnet. This is the preferred default when only your own devices need access.
Start OpenCode on loopback:
export OPENCODE_SERVER_USERNAME=your-user
export OPENCODE_SERVER_PASSWORD='use-a-strong-password'
opencode serve --hostname 127.0.0.1 --port 4096
Publish it inside the tailnet:
tailscale serve --bg 4096
tailscale serve status
The status output gives an address similar to https://machine-name.tailnet-name.ts.net. Install Tailscale on the iPhone, sign in to the same tailnet, and enter that HTTPS address in KKCode.
Verify from a tailnet-connected device:
curl -u your-user:use-a-strong-password \
https://machine-name.tailnet-name.ts.net/global/health
Method 3 — Cloudflare Tunnel
Cloudflare Tunnel provides a public HTTPS address without router port forwarding. Because the hostname is publicly reachable, OpenCode authentication is mandatory. Prefer Tailscale when access only needs to work between your own devices.
Quick tunnel — for short testing:
cloudflared tunnel --url http://127.0.0.1:4096
Cloudflare prints a temporary public HTTPS URL. Enter that URL in KKCode and keep OpenCode authentication enabled.
Named tunnel — for a stable hostname:
cloudflared tunnel login
cloudflared tunnel create opencode-mobile
cloudflared tunnel route dns opencode-mobile opencode.example.com
Example configuration:
tunnel: opencode-mobile
credentials-file: /home/your-user/.cloudflared/<tunnel-id>.json
ingress:
- hostname: opencode.example.com
service: http://127.0.0.1:4096
- service: http_status:404
Then run cloudflared tunnel run opencode-mobile and use https://opencode.example.com in KKCode.
Method 4 — reverse proxy or API path prefix
KKCode accepts a base URL with a prefix, for example https://dev.example.com/api. With that setting, health and session calls stay under the prefix, and the SSE stream and any terminal channel switch to wss: automatically for HTTPS origins.
Use this form when:
- The
/path serves a web application instead of the OpenCode API. - A proxy mounts OpenCode under
/apior another subpath. - KKCode reports that the server returned HTML, a JSON parse error, 404, or another non-API response.
Do not append /api blindly. Verify the resulting /global/health endpoint first.
Method 5 — built-in QR tunnel
If you do not want to manage Tailscale, Cloudflare, or a reverse proxy, run the KKCode agent on the dev machine:
npx -y @kkcode-app/agent@latest
It starts opencode serve, opens a relay tunnel, and prints a QR code. Scan the code in KKCode and the connection screen is filled in automatically. Works across cellular and Wi-Fi, no router config, no public IP.
Security guidance by method
| Method | Exposure | Minimum guidance |
|---|---|---|
| LAN | Private network | Use auth, trusted Wi-Fi, and a private firewall rule |
| Tailscale | Tailnet only | Keep auth enabled and restrict tailnet membership/ACLs |
| Cloudflare Tunnel | Public HTTPS URL | Always use OpenCode auth; treat the URL as public and disposable |
| Reverse proxy | Depends on proxy | Use HTTPS, preserve streaming behavior, require OpenCode auth |
| Built-in QR tunnel | Outbound relay | Keep auth enabled; rotate the password if the QR is leaked |