| name | setup-cloudflare-tunnel |
| description | Walk the user through bringing up a Cloudflare quick-tunnel to expose their local @threadbase/streamer to tb-mobile. Drives scripts/remote-access/cloudflare.sh (or .ps1 on Windows / when pwsh is preferred), explains the quick-tunnel-vs-named-tunnel tradeoff, and — if asked — guides the upgrade to a persistent named tunnel with optional Cloudflare Access. Use when the user says "expose my streamer", "set up a tunnel", "let my phone reach my streamer from outside the LAN", "set up cloudflared", "set up Cloudflare Tunnel", "I want a public URL for the streamer", or asks how to onboard tb-mobile remote pairing. The full reference lives in docs/guides/remote-access/README.md and docs/guides/remote-access/cloudflare.md — read those first before going beyond the happy-path setup. |
Set up a Cloudflare quick-tunnel for the streamer
The streamer binds to 127.0.0.1:8766 and isn't reachable from the network. To pair the mobile app from outside your LAN, you need a tunnel forwarding HTTPS traffic to that local port. A Cloudflare quick-tunnel is the fastest start — no account, no domain, ~30 seconds — and that's what this skill handles. Graduating to a persistent named tunnel (with optional Cloudflare Access) is a separate step the user can opt into at the end.
Authoritative references — read these before going beyond the happy path:
Step 1 — Make sure the streamer is actually running
curl -s http://127.0.0.1:8766/healthz
Should print {"ok":true,...} with a version. If it doesn't, fix that first — the tunnel will be 502-ing if there's nothing on 8766. Send the user to local-deploy skill or scripts/deploy.sh to bring the streamer up.
Step 2 — Pick the runner
Prefer the Go TUI when go is on PATH — it renders progress more clearly. Otherwise run the shell script directly. Both produce identical results.
command -v go >/dev/null 2>&1 && echo "go available" || echo "no go — use plain scripts"
With Go TUI:
cd scripts/remote-access/tui
go run .
Plain bash (macOS / Linux / WSL / Git Bash):
bash scripts/remote-access/cloudflare.sh
Plain pwsh (Windows native, or macOS/Linux with pwsh installed):
pwsh scripts/remote-access/cloudflare.ps1
The script will:
- Check
cloudflared is installed. If not, it prints the install command for the current OS and exits non-zero — install per its hint, then re-run.
- Start a tiny throwaway HTTP server on a free port (8767–8776) serving a "✅ you made it" page.
- Start
cloudflared tunnel --url http://127.0.0.1:<that-port> and parse the *.trycloudflare.com URL out of its output.
- Print the URL big and ask the user to open it on their phone.
- On
y confirmation (or Ctrl-C), tear down the tunnel and the HTTP server.
The protocol lines (STATUS:, URL:, PROMPT:, DONE:) are intentional — you can parse them to drive your own UI if the user is running you in a non-interactive context.
Step 3 — Explain what just happened (and what to do next)
When DONE: ok lands, give the user three points:
- That URL is gone now. The script tore down the tunnel. Quick-tunnel URLs rotate per run; the next
cloudflared tunnel --url ... invocation will get a different *.trycloudflare.com.
- The streamer's Bearer auth was the only gate. Quick-tunnels can't be put behind Cloudflare Access — Access requires a hostname in a Cloudflare zone you own, and
trycloudflare.com isn't yours. This is fine for a 5-minute pairing flow; not fine for always-on exposure.
- For persistent + protected exposure, graduate to a named tunnel. Offer to walk them through it — see Step 4.
If DONE: aborted or DONE: error, the script already tore everything down. Check the STATUS: ERROR: lines and the tail of cloudflared's log (the script prints both on failure). Common causes:
cloudflared not on PATH (Step 2's install hint not followed).
- Port 8767–8776 all taken (unusual). Re-run; the bash script falls back to a free port via python.
- Outbound 443 blocked by firewall (corporate networks). Try a different network.
Step 4 (optional) — Graduate to a named tunnel
Only do this if the user explicitly asks. Quick-tunnel is the right answer for "does the mobile pairing work?" — named tunnel is the right answer for "I want this URL to keep working tomorrow."
Walk through the checklist in docs/guides/remote-access/cloudflare.md → Phase 2 — Named tunnel:
cloudflared tunnel login
cloudflared tunnel create tb-streamer
cloudflared tunnel route dns tb-streamer tb-pc.example.com
cloudflared tunnel run tb-streamer
sudo cloudflared service install
Prerequisites: a Cloudflare account + a domain whose DNS is on Cloudflare. The user must own the domain — Access policies and persistent hostnames both require it.
Once the named tunnel works, set the public hostname on the streamer so the pairing QR encodes it:
public_url: https://tb-pc.example.com
Don't write public_url: for a quick-tunnel. Quick-tunnel URLs rotate per run; pinning one will silently break pairing on the next launch. The docs say this; this skill enforces it.
Platform gotchas worth a one-line callout
- macOS: pick LaunchDaemon (
sudo cloudflared service install) OR LaunchAgent (no sudo), not both. Running both produces duplicate connectors in the Cloudflare dashboard.
- Windows:
Restart-Service cloudflared after editing config.yml. The service caches the config at start.
- macOS LaunchDaemon reads
/etc/cloudflared/, not ~/.cloudflared/ — copy config.yml and the credentials JSON over if you went the sudo route.
Step 5 (optional, advanced) — Cloudflare Access
Once the named tunnel is up, the user can put Cloudflare Access in front of it for identity-based protection (Google SSO, GitHub, email-OTP, service tokens). This is what tb-pc.rbv1000.win in this repo uses.
This is out of scope for the quick-tunnel onboarding flow. Point at docs/guides/remote-access/cloudflare.md → Phase 3 — Cloudflare Access and leave the policy authoring to the dashboard. Important caveat the user needs to know: the mobile app sends a Bearer token, not interactive login — so Access policies will need a Service Token rule (or the Access app needs to be off for the mobile-facing endpoint) for tb-mobile to pair through it.
What this skill won't do
- It won't write
public_url: into ~/.threadbase/server.yaml without explicit confirmation. Mis-pinning a quick-tunnel URL there is the most common foot-gun. If the user asks for a persistent hostname, Step 4 first.
- It won't bypass
cloudflared's install step. If command -v cloudflared fails, instruct the user to install it; don't try to download a binary directly.
- It won't touch any of the deploy scripts (
scripts/deploy.sh, scripts/deploy.ps1, scripts/deploy-linux.sh). Tunnel onboarding lives in scripts/remote-access/ deliberately to keep deploy in flight unaffected.