# Clipper pipes a remote tmux buffer into your local clipboard

> Clipper is a small Go program that runs as a macOS launch agent or a Linux daemon and listens on a port or a UNIX socket, so text yanked inside a remote tmux session can be forwarded to the clipboard on your own machine. The whole mechanism is netcat and an SSH remote forward, which is its strength and its constraint.

**wincent/clipper** — ✂️ Clipboard access for local and remote tmux sessions

- Repository: https://github.com/wincent/clipper
- Stars: 690 · Forks: 30
- Language: Go
- License: BSD-2-Clause
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/wincent-clipper

## The problem is a six step ritual for one copy

The problem section of the project describes the situation precisely. You are running tmux, possibly on a remote machine over ssh, and want to copy something using tmux copy mode into your local system clipboard. The obvious workaround, holding down Option and clicking to make a selection, bypasses tmux, and it fails in two ways. It does not work with vertical splits, because the selection then operates across the entire width of the terminal and crosses the splits, and it does not let you grab more than what is currently visible on screen. The rectangular selection workaround, Option plus Command, fixes the split problem but drags in trailing whitespace that you then have to clean up manually, and it still will not reach past the visible region. The result is the tiresome sequence the project spells out: copy a selection with tmux copy mode on the remote machine, open a new empty buffer in vim, set paste mode, paste the copy buffer into it, write the file to a temporary location, then from the local machine pipe that file into the system clipboard with something like ssh user@host cat /tmp/buff | pbcopy. Six steps and two files to move one selection. Clipper exists to collapse that into one keystroke.

## The service is a listener, and the client is netcat

Clipper is a macOS launch agent or a Linux daemon that runs in the background providing a service that exposes the local clipboard, and optionally the capacity to display desktop notifications, to tmux sessions and other processes running both locally and remotely. The architecture is deliberately minimal, and the diagram in the README makes the flow obvious. You start in a shell on your local machine, ssh to a remote machine, and there you run vim inside tmux inside a shell. When you yank text in vim it is fed into the ~/.clipper.sock socket, and via an SSH RemoteForward connection the yanked text arrives back at the Clipper process running on your local machine, which then puts the text in your system clipboard. The tool on the remote side is ordinary netcat, and the tool on the local side is pbcopy on macOS or xclip on Linux. The README is explicit that the same patterns apply to other platforms and tools beyond the macOS, vim and tmux example, and that once everything is configured all of this happens transparently, so editing in vim on a remote machine feels like doing it locally.

## Installing the launch agent and the tmux binding

The macOS install is a single Homebrew command, and the README notes that it should be run outside of a tmux session.

```bash
    brew install clipper # run this outside of a tmux session
```

The tmux configuration is where the versions start to matter, because the binding key table changed in tmux 2.4. For tmux 2.4 and later the copy-mode-vi table is used, and Enter is bound to copy and forward to Clipper in one step.

```bash
    bind-key -T copy-mode-vi Enter send-keys -X copy-pipe-and-cancel "nc localhost 8377"
```

For tmux 1.8 and later but older than 2.4 the older vi-copy table is used with copy-pipe instead of copy-pipe-and-cancel, and for tmux below 1.8 there is no copy-pipe at all, so the binding goes through tmux save-buffer piped into netcat, bound to a prefixed y key. The project also documents three transport variants for every binding. The default talks to a TCP port on localhost, the -N switch is needed on platforms such as Ubuntu where netcat requires it, and a UNIX domain socket can be used instead with nc -U ~/.clipper.sock. If your netcat has no socket support, socat is the documented fallback with the - UNIX-CLIENT:~/.clipper.sock form. Editor and shell integration follow the same pattern, with a vim mapping that calls system with netcat on the last yanked text, and shell aliases so that anything piped into clip reaches Clipper.

## The SSH RemoteForward is what makes it remote

The piece that turns a local tool into a remote one is the SSH remote forward, and the configuration is two lines in ~/.ssh/config for the TCP case, forwarding the remote port back to the local one.

```bash
    # Forward Clipper connection to remote host
    Host host.example.org
      RemoteForward 8377 localhost:8377
```

The UNIX socket variant forwards the socket path instead of the port, with the remote path first and the local path second, which is the direction that surprises people: the remote machine's socket is where netcat on the server writes, and the local machine's socket is where Clipper is listening. Once that is in place, the tmux binding on the remote host writes into a channel that SSH carries back to your workstation, and the Clipper process there puts it on the clipboard. There is no agent to install on the server, no daemon to run over there, and nothing listening on the remote side beyond the forwarded channel, which is why the tool stays out of the way of a locked-down account. The trade is that Clipper must be running on your own machine, and the port has to be free, since the default in every configuration snippet is 8377.

