Remote Pi — Mobile Control and Agent Mesh

Remote Pi — Mobile Control & Local Agent Mesh for the Pi Coding Agent

Pair your phone via QR, watch tool calls live, run multi-agent sessions over Unix sockets, and let agents talk to each other — all from a single slash command.

jacobmoura7 · v0.4.2 · Published Jun 2, 2026 · MIT License
📦 Pi Extension 🎤 jacobmoura7 🏢 Pi Ecosystem 🏷 Agent Mesh · Mobile Remote · Multi-Agent · Unix Sockets · Daemon Mode

📋 Overview

Remote Pi is a Pi extension that adds two independent superpowers to the Pi coding agent: a local agent mesh where multiple Pi instances discover each other and exchange structured messages over Unix domain sockets, and a mobile companion app that lets you drive Pi from your phone via a WebSocket relay with QR-code pairing. Both are activated with a single /remote-pi slash command.

1 What Is Remote Pi?

Remote Pi is an open-source extension (npm:remote-pi, v0.4.2, MIT) for the Pi coding agent that adds two independent layers:

  • Agent Network (local) — multiple Pi instances on the same machine discover each other via a Unix domain socket broker and exchange structured messages. The LLM gets agent_send and agent_request tools to talk to other agents directly.
  • Mobile App (over relay) — a companion app for iOS/Android that sends prompts to Pi and receives responses through a WebSocket relay. Pairing is one-time via QR code.

Both features are wired together by a single /remote-pi slash command. On first run, a short wizard asks three questions (agent name, session name, auto-start relay). After that, /remote-pi joins the mesh and starts the relay automatically.

One slash command, two superpowers: agents that talk to each other on the same machine, and a mobile app that drives Pi from your phone.

2 Quick Start

Install the extension (one-time):

pi install npm:remote-pi

Then in any Pi terminal:

/remote-pi

The first run shows the interactive wizard. On every following run, it joins the local agent session and starts the relay automatically.

Try the Agent Network in 30 Seconds

Open two Pi terminals in the same directory and run /remote-pi in each. Both join the same session. Then in terminal A:

Who else is connected in our agent session? List them.

The LLM calls agent_send to broker with { type: "list_peers" } and replies with the names it sees. Then:

Send a ping to agent-B and wait for a reply.

Pi calls agent_request({ to: "agent-B", body: { type: "ping" } }). The message arrives in terminal B as a user-facing turn — terminal B's LLM answers, and the reply lands back in terminal A. Two agents, one prompt each, full round trip.

3 Agent Network — Local Multi-Agent Mesh

The agent network connects multiple Pi instances running in different terminals on the same machine. Each instance is a peer in a named session and gets two LLM-callable tools:

  • agent_send — fire-and-forget message to another agent (or multicast to several)
  • agent_request — send and await a reply, correlated by message ID (default 30s timeout)

Communication is purely local via Unix domain socket at ~/.pi/remote/sessions/<session-name>/broker.sock. No network involved.

Leader Election & Failover

The first agent to enter a session becomes the leader (hosts the broker). Others are followers. If the leader exits, a follower automatically takes over — the failover is invisible to the LLMs.

Use Cases

Split work across roles — backend, frontend, tests, orchestrator — and let them coordinate through structured messages. Name collisions inside a session get automatic numeric suffixes (backend, backend#2, backend#3).

4 Mobile App — Drive Pi from Your Phone

The companion app lets you send prompts to Pi and read responses from your phone. Pairing is one-time per device via QR code:

/remote-pi pair

Scan the QR with the Remote Pi mobile app. Pairing is per-machine — once paired, every Pi process on the machine accepts the device.

Quick Actions

Beyond chat, the app surfaces typed actions via the ⚙ button:

  • Compact context — runs ctx.compact() (same as /compact)
  • New session — runs ctx.newSession() with confirmation
  • Model — picker fed by your authenticated providers
  • Thinking — 6 levels: off · minimal · low · medium · high · xhigh

Image Support

Attach one image (camera or gallery) to a message. It's compressed on-device and sent inline as base64. The extension converts it to the SDK's multimodal content format. Models without vision grey out the attach button automatically (based on the vision flag on each WireModel).

5 The Relay — How Phone Meets Agent

The relay is the only network-touching piece of Remote Pi — a WebSocket server that ferries messages between the phone and Pi.

  • What the relay sees: connection metadata — which keypair is online, room/cwd identifiers, message timing, sizes
  • What it doesn't see: message content (encrypted end-to-end between Pi and paired device)

Community Relay (Default)

https://relay-rp1.jacobmoura.work — zero setup, best-effort availability. Good for trying things out. The extension converts to wss:// internally.

Resolution Order

  • REMOTE_PI_RELAY env var (highest precedence — for CI/one-off overrides)
  • ~/.pi/remote/config.json
  • Built-in default (community relay)

6 Self-Hosting the Relay

For privacy, run the relay yourself in Docker behind a VPN (Tailscale, WireGuard, or VPC). This adds defense in depth — only your devices can even reach the WebSocket port.

docker run -d \
  --name remote-pi-relay \
  -p 3000:3000 \
  --restart unless-stopped \
  ghcr.io/jacobaraujo7/remote-pi-relay:latest

Bind the container to your VPN interface, terminate TLS in a reverse proxy, then point Pi at it:

/remote-pi relay url https://relay.yourdomain.tld

The URL must be http:// or https://ws:///wss:// are rejected at validation. The mobile app has its own relay-URL setting in preferences — keep both pointing at the same relay.

Self-hosting is recommended for any production or privacy-sensitive use. The relay image is lightweight and only ferries encrypted blobs.

7 Agent Messaging — Wire Format & Tools

The wire format is a 5-field envelope serialized as one JSON line per message:

{ from, to, id, re, body }

The two LLM-exposed tools:

// Fire-and-forget
agent_send({
  to: "backend",      // peer name (or array for multicast)
  body: { task: "add /healthz endpoint" },
  re: "<id>"          // optional — set when replying
})

// Send + await reply (default 30s timeout)
agent_request({
  to: "backend",
  body: { question: "is the migration applied?" }
})

The leader's broker writes an audit.jsonl log at ~/.pi/remote/sessions/<name>/audit.jsonl for postmortem inspection.

8 Daemon Mode — 24/7 Background Agents

Promote any Pi session to a daemon managed by an OS-level supervisor. The agent keeps running — responding to mobile prompts at 3am, processing cron jobs, monitoring folders.

One-Time Setup

# Install globally for CLI binaries
npm install -g remote-pi

# Install supervisor as system service
# Linux: systemd --user | macOS: launchd LaunchAgent
remote-pi install

Per-Folder Workflow

# 1. Configure interactively first
cd ~/Movies
pi    # run /remote-pi → setup wizard

# 2. Promote to daemon
remote-pi create ~/Movies --name "Video Editor"
# → Daemon registered: id=4e39152d

# 3. Start all daemons
remote-pi daemon start

The supervisor spawns pi --mode rpc for each registered folder. Daemons auto-restart on login and survive reboots.

Caveats

  • Tool approval not gated — daemons inherit Pi's config; Bash/Edit/Write execute without prompting. Configure tool permissions before promoting.
  • One daemon per cwd — the room ID is derived from the realpath; duplicate registrations are rejected.
  • Single supervisor — if pi-supervisord crashes, all daemons go down (systemd/launchd restarts it within seconds).

9 Command Reference

Local Session

CommandDescription
/remote-piConnect (join mesh + start relay), or setup on first use
/remote-pi setupRun setup wizard, update config
/remote-pi statusShow mesh + relay status
/remote-pi stopStop mesh + relay for this terminal
/remote-pi pairShow QR code for mobile pairing
/remote-pi devicesList paired mobile devices
/remote-pi revoke <id>Revoke a paired device
/remote-pi set-relay <url>Persist a new relay URL

Agent Network

CommandDescription
/remote-pi join [name]Join or create a session
/remote-pi leaveLeave current session
/remote-pi sessionsList local sessions
/remote-pi rename <new>Rename agent in current session

Daemon Fleet

CommandDescription
remote-pi create <cwd>Register folder as daemon
remote-pi remove <id>Unregister a daemon
remote-pi daemonsList daemons + state
remote-pi daemon startStart all registered daemons
remote-pi daemon stopStop all running daemons
remote-pi daemon send <id> "text"Send prompt to specific daemon
remote-pi installInstall supervisor as system service
remote-pi uninstallRemove system service

10 Configuration Files

PathScopeContents
<cwd>/.pi/remote-pi/config.jsonPer-directoryagent_name, session_name, auto_start_relay
~/.pi/remote/config.jsonPer-userRelay URL
~/.pi/remote/peers.jsonPer-machinePaired mobile devices
~/.pi/remote/sessions/<name>/Per-sessionBroker socket + audit.jsonl
~/.pi/remote/skills/agent-network/SKILL.mdPer-userAgent skill the LLM reads
~/.pi/remote/daemons.jsonPer-userDaemon registry

Override the relay for a single run: REMOTE_PI_RELAY=https://staging.example.tld pi

11 Troubleshooting

  • 🟡 "relay waiting for pairing" even though paired — the icon reflects whether any device has been paired on this machine. Restart Pi if the cache is stale.
  • Mobile app times out — verify the same relay URL on both sides. If self-hosting behind VPN, the phone must also be on the VPN.
  • agent_request keeps timing out — default timeout is 30s. For longer tasks, the receiver should reply with agent_send including re: "<original-id>" for correlation.
  • Multiple terminals, same directory — supported. They share the same session. If the relay refuses with RoomAlreadyOpenError, stop the other terminal first.

Logs

  • Linux: journalctl --user -u remote-pi-supervisord -f
  • macOS: tail -f ~/.pi/remote/supervisord.log

Each daemon's stderr is forwarded with a [<cwd>] prefix — one log stream for all agents.

🎯 Key Takeaways

🔑 Key Takeaways

  • Two independent superpowers in one extension — local agent mesh + mobile remote control, activated by a single /remote-pi command
  • Local agent mesh over Unix sockets — zero network overhead, automatic leader election with transparent failover
  • LLM-native messagingagent_send (fire-and-forget) and agent_request (send + await reply) are registered as tools the LLM calls directly
  • Mobile pairing via QR — one-time per device, all Pi processes on the machine accept it
  • Self-hostable relay — single Docker container; recommended behind VPN for defense in depth
  • Daemon mode — promote any Pi session to a 24/7 background agent with OS-level supervision (systemd/launchd)
  • Full audit trail — broker writes audit.jsonl per session for postmortem inspection
  • Role-based multi-agent — split work across backend/frontend/tests/orchestrator with automatic name collision handling
  • Image support in mobile — camera/gallery attach, compressed inline, vision-flag aware
  • Configuration is hierarchical — per-directory, per-user, per-machine, with env var override at the top

🔗 Resources & Links