COTTY
OPEN SOURCEMIT · one Go binary · Linux & macOS
the multiplayer terminal

Your shell. Your guests.
Type together

Host your terminal, let teammates join from any terminal or a browser — watch together, and when you allow it, type together. End-to-end encrypted, per-guest permissions, and a trail of who typed what.

$ go install github.com/tylerbroqs/cotty/cmd/cotty@latest
$COTTYofficial CA0x8b39b55857cea6d173af2b5bb1144c2633739960
Only trust this contract address — anything else is not official.
tyler@devbox — cotty host --relay relay.example.com:7374 🔒 E2EE
waiting for guests…
↑ simulated session —
// features

Pair programming, minus the screen share.

First-class sessions with per-guest permissions, live presence, accountability and real encryption — not a Zoom window of your terminal.

Host anywhere, join from anything

cotty host spawns your shell in a PTY and serves it over a websocket. Your local terminal stays attached as usual. Guests join with cotty join — or straight from a browser, no install needed.

$ cotty host --write cotty: session code XJ4K2P cotty: guests join with: cotty join "ws://192.168.1.10:7373/ws?code=XJ4K2P" $ cotty join -name alice "ws://192.168.1.10:7373/ws?code=XJ4K2P"

Guests can't type. Until you say so.

View-only by default. Grant, revoke and kick live — try it:

Aaliceview-only
Bbobview-only
$ cotty ctl list

E2EE by default

Relayed sessions are sealed with AES-256-GCM. The relay forwards ciphertext it cannot read.

NAT-friendly relay

The host dials out to cotty relay. No port forwarding on either side — home, office or coffee shop.

Record & replay

-record session.cast writes asciicast v2 — play it with cotty replay or asciinema.

An audit trail of who typed what

Every keystroke that reached the shell, attributed to the participant who typed it — plus joins, leaves, permission changes and kicks. Rejected input never runs, so it's never logged.

{"kind":"join","who":"alice"} {"kind":"input","who":"alice","data":"go test ./...\r"}

Live presence & session codes

Everyone sees who joins, who leaves and who's typing. Every session is protected by a random join code, and guests leave with Ctrl-].

$ cotty ctl list alice read-write joined 4m12s ago bob view-only joined 38s ago
// end-to-end encryption

The relay sees noise.

The host generates a 256-bit session key and puts it in the join URL's fragment — the part after # that clients strip before any request is made.

cotty join "ws://relay.example.com:7374/ws?code=XJ4K2P#k=8D0Uy-5ugL…"
↑ never sent over the network
host
$ git push
🔑 has key
relay
…
✕ no key
guest
$ git push
🔑 has key
Wrong key fails loudlyA guest without the key is refused with an explanation — never shown garbage.
WebCrypto in the browserThe browser client decrypts in-page. Code and key live in the fragment, which browsers never send.
Honest about metadataThe relay still sees guest names, join/leave events, the code, terminal size and traffic timing.
// how it works

One PTY. Everyone attached.

The host process owns the PTY. Local keystrokes — and guest keystrokes, if allowed — are written to it. Everything the PTY emits fans out to your terminal and every connected guest.

  1. 01
    HostSpawn your shell. Cotty prints a session code and a join URL.
  2. 02
    ShareSend the URL over a channel you trust — it carries the key.
  3. 03
    CollaborateGuests watch. You allow who types. The trail remembers.
HOST PTY your shell RELAY ciphertext only aliceterminal · rw bobbrowser · view samterminal · view outbound local terminal JSON frames over websocket — deliberately debuggable
// get started

Up and running in 30 seconds.

Requires Go 1.24+. Linux and macOS hosts; Windows guests should work too, since join uses no PTY.

0
binary
0
bit session key
0
ports to forward
0
CDN calls from the web client
// cotty = collaborative + tty

Stop screen-sharing
your terminal.

Share the real thing. Open source, MIT licensed, built in the open.

$COTTYofficial CA0x8b39b55857cea6d173af2b5bb1144c2633739960