## Building it yourself is a single Go file

The repository is small in a way that is unusual for a Go project. The top level holds clipper.go as the entire program, a Makefile, a LICENSE.txt, a README, a contrib/ directory, a media/ directory with the topology diagram, a logo, a .dprint.jsonc formatter configuration and a .mailmap. The Makefile shows the build targets, with a native clipper target and cross-compiled clipper_linux and clipper_darwin targets that set GOOS and GOARCH and stamp the version into the binary with -ldflags.

```bash
clipper_linux:
	GOOS=linux GOARCH=amd64 go build -ldflags="-X main.version=${VERSION}" -o clipper_linux clipper.go
```

There is also a release chain: the tag target signs the current HEAD with git tag -s and the version, the archive target produces a zip named after the version, and the upload target copies that zip to S3 with the acl set to public-read, which requires aws configure to have been set up and can be checked with aws sts get-caller-identity. The all target chains tag, build, archive and upload, and the clean target removes the built binary and the zips. The version itself comes from git describe --always --dirty, so a working tree with local edits produces a dirty suffix in the version string. Building it yourself is therefore a one line go build, and the Makefile exists mainly to package and publish.

## Where Clipper is the wrong tool

Three honest limits. The first is that Clipper does nothing for the local case. If you edit in tmux on the machine whose clipboard you want, the one line tmux binding to pbcopy does the whole job, and the README itself shows that as the starting point of the solution section. Clipper earns its keep across a machine boundary, and nothing else. The second is the security shape of the design. Clipper is a background service that accepts whatever is written to it and places it on your clipboard, so anything that can reach the port or the socket can set your clipboard, and the SSH remote forward is what keeps that channel private in the recommended setup. Exposing the port on a shared or untrusted network is a decision with consequences, and the tool is built for a personal workstation rather than a shared host. The third is maintenance. The last push to the repository was on 2026-04-28, which is more than six months before the current date, so the code has not moved since the 3.0.0 release on 2026-04-24, and the release before that, 2.1.0, dates from October 2023. That is fine for a program whose entire job is a socket and a clipboard write, and it does mean you should read the source before you trust it with a network listener.

## Conclusion

Adopt clipper if you edit over SSH inside tmux and want copy mode to fill the clipboard on your own machine, since it is a single static Go binary with a documented tmux, vim and ssh configuration. Skip it if you only ever work locally, since a plain pbcopy or xclip binding is enough, and skip it if you cannot run a listener on your workstation, because Clipper needs a process bound to a port or socket waiting for the remote side. Before you wire it up, decide whether to use the TCP port or the UNIX socket, since the ssh RemoteForward line differs between them, and remember that Clipper is a development convenience rather than something to leave exposed on a shared network.

## FAQ

### How do I install Clipper on macOS?

With Homebrew, run brew install clipper outside of a tmux session. The project also ships Go build targets for Linux and macOS in its Makefile, so a local go build of clipper.go works as well.

### How do I forward a remote tmux copy to my local clipboard?

Bind Enter in tmux copy mode to copy-pipe-and-cancel piping into nc localhost 8377, and add a RemoteForward 8377 localhost:8377 line for the host in your ~/.ssh/config. A UNIX socket variant is also documented, using nc -U ~/.clipper.sock and a RemoteForward of the socket path.

### Which tmux versions does the Clipper configuration cover?

The README documents three cases: tmux 2.4 and later using the copy-mode-vi table with copy-pipe-and-cancel, tmux 1.8 and later but older than 2.4 using the vi-copy table with copy-pipe, and tmux below 1.8 using tmux save-buffer piped to netcat bound to a prefixed y key.

### What licence is Clipper released under?

BSD 2-Clause, with the licence text in the LICENSE.txt file in the repository root. The project is written in Go and the whole program lives in a single clipper.go file.

## Sources

- [Issues](https://github.com/wincent/clipper/issues)
- [License: BSD-2-Clause](https://github.com/wincent/clipper/blob/main/LICENSE)
- [README](https://github.com/wincent/clipper/blob/main/README.md)
- [Releases](https://github.com/wincent/clipper/releases)
- [wincent/clipper on GitHub](https://github.com/wincent/clipper)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wincent-clipper
