# Remote T3 Architecture (PoC) ## Summary This PoC supports running `apps/server` on a remote machine and connecting both frontend clients to it: - Browser web app (via env or runtime URL params) - Electron desktop app (remote mode; no local backend spawn) ## Final Architecture ```mermaid flowchart LR subgraph ClientMachine[Client Machine] Web[Web App\n(React/Vite)] Desktop[Desktop App\n(Electron Renderer)] end subgraph RemoteMachine[Remote Machine] Server[T3 Server\n(HTTP + WS RPC)] Codex[Codex App Server\n(JSON-RPC over stdio)] end Web -- "wss/ws + token auth" --> Server Desktop -- "wss/ws + token auth" --> Server Server -- "stdio JSON-RPC" --> Codex ``` ## Connection Modes ### 1) SSH Tunnel (recommended for operator security) Run remote server loopback-only: ```bash T3CODE_HOST=127.0.0.1 T3CODE_PORT=3773 T3CODE_AUTH_TOKEN= bun run start ``` From client machine, forward port: ```bash ssh -L 3773:127.0.0.1:3773 @ ``` Then connect clients to `ws://127.0.0.1:3773` with the same token. ### 1b) Private Tunnel With Tailscale (no public exposure) This keeps your T3 server private to your tailnet and avoids opening router/firewall ports to the public internet. 1. Install and log in to Tailscale on both machines. 2. Verify the two machines can reach each other over tailnet: ```bash tailscale status ``` 3. On the remote machine, run T3 loopback-only: ```bash T3CODE_HOST=127.0.0.1 T3CODE_PORT=3773 T3CODE_AUTH_TOKEN= bun run start ``` 4. From your client machine, create an SSH local-forward over Tailscale: ```bash ssh -N -L 3773:127.0.0.1:3773 @ ``` Now your local machine has a private tunnel at `127.0.0.1:3773` to the remote T3 server. Use clients exactly like local: - Web: `http://localhost:/?t3WsUrl=ws://127.0.0.1:3773&t3Token=` - Desktop: ```bash T3CODE_REMOTE_WS_URL=ws://127.0.0.1:3773 T3CODE_REMOTE_WS_TOKEN= bun run start:desktop ``` Notes: - If you use Tailscale SSH, the same `ssh -L` pattern works. - This model does not expose T3 to the public internet; access is limited by your tailnet + SSH auth + T3 token. ### 2) Direct Authenticated WS Run remote server network-bound: ```bash T3CODE_HOST=0.0.0.0 T3CODE_PORT=3773 T3CODE_AUTH_TOKEN= bun run start ``` Use TLS termination/reverse proxy in front for production internet exposure. ## Client Configuration ### Web App Supported config sources: - Build/dev env: `VITE_WS_URL`, optional `VITE_WS_TOKEN` - Runtime URL params: `t3WsUrl`, `t3Token` Examples: ```text https://web-host/?t3WsUrl=wss://api.example.com&t3Token=secret https://api.example.com/?t3Token=secret ``` Notes: - If `t3WsUrl` is `http://` or `https://`, it is normalized to `ws://` or `wss://`. - If no URL is provided, web falls back to same-origin WS using page protocol. - To avoid putting tokens in request logs/history, prefer fragment form (supported): `#t3WsUrl=...&t3Token=...` ### Desktop App Set remote mode env vars before launch: - `T3CODE_REMOTE_WS_URL` (required for remote mode) - `T3CODE_REMOTE_WS_TOKEN` (optional if URL already includes `?token=`) Example: ```bash T3CODE_REMOTE_WS_URL=ws://127.0.0.1:3773 T3CODE_REMOTE_WS_TOKEN=secret bun run start:desktop ``` When `T3CODE_REMOTE_WS_URL` is set, desktop skips spawning the local server process. ## Auth Behavior Server WS auth now accepts either: - Query token: `?token=...` (browser-compatible) - `Authorization: Bearer ` header (non-browser clients) ## New/Relevant Env Vars - Server: - `T3CODE_HOST` - `T3CODE_PORT` - `T3CODE_AUTH_TOKEN` - Web: - `VITE_WS_URL` - `VITE_WS_TOKEN` - Desktop: - `T3CODE_REMOTE_WS_URL` - `T3CODE_REMOTE_WS_TOKEN`