1# Remote access
2
3Connect a phone, browser, or another desktop app to T3 Code running on a different
4machine. That machine must stay running and reachable while you work.
5
6## T3 Connect
7
8T3 Connect makes an environment available to your other devices without setting
9up router forwarding. In the desktop app on the host, open **Settings →
10Connections**, sign in, and enable **T3 Connect** for that environment.
11
12For a command-line host, run:
13
14```bash
15t3 connect
16```
17
18Follow the sign-in instructions. Setup offers a
19[background service](./background-service.md); if you decline it, start the
20server with `t3 serve`. Saving your sign-in alone does not make the machine
21reachable.
22
23On your other device, sign in to the same T3 Connect account and choose the
24environment. Over SSH, the CLI prints a browser link and a short code. Open the
25link on any device, confirm the code matches, and approve. The CLI continues on
26its own, so you do not need to forward an OAuth callback port.
27
28T3 Connect renews access credentials when needed without disconnecting a healthy
29connection. Pull request diffs and provider settings keep working after the
30previous credential expires. A failed renewal affects that request; it does not
31disconnect an otherwise healthy conversation.
32
33## Pair over a LAN or private network
34
35Use direct pairing when the other device can reach the host's network address.
36
37On a desktop host, open **Settings → Connections**, enable **Network access**,
38then create a pairing link using an address the other device can reach. Changing
39network access restarts the desktop app. You can turn it off in the same place.
40
41For a command-line host, replace `<private-ip>` with the host's LAN or tailnet
42address:
43
44```bash
45t3 serve --host <private-ip>
46```
47
48If a server is already running, generate a fresh link without restarting it:
49
50```bash
51t3 pair
52```
53
54Scan the QR code on your phone or paste the pairing URL into **Add environment**
55in the receiving app. Connection settings are under **Settings → Connections**
56on web and desktop and **Settings → Environments** on mobile. A loopback address
57such as `127.0.0.1` reaches only the device opening the link.
58
59Pairing authorizes that device for future connections. Use a fresh one-time link
60for each new device; you do not need the original token to reconnect. Links
61created in Settings can only be copied from the client that created them while
62its Connections page stays open. If you leave or reload that page, create
63another link to share.
64
65### Reach one machine several ways
66
67A machine can have more than one route: LAN, Tailscale, another VPN, a public
68URL, SSH, or T3 Connect. Tailscale shares its `100.64.0.0/10` address range with
69other VPNs such as Cloudflare WARP, so an address in that range shows as VPN
70unless the machine confirms it is on Tailscale. To add a route, choose **Add
71route** in the machine's route list, or next to it in the T3 Connect list.
72Pairing the same machine again over another address also adds a route instead
73of a second machine. A new route is placed by speed, in that order, and you can
74reorder routes at any time.
75
76While connected through T3 Connect or a paired address, T3 Code also learns the
77machine's current LAN and Tailscale addresses and adds them as routes, so
78pairing once through T3 Connect is enough to use the LAN at home. When the
79machine's LAN address changes, for example after it joins another Wi-Fi network,
80the learned route follows it. The machine must allow network access for its LAN
81address to be learned. You can reorder a learned route, but not remove it; it
82goes away with the route it was learned through, or when the machine stops
83reporting that address.
84
85T3 Code connects over the first route that answers. Away from home, a LAN
86address that does not answer is checked briefly and skipped. It is only tried
87again, after the other routes, if none of them connect. While connected over a
88later route, T3 Code checks the earlier ones when your network changes, when you
89return to the app, and every minute, and moves back as soon as one works.
90
91On web and desktop, select the route count under the machine's name in
92**Settings → Connections** to see its routes. Drag a route to change the order,
93or remove it. On mobile, open the machine under **Settings → Environments** and
94choose **Edit**. Signing out of T3 Connect removes only that route; a machine
95you can still reach another way stays saved.
96
97Open **Permissions** next to **Routes** in web or desktop, or **Your permissions**
98in the mobile route details, to see what your current connection can do on that
99environment. For a remote environment, this is in its route details. Permissions
100shown there apply only to the route marked **In use**; other routes are not
101checked. Direct pairing and T3 Connect have separate sessions and may grant
102different permissions.
103
104### Balance new threads across machines
105
106Auto balance is off by default. On web and desktop, enable it in
107**Settings → Connections → Load balancing** to automatically choose a machine for
108new threads in projects grouped across connected environments. The section
109appears once two or more machines are switched on.
110Each machine starts at **Normal**. Choose **Prefer** to favor it when it has CPU and
111memory available, **Less often** to reduce its share, or **Manual only** to exclude
112it from automatic selection. These are preferences, not fixed traffic percentages.
113Preferences are saved separately in each client.
114
115The composer checks eligible machines when choosing a draft's environment, then keeps
116that choice stable. Choose **Auto balance** again to check current resources, or choose
117a specific machine to override it. Choosing a branch or worktree also keeps the draft
118on that machine. Existing threads stay where they started. If resource checks are
119unavailable or all eligible machines are full, choose a machine manually to continue.
120Mobile keeps its manual environment selection.
121
122### Tailscale HTTPS
123
124Join both devices to the same tailnet. In the desktop app, enable **Tailscale
125HTTPS** in **Settings → Connections**. Turn it off there to remove that route.
126
127To start a command-line server with Tailscale HTTPS:
128
129```bash
130t3 serve --tailscale-serve
131```
132
133For an already-running server:
134
135```bash
136t3 pair --tailscale
137```
138
139The pairing link uses an address such as `https://machine.tailnet.ts.net/`.
140The mapping created by `pair --tailscale` persists across restarts. Remove its
141default-port mapping with:
142
143```bash
144tailscale serve --https=443 off
145```
146
147If that port is already in use, choose another with
148`--tailscale-serve-port`. See `t3 pair --help` for other pairing options.
149
150### Hosted web app
151
152[app.t3.codes](https://app.t3.codes) needs an HTTPS endpoint. It connects directly
153to your server; a hosted pairing link does not make an unreachable backend
154reachable or convert HTTP to HTTPS.
155
156For a plain HTTP LAN endpoint, use the direct pairing URL in a browser that can
157open it, or pair from the desktop app. On mobile, an IP address entered without a
158scheme uses HTTP, so include `https://` when your server uses HTTPS.
159
160## Desktop-managed SSH
161
162In the desktop app, open **Settings → Connections → Add environment**, choose
163**SSH**, and enter a host or SSH alias such as `user@example.com`. T3 Code starts
164or reuses a server there and opens the port forward for you. Projects, provider
165credentials, and agent work stay on the remote machine.
166
167The remote host must be Linux or an Apple Silicon Mac with `curl` or `wget`,
168`tar`, `sha256sum` or `shasum`, and [provider setup](./install.md#providers).
169The first launch downloads T3 Code's server to `~/.t3/runtime` on the host, so
170it takes longer than later ones.
171Provider CLIs must be on the `PATH` of a non-interactive login shell there;
172check with:
173
174```bash
175ssh user@example.com 'sh -lc "command -v claude codex"'
176```
177
178If SSH reconnecting fails after an app update, retry the launch once. Removing
179the connection stops a server that T3 Code launched; a server that was already
180running is left alone.
181
182For Antigravity's Google callback on a remote host, see
183[remote sign-in](./providers-antigravity.md#sign-in-from-a-remote-device).
184
185## Browser on a remote environment
186
187Browser tabs belong to the environment, so you and your agents see the same
188tabs from any device. The desktop app shows its own environment's tabs
189directly. Every other device, and the desktop app for other environments,
190streams them from the host. Agents keep using them while no device is
191connected, and `localhost` addresses reach servers on the host.
192
193The first tab downloads a headless Chrome, about 120 MB, into the T3 home. It
194is the same browser [HTML renders](html-renders.md) use, so a host downloads it
195only once. Some Linux hosts need [setup](#browser-host-setup) before it can
196start.
197
198Agent tabs have separate storage and share a Chromium process. Take control before
199typing into an agent's tab, then release control when you want the agent to
200continue. Read-only connections can watch without changing the page.
201
202While you have control, the tab works with your device: text the page copies or
203cuts goes to your clipboard, a file picker on the page opens your device's
204picker, and a finished download is offered for you to save. Popups such as
205sign-in windows open as their own tabs. Downloads stay on the host until the
206tab closes. Audio does not play on your device.
207
208On a phone, tap the floating preview's corner dot to show its controls, then
209**Pop into separate window** to keep watching in picture-in-picture over other
210apps.
211
212### Browser host setup
213
214macOS, Windows, and Linux desktops run the browser as is. Some Linux hosts need
215one-time setup: Ubuntu 23.10 and later block the sandbox the browser runs in,
216and minimal images and containers lack libraries it loads. When that happens,
217the server says so at startup, and browser tabs and HTML previews show the
218command to run on the host:
219
220```sh
221sudo t3 browser setup
222```
223
224The server shows the exact line for how you started it, such as
225`sudo npx t3 browser setup`, and keeps your `PATH` when Node is installed only
226for your user. Where `t3` is not on your `PATH`, such as with only the
227desktop app installed, it names the full path of the app's own `t3` instead. It allows Chrome's sandbox with an AppArmor profile and installs
228any missing libraries with apt. It is safe to run again. Without `sudo`, it
229only reports what it would change.
230
231The browser always runs in Chrome's sandbox. Where you cannot change the host,
232set `T3CODE_SERVER_BROWSER_SANDBOX=0` for the environment to run without it.
233
234## Connect an outside agent
235
236Claude Code, Codex, ChatGPT and other agents T3 Code did not start can drive
237threads on an environment through its MCP server. See
238[outside agents](./outside-agents.md) for setup.
239
240## Manage or revoke access
241
242On the host, **Settings → Connections** lets authorized administrators create
243pairing links and revoke client sessions. Revoking an unused link prevents new
244pairings; revoke a device's session to remove its existing access. Command-line
245management is available through `t3 auth --help`.
246
247A session with an open connection stays listed after its access credential
248expires.
249
250To choose a token's permissions, pass `--scope` once for each scope you want:
251
252```sh
253npx t3 pair --scope orchestration:read --scope relay:read
254```
255
256The selected scopes replace the default permissions. The same option works with
257`npx t3 auth pairing create` and `npx t3 auth session issue`; each command's
258`--help` lists the available scopes. Without `--scope`, pairing tokens retain
259standard client permissions and issued bearer sessions retain administrative
260permissions.
261
262To change an existing client's permissions, create a fresh pairing link with the
263scopes it needs. In a browser opened directly on the environment, open that link
264to replace the browser's current grant. For mobile or a saved remote environment
265in web or desktop, use **Add Environment** with the fresh link or code; pairing
266the same environment replaces its saved grant. Reconnecting alone does not change
267permissions.
268
269Grouping checkouts does not combine their permissions. Shared project settings
270require `orchestration:operate` on every member environment; actions on one
271checkout use that checkout's permissions.
272
273`source-control:write` covers direct Git and pull request changes made from the
274client: pushing, switching or creating branches, cloning, and removing
275worktrees. It does not restrict what a task does. Starting a task in a new
276worktree still creates that branch and worktree with `orchestration:operate`,
277and the agent it runs can use Git however the environment allows.
278
279Settings changes, provider management, and environment maintenance can be granted
280separately from access administration. New standard pairings include these
281permissions. Existing clients can stay connected after an update, but newly separated
282features may require pairing again with the permissions they need. Older clients
283may show controls that the server denies. Create a fresh pairing link to change
284a client's permissions.
285
286`filesystem:read` allows browsing host files, opening workspace files, and viewing
287local changes. Add `filesystem:write` to allow editing files or saving plans to
288the workspace. These scopes control direct file access from the client.
289
290To remove an environment from T3 Connect, open your account menu's **T3 Connect**
291page, or **Settings → T3 Connect** on mobile, and choose **Deregister**. This
292revokes its cloud access and frees its host space even when the environment is
293offline or has been wiped. When T3 Connect rejects a host's link, the host
294shows that it was removed from T3 Connect. To link it again, turn on
295**T3 Connect** in **Settings → Connections** on a desktop host, or run
296`t3 connect link` on a command-line host and then restart T3 Code there. A
297command-line host that released its tunnel when it last stopped may link itself
298again on its next start; run `t3 connect unlink` on that host to keep it off.
299Removing an environment from a device's connection settings only forgets it on
300that device; it stays registered to your account.
301
302When idle tunnel cleanup is enabled, T3 Connect removes a linked environment's
303tunnel after it stays offline for several minutes. The environment stays linked
304and keeps the same address. When the host starts again or wakes, T3 Connect
305creates a replacement tunnel on its own. You do not need to pair again. Cleanup
306usually runs five to ten minutes after the tunnel goes down.
307
308T3 Connect also removes the tunnel of an environment running an older version of
309T3 Code once it has been offline for seven days. That environment shows a message
310asking you to update. Start T3 Code on that computer and update it to the latest
311version; it reconnects at the same address without pairing again.
312
313On a command-line host, `t3 connect unlink` disables exposure while retaining
314your login; `t3 connect logout` also clears that login. Background-service
315[removal](./background-service.md#manage-the-service) is separate.
316
317Treat pairing URLs and authorization codes as passwords. Do not include them in
318screenshots, logs, or bug reports.
319
320## T3 Connect troubleshooting
321
322Run `t3 connect status` on the host to inspect saved authorization and link
323configuration. It is not a live reachability check. If the environment appears
324offline, run `t3 service status` and read the displayed log. If it disappears
325when SSH closes, see [background-service troubleshooting](./background-service.md#troubleshooting).
326
327| Error | Recovery |
328| --------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
329| `environment_link_limit_exceeded` or managed tunnel limit | Deregister an unused environment, then restart T3 Code on the host. |
330| `auth_invalid` or `invalid_bearer` | Run `t3 connect login`. If credentials were revoked, run `t3 connect logout`, then `t3 connect` again. Restart the server after signing in. |
331| Expired or invalid link proof | Check the host's date and time, update T3 Code, then restart it. |
332| HTTP 403 without a recognized error | Check relay access, proxies, and firewall rules. Keep any Cloudflare Ray ID for a bug report. |
333| HTTP 408, 429, or 5xx | Check network and relay availability. Startup retries temporary failures for up to ten minutes. |
334
335After fixing a permanent rejection, restart the host's server. On Linux, use
336`systemctl --user restart t3code.service` for the background service. For a
337foreground server, stop it and run `t3 serve` again with your usual options.
338Include the diagnostic message and trace ID when reporting a persistent failure.
339
340For a connection that still fails after linking, check the date and time on both
341devices. For server version warnings, follow [Updating T3 Code](./updating.md).
342
343## Using the Desktop App as a Remote Only
344
345If a computer should only drive work running elsewhere, turn off its local environment. In the
346desktop app, open **Settings → Connections** and switch off **Local
347environment**. T3 Code restarts without a local server: no local agents or terminals run, WSL
348backends stay off, and other devices can no longer connect to this computer. Your projects,
349history, and saved connections are kept, and you keep working through pairing, T3 Connect, or SSH.
350
351Switch **Local environment** back on in the same place to restart with your previous local
352settings.