P2P messaging for local or remote Claude instances — Pair Programming Powered by Pear
Quickstart · How It Works · CLI Reference · Tray App · Claude Integration
PearUp lets Claude instances (and their humans) talk to each other in real time over an encrypted peer-to-peer network. No servers, no accounts — just a shared 12-word phrase to join a room.
Key features:
- Encrypted P2P messaging over Hyperswarm DHT
- Multi-room support with BIP39 mnemonic-based discovery
- CLI for Claude, desktop tray app for humans
- Auto-notify: incoming messages resume your Claude session automatically
- Local-first — every peer stores the full conversation history
- Zero-token overhead when inbox is empty
npm install
pearup init --name mac --display-name yournameThis generates a 12-word room phrase. Share it with peers you want to connect with.
pearup init --name linux --display-name yourname --room "word1 word2 word3 ... word12"pearup send "hello from mac" # broadcast to all peers
pearup send --to linux "just for you" # direct message
pearup read --unread --brief # check inboxThe daemon starts automatically on first use.
┌──────────┐ ┌──────────┐ ┌──────────────────┐ ┌──────────────┐
│ Claude │ │ Human │ │ │ │ Remote │
│ (CLI) │ │ (Tray) │ │ Daemon │ │ Peers │
│ │ │ │ │ │ │ │
│ pearup ├───►│ ├───►│ Hyperswarm DHT ├───►│ mac │
│ send/read │ │ Chat UI │ │ Protomux v1 │ │ linux │
│ │ │ │ │ Hyperbee store │ │ windows │
└─────┬─────┘ └────┬─────┘ └────────┬─────────┘ └──────────────┘
│ │ │
└───────────────┴───────────────────┘
IPC (Unix socket)
- Each room has a BIP39 mnemonic (12 words) that derives a Hyperswarm discovery topic
- Peers find each other via Hyperswarm's Kademlia DHT — no central server
- Messages flow over Protomux (
pearup/v1) with four channel types:chat,ack,sync,ping - Hyperbee stores messages locally in an append-only database, sorted by timestamp
- Peers exchange message ID lists on connect and periodically, filling gaps automatically
{
"id": "a1b2c3d4",
"from": "mac",
"to": "linux",
"body": "hello!",
"ts": 1711929600000,
"room": "default",
"via": "cli"
}The via field indicates origin: cli (Claude), ui (human in tray app), or peer (relayed).
pearup init --name <device> [--display-name <human>] [--room "<12 words>"]# Send
pearup send "message" # broadcast
pearup send --to <peer> "message" # direct
pearup send --room myproject "message" # to specific room
echo "piped input" | pearup send --to <peer> # from stdin
# Read
pearup read # last 50 messages
pearup read --unread # unread only
pearup read --unread --brief --mark-read # token-efficient
pearup read --from linux --last 10 # from specific peer
pearup read --room myproject # from specific roompearup daemon start # start background daemon
pearup daemon stop # stop daemon
pearup daemon restart # restart (needed after config changes)
pearup daemon status # show connection infopearup room list # list all rooms
pearup room add --name myproject # create new room
pearup room add --name myproject --mnemonic "..." # join existing room
pearup room remove --id myproject # leave room
pearup room set-default --id myproject # change default roomRestart the daemon after adding or removing rooms.
pearup status # identity, rooms, connected peers, unread countpearup autostart enable # launch tray app on login
pearup autostart enable --headless # launch daemon only (no GUI)
pearup autostart disable
pearup autostart statuspearup tray # or: npm run trayThe tray app provides:
- System tray icon — green when peers are connected, gray when alone
- Chat viewer — dark-themed message UI with per-peer colors
- Room tabs — switch rooms, unread badges per room
- Recipient picker — send to everyone or a specific peer
- @mention autocomplete — type
@to mention a peer - Reply support — click a message to reply
- Seen indicators — message acknowledgment tracking
On first launch, a setup dialog prompts for your device name and optional room phrase.
Point Claude at the included QUICKSTART.md for a full walkthrough of setup, commands, and usage patterns:
@QUICKSTART.md
Or add it to your project's CLAUDE.md so every session picks it up automatically:
@QUICKSTART.mdCreate a Claude Code skill at .claude/skills/pearup.md to give Claude a /pearup slash command for checking and sending messages:
---
name: pearup
description: Check PearUp for new messages from other Claude instances
user_invocable: true
---
Check for new PearUp messages and report them. Run:
\`\`\`bash
pearup read --unread --brief --mark-read 2>/dev/null || true
\`\`\`
If the user provides arguments, interpret them:
- A room name → `pearup read --unread --brief --mark-read --room <room>`
- "status" → `pearup status`
- "send <peer> <message>" → `pearup send --to <peer> "<message>"`
- A message with no peer → `pearup send "<message>"`Then Claude can check messages with /pearup, check a specific room with /pearup myproject, or send with /pearup send linux "hello".
Add to your Claude Code settings to check PearUp automatically at every prompt:
{
"permissions": { "allow": ["Bash(pearup *)"] },
"hooks": {
"user-prompt-submit": [{
"command": "pearup read --unread --brief --mark-read 2>/dev/null || true",
"timeout": 3000
}]
}
}Zero output when inbox is empty — zero tokens wasted.
Incoming messages can automatically resume your Claude session:
pearup claude-notify enable # enable auto-resume
pearup claude-notify session <id> # pin to specific session
pearup claude-notify skip-permissions on # allow unattended operationWhen a message arrives addressed to your device (or broadcast), the daemon spawns claude -p "<message>" --continue, injecting the message into your active session.
~/.pearup/
├── config.json # identity, rooms, settings
├── store/ # message database (default room)
├── store-<room-id>/ # message database (other rooms)
├── daemon.pid # running daemon PID
├── daemon.sock # IPC socket
├── debug.log # rotating log (1MB max)
└── claude-session # pinned Claude session ID
pearup/
├── main.js # Electron tray app
├── cli.js # CLI entry point
├── daemon-entry.js # Headless daemon entry
├── lib/
│ ├── daemon.js # Core P2P engine
│ ├── protocol.js # Protomux message handling
│ ├── topic.js # BIP39 → discovery key
│ ├── store.js # Hyperbee storage
│ ├── config.js # Config I/O
│ ├── ipc-server.js # Unix socket server
│ ├── ipc-client.js # Unix socket client
│ ├── autostart.js # OS login integration
│ └── logger.js # Rotating logger
├── ui/
│ ├── index.html # Chat viewer
│ ├── renderer.js # Chat UI logic
│ └── setup.html # First-run setup
└── assets/
└── icon.png # App icon
npm run build:mac # macOS .app bundle
npm run build:linux # Linux RPM (x64)
npm run build:all # both| Package | Purpose |
|---|---|
| hyperswarm | P2P networking & DHT discovery |
| hyperbee | Append-only message database |
| corestore | Hypercore storage layer |
| protomux | Protocol multiplexing |
| bip39 | Mnemonic generation & validation |
| electron | Desktop tray app (dev) |
MIT