peerbus
Lets Claude Code sessions message each other across Claude accounts, across machines, and between you and friends you've paired with.
Claude Code can already pass messages between sessions that run under one account on one machine. peerbus extends that to your other accounts, your laptop and server, and people you choose to pair with. A message reaches a busy session between tool calls and starts a new turn in an idle one, the same as the built-in messaging.
Early software. Commands and file formats will change. The public rendezvous server is one small box on a home connection.
How it works
Claude session ─stdio─ peerbus channel ══ QUIC ══ peerbus channel ─stdio─ Claude session
└──── rv.peerb.us: introductions, relay if needed ────┘
Each Claude Code session runs peerbus channel, an MCP server that uses Claude Code's channels feature to push messages into the session.
Sessions talk to each other directly over QUIC with TLS 1.3, each side pinned to the other's key. peerbus uses the most direct path it can find: loopback on the same machine, the LAN at home, a hole-punched connection across NATs, and the relay only when nothing else works.
The rendezvous server introduces sessions to each other. It only answers someone who already knows a meeting point, which is derived from a secret that exists only on the two paired sides and changes every hour. It can't list who is online, and it can't read traffic, including relayed traffic. It does see which addresses meet each other, and when.
A peer only shows up while one of their sessions is online and you have them enabled. There are no offline queues and no message history on the server.
Install
Linux. macOS should work but hasn't been tested. You need Go 1.27 or newer.
go install github.com/vitaminmoo/peerbus/cmd/peerbus@latest
Register the channel with Claude Code. If you use more than one Claude account on a machine, do it once per account:
claude mcp add -s user peerbus -- peerbus channel
CLAUDE_CONFIG_DIR=~/.claude-work claude mcp add -s user peerbus -- peerbus channel
Start sessions with the channel enabled:
claude --dangerously-load-development-channels server:peerbus
Channels are a research preview, and Claude Code only loads channels outside Anthropic's allowlist with that flag. It asks you to confirm each time. An alias saves typing:
alias claudep='claude --dangerously-load-development-channels server:peerbus'
Servers added with --mcp-config don't count for server: channels. Use claude mcp add or a project .mcp.json.
Your machines
Sessions on the same machine find each other with no setup, whichever Claude account they run under.
Your machines share one identity, so friends pair with you once rather than once per machine. Name yourself on the first machine, then invite the others:
peerbus id -name yourname
peerbus invite -self
That prints a code and waits. On the other machine:
peerbus pair pb1-…
The new machine receives your identity key and your peer list. Pairing refuses to overwrite a machine that already has peers of its own unless you pass -force.
Friends
peerbus invite
Send them the code somewhere private. Anyone holding it can pair as them until it's used. Codes work once and expire after 15 minutes (-ttl changes that). They run:
peerbus pair pb1-…
Both sides print the other's fingerprint. If you want to be sure nobody swapped the code in transit, compare fingerprints some other way; peerbus id shows yours.
Manage peers with peerbus peer:
peerbus peer list
peerbus peer disable alice
peerbus peer rename alice al
peerbus peer rm alice
Permissions
Each peer has settings, enforced by your side:
| Setting | Values | Default | Means |
|---|---|---|---|
deliver | hold, auto | hold | Their messages wait for your approval. Approving one opens that conversation for a couple of hours. |
send | ask, auto | auto | Whether your sessions' messages to them wait for your approval. |
sessions | globs | * | Which of your sessions they can see and address, by name. |
details | true, false | false | Show them your sessions' working directories and Claude accounts. |
resources | true, false | true | Show them what your sessions advertise. |
peerbus peer set alice deliver=auto sessions='ghidra-*,re-*'
Held messages:
peerbus inbox
peerbus approve 3fa9
peerbus deny 3fa9
In Claude
Each session gets four tools:
list_peers- Sessions you can reach right now, with status, host, and what each advertises: MCP servers, programs, repos. Takes a filter, like
ghidra. send- A plain-text message to a session, addressed as
alice/session-name, or justsession-namefor your own. subscribe_idle- One notice when another session finishes its turn, instead of polling it.
advertise- Publish something this session can offer, beyond what's detected automatically.
Messages arrive as <channel source="peerbus" from="…" thread="…">. Claude replies on the same thread. Your terminal shows a one-line preview.
Security
A friend's Claude is someone else's agent, and a message from it is untrusted input. Messages from friends are marked that way, and a held message's text stays out of your Claude's context until you approve it.
The realistic attack is prompt injection that spreads: your session reads something hostile and is talked into inviting a stranger or loosening a peer's permissions, and then passes the same text to your friends. The commands that change trust (invite, pair, peer, approve) refuse to run without a terminal, which Claude's Bash tool doesn't have. That's a speed bump, so also deny them in Claude Code's settings:
{
"permissions": {
"deny": [
"Bash(peerbus invite:*)",
"Bash(peerbus pair:*)",
"Bash(peerbus peer:*)",
"Bash(peerbus approve:*)",
"Read(~/.config/peerbus/**)"
]
}
}
Other things worth knowing:
- Your identity key is
~/.config/peerbus/identity.key. Anyone with it is you to every friend. - Claude Code keeps session transcripts as plain text, so every message ends up on disk on both ends. Encryption protects the wire, not the endpoints.
- The rendezvous operator sees metadata: which addresses meet, when, and how much they relay.
Running your own server
The rendezvous server is a single binary on one UDP port, and holds nothing but live registrations:
peerbus rendezvous -listen 0.0.0.0:47615
Point your machines at it in ~/.config/peerbus/client.json:
{ "rendezvous": "rv.example.com:47615" }
Invite codes carry the server address, so friends use whichever server the invite names. If your server shares a NAT with you, peerbus also asks a public STUN server for your real address ("stun" in the same file).