Connecting MCP Servers to Agents Across Any Network
Your MCP server can query a database, call an API, read a file system. But the agent holding those results cannot send them to another agent without building your own transport layer. This is the networking gap in the MCP ecosystem.
Pilot Protocol fills that gap. It gives every agent a permanent virtual address, encrypted peer-to-peer tunnels, NAT traversal, and hostname-based discovery. This article walks through the concrete problem and shows you how to connect MCP-equipped agents across any network — with zero networking configuration.
The Problem: MCP Stops at the Agent Boundary
MCP (Model Context Protocol) standardizes how agents access tools. An agent runs an MCP client, connects to MCP servers, and invokes tools through a structured JSON-RPC interface. This works well for the vertical axis: agent → tool.
But what about the horizontal axis? Agent A queries a Postgres database via MCP and gets 1,842 rows of sales data. Agent B needs those results to generate a report. How does Agent A send the data to Agent B?
Without a networking layer, your options are:
- HTTP webhooks — Agent B needs a public URL. Fails behind NAT. Requires a web server. No encryption by default.
- Message broker (Kafka, RabbitMQ, Redis) — Now you have infrastructure to manage, configuration to write, and a single point of failure.
- Shared database — Agent A writes results to a DB, Agent B polls for them. Latency. Complexity. Polling waste.
- Cloud pub/sub (SNS, Cloud Pub/Sub) — Vendor lock-in. API keys. Monthly bills. Egress charges.
Every one of these adds infrastructure, configuration, and failure modes. Every one requires Agent B to have a reachable endpoint or both agents to share a third-party service.
The core issue: MCP gives agents eyes and hands (access to data and tools). But it gives them no voice — no way to tell another agent what they found. Pilot provides that voice.
The Solution: One Install, Direct Connection
Pilot Protocol is a single binary that gives your agent a network identity, encrypted connections, and the ability to dial any other agent by hostname — regardless of NAT, firewall, or cloud provider.
Here is what the full flow looks like:
# Install Pilot (one command, under 30 seconds)
curl -fsSL https://pilotprotocol.network/install.sh | sh
# Start Agent A with a hostname
pilotctl daemon start --hostname analyst-agent
# Start Agent B on a different machine (same command)
pilotctl daemon start --hostname reporter-agent
# Agent A sends MCP query results to Agent B
pilotctl connect reporter-agent --message '{"rows":1842,"summary":"Q4 up 23%"}'
That is the entire setup. No YAML. No Docker. No cloud accounts. No port forwarding. Agent A dials Agent B by hostname, a trust handshake and encrypted tunnel are established automatically, and the data flows directly between them.
Architecture: MCP Vertical + Pilot Horizontal
Think of agent infrastructure as two orthogonal planes:
Vertical (MCP): Agent reaches down into systems. Queries databases, calls APIs, reads files, executes code. The agent talks to systems.
Horizontal (Pilot): Agent reaches across to peers. Discovers other agents, opens encrypted connections, sends messages, delegates tasks. The agent talks to agents.
Neither layer knows about the other. Your MCP configuration is unchanged. Your Pilot configuration is unchanged. At the application level, your agent code does both:
// Go example: Agent A — query via MCP, deliver via Pilot
// 1. Query database through MCP
results := mcpClient.CallTool("postgres", "query", map[string]any{
"sql": "SELECT * FROM sales WHERE quarter = 'Q4'",
})
// 2. Send results to peer agent via Pilot
d, _ := driver.New("/tmp/pilot.sock")
conn, _ := d.Dial("reporter-agent", 1001)
conn.Write(results.JSON())
conn.Close()
# Python example: Agent A — query via MCP, deliver via Pilot
import pilotprotocol as pilot
import mcp
# 1. Query database through MCP
async with mcp.Client("postgres-server") as client:
results = await client.call_tool("query", sql="SELECT * FROM sales")
# 2. Send results to peer agent via Pilot
async with pilot.connect("reporter-agent", port=1001) as conn:
await conn.send(results.to_json())
Crossing NATs: The Real Problem
The reason you cannot just "open a TCP connection" between two agents is NAT. 88% of networks involve NAT. Your MCP server is behind a firewall. Your peer agent is behind a different firewall. Neither has a public IP.
Pilot handles this transparently with three-tier traversal:
- STUN discovery — Determines your NAT type and public-facing endpoint.
- UDP hole-punching — For restricted and port-restricted cone NAT, the beacon coordinates simultaneous punches from both sides.
- Relay fallback — For symmetric NAT (unpredictable port mapping), data is relayed through the beacon. The relay only forwards opaque encrypted packets — it cannot read your data.
All of this is automatic. Your code dials a hostname. Pilot figures out the traversal strategy.
# This works whether the peer is on the same LAN, behind NAT, or across clouds
pilotctl connect reporter-agent --message '{"data": "..."}'
# ✓ Connected via hole-punch. RTT: 34ms. Encrypted.
Full Scenario: Database Agent → Report Agent
Let us walk through the complete flow for the most common MCP + Pilot pattern:
Agent A (analyst-agent):
- MCP servers: Postgres, Python executor
- Location: Corporate office, behind NAT
- Job: Query sales data, run analysis
Agent B (reporter-agent):
- MCP servers: Slack API, email
- Location: AWS EC2 instance
- Job: Receive insights, post to Slack, send email reports
Step 1: Install on both machines
# Same command on both machines
curl -fsSL https://pilotprotocol.network/install.sh | sh
Step 2: Start daemons
# Machine A (behind corporate NAT)
pilotctl daemon start --hostname analyst-agent
# Machine B (AWS EC2)
pilotctl daemon start --hostname reporter-agent
Step 3: Establish trust
# Agent A trusts Agent B
pilotctl trust add reporter-agent
# Agent B trusts Agent A
pilotctl trust add analyst-agent
Step 4: Agent A queries and delivers
# Agent A's application code
results = mcp_query("SELECT * FROM sales WHERE quarter = 'Q4'")
analysis = mcp_run_python(f"analyze({results})")
# Send to reporter — Pilot handles NAT, encryption, everything
pilot_send("reporter-agent", port=1001, data=analysis.to_json())
Step 5: Agent B receives and acts
# Agent B's application code — listening on port 1001
data = pilot_receive(port=1001)
mcp_call("slack", "post_message", channel="#reports", text=data["summary"])
mcp_call("email", "send", to="[email protected]", body=data["full_report"])
The entire data path is: Postgres → Agent A → Pilot tunnel (encrypted, direct) → Agent B → Slack/Email. No intermediary server. No broker. No shared infrastructure.
Multi-Agent Pipelines Over Pilot
The pattern scales to N agents. Each agent has different MCP tools, and they coordinate over Pilot tunnels:
# Pipeline: scraper → analyzer → reporter
# Each agent has its own MCP servers
# scraper (MCP: browser, fetch)
data = mcp_fetch("https://api.example.com/data")
pilot_send("analyzer", port=1001, data=data)
# analyzer (MCP: postgres, python)
raw = pilot_receive(port=1001)
insights = mcp_run_python(f"analyze({raw})")
pilot_send("reporter", port=1001, data=insights)
# reporter (MCP: slack, email)
results = pilot_receive(port=1001)
mcp_call("slack", "post_message", text=results["summary"])
Every link in the pipeline is a direct encrypted tunnel. No central orchestrator needed — each agent knows its upstream and downstream peers by hostname.
Discovering MCP Servers Behind NAT
A common pattern: you have an MCP tool server (say, a database wrapper) running behind NAT. Other agents need to discover and use it.
With Pilot, the MCP server machine registers a hostname:
# On the MCP server machine (behind NAT, no public IP)
pilotctl daemon start --hostname db-tool-server
Any trusted agent can now resolve and connect:
# On any other machine, anywhere
pilotctl connect db-tool-server --port 80
# ✓ Connected. NAT traversed automatically.
The MCP server never needs a public IP, a reverse proxy, or an ngrok tunnel. Pilot's hostname resolution + NAT traversal makes it reachable from any trusted agent on the network.
How This Differs From MCP + Pilot: Tools and Network
We published MCP + Pilot: Give Your Agent Tools AND a Network earlier, which covers the conceptual architecture: what each protocol provides and how they complement each other.
This article focuses on the practical networking problem:
- NAT traversal — Concrete walkthrough of how agents behind different firewalls connect
- Zero configuration — Emphasis on one-command install, no infrastructure to manage
- Code examples — Go and Python examples you can copy and run
- Full scenario — Step-by-step from install to data flowing between agents
If you want the "why" — read the original post. If you want the "how" — you are in the right place.
Get Started
# Install (30 seconds)
curl -fsSL https://pilotprotocol.network/install.sh | sh
# Or with Python
pip install pilotprotocol
That is it. One command. Your MCP-equipped agent now has a network.