Share a paste with another machine on the same network. No server, account, or internet connection required. The sender keeps the paste in memory and serves it directly to the receiving machine. Stopping the daemon or rebooting the sender destroys it.
tp post notes.txt # echo "Terminal Paste" | tp post
otter-piano-cobalt
tp get otter-piano-cobalt # on the other machinecurl -fsSL https://raw.githubusercontent.com/shaiq-dev/tp/main/install.sh | sh
The installer downloads the latest release archive to ~/.local/bin/tp. It does not use sudo or modify shell startup files. Set TP_VERSION to install a specific release or TP_PREFIX to choose another location:
curl -fsSL https://raw.githubusercontent.com/shaiq-dev/tp/main/install.sh | TP_VERSION=v0.1.0 sh
curl -fsSL https://raw.githubusercontent.com/shaiq-dev/tp/main/install.sh | TP_PREFIX=/opt/tp sh
You can also install from source:
go install github.com/shaiq-dev/tp@latest| OS | Architectures |
|---|---|
| macOS 12 Monterey or later | amd64, arm64 |
| Linux, kernel 3.2 or later | amd64, arm64, armv7, 386 |
Release builds use CGO_ENABLED=0. Linux binaries do not depend on glibc, musl, or a particular distribution.
| Command | Description |
|---|---|
tp post [file] |
Read a file or standard input and print its code |
tp get <code> |
Fetch a paste and write it to standard output |
tp list |
List pastes served by this machine |
tp del <code> |
Stop serving a paste |
tp doctor |
Diagnose discovery and local network problems |
tp uninstall |
Remove tp and its local data |
tp completion <shell> |
Generate completion for Bash, Zsh, or Fish |
tp version |
Build and platform information |
Post options:
tp post --label notes --ttl 30m notes.txt
tp post --burn secret.txt
tp post --max-gets 3 archive.tar.gz
tp post --code-style=digits notes.txt
Use --host when you know the sender's address and want to bypass discovery:
tp get --host 192.168.1.20 otter-piano-cobalt
Word codes accept any unambiguous prefix, so this works too:
tp get otte-pian-cobatp postgenerates a three word code with about 31 bits of entropy, then derives a PAKE secret using scrypt. Each derivation uses roughly 32 MiB of memory, and the code itself is not retained.- Machines advertise candidate addresses over mDNS. These records are untrusted, a spoofed peer still has to complete PAKE key confirmation.
- The receiver connects over TLS 1.3 and runs CPace over ristretto255. The code is never sent, and a wrong code produces nothing useful for offline guessing.
- The sender returns a padded, shuffled set of confirmations because it cannot tell which stored paste the code identifies. Padding hides the exact number of live pastes.
- After mutual confirmation, the payload is encrypted with a key derived from the PAKE session, in addition to TLS. Successful peers are pinned so later key changes are not silently accepted.
Each source address is limited to 20 connection attempts per minute. A global bucket limits testable guesses to 10 per second even when source addresses are rotated.
Pastes and derived PAKE secrets remain in the daemon's memory. Anyone who can read that process should be considered to have access to them, tp protects the network transfer, not a compromised endpoint.
Discovery uses IPv4 multicast and expects both machines to be on the same LAN. If no peer appears, run tp doctor or tp doctor --listen 10s.
Common blockers:
- Guest, hotel, and enterprise Wi-Fi often isolate clients or block multicast.
- macOS 15 or later requires Local Network permission for tp's signing identity. Run
tp doctor --fix, or enable tp under System Settings > Privacy & Security > Local Network. - WSL2 NAT mode does not pass multicast to the LAN. Set
networkingMode=mirroredunder[wsl2]in%UserProfile%\.wslconfig, then runwsl --shutdown.
The CLI starts the daemon automatically when its control socket is absent. The daemon stops after its store is empty and it has been idle for 30 minutes.
An optional systemd user service is included in contrib/tp.service for users who prefer systemd to manage the daemon.
tp uninstallOn macOS, the Local Network entry remains visible in System Settings but is inert after the binary is removed.
make build # Build ./tp for this machine
make test # Run tests with the race detector
make lint # Run golangci-lint
make check # Run all CI checks
make dist # Build release archives, checksums, and manifestThe build requires Go, a POSIX shell, and GNU Make 3.81 or later. Run make help for the complete target list.
Cross compilation and packaging can also run without Make:
VERSION=v0.1.0 scripts/build.sh