Getting Started
Install uniclip, start the daemon, and create or join a space — all from the terminal.
The uniclip binary is the terminal-side equivalent of the desktop
app. It talks to the background daemon over HTTP, so anything the GUI
can do — pair, sync, send, search — works headlessly over SSH, in
tmux, on a server, or from a script. If no daemon is running, uniclip
starts one automatically.
Install via the Install page (Homebrew
on macOS, the headless uniclip artefact on Linux servers, etc.).
Global flags
These work on every subcommand:
| Flag | Effect |
|---|---|
--json | Emit machine-readable JSON. Field names are stable; suitable for scripting. |
-v, --verbose | Show debug-level diagnostics on the console. |
--profile <NAME> | Run as a separate profile — isolates data dir, keychain entry, and iroh identity. |
--dev | Use file-based secure storage instead of the system keychain. Development only. |
--profile is the supported way to simulate two devices on one
machine for end-to-end testing — run two terminals, each with a
different --profile value.
Daemon lifecycle
| Command | Effect |
|---|---|
uniclip start | Start the daemon in the background. |
uniclip start --foreground | Run the daemon in the foreground; logs go to the TTY. |
uniclip start --server | Run as a headless server node: no system clipboard or clipboard watcher; syncs over iroh as a normal member. For a VPS / container with no display. |
uniclip stop | Stop the running daemon. |
uniclip status | Show daemon health and a device-trust summary, including local membership, pending changes, and devices that need an update. |
The daemon starts automatically when you run a command that needs it,
so explicit start is mostly for log-streaming setups and headless
servers that want a long-lived background process.
Space lifecycle
The CLI mirrors the GUI flow described in Pairing & sync.
# Create a fresh encrypted space on this profile
uniclip init
# Issue a one-time invitation and wait for the joiner
uniclip inviteinit prompts for the passphrase interactively. Pass --passphrase
or --device-name only in non-interactive contexts (e.g. an E2E test
script).
# Redeem an invitation and join the sponsor's space
uniclip join <invitation-code>
# Verify the pairing landed
uniclip membersjoin prompts for the passphrase if --passphrase is omitted. The
passphrase is verified locally via PAKE — a wrong value fails fast
without leaking the guess to the sponsor.
By default, join waits until the request is accepted or rejected. Use
--no-wait to return as soon as the pending request is recorded, then inspect
or cancel that same request later:
uniclip join status
uniclip join cancelPressing Ctrl-C only stops the local wait. It does not cancel the join request.
To switch this device to a different sponsor's space (re-encrypting
local history under the new MasterKey), run join with the new
sponsor's invitation and the --switch flag:
uniclip join --switch --code <new-invitation-code>The switch is destructive (local history is re-encrypted), so join
prompts for confirmation first. Pass --yes to skip the prompt in
non-interactive contexts.
Without --switch, join always takes the non-destructive re-pair
path — which is also how you re-pair after a one-sided unpair (it
redeems against the space you're already in and replaces the stale
records).