If you have ever tried connecting two AI agents running on different machines, you already know the moment things break. Local dev works perfectly. The second you put one agent on an EC2 instance and another on your laptop behind a home router, they cannot reach each other. You reach for ngrok. Or you spin up a message broker. Or you start writing a relay server. None of these feel like the right answer because they are not.
I built Pilot Protocol to fix exactly this. It gives every agent a permanent virtual address and handles NAT traversal automatically, so two agents on completely different networks can connect directly with a single command. No port forwarding. No ngrok. No relay server sitting in the middle reading your traffic.
Try it in 5 minutes
Here is the fast path. Install on two machines, register them, connect.
Machine 1 (your laptop, behind home NAT):
# Install Pilot Protocol
curl -fsSL https://pilotprotocol.network/install.sh | sh
# Start the daemon and register a hostname
pilotctl daemon start --hostname agent-alpha
# Output:
# STUN: discovered public endpoint 73.162.88.14:4000 (port_restricted_cone)
# Registered as agent-alpha (0:A91F.0000.7C2E)
Machine 2 (EC2 instance, different network entirely):
curl -fsSL https://pilotprotocol.network/install.sh | sh
pilotctl daemon start --hostname agent-beta
# Output:
# STUN: discovered public endpoint 54.211.34.99:4000 (restricted_cone)
# Registered as agent-beta (0:B84C.0000.3F11)
Establish mutual trust and connect:
# From agent-alpha: initiate handshake
pilotctl handshake agent-beta "requesting connection"
# From agent-beta: approve
pilotctl approve agent-alpha
# Ping across the tunnel
pilotctl ping agent-beta --count 4
# PING agent-beta:
# Reply: 11ms (hole-punched, encrypted)
# Reply: 11ms
# Reply: 12ms
# Reply: 11ms
# 4 packets, 0% loss, avg 11ms
Direct peer-to-peer. Encrypted. No relay. No configuration beyond curl and a hostname.
Why every other solution falls short
The real problem with NAT is that it is not one problem. RFC 3489 defines four NAT types and each one breaks differently. About 15% of networks are full cone NAT, where a direct connection just works. Another 60% are restricted or port-restricted cone NAT, where you need hole-punching. The remaining 25% are symmetric NAT, the kind you find behind corporate firewalls and carrier-grade NAT, where a relay is the only option.
ngrok solves reachability for a single endpoint but it does not scale. With 10 agents you need 10 tunnels and the cost compounds fast. It also routes all your traffic through ngrok's servers, which is a problem if your agents are handling anything sensitive.
A message broker solves the coordination problem but adds two hops to every message, creates a single point of failure, and terminates your encryption at the broker. The broker can read everything passing through it.
VPNs like Tailscale work well for human-managed devices but the overhead is prohibitive for ephemeral agent fleets. You cannot provision WireGuard keys for agents that spin up and down dynamically at any real scale.
Pilot handles all four NAT types automatically. It tries a direct connection first, falls back to UDP hole-punching for restricted NAT, and falls back to an encrypted relay only for symmetric NAT. Even in relay mode, the relay server forwards opaque encrypted bytes and cannot read your traffic. The application layer sees none of this machinery.
What this looks like with MCP
The most common place this pain shows up in 2026 is MCP server deployments. You build an MCP server wrapping a local database or a proprietary tool. It runs on a machine behind NAT. Your agent is somewhere else. MCP does not solve the transport problem, it assumes the server is reachable.
With Pilot, you register the MCP server machine once and it becomes reachable from any trusted agent regardless of network topology:
# On the MCP server machine (behind NAT, no public IP)
pilotctl daemon start --hostname db-tool-server
# From any agent with trust established
pilotctl connect db-tool-server --port 80
# Connected. NAT traversed. Encrypted tunnel established.
In code, the pattern is clean. MCP handles the vertical axis (agent to tools). Pilot handles the horizontal axis (agent to agent):
import pilotprotocol as pilot
import mcp
# Agent queries its local MCP tools
async with mcp.Client("postgres-server") as client:
results = await client.call_tool("query", sql="SELECT * FROM orders WHERE status = 'pending'")
# Agent sends results directly to a peer agent over an encrypted P2P tunnel
async with pilot.connect("analyst-agent", port=1001) as conn:
await conn.send(results.to_json())
The MCP configuration is unchanged. The peer networking is a separate layer underneath.
How the trust model works
Agents are private by default. There is no discoverable endpoint, no public capability listing, nothing visible until a mutual handshake is complete. Either side can revoke trust instantly:
# Revoke access
pilotctl revoke agent-beta
# agent-beta is now unreachable, connection drops at next heartbeat
This matters more than it sounds. HTTP-based agent frameworks are typically discoverable by default. For agents handling sensitive data or running without continuous human supervision, you want private-by-default with explicit opt-in, not the other way around.
The network today
The Pilot Protocol network is live. It is currently running 79,000 online nodes, has processed over 7.4 billion requests, and has maintained above 99.79% uptime across all core services since launch.
The protocol has two IETF Internet-Drafts published and was presented at the CATALIST Birds of a Feather session, which is the working group looking at agent communication standards.
Get started
curl -fsSL https://pilotprotocol.network/install.sh | sh
Docs, architecture deep-dives, and the Go source are at pilotprotocol.network. If this is useful, a GitHub star goes a long way.
What NAT or connectivity problem are you hitting in your agent work? Drop it in the comments and I will reply to everything.