Setting up secure communication between two AI agents usually means picking your poison: expose a webhook and manage auth yourself, stand up a message broker, or wire a VPN and hope your NAT cooperates. None of those were built with "AI agent" as the client in mind — they were built for services, and agents inherit all the plumbing.
Pilot Protocol takes a different starting point: give every agent a permanent virtual address, an encrypted tunnel, and an explicit trust model, and let discovery and messaging ride on top of that. Here's how to get two agents talking, end to end, in about five minutes.
What you're building
Two agents — call them Alice and Bob — each get:
- A permanent identity (an Ed25519 keypair, generated once)
- A daemon that registers them on the network and opens an encrypted UDP tunnel
- A discoverable hostname (optional — agents can also stay private)
- A mutual handshake before either side can send the other anything
That last point matters. On most networking layers, "joined the network" and "trusted" are the same thing — if you're on the VPN, you're in. Pilot decouples them: every peer relationship needs an explicit handshake, approved by both sides, before a tunnel does anything useful. Membership doesn't imply trust.
Step 1 — Install the CLI
curl -fsSL https://pilotprotocol.network/install.sh | sh
This installs pilotctl, the CLI that drives your local daemon. The whole stack is Go with no external dependencies — a single static binary, nothing else to install.
Step 2 — Start two agents
Each agent generates its own identity, then starts its daemon:
Alice:
pilotctl init
pilotctl daemon start --hostname alice --public
Bob:
pilotctl init
pilotctl daemon start --hostname bob --public
init creates ~/.pilot/identity.json — the permanent keypair backing the agent's identity. It survives restarts, IP changes, and moving the agent to a different machine entirely, because the identity is cryptographic, not tied to a network location.
--public makes the hostname resolvable by others. Leave it off and the agent is still fully functional — just not discoverable by name, only reachable by peers who already know its address.
If you're testing both agents on one machine, give each its own PILOT_HOME and tunnel port so they don't collide.
Step 3 — Discover and establish trust
Alice looks Bob up by hostname:
pilotctl find bob
Then sends a handshake request with a short justification:
pilotctl handshake bob "collaborating on a shared task"
Bob sees it waiting and decides whether to accept:
pilotctl pending
pilotctl approve <alice's-id>
Only after Bob approves does the relationship become bidirectional. This is the part worth sitting with: a handshake request costs the sender nothing and grants the sender nothing. The receiver has to act. That single design choice is what keeps an open, permissionless discovery layer from turning into an open door.
Step 4 — Actually talk
With trust established, the primitives are what you'd expect from a real network stack, not a REST wrapper:
pilotctl ping bob # connectivity/latency check
pilotctl send-message bob --data "..." # direct message over the tunnel
pilotctl send-file bob ./report.pdf # file transfer, no cloud intermediary
Everything here happens over an encrypted UDP tunnel with NAT traversal built in — STUN discovery plus hole-punching, falling back to a relay when a direct path isn't available. Neither agent needs a public IP or an open inbound port for this to work.
Where this fits next to what you already know
If you've built agent infrastructure before, you've probably reached for one of these:
- Webhooks — simple, but the caller has to already know a reachable URL, and there's no persistent connection or NAT handling; you're responsible for auth, retries, and exposing an endpoint at all.
- Message brokers (Kafka, etc.) — great for fan-out and durability, but you're now running and operating a broker, and it's addressed by topic, not by agent identity.
- VPNs / mesh networks (Tailscale, Nebula, ZeroTier) — solve the "reach a private machine" problem well, and are worth comparing against directly if that's your primary need. Where Pilot differs is the trust model: on a VPN, joining the network typically is the trust boundary. Pilot separates "on the network" from "trusted by this specific peer," which matters more once agents outnumber the humans managing them.
None of these are wrong tools — they solve real problems. Pilot's bet is that agent-to-agent communication is common enough, and different enough (ephemeral compute, no fixed IP, machine-speed request rates), to deserve infrastructure that treats an agent as a first-class network citizen from the start, rather than treating it as another service behind a webhook.
Beyond messaging: the app store
Once two agents can reach each other, the next question is usually "what can I actually call?" Pilot ships an app store on top of the same daemon: installable capabilities that run locally as typed JSON-in/JSON-out services.
pilotctl appstore catalogue
pilotctl appstore install <app-id>
pilotctl appstore call <app-id> <method> '{"...":"..."}'
Discover → install → call. Each app is signature-verified before it runs and only gets the permissions you grant at install time — no ambient authority, no browser, no REST client to write by hand.
Try it
The full walkthrough, including pub/sub events and file transfer, is on the Pilot Protocol blog. If you're building anything where agents need to find and trust each other without you hand-rolling the networking layer, it's worth five minutes to see how it feels.
Originally published on the Pilot Protocol blog.
Top comments (0)