Mobile AI Bridge
Saga the Watchful — Seneschal
By the end of this chapter you’ll understand:
- How a one-time pairing flow binds an iOS device to the local macOS AI daemon using a short-lived PIN
- How every subsequent request is authenticated and forwarded through the Cloudflare Worker tunnel
- Why the versioned command envelope makes the bridge extensible without breaking existing clients
The core idea
The macOS AI daemon runs claude locally — there is no cloud AI subscription billed per request, and no transcript leaves the household. The problem is that the iPhone cannot reach a process running on a LAN Mac directly. The solution is a Cloudflare Worker sitting at ai-bridge.casaconomy.com that acts as a secure relay. The daemon opens an outbound tunnel to Cloudflare (via cloudflared). When iOS sends a request to the Worker, the Worker authenticates it and forwards it down the tunnel.
The Worker is stateless — it verifies the bearer token and proxies. It never stores prompt content or response text.
Pairing
Before iOS can send a request, it needs a bearer token. The pairing flow issues one.
The PIN is a six-digit code the regent reads from the Mac and types into the iPhone. It expires in five minutes. A successful pairing stores two items in iOS Keychain: the bearer token (used for authentication) and the daemon’s X25519 public key (reserved for future end-to-end encryption). Re-pairing clears and replaces both items.
Command envelope
All bridge calls use a versioned command envelope. The version field lets the daemon evolve its command set without breaking older iOS clients.
{ "command": "ai_chat", "version": 1, "payload": { "conversation_id": "uuid-or-client-id", "message": "user prompt" }}If the daemon does not recognise a command, it returns HTTP 400 with a typed error that names the unsupported command and lists what it does support. iOS shows an informative banner and does not crash or spin.
Dispatcher pattern
The daemon handles commands through a match-based dispatcher. Adding a new command means adding one match arm and one handler — existing commands are untouched and their contracts do not change. This keeps the bridge extensible: a new capability (for example, an image-analysis command) is one CAS, not an architectural change.
Security model
| Surface | Control |
|---|---|
| Bearer token | Issued at pairing; stored in iOS Keychain; verified by Worker on every request |
| cloudflared tunnel | Outbound-only from Mac; Cloudflare terminates TLS at the edge |
| Prompt content | Never logged by the Worker or stored on Cloudflare |
| Server public key | Pinned in Keychain at pairing; reserved for future E2E encryption layer |
| Re-pair | Clears and replaces Keychain items; old token is invalidated |
The Worker and daemon logs must not include prompt body or secret tokens. This is verified during incident review when wrangler tail is used for diagnostics.
Worked example
- Regent opens the bug-report sheet on iPhone.
- The sheet calls
POST https://ai-bridge.casaconomy.com/v1/chatwithAuthorization: Bearer <token>and a body of{"command":"ai_chat","version":1,"payload":{"conversation_id":"...","message":"the bug description"}}. - The Cloudflare Worker validates the bearer token. On success, it forwards the request body down the cloudflared tunnel to the Mac daemon.
- The Mac daemon dispatches on
"ai_chat", invokes theclaudeCLI with the prompt, and streams the response back through the tunnel. - The Worker streams the response back to iOS.
- The bug-report sheet displays the streamed response in the chat UI.
- If the Mac is offline, the Worker receives a connection error from the tunnel and returns
HTTP 503 {"code":"bridge_offline"}. iOS shows an offline banner immediately — no spinner hang.
iPhone log capture quick path
For incident reports from TestFlight/iPhone, collect diagnostics in this order:
- About path (copy only):
Settings→About→ Copy diagnostic logs. - Bug-report path (submit): open bug-report sheet and submit; the same recent diagnostic log lines are now attached automatically in the GitHub issue diagnostics comments.
- Escalation artifact: paste the copied logs into the CAS if the app cannot submit the report itself.
Recap
- The bridge is a Cloudflare Worker that authenticates bearer tokens and proxies requests through a cloudflared tunnel — the Mac never opens a public port.
- Pairing issues a bearer token via a six-digit PIN with a five-minute TTL; re-pairing invalidates the old token and replaces both Keychain items.
- The versioned command envelope (
command+version+payload) lets the daemon add new capabilities without breaking existing iOS clients.
What changed {#what-changed}
This chapter was introduced in CAS-3637 Phase 3 (The Casaconomy Book) as the canonical reference for the Mobile AI Bridge.