REMOTE.md
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
| 1 | flowchart LR |
| 2 | subgraph ClientMachine[Client Machine] |
| 3 | Web[Web App\n(React/Vite)] |
| 4 | Desktop[Desktop App\n(Electron Renderer)] |
| 5 | end |
| 6 | |
| 7 | subgraph RemoteMachine[Remote Machine] |
| 8 | Server[T3 Server\n(HTTP + WS RPC)] |
| 9 | Codex[Codex App Server\n(JSON-RPC over stdio)] |
| 10 | end |
| 11 | |
| 12 | Web -- "wss/ws + token auth" --> Server |
| 13 | Desktop -- "wss/ws + token auth" --> Server |
| 14 | Server -- "stdio JSON-RPC" --> Codex |
Connection Modes
1) SSH Tunnel (recommended for operator security)
Run remote server loopback-only:
| 1 | T3CODE_HOST=127.0.0.1 T3CODE_PORT=3773 T3CODE_AUTH_TOKEN=<token> bun run start |
From client machine, forward port:
| 1 | ssh -L 3773:127.0.0.1:3773 <user>@<remote-host> |
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.
- Install and log in to Tailscale on both machines.
- Verify the two machines can reach each other over tailnet:
| 1 | tailscale status |
- On the remote machine, run T3 loopback-only:
| 1 | T3CODE_HOST=127.0.0.1 T3CODE_PORT=3773 T3CODE_AUTH_TOKEN=<token> bun run start |
- From your client machine, create an SSH local-forward over Tailscale:
| 1 | ssh -N -L 3773:127.0.0.1:3773 <user>@<remote-tailnet-name-or-100.x.y.z> |
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:<web-port>/?t3WsUrl=ws://127.0.0.1:3773&t3Token=<token> - Desktop:
| 1 | T3CODE_REMOTE_WS_URL=ws://127.0.0.1:3773 T3CODE_REMOTE_WS_TOKEN=<token> bun run start:desktop |
Notes:
- If you use Tailscale SSH, the same
ssh -Lpattern 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:
| 1 | T3CODE_HOST=0.0.0.0 T3CODE_PORT=3773 T3CODE_AUTH_TOKEN=<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, optionalVITE_WS_TOKEN - Runtime URL params:
t3WsUrl,t3Token
Examples:
| 1 | https://web-host/?t3WsUrl=wss://api.example.com&t3Token=secret |
| 2 | https://api.example.com/?t3Token=secret |
Notes:
- If
t3WsUrlishttp://orhttps://, it is normalized tows://orwss://. - 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:
| 1 | 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 <token>header (non-browser clients)
New/Relevant Env Vars
- Server:
T3CODE_HOSTT3CODE_PORTT3CODE_AUTH_TOKEN
- Web:
VITE_WS_URLVITE_WS_TOKEN
- Desktop:
T3CODE_REMOTE_WS_URLT3CODE_REMOTE_WS_TOKEN