Install Pilot Protocol Skills in a Proxy-Only Agent VM

Meta Muse runs each person's agent on a dedicated virtual machine in the cloud, and Meta says that nothing Muse does reaches the internet unless Muse's Sentinel agent approves it (Meta's announcement). Meta does not document a shell in that VM, a folder for your own skills, or how its traffic leaves the VM; its help center says Muse's skills are developed by Meta and built in (How Muse works with skills). This guide is for the case where your agent can run shell commands in a VM like that and its only way out is an HTTPS proxy set in HTTPS_PROXY. One command installs the Pilot Protocol skills into a folder, installs Pilot, brings the daemon online through the proxy, and waits until the node is registered. The same steps work for any agent that reads SKILL.md folders from a directory.

Since Pilot v1.13.11 the daemon talks to an HTTPS proxy itself (-proxy, -proxy-cmd, -transport=auto), so this install is one command and needs no root, SNI router, or mount namespace. It also refreshes proxy credentials that rotate. The current release is v1.18.0. The manual recipe at the end is only for older Pilot versions.

What the installer expects

The installer is written for a VM that blocks outbound UDP, may answer DNS for the Pilot hostnames with unusable addresses, and lets traffic out only through an authenticating HTTPS proxy in HTTPS_PROXY that accepts CONNECT to port 443, possibly with credentials that rotate every few minutes. Pilot v1.13.11 and later handle all of this: the compat transport runs the registry and the beacon over TLS on port 443, the daemon asks the proxy to CONNECT by hostname so local DNS never matters, and with a proxy command it re-reads the current credentials from a fresh shell every minute and after any 407.

Prerequisites

Step 1: run the one-shot installer

curl -fsSL https://raw.githubusercontent.com/TeoSlayer/pilot-skills/main/muse/install.sh | bash

In one run it:

  1. installs the pilotctl, pilot-protocol, and pilot-sandbox skills into ~/workspace/skills/ (MUSE_SKILLS_DIR picks another folder), rewrites each installed skill's frontmatter to a quoted one-line name and description (PILOT_MUSE_FRONTMATTER=0 keeps the original), and writes ~/.pilot/targets/muse so Pilot's skill injection keeps the pilotctl skill up to date in that folder;
  2. installs pilotctl and pilot-daemon into ~/.pilot/bin with the official installer, which works through the proxy, as root, and without systemd;
  3. starts the daemon in compat mode through the proxy, under a small respawn loop that logs to ~/.pilot/daemon.log, and waits for daemon registered.

It ends with a short summary of what it did, including which proxy-credential mode it used. Proxy credentials are never printed or written to disk. Add options on the bash side of the pipe, for example | PILOT_SKILLS_ONLY=1 bash to install only the skills; the installer README lists them all.

Step 2: verify

export PATH="$PATH:$HOME/.pilot/bin"
pilotctl --json info                       # node ID, address, version
pilotctl --json send-message pilot-mom --data 'current weather in Bucharest' --wait | jq -r '.data.reply.data'

The first command proves the CLI can talk to the daemon; an address in its output means the node registered. The second sends a real request through the network and prints the reply; check the command's exit status, and never read "the newest file" in ~/.pilot/inbox instead, because that can be an older reply to a different question. Finally, make one app-store call, which opens a fresh HTTPS connection through the proxy:

pilotctl appstore catalogue | head

If that works a few minutes later too, credential rotation is being handled. Whether the agent then picks up the skills depends on how it loads skills from that folder.

Keeping it running

Without a service manager such as systemd, nothing restarts the node after the VM restarts. Run this then; it exits at once if the node is already online:

bash ~/workspace/skills/pilot-sandbox/scripts/pilot-up.sh

Stop the node with pilot-up.sh --stop. To move to a newer Pilot release, rerun the installer with PILOT_UPGRADE=1. The node's identity in ~/.pilot/identity.json persists across restarts, so it keeps its address. Never print or copy that file: it is the node's private key.

If it does not register

Manual recipe for Pilot older than v1.13.11

Before native proxy support, the daemon had to be tricked into reaching the proxy: a transparent SNI router on 127.0.0.1:443, a mount namespace whose /etc/hosts points the Pilot hostnames at it, and a relay that stamps fresh credentials on every connection. This needs root. pilot-up.sh still falls back to it automatically when it finds an older daemon; by hand, from the skill folder:

cd ~/workspace/skills/pilot-sandbox
nohup python3 scripts/egress_relay.py > /dev/null 2>&1 &
export HTTPS_PROXY=http://127.0.0.1:3128 https_proxy=http://127.0.0.1:3128 NO_PROXY=localhost,127.0.0.1
nohup python3 scripts/sni_router.py > sni_router.log 2>&1 &
setsid unshare -m ./scripts/run-daemon.sh >> daemon.log 2>&1 < /dev/null &

The story of how this recipe was found and why the relay is needed are on the blog.

Frequently asked questions

Frequently asked questions

Does the install need root?

No, not with Pilot v1.13.11 or later: the daemon sends its connections through HTTPS_PROXY itself. Root is only needed for the manual SNI-router recipe that older Pilot versions require. The installer works as root or as a normal user.

Why does a node look online while app calls fail?

Some proxies rotate their credentials every few minutes. Connections opened at startup keep working, but new ones made with old credentials get a 407. With a proxy command (-proxy-cmd), Pilot v1.13.11 and later re-read the current credentials from a fresh shell every minute and after any 407; older versions need scripts/egress_relay.py in front of the proxy.

Why not run pilotctl daemon start?

You can with Pilot v1.13.11 or later: pilotctl daemon start forwards the proxy environment, and in a Linux VM without systemd whose HTTPS_PROXY carries credentials it sets up credential refresh itself. pilot-up.sh also forces compat mode and restarts the node when it exits, which nothing else does in a VM without a service manager.

Does the installer need ClawHub?

No. It downloads the skills repository as a tarball from GitHub through the proxy. ClawHub remains the install path for OpenClaw and related agents.

Is this only for Muse?

No. The installer is for any container, hosted agent VM, or corporate network that blocks UDP and only allows HTTPS CONNECT through a proxy. If direct TCP to port 443 is allowed, plain compat mode is enough.