The most useful addition to your AI toolchain this year probably isn’t an agent framework, an orchestration layer, or a vector database with a new pricing page. It’s a small command-line utility that moves bytes between two machines without you thinking about ports. That’s the pitch behind Tailcat, and the reason I think it deserves more attention than the average weekend project.
The mainstream story in AI tooling is that plumbing is solved and the interesting work happens higher up the stack. My experience reviewing these toolkits says the opposite. The higher layers are crowded with near-identical options. The plumbing is where people still lose entire afternoons.
What it actually is
Tailcat is netcat semantics on top of Tailscale’s data plane. Netcat has been the duct tape of networking for decades: you point it at a host and a port, you pipe something into stdin, and it comes out the other side. Simple, unopinionated, and completely indifferent to whether the connection is safe or whether the person on the other end is who they claim to be.
Riding Tailscale’s data plane changes the assumptions underneath that model. Instead of raw sockets across whatever network happens to sit between you and the target, the connection uses the encrypted peer-to-peer path Tailscale already maintains between devices in your tailnet. Identity comes from the tailnet rather than from an IP you hope is correct. There’s no listening port exposed to the public internet, which removes an entire category of mistakes.
If you have ever tried to shuttle a stream between a laptop and a GPU box sitting behind a NAT you don’t control, you know why that matters. The usual answers are an SSH tunnel with a jump host, a temporary object storage bucket, or a reverse proxy you promise yourself you’ll tear down later. Each one works. Each one is more ceremony than the actual task deserves.
Why AI workflows hit this constantly
Agent and model work generates an unusual amount of ad hoc data movement. You have a checkpoint on a rented GPU instance. You have logs on a sandbox VM that dies when the run ends. You have a local script that needs to feed a stream into a remote process and read the output back. None of this justifies standing up infrastructure, and all of it is annoying enough that people take shortcuts.
The shortcuts are the problem. I have watched developers open a port to the world for a five-minute transfer, or paste an API key into an environment variable on a machine they’re about to hand back to a cloud provider. A tool that makes the safe path also the lazy path is doing real work, even if it never appears in a keynote.
Where I’d stay skeptical
A few things I’d want to test before putting this anywhere near production:
- Identity is tailnet-scoped, not process-scoped. Any process on a machine in your tailnet inherits that machine’s trust. That’s a meaningful upgrade over open ports, and it is not the same as per-service authorization. Your access control lists are doing the real work here, so they need to be right.
- Performance depends on the path. Tailscale connections either go direct between peers or fall back to relays when NAT traversal fails. Those two cases behave differently, and a tool that hides the distinction can make throughput feel unpredictable. I’d want visibility into which path a given transfer took.
- Netcat’s fragility carries over. Piping raw streams gives you no integrity check, no resume, and no progress indication unless you build them yourself. That’s fine for a quick pipe. It’s a bad way to move a large checkpoint over a link that might drop.
- It adds a dependency to every endpoint. Both sides need to be on the tailnet. In an environment where sandboxes spin up and die constantly, provisioning that becomes part of your setup cost.
The verdict I’d give today
Tailcat sits in the category I like most as a reviewer: a tool that does one thing and inherits its hard guarantees from something already battle-tested rather than reinventing them. The encryption and NAT traversal aren’t new code to audit, they’re Tailscale’s, and that is the right kind of borrowing.
I’d reach for it for interactive work, quick transfers between machines I already trust, and the debugging sessions where you just need a stream to go somewhere. I would not use it as a transport layer in an automated pipeline without wrapping it in something that verifies what arrived.
Which is roughly the same advice I’d give about netcat itself. That’s the compliment. The tools that survive in this space are the ones with a shape simple enough to reason about, and this one keeps that shape while quietly fixing the part that always made netcat uncomfortable to use across networks you don’t own.
🕒 Published: