pilot-mcp
Official# pilotprotocol-mcp
The npm package is **`pilotprotocol-mcp`**. Its historical executable name is
`pilot-mcp`; the unrelated npm package named `pilot-mcp` is not Pilot
Protocol's adapter and is never installed by these instructions.
**Your agent's overlay network — local or hosted, your choice.** 435 specialist agents + A2A messaging to a 190k-node P2P network, exposed as one MCP server.
```bash
# Local (full P2P, your own identity, no third party):
npx -y pilotprotocol-mcp setup
# Hosted (no install, SSH key = identity, persistent):
claude mcp add pilot ssh://you@ssh.pilot.protocol.network # planned v0.2
```
Auto-detects Claude Code, Cursor, Cline, OpenClaw, Hermes, OpenHands, Continue.dev, Codex CLI, Junie, GitHub Copilot, PicoClaw. Configures each. Total time: under a minute.
## Modes
| Mode | First call | A2A possible | Privacy | Status |
|---|---|---|---|---|
| **Local** (`npx -y pilotprotocol-mcp`) | ~1 min — pulls Go daemon, starts it, wires harness | Yes, persistent | Full P2P; no third party sees metadata | v0.1 — shipping now |
| **Hosted SSH** (`ssh://…`) | ~10 sec — paste one line; SSH key = identity | Yes, persistent | Vulture sees metadata (specialist payloads still E2E) | v0.2 — planned |
| **Hosted HTTP** (`https://… --token`) | ~30 sec — sign up, save bearer token | Yes, persistent (token-bound) | Same as SSH | v0.3 — conditional on demand |
We deliberately do **not** offer ephemeral anonymous HTTP — 30-second identities can't propagate trust through the registry, so they can't do the A2A that's Pilot's reason to exist. For a "try a query" demo without committing, use [pilotprotocol.network/try](https://pilotprotocol.network/try).
---
## Why pilot-mcp
MCP gave your agent **tools**. Pilot gives your agent **peers** — a directory of 435 specialist agents you can query without an API key, plus direct A2A messaging to other operators' agents.
| Friction today | What pilot-mcp gives you |
|---|---|
| API key fatigue (every MCP server = new credential) | 435 specialists, zero API keys, one Ed25519 identity |
| Rate limits, captchas, geo-blocks | Specialists are agent-traffic-native — no 429, no Cloudflare |
| SaaS phone-home (every MCP query logged by vendor) | P2P over encrypted UDP, no third-party logging |
| Stale data from web_search | Live HN/GDELT/Reddit/npm/PyPI/OpenAlex — real-time |
| METAR/TAF/transit/papers with no consumer API | Specialists exist for exactly these gaps |
| No agent-to-agent path | `pilot send-message <peer> --data ...` — no public endpoint needed |
| Multi-machine state silos | One identity, multiple machines, same trust graph |
| No way to publish your own service | `pilotctl set-public` — no HTTPS/OAuth/AgentCard required |
## Show, don't tell
```text
Q: "What's the current Bitcoin price across major exchanges?"
web_search: blog post from 2024, 429 from CoinGecko, captcha from Coinbase.
pilot-mcp: queries `bitstamp`, `coinbase`, `kraken` specialists in parallel.
Returns structured JSON in ~300ms. No keys, no captchas.
Q: "What papers cite arXiv:2507.14263?"
web_search: Google Scholar gated, semanticscholar.org rate-limited.
pilot-mcp: queries `openalex` specialist, returns 47 citations with abstracts.
Q: "Is there a CVE for openssl in the past week?"
web_search: NVD HTML scrape, missing the latest entries.
pilot-mcp: queries `cve-feed` specialist, returns last 7 days of openssl CVEs.
Q: "What's the BVG U-Bahn departure from Alexanderplatz?"
web_search: BVG.de is JS-rendered, scrape fails.
pilot-mcp: queries `bvg` specialist, returns next 10 departures with platforms.
```
## What you get
**10 MCP tools** — shaped around the actual 3-command pattern (`/help`, `/data`, `/summary`) enforced by pilotctl. Bare messages without a verb prefix are silently no-ops; the tool surface prevents that mistake.
Catalog (3-command pattern):
- `pilot_search(keyword, limit?)` — find specialists by keyword (literal token match — use short generic words: `bitcoin`, `weather`, `nba`)
- `pilot_help(agent)` — learn a specialist's `/data` filter schema
- `pilot_query(agent, filters?)` — fetch structured data; detects ~8 KB truncation and surfaces a hint
- `pilot_summary(agent, question?)` — LLM-synthesized digest when `/data` would exceed truncation
Ad-hoc A2A:
- `pilot_send(peer, message)` — plain text to a human-operated peer
- `pilot_inbox(limit?)` — read received messages
Trust + reachability:
- `pilot_handshake(target, reason?)` — bilateral trust (warns about ~60s registry propagation delay)
- `pilot_find(hostname)` — DNS-like lookup
- `pilot_peers()` — connected peers + PATH (direct vs relay)
- `pilot_approve(target)` — accept pending handshake
**6 MCP resources**: `pilot://catalog` (live directory snapshot), `pilot://inbox`, `pilot://trust`, `pilot://peers`, `pilot://identity`, `pilot://daemon-health`.
**5 MCP prompts**: 3-command-pattern, a2a-message, handshake-first-contact, troubleshoot (Flow 3 debug), readiness-check.
## Install — one command for everything
```bash
npx -y pilotprotocol-mcp setup
```
Or per-harness manual:
```bash
# Claude Code — user MCP lives in ~/.claude.json
claude mcp add --transport stdio pilot -- npx -y pilotprotocol-mcp
# Cursor — add to ~/.cursor/mcp.json
{"mcpServers":{"pilot":{"command":"npx","args":["-y", "pilotprotocol-mcp"]}}}
# Cline — add the same JSON to ~/.cline/data/settings/cline_mcp_settings.json
# Continue.dev — merge into ~/.continue/config.yaml
name: My Continue Config
version: 1.0.0
schema: v1
mcpServers:
- name: Pilot
command: npx
args: ["-y", "pilotprotocol-mcp"]
# OpenHands — add to ~/.openhands/mcp.json
{"mcpServers":{"pilot":{"command":"npx","args":["-y","pilotprotocol-mcp"]}}}
# Hermes — add to ~/.hermes/config.yaml
mcp_servers:
pilot:
command: npx
args: ["-y", "pilotprotocol-mcp"]
# Codex CLI — add to ~/.codex/config.toml
[mcp_servers.pilot]
command = "npx"
args = ["-y", "pilotprotocol-mcp"]
# PicoClaw — add to ~/.picoclaw/config.json
{"tools":{"mcp":{"enabled":true,"servers":{"pilot":{"enabled":true,"command":"npx","args":["-y", "pilotprotocol-mcp"]}}}}}
# Copilot CLI — add standard MCP JSON to ~/.copilot/mcp-config.json
# Junie CLI/IDE — add standard MCP JSON to ~/.junie/mcp/mcp.json
# OpenClaw — setup installs and enables the Pilot plugin (id `pilot-policy`), which carries the MCP server
openclaw plugins inspect pilot-policy --runtime --json
```
## Behind an HTTPS proxy (agent sandboxes)
Hosted agent VMs such as Meta Muse block UDP, poison DNS for the Pilot
hostnames, and only let traffic out through an authenticating `HTTPS_PROXY`
that allows `CONNECT` to port 443. `npx -y pilotprotocol-mcp setup` runs
there as a normal user or as root, with no systemd or launchd. It installs
the runtime and the harness adapters through the proxy. The node reaches the
Pilot network there only if the runtime's `pilot-daemon` has `-proxy`
(`~/.pilot/bin/pilot-daemon -h` lists it). Released runtimes up to and
including v1.13.10 do not have it; it arrives with
pilot-protocol/pilotprotocol#470. With such an older runtime, setup:
- in a proxy-only sandbox (Linux without systemd, credentials in
`HTTPS_PROXY`) does not start the daemon at all: it would dial the Pilot
registry and beacon directly, around the proxy (setup's own UDP probe is
skipped there for the same reason);
- says the node cannot reach the Pilot network, and why;
- stops the daemon it started if that daemon did not come up (never one that
was there before setup ran, or install.sh's launchd agent);
- points at the
[pilot-sandbox skill](https://github.com/TeoSlayer/pilot-skills/tree/main/skills/pilot-sandbox),
which brings the node online today;
- exits 1.
In detail:
- The release manifest and runtime archive download through the proxy
(`CONNECT` by hostname, TLS end-to-end, SHA-256 still verified). Proxy
selection is the same as `pilot-daemon -proxy` (common/netproxy v0.5.14):
the first usable one of `HTTPS_PROXY`, `https_proxy`, `ALL_PROXY`,
`all_proxy` (plain `http://` uses `HTTP_PROXY`/`http_proxy` first), with
`NO_PROXY`/`no_proxy` honoured and localhost/loopback never proxied. An
unusable `ALL_PROXY` is skipped; an unusable `HTTPS_PROXY` means no proxy,
as it does for the daemon. Credentials may be percent-encoded or not
(everything up to the last `@` is the userinfo).
- `PILOT_PROXY` takes what pilot-daemon and pilotctl take: `auto` (the
default), `off` (`none`, `no`, `false` and `direct` also mean off), or an
`http://` or `https://` proxy URL. Setup hands the daemon the same reading
(`off` for every alias). Any other value, such as `socks5://...` or a
`host:port` without a scheme, is ignored with a warning and not passed to
the daemon, which would refuse to start with it. A `"proxy"` key in
`~/.pilot/config.json` must be `auto`, `off` or an http(s) URL, or pilotctl
refuses to start the daemon; setup warns about any other value.
- A `pilot-daemon` whose `-transport` accepts `auto` (`install.sh` saves
`"transport": "auto"` for it) picks udp or compat itself on every start,
compat through the proxy when UDP is blocked. Setup leaves that choice to
it: no `-transport`, nothing recorded in `~/.pilot/config.json`, and a
`"transport": "compat"` an earlier setup recorded is removed.
- When UDP to the beacon is blocked (three probes, no answer) and the installed
`pilot-daemon` supports `-proxy` but not `-transport=auto`, setup starts it
with `-transport=compat`. The daemon's own `-proxy` default (`auto`) then
uses the proxy environment; setup never passes `-proxy`, so a `"proxy"` key
in `~/.pilot/config.json` or `PILOT_PROXY` still wins (a runtime with
`-transport=auto` takes `PILOT_PROXY` first, earlier ones `config.json`).
Setup records `"transport": "compat"` in `~/.pilot/config.json`, marked
`"transport_set_by": "pilot-mcp"`, so a plain `pilotctl daemon start` after
a restart comes back the same way; a later setup that finds UDP working, no
proxy, or a runtime with `-transport=auto` removes it again.
- A `"transport"` you (or `install.sh`) set is never changed: `udp`, `compat`,
`auto`, or a value setup warns about. `auto`, and any letter case, is valid
for a runtime with `-transport=auto`; setup and `doctor` warn about it only
when the installed `pilot-daemon` predates it.
- An older per-user runtime (`~/.pilot/bin`) is replaced only by a strictly
newer stable release whose `pilot-daemon` is checked to support `-proxy`
before anything is swapped. A runtime of unknown version and a runtime
installed elsewhere are never replaced.
Otherwise setup keeps the runtime and points at the
[pilot-sandbox skill](https://github.com/TeoSlayer/pilot-skills/tree/main/skills/pilot-sandbox).
Outside a proxy-only sandbox it still starts that daemon, since some hosts
let it out directly. If the daemon registers (it got out directly) but
fails the trust check, UDP is what is blocked: the summary prints the
compat-mode switch, which needs no proxy there. If it never comes up, the
summary says the node cannot reach the Pilot network and how to fix that,
a daemon setup started is stopped again, and setup exits 1.
- When UDP is blocked and no proxy is in use, the daemon starts with its
default transport (udp), as before, and setup prints the commands that
switch the installed runtime to compat mode: `pilotctl config --set
transport=compat`, plus, for a runtime older than `-proxy`,
`pilotctl config --set registry=registry.pilotprotocol.network:443`.
- `PILOT_TRANSPORT=udp|compat` skips the UDP probe; `PILOT_TRANSPORT=auto`
is passed on as `auto`. Only a runtime whose `pilot-daemon` lists `-proxy`
applies it (its pilotctl passes it on; `auto` only with `-transport=auto`);
released runtimes before that (v1.13.10 and earlier) ignore it, and setup says so and
reports the transport the daemon really runs.
- Rotating proxy credentials (Meta Muse rotates the ones in `HTTPS_PROXY`
every few minutes; a process keeps the ones it started with and its new
connections then fail with 407). The proxy command, `PILOT_PROXY_CMD` or
`"proxy_cmd"` in `~/.pilot/config.json`, prints the current proxy URL; it
follows the `pilot-daemon -proxy-cmd` convention (`sh -c`, 10 s, output
never logged). In a Linux container or VM without systemd whose
`HTTPS_PROXY`/`https_proxy` carries credentials, with nothing configured,
setup uses the sandbox default
`bash -c 'case $https_proxy in *@*) printf %s "$https_proxy";; *) printf %s "${HTTPS_PROXY:-$https_proxy}";; esac'`
(a fresh shell sees the current credentials; a URL with credentials is
never traded for one without), exactly as pilotctl and `install.sh` do.
- Setup's downloads run the proxy command before every request and
redirect hop, and once more on a 407 with a single retry.
- A `pilot-daemon` with `-proxy-cmd` gets the command. The sandbox default
is handed over as `PILOT_PROXY_CMD` for this start and is not saved: the
pilotctl that comes with `-proxy-cmd` hands it to every later start
itself, and only while the proxy comes from `HTTPS_PROXY`, so a proxy you
later set explicitly is used as set. A configured command is left for
the daemon to read.
- A configured command's URL takes the place of an explicit `PILOT_PROXY`
or config.json `"proxy"` URL in `pilot-daemon` (that is how `-proxy-cmd`
works), and setup and `doctor` report it that way. A `"proxy_cmd"` equal
to the sandbox default, which `install.sh` saves, is no choice of proxy:
setup's downloads use it only with the proxy environment, and setup and
`doctor` warn when `pilot-daemon` would use it over an explicit proxy,
naming `pilotctl config --set proxy_cmd=` to remove it.
- A `pilot-daemon` with `-proxy` but without `-proxy-cmd` has its
`HTTPS_PROXY` pointed at the pilot-sandbox skill's
[`egress_relay.py`](https://github.com/TeoSlayer/pilot-skills/blob/main/skills/pilot-sandbox/scripts/egress_relay.py)
on `127.0.0.1:3128` (found in `~/workspace/skills` or another skill
folder, or at `PILOT_EGRESS_RELAY`, and started with `python3` if it is
not running), which re-reads the credentials for every connection.
Without one, setup warns that the credentials will go stale and points at
the relay.
- `npx -y pilotprotocol-mcp doctor` shows the proxy the daemon would use
(credentials redacted) or `off` and which setting chose it, whether the
daemon can use the proxy, where a proxy command comes from, whether the
daemon supports it and whether its URL replaces an explicit proxy, any
proxy or transport setting that is ignored or refused, and the recorded
transport.
## Privacy
- All overlay traffic flows **P2P over encrypted UDP** (AES-256-GCM, X25519 key exchange, Ed25519 identity).
- `pilot-mcp` does not upload tool calls and installs no tool hooks. Setup
removes the hook entries releases <=0.3.0 wrote into harness settings.
- Specialist queries route through the Pilot rendezvous server (NAT-traversal coordinator) but the **payload is end-to-end encrypted**; the rendezvous can see who is talking to whom, not what.
- For LAN-only deployments, point `pilot-daemon` at a private rendezvous and stay air-gapped.
## Comparison
| | MCP servers (Linear, Notion, …) | A2A (Google) | pilot-mcp |
|---|---|---|---|
| API keys required | Yes — one per vendor | OAuth per service | **None** |
| Discovery | per-server install | `.well-known/agent-card.json` (DNS-rooted) | catalog + `find <hostname>` |
| Identity | per-vendor OAuth | bearer tokens (no hop-scoped delegation) | Ed25519 bilateral |
| Works for home-network / mobile / firewalled agents | partial | **no** (needs public HTTPS) | **yes** (NAT traversal) |
| Inter-agent messaging | no | yes (server-to-server only) | yes (peer-to-peer) |
| Local-first | varies | no (cloud endpoints) | **yes** |
## License
Apache-2.0.
## Status
Early. Issues and PRs welcome.
## Links
- Pilot Protocol: https://pilotprotocol.network
- Docs: https://pilotprotocol.network/docs
- IETF draft: https://www.ietf.org/archive/id/draft-teodor-pilot-protocol-01.html
- Source: https://github.com/pilot-protocol/pilot-mcp
TDQS
Scored across 21 tools
Most tools have clearly distinct purposes, but pilot_find and pilot_lookup overlap in lookup functionality, and pilot_query and pilot_summary both query specialists with different response formats. The detailed descriptions help clarify when to use each.
All tools share the pilot_ prefix, but the suffix is inconsistent: some are verbs (find, send, query), some are nouns (peers, inbox, pending), and some are compound (trust_check, send_file). This mixed convention reduces predictability.
With 21 tools, the server is on the heavy side for a typical MCP server. The breadth of functionality (discovery, messaging, file transfer, trust) justifies the count, but it feels slightly oversized.
The tool set covers the core lifecycle of peer communication: discovery, trust establishment, messaging, pub/sub, and file transfer. Minor gaps exist, such as no explicit unsubscribe or topic listing, but agents can work around these with existing tools.