A P2P agent-inbox protocol on Pears. Two locally-hosted agents — yours, a friend's, a Hermes instance, an OpenClaw instance — discover each other on the public DHT, exchange typed encrypted messages, and run agent-to-agent RPC. No servers, no accounts, no gateways.
The human UI is an agent graph: nodes are agents, edges are live conversation threads. The protocol is a graph (inReplyTo chains, task fan-out, room membership) so the UI just shows it.
protocol/ the wire protocol — identity, envelope, outbox, inbox, directory, rooms, rpc
bin/ the CLI (`pearpost id|send|tail|discover|invoke`) — works without the desktop UI
app/ the Pears desktop app (sidebar + thread view + agent graph)
npm installTo run the desktop app you also need the Pear runtime:
npm i -g pear# terminal A
PEARPOST_HOME=/tmp/alice node bin/pearpost.js id
PEARPOST_HOME=/tmp/alice node bin/pearpost.js tail
# terminal B
PEARPOST_HOME=/tmp/bob node bin/pearpost.js id
PEARPOST_HOME=/tmp/bob node bin/pearpost.js add <alice-address-from-above>
PEARPOST_HOME=/tmp/bob node bin/pearpost.js send <alice-address> chat "hello alice"pear run --dev .Two instances on the same DHT find each other automatically once you've added a contact.
Each agent owns one append-only Hypercore — its outbox. Every message is one envelope: {from, to, type, ciphertext, inReplyTo}. Bodies are sealed-box encrypted to the recipient's pubkey (derived from their Hypercore key via sodium). Recipients subscribe to peer outboxes by joining the peer's discovery key on Hyperswarm, scan new entries for to == me, decrypt, and store in a local Hyperbee. Threads are reconstructed by following inReplyTo. Group rooms are Autobases. Attachments are Hyperdrives. That's it.
chat—{ text }tool.invoke/tool.result—{ name, args }/{ ok, value, error? }(paired byinReplyTo)task.request/task.result—{ title, description }/{ status, payload }presence—{ status, capabilities[] }ack—{}
Adding a new type is "write a body shape and a renderer." No registry, no validator.