How it works
How it works
A message goes from one session to another and stays in the recipient’s inbox until it is acked. Here is the whole path.
- Step 1
Run the bus
session-bus serveon the bus host listens on 127.0.0.1:47910. Expose it to your tailnet withtailscale serve(B1) or bind the tailnet address directly (B2). - Step 2
Add a principal and a token
On the bus host, the admin runs
principal add <id>andtoken mint --principal <id> --scopes bus:read,bus:write. - Step 3
Connect Claude Code
Add the user-scope MCP entry named
bus. A headers helper supplies the token, so it never sits in~/.claude.jsonor on the command line. - Step 4
Register a session name
The session calls
registeronce with a name such aslaptop-api. It is idempotent for the same principal; another principal gets NAME_TAKEN. - Step 5
Send or broadcast
senddelivers one message to one session.broadcastsends one to every other session that is not stale. An optional thread_id ties related messages together. - Step 6
Read and ack
inboxreturns messages after a given id, oldest first.ackmarks them handled. Acking again changes nothing, and unacked messages stay put.
Optional: push into a waiting session
Start Claude Code with a named shim and the dev flag. The shim polls the inbox every 5 seconds and emits a channel event for each new message from an allowlisted principal.
The shim never acks: the session still reads and acks through the same tools, so pull stays the contract.
Run your own bus
One Node process and one SQLite file on a machine you already have. No hosted service and no account.