Tailcat is a new open source command-line tool from Tailscale that works like netcat, but tunnels traffic through Tailscale's encrypted WireGuard data plane without needing a Tailscale account, admin rights, or any control-plane sign-in at all. It picked up 789 stars in a single day on GitHub's trending page and has crossed 3,500 total, most of that momentum arriving since the project was open sourced this month at the TailscaleUp conference.
- Install is one command,
go install github.com/tailscale/tailcat/cmd/tailcat@latest, and there is nothing to sign up for: no Tailscale account, no API key, no control plane at all. - Every connection is a point-to-point WireGuard tunnel that bootstraps through a free public DERP relay, then upgrades to a direct encrypted UDP path once NAT hole-punching succeeds.
- One binary covers a surprising amount of ground: piping stdin/stdout between machines, forwarding local TCP ports, running an auth-free SSH server, and even acting as a SOCKS5 proxy or an exit node.
- Server addresses are ephemeral by default, a fresh unguessable token every run, though
tailcat genkeycan pin a stable one when you actually want to keep reusing the same address.
The exact steps, start to finish
- Check prerequisites. Tailcat's go.mod requires Go 1.26 or newer, so confirm your Go toolchain is current before installing:
go version - Install Tailcat. This pulls the module straight from GitHub via the Go module proxy and builds the CLI:
Or, if you use Nix flakes, skip the Go toolchain entirely:go install github.com/tailscale/tailcat/cmd/tailcat@latestnix run github:tailscale/tailcat - Make sure the binary is on your PATH.
go installdrops the binary in your Go bin directory, which is not always on PATH by default, especially on a fresh Windows machine. macOS/Linux (bash/zsh):
Windows (PowerShell):export PATH="$PATH:$(go env GOPATH)/bin"$env:Path += ";$(go env GOPATH)\bin" - Start a server. Run it with no arguments in one terminal. It prints a short connection token and then waits:
tailcat # Selected bootstrap relay region 302, San Francisco # Server listening with new address: tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu - Connect from a second terminal (or a second machine) and see it work. Pass the token your server printed as the argument. This is the moment you actually see the tunnel working, your server's terminal unblocks and prints whatever the client sent:
echo hello | tailcat tcomFwWCCcjS5nKNqAod034nWoJZW0LZqDhhC8U_dKdnDRYQ8uNGFpGQEu
What is Tailcat and why is it trending?
Tailscale built its whole product around a control plane, the coordination server that hands out keys, enforces access rules, and tells every device in your tailnet who else exists. Tailcat strips that layer out entirely and keeps only the plumbing underneath: magicsock for NAT traversal, a userspace WireGuard implementation, gVisor's netstack for handling TCP without root, and Tailscale's DERP relay protocol as a rendezvous channel. What's left is a tool that behaves like classic netcat, point a client at a server and move bytes, except every byte is WireGuard-encrypted and the two ends can find each other across almost any NAT without opening a port.
RelatedDesktop Commander Setup: Give Claude Terminal Control
The project itself has a fun origin story: it began life in September 2023 as a side project called "derpcat," sketched out on a long flight, and lived inside a fork of the main Tailscale repository for years before finally being refactored into a standalone module and open sourced in August 2026. That backstory, plus the fact that it needs zero signup to try, is a big part of why it jumped straight onto GitHub's daily trending page.
How do you install Tailcat on macOS, Linux, and Windows?
Because Tailcat ships as a Go module rather than platform-specific binaries, the install command is identical across macOS, Linux, and Windows: go install github.com/tailscale/tailcat/cmd/tailcat@latest. The only platform difference worth knowing is where go install puts the resulting binary. On macOS and Linux it typically lands in ~/go/bin; on Windows it's usually %USERPROFILE%\go\bin. Either way, that directory needs to be on your PATH before a plain tailcat command works from any terminal, which is the step people most often skip on a machine where they just installed Go for the first time.
If you'd rather not touch a Go toolchain at all, the README documents a Nix flakes path (nix run github:tailscale/tailcat to try it once, or nix profile install github:tailscale/tailcat to keep it installed) that works the same way on any system with Nix set up. There's also an experimental in-browser WebAssembly build at Tailscale's GitHub Pages demo that can send files or text without installing anything locally, though it currently relays over DERP only since it predates WebRTC support.
What can you actually do with Tailcat once it's running?
The stdin/stdout pipe in the checklist above is the simplest demo, but it's really a stand-in for a handful of genuinely useful patterns. Point it at a local port with tailcat --serve=8080,8443 and a client anywhere can reach that port through the tunnel, no port forwarding or firewall rule required on the server's router. Run tailcat --serve=no-auth-ssh on Linux or macOS and you get a working SSH server reachable only by whoever holds the printed token, with WireGuard authenticating the client before your actual SSH daemon (or Tailcat's own auth-free listener) ever sees a packet. tailcat socks <token> curl http://server.tailcat:8081/ routes an arbitrary command through a SOCKS5 proxy over the tunnel, and tailcat --serve=exit-node turns the server into a full exit node for the client's outbound traffic.
Addresses are ephemeral by default, which is the safe posture: each run generates a fresh in-memory key, prints an address nobody has seen before, and throws the key away on exit, so sharing that address only ever refers to that one session. When you want a stable address instead, for example to publish it as a DNS TXT record so a home server is reachable by name, tailcat genkey writes a persistent key to disk and --allow=<client-key> restricts who that saved key will accept connections from.
RelatedOpen Interpreter Setup: A Coding Agent for Cheap Models
Tailcat versus the tools it overlaps with
| Tailcat | Plain netcat | ngrok | Full Tailscale | |
|---|---|---|---|---|
| Encryption | WireGuard, always on | None | TLS to ngrok's edge | WireGuard, always on |
| Account required | No | No | Yes | Yes |
| NAT traversal | Automatic, direct UDP when possible | None, needs a reachable IP | Handled via ngrok's cloud tunnel | Automatic, direct UDP when possible |
| Root/admin needed | No, pure userspace | No | No | Often yes, for TUN/routing |
| Persistent device identity | Optional, opt in with genkey | N/A | Tied to account | Always, part of the tailnet |
What are the gotchas before you rely on it?
Tailcat's own README is upfront that it comes with no stability promises: the Go API, the CLI flags, and even the wire format may change, and Tailscale's free public DERP relays carry no uptime guarantee and can be rate-limited or revoked without notice. That's fine for ad hoc use, piping a file to a colleague, spinning up a throwaway SSH session, testing something across two machines on different networks, but it's not something to build production infrastructure on without running your own DERP relay via Tailscale's cmd/derper. Worth noting too, the client-side address matching is case-sensitive, so tokens work as hostnames with curl and most CLI tools but not with browsers, which lowercase hostnames automatically. And if you want an authenticated SSH server rather than the auth-free listener, you'll want tailcat --serve=22 pointed at your system's own SSH daemon rather than the built-in no-auth mode.
Our take
Tailcat is a genuinely clever bit of engineering: it takes the hardest part of Tailscale, the NAT traversal and encrypted transport, and makes it usable without the coordination server that normally goes with it. That's a real gap in the ecosystem. Plain netcat is unencrypted and needs a reachable IP. ngrok solves NAT but wants an account and routes through its own cloud. Tailcat needs neither, and for the specific job of moving bytes between two machines that can't otherwise reach each other, it's about as low-friction as this category gets. The explicit no-stability-promise caveat is honest rather than a red flag, and it means treating this as a power-user utility for now, not a production dependency, until Tailscale (if it chooses to) commits to something firmer.
- Whether Tailcat gets tagged releases with prebuilt binaries instead of requiring a Go toolchain or Nix.
- Whether the in-browser WebAssembly demo gains WebRTC support for true peer-to-peer connections from a browser tab.
- Whether Tailscale formalizes any stability guarantees on the CLI flags or wire format as adoption grows.
- Whether the pattern (data plane without control plane) gets adopted by other WireGuard-based tools facing the same NAT traversal problem.
- OFFICIALtailscale/tailcat on GitHub source, README, and install instructions
- REFERENCETailcat on pkg.go.dev Go package documentation for using it as a library
- DEPENDENCYTailscale's cmd/derper how to run your own DERP relay instead of the shared public ones
- DEMOTailcat in-browser WebAssembly demo send files or text from a browser tab, no install required
Original analysis by GenZTech.
