5 min readPilot Protocol editorial team
Build a Multi-Agent Network in 5 Minutes
Step-by-step tutorial: install Pilot Protocol, register agents, establish trust, and send your first encrypted message. See the technical details.
- tutorial
- quickstart
- getting-started
This tutorial takes you from zero to a working multi-agent network. Two agents, on different machines (or the same machine), communicating over encrypted tunnels with a mutual trust relationship. The whole thing takes about 5 minutes.
By the end, you will have two agents that can send messages, transfer files, ping each other, and publish/subscribe to event streams -- all over Pilot Protocol's encrypted UDP overlay.
Prerequisites
The one-line installer ships prebuilt binaries — no Go toolchain required. (Building from source needs Go 1.25+.) The install drops a small set of binaries: pilotctl, pilot-daemon, and the auto-updater.
You don't need to set up any servers. By default the daemon registers with the public registry and beacon that Vulture Labs runs at 34.71.57.205, free for anyone.
Step 1: Install pilotctl
Install the CLI tool with a single command:
curl -fsSL https://pilotprotocol.network/install.sh | shThis installs the binaries to ~/.pilot/bin and adds that directory to your $PATH.
Verify the installation:
$ pilotctl version
1.18.0Alternative: You can also clone the repository and build from source with make build, which builds both pilotctl and the daemon. See the Getting Started guide for details.
Step 2: Start Two Agents
Each agent needs its own identity. The daemon generates a cryptographic identity (Ed25519 key pair) the first time it starts and stores it locally.
Agent Alice (Terminal 1)
# Start the daemon and register as "alice"
# (first start creates the identity in ~/.pilot/identity.json)
$ pilotctl daemon start --hostname alice --email alice@example.com --public
Daemon running (pid 48213)
Address: 0:0000.0000.0003
Hostname: alice
Transport: udp
Socket: /tmp/pilot.sock
Logs: /home/alice/.pilot/pilot-48213.logAgent Bob (Terminal 2)
# On a different machine, start the daemon and register as "bob"
$ pilotctl daemon start --hostname bob --email bob@example.com --public
Daemon running (pid 51007)
Address: 0:0000.0000.0004
Hostname: bob
Transport: udp
Socket: /tmp/pilot.sock
Logs: /home/bob/.pilot/pilot-51007.logBoth agents are now running. The --public flag makes them resolvable by hostname for anyone. Without it, agents are private and resolve only for trusted peers. (Your addresses will differ; the registry assigns them in order.)
Same machine? If you are running both agents on one machine for testing, give the second one its own state directory and socket: run Bob's commands as PILOT_HOME=~/bob PILOT_SOCKET=/tmp/pilot-bob.sock pilotctl ... and start his daemon with --socket /tmp/pilot-bob.sock. The tunnel listen port is picked at random by default, so the two daemons don't collide.
Step 3: Discover and Establish Trust
Alice can find Bob by hostname because he registered as public:
# From Alice's terminal
$ pilotctl find bob
Hostname: bob
Node ID: 4
Address: 0:0000.0000.0004
Visible: publicNow Alice initiates a trust handshake. The justification message tells Bob why Alice wants to connect:
# Alice requests trust
$ pilotctl handshake bob "Collaborating on the Q1 data analysis project"
handshake request sent to node 4
they must approve on their side · check status: pilotctl trust · propagation can take ~60sOn Bob's side, the handshake request appears. Bob reviews it and approves:
# Bob sees the pending request
$ pilotctl pending
Pending handshakes — 1
node 3 · 12s ago (2026-02-28 10:14)
Collaborating on the Q1 data analysis project
accept: pilotctl approve 3 · decline: pilotctl reject 3 "reason"
# Bob approves
$ pilotctl approve 3
trust established with node 3
trust is now mutual — message them: pilotctl send-message 3 --data "hi"Done. Alice and Bob now have a mutual trust relationship, signed with Ed25519 keys. An encrypted tunnel is established automatically.
Step 4: Communicate
With trust established, Alice and Bob can use the full set of communication primitives.
Ping
Test connectivity and measure latency:
$ pilotctl ping bob
PING 0:0000.0000.0004
# then one line per reply (4 by default) with its round-trip timeSend a Message
Send a message through the Data Exchange service on port 1001. Bob's daemon acknowledges it and saves it to his inbox:
# Alice sends a message to Bob
$ pilotctl send-message bob --data "Analysis complete. 47 anomalies detected in dataset-7."
{
"ack": "ACK TEXT 54 bytes",
"bytes": 54,
"reused": false,
"seq": 0,
"target": "0:0000.0000.0004",
"to": "0:0000.0000.0004",
"type": "text"
}
# Bob reads his inbox
$ pilotctl inbox
Inbox — 1 message(s) · showing 1 newest
TEXT-20260228-101502.481-000001
0:0000.0000.0003 · TEXT · 9s ago · 54 B
Analysis complete. 47 anomalies detected in dataset-7.Transfer a File
Send files through the encrypted agent tunnel -- no S3 bucket or workflow-specific file broker:
# Alice sends a file to Bob
$ pilotctl send-file bob ./report.pdf
# prints a JSON summary: filename, bytes, elapsed_ms, throughput_mbps, ack
# Bob receives files into ~/.pilot/received/
$ pilotctl receivedPublish/Subscribe Events
Every daemon runs a pub/sub broker on port 1002. You subscribe to a topic on a peer's broker, and anything published to that topic on that broker reaches every subscriber. Publish and subscribe always target a peer's broker, not your own daemon's, so here both commands target Alice's:
# Bob subscribes to topic "status" on Alice's broker
$ pilotctl subscribe alice status
subscribed to "status" on 0:0000.0000.0003 — waiting for events...
# From a second terminal on Bob's machine (or any other trusted peer),
# publish to the same topic on Alice's broker
$ pilotctl publish alice status --data "processing batch 1/10"
$ pilotctl publish alice status --data "processing batch 2/10"
# The subscriber sees them in real time
[status] processing batch 1/10
[status] processing batch 2/10What Just Happened
Behind those simple CLI commands, a surprising amount happened:
- Identity generation-- the daemon generated anEd25519key pair on first start and stored it in
~/.pilot/identity.json. This key pair is the agent's permanent cryptographic identity. - STUN discovery-- when the daemon started, it sent a UDP packet to the beacon server and learned its own public IP:port mapping. This is how other agents can reach it through NAT.
- Registration-- the daemon connected to the registry and registered its hostname, public key, and STUN-discovered endpoint; the registry assigned its address.
- Handshake-- Alice's handshake request was signed with her Ed25519 private key and relayed through the network to Bob. Bob verified the signature, approved, and signed his response. Both sides now store the peer's public key.
- Tunnel establishment-- with trust established, Alice's daemon resolved Bob's endpoint from the registry, attempted direct UDP connection (using hole-punching if needed), and performed X25519 key exchange to set up AES-256-GCM encryption.
- Communication-- every message, file, and ping traveled over the encrypted tunnel as Pilot Protocol packets with the 34-byte header, CRC32 checksums, sequence numbers, and acknowledgments.
All of this happened without configuring firewalls, opening ports, setting up TLS certificates, or deploying your own servers. The agents found each other through the public registry, established trust, traversed NAT, and communicated. If you want to take this further, you can build a self-organizing agent swarm, use the built-in pub/sub in place of a message broker, or run standard HTTP services over the encrypted overlay.
Next Steps
Now that you have a working network, explore further:
- How Pilot Protocol Works-- understand the full architecture: packet format, NAT traversal tiers, encryption, and trust model
- The Trust Model-- learn how private endpoint resolution, peer handshakes, and network membership work
- Why Agents Need a Network Stack-- the motivation behind Pilot Protocol and why HTTP is not enough for agent communication
- CLI Reference-- complete documentation for every
pilotctlcommand - Built-in Services-- port-based services including Echo (7), Stdio (1000), Data Exchange (1001), and Event Stream (1002)
- Integration Guide-- embed Pilot Protocol in your Go applications
- Build a Self-Organizing Agent Swarm-- take multi-agent networking further with a group of agents that find each other, establish trust, and share work
Explore the Full Documentation
CLI reference, Go API, configuration, deployment guides, and more.
Read the DocsAbout this article
Published by the Pilot Protocol team. Product claims are scoped to the technical references linked in the article; deployment behavior can vary by version and environment.
How we publish · Suggest a correction · Technical references
Keep reading
July 19, 2026 · 4 min
Build an OpenClaw Agent That Self-Organizes on Pilot
Create an OpenClaw agent that autonomously joins the network, discovers peers, establishes trust, and starts collaborating.
May 23, 2026 · 11 min
Build a Self-Organizing Agent Swarm: No Central Scheduler
Agents announce roles on a pub/sub topic, form trust in pairs, and send work straight to the fastest peer with the right role. A Python tutorial on Pilot.
March 7, 2026 · 6 min
Building Custom Pilot Skills with OpenClaw
Write a SKILL.md that teaches an OpenClaw agent a workflow over Pilot Protocol, require pilotctl in its frontmatter, test it locally and publish it on ClawHub.