Remote access and session management for Claude Code, Codex CLI, Cursor Agent, and other coding agents that run in a terminal.
Use an agent running on your own Mac, Linux, or Windows machine from any browser or phone — without SSH, VPN, or open ports. Your machine dials out; nothing listens for inbound connections.
Claude Code is the agent we support most closely; Codex CLI and Cursor Agent are both in daily use here.
- getterm.link — what TermLink is, how it works, and pricing
- Docs — install · CLI reference · sessions and limits · troubleshooting
- Download — hosts for macOS, Linux, and Windows
- Getting started — sign in, register a machine, connect
- Run Claude Code remotely · from your phone · across several machines
- Codex CLI remote access — what recognising an agent actually buys you
- Stop Claude Code asking for permission every time — how Auto-Yes works, and when to leave it off
- TermLink vs SSH, tmux, and remote desktop
TermLink is a commercial product. This repository is its open-source subset — the
connection protocol and a single termrelay binary that speaks it, under Apache 2.0.
It is the same idea the product is built on, reduced to what one binary can carry: a relay in the middle, a host that dials out to it, and a client that reaches the host through it. You can run the whole path yourself, on your own server, with no account and no dependency on our infrastructure.
[Client PC] ──ws──▶ [Relay Server] ◀──ws── [Host PC]
(public IP, :9000)
- Host — the machine that registers its shell (PTY) with the relay server. Linux / macOS only.
- Client — the machine that connects to the host's shell through the relay server. Linux / macOS.
- Server — the relay that connects host and client within the same code. Run it where a public IP is available.
Authentication here is per session: when the host starts, the relay allocates a 6-digit
code and a 4-digit pin and the host displays them. The client connects by supplying that
same -code and -pin.
The protocol is specified in SPEC.md, so anyone can implement and operate
their own relay against it.
⚠️ Security scope of this relay It allocates a per-session code + PIN (6-digit code, 4-digit PIN) and performs no WebSocketOrigincheck (CheckOriginalways allows). The small credential space is fine for self-hosting, testing, and single-user use, but it does not resist online guessing on a public relay and provides no multi-tenant security. For a multi-user production deployment, replace the authentication layer (e.g. per-session token auth) as described inSPEC.md.
Everything in this repository is in the product too. The product adds the parts a single self-contained binary cannot carry:
| This repository | TermLink | |
|---|---|---|
| Terminal over a relay | ✓ | ✓ |
| Self-hosted relay | ✓ | — (we run it) |
| Sign-in | per-session code + PIN | Google account, machine registered once |
| Host platforms | Linux, macOS | Linux, macOS, Windows |
| Client | terminal | terminal, browser, phone |
| Several machines in one list | — | ✓ |
| TUI repainted on reconnect | — | ✓ |
| Auto-Yes for permission prompts | — | ✓ (reads Claude Code, Codex, and Cursor prompts) |
| Screenshot upload into the session | — | ✓ |
Pick this repository if you want to run the protocol yourself. Pick the product if you want the browser and phone clients, Windows hosts, and Auto-Yes. There is a free plan.
Yes. That is what this repository is for. Run termrelay server on any box with a public
IP and you have a self-hosted remote terminal — no sign-up, no dependency on our
infrastructure, and nothing reporting back to us. Read the security note above first: the
per-session code + PIN is fine for yourself and not fine for a public multi-user relay.
The relay carries a terminal, so whatever runs in a terminal runs through it — Claude Code, Codex CLI, Cursor Agent, a build, a log. It does not know or care which one.
Recognising an agent is a different thing, and that lives in the product rather than here: reading each agent's own permission prompt for Auto-Yes, and pulling a readable last line out of its transcript for the session list. See Codex CLI remote access for what that looks like.
Yes, and this is the reason the design is shaped this way. The host dials out to the relay and never listens for inbound connections, so there is no port to forward, no firewall rule to add, and no static IP required. A network that blocks outbound WebSocket traffic will stop it; nothing else needs to change.
For this use it can be, and it is honest about where it is not. SSH gives you authentication, file transfer, tunnelling, and a config ecosystem. This gives you one terminal through a relay you control, reachable from behind NAT. If you are weighing them properly, TermLink vs SSH, tmux, and remote desktop sets out what each one is actually for, including where SSH wins.
Host mode allocates a PTY, and this binary does not implement the Windows equivalent.
Server and client modes are unaffected and run anywhere Go does. Windows hosts are in the
product — see installing on Windows,
including why the host there defaults to cmd.exe rather than PowerShell.
Requires Go 1.22 or newer. Works on macOS, Linux, and Windows.
# macOS / Linux
./build.sh
# Windows
build.bat
# or directly with the Go toolchain (any OS)
go build -o termrelay ./cmd/termlinkThis produces a termrelay (termrelay.exe on Windows) binary in the project root.
Run the whole flow with three terminals.
# Terminal 1 — server
./termrelay server -addr :9000
# Terminal 2 — host (Linux/macOS). The relay allocates a code + PIN, shown in a banner:
./termrelay host -server ws://localhost:9000
# ╭──────────────────────────────╮
# │ termlink session ready │
# │ CODE : 481572 │
# │ PIN : 6401 │
# ╰──────────────────────────────╯
# Terminal 3 — client (use the code + PIN the host displayed)
./termrelay client -server ws://localhost:9000 -code 481572 -pin 6401Type in terminal 3 → the shell runs in terminal 2 → its output appears in terminal 3.
The host needs no
-code/-pin— the relay allocates them and the host prints them. The client must supply that exact-codeand-pin.
When connecting to a remote server, you can set an environment variable instead of passing
-server every time.
export TERMLINK_SERVER="ws://RELAY_IP:9000"
./termrelay host # relay allocates and prints the code + PIN
./termrelay client -code 481572 -pin 6401| Command | Description | Key flags |
|---|---|---|
termrelay server |
Run the relay server | -addr |
termrelay host |
Share this machine's terminal | -server |
termrelay client |
Connect to a shared terminal | -server -code -pin |
| Flag | Default | Description |
|---|---|---|
-server |
ws://localhost:9000 (or TERMLINK_SERVER) |
relay URL, e.g. ws://1.2.3.4:9000 |
-code |
(client, required) | session code shown by the host |
-pin |
(client, required) | session PIN shown by the host |
-addr |
:9000 |
server listen address |
The host takes no
-code/-pin: the relay allocates both (6-digit code, 4-digit PIN) per session.
termrelay -mode server -addr :9000
termrelay -mode host -server ws://HOST:9000
termrelay -mode client -server ws://HOST:9000 -code 481572 -pin 6401In -mode host, only -server is required (the relay allocates the code + PIN). In
-mode client, all of -server -code -pin are required.
| Variable | Purpose |
|---|---|
TERMLINK_SERVER |
default relay URL for host/client |
| Path | Purpose |
|---|---|
/ws |
host/client WebSocket connection (code relay) |
/health |
health check — curl http://RELAY_IP:9000/health |
- Resizing the client terminal window is propagated to the host PTY automatically.
- To exit: type
exit(ends the shell) or drop the connection — it returns automatically. - Host mode uses a PTY, so it is Linux / macOS only (server/client are unaffected).
Not affiliated with or endorsed by Anthropic. Claude and Claude Code are trademarks of Anthropic, PBC.
Bert Shim <bertshim@gmail.com> GitHub: github.com/bertshim/termlink-relay
Contributions, issues, and pull requests are welcome.
Copyright © 2026 Bert Shim <bertshim@gmail.com>
Licensed under the Apache License 2.0. See NOTICE for
attribution requirements. You may use, modify, and distribute this software in
compliance with the License.