| 1 | # Self-hosted server |
| 2 | |
| 3 | A self-hosted server gives your browser and desktop one address for your machines and archived chats. Each machine keeps its workspaces and running agents. T3 Connect remains optional. |
| 4 | |
| 5 | ## Connect your machines |
| 6 | |
| 7 | On a current Knife desktop, open **Connections**, choose **Self-hosted server**, and enter its HTTPS address. Sign in through the system browser. The desktop enrolls this machine and connects it to the server; private network addresses and transferred token files are unnecessary. Provider credentials stay on the machine unless you explicitly share them. |
| 8 | |
| 9 | Open the same address in a web browser to sign in and see your machines. A sleeping machine stays listed. Synced chats can be settled, snoozed, woken, and pinned while it is offline. The machine must reconnect before it can run work; cleanup from settling waits until then. Disconnecting keeps unsent drafts and leaves direct connections and running agents in place. |
| 10 | |
| 11 | Device access renews automatically until the server requires sign-in again. Revoking a device closes its connections and stops renewal. Existing manually paired machines keep their identities and saved chats; their pairing and `t3 shared hub` commands remain available for recovery. |
| 12 | |
| 13 | ## Share agent accounts |
| 14 | |
| 15 | A private T3 server can hold managed Codex and Claude accounts for your other hosts. Each host runs agents against its own workspaces. The shared server can run agents too. Provider homes and cached credentials live inside each host’s T3 home; existing CLI homes stay separate. This is opt-in and does not move native CLI history between machines. |
| 16 | |
| 17 | Start the shared server, then issue a separate revocable credential for each execution host. Keep the token in a private file: |
| 18 | |
| 19 | ```sh |
| 20 | umask 077 |
| 21 | t3 auth session issue --label laptop --ttl 3650d --scope providers:manage --scope orchestration:read --scope orchestration:operate --token-only > laptop-token |
| 22 | ``` |
| 23 | |
| 24 | On the host with your signed-in profiles, connect its running T3 server and import each profile by its instance ID from Providers settings: |
| 25 | |
| 26 | ```sh |
| 27 | t3 shared connect https://t3.example.com --token-file /private/path/laptop-token |
| 28 | t3 shared import codex_personal |
| 29 | t3 shared import claude_personal --token-file /private/path/claude-setup-token |
| 30 | ``` |
| 31 | |
| 32 | For Claude, generate the token once with `claude setup-token` while signed into the intended account. The token lasts one year. Other execution hosts only need their own shared-server credential and `t3 shared connect`; the managed profiles appear in their model pickers. Select those profiles for shared accounts. Avoid running the original Codex profile concurrently: it owns an independent copy of the same refresh credential. |
| 33 | |
| 34 | Connected hosts coordinate Codex refreshes with expiring claims. Another host can take over an abandoned claim. During a shared-server outage, already cached access works until it expires; refresh waits for the server to return. A lost provider response can still require signing in again. |
| 35 | |
| 36 | Use `t3 shared status` to list shared accounts, `t3 shared sync` for an immediate refresh, and `t3 shared disconnect` to disable managed profiles on this host. Remove an account everywhere with `t3 shared remove ACCOUNT_ID`. To renew credentials without changing its shared identity, import the signed-in source profile again with `--replace ACCOUNT_ID` (and the new `--token-file` for Claude). |
| 37 | |
| 38 | ## Run in a container |
| 39 | |
| 40 | The image includes the web client, server, Codex, and Claude. Follow the [container and hosted sign-in setup](../operations/development.md#private-server-container), including the Compose SSO overlay, private configuration mount, and archive storage identity. The process runs as UID 1000; give it access to the mounted directories. Put an HTTPS reverse proxy in front of port 3773, including WebSocket upgrades, then connect clients using the server’s HTTPS address. Provider account sharing remains optional. Back up `/data` and `/home/node`, including their private credentials, independently of `/archives`. |
| 41 | |
| 42 | ## Offload archived chats |
| 43 | |
| 44 | The container’s `T3CODE_ARCHIVE_DIR` points at the private archive mount. Signing a desktop into the self-hosted server also configures its background archive uploads while its local server runs. Keep the archive mount separate from the T3 state mount. Existing hosts using `t3 shared connect` and `T3CODE_ARCHIVE_OFFLOAD=true` keep their saved archive locations. |
| 45 | |
| 46 | Archived chats upload automatically in the background. Message and tool bodies are removed locally only after verified upload; titles, projects, timeline indexes, and control metadata stay local. Opening a chat fetches its bodies without retaining them. Unarchiving restores the bodies and attachments before the chat can run again. Local attachment bytes stay while an active chat or fork needs them. Workspace media is copied into the archive; your original files are left to the normal workspace lifecycle. |
| 47 | |
| 48 | Uploads retry automatically after failures, with delays increasing from one minute to one hour; the queue survives restarts. `t3 shared archive status` shows pending uploads and failures; `t3 shared archive retry [THREAD_ID]` requests an immediate attempt. A missing mount, failed verification, or concurrent chat change retains the local copy. Synced chats and attachments remain readable from the server while their source machine sleeps. Back up the archive mount: its verified objects become the authoritative copy of offloaded bodies. |