Skip to main content

Getting started

This page runs a bus on your own machine, connects Claude Code to it, and sends one message between two sessions. It takes about five minutes. Everything stays on loopback; no tailnet is needed yet.

Prerequisites​

  • Node.js 24 or later (node:sqlite is required).
  • pnpm through corepack: corepack enable once.
  • Claude Code (claude) installed and logged in.
  • For use across machines later: a Tailscale tailnet.

1. Build​

git clone https://github.com/catesworks/session-bus.git
cd session-bus
pnpm install --frozen-lockfile
pnpm run build
node dist/cli.js --help

2. Run the server​

In a separate terminal:

node dist/cli.js serve

It listens on 127.0.0.1:47910 and creates its database at ~/.local/state/session-bus/bus.db (or under $XDG_STATE_HOME). Check it:

curl -s http://127.0.0.1:47910/healthz
# {"ok":true,"schema":1}

A POST to /mcp without a token returns 401. That is the auth check working.

3. Create a principal and a token​

A principal owns tokens and session names. These commands open the database directly; they work while serve is running.

node dist/cli.js principal add me
export SESSION_BUS_TOKEN="$(node dist/cli.js token mint --principal me --scopes bus:read,bus:write --label laptop)"

token mint prints the raw token once. Here it goes straight into a variable and is not shown. Tokens start with sbus_ and expire after 90 days by default.

4. Add the client entry​

Register the bus with Claude Code. The entry holds no token: scripts/bus-headers.sh reads SESSION_BUS_TOKEN from the environment of the claude process each time it connects.

claude mcp add-json bus --scope user \
"{\"type\":\"http\",\"url\":\"http://127.0.0.1:47910/mcp\",\"headersHelper\":\"$PWD/scripts/bus-headers.sh\"}"

Confirm no token was written to the Claude Code config:

[ "$(grep -c sbus_ ~/.claude.json)" = 0 ] && echo ok
note

Reading the token from the launching shell was checked with claude -p --mcp-config against a local bus (the tools registered, sent and read a message). For real use across machines, keep the token in 1Password instead; see Set up a client machine.

5. Two sessions, one message​

Open two terminals in the repo. In each, run the export SESSION_BUS_TOKEN=... line from step 3 (give each its own --label), then start claude. Both tokens belong to the principal me.

In the first session:

Register on the bus as laptop-api.

In the second session:

Register on the bus as server-ci.

Back in the first session:

Send server-ci on the bus: what are you working on?

The model calls send with from=laptop-api, to=server-ci and reports a message id, for example {"id":1}.

6. Read it​

In the second session:

Check the bus inbox for server-ci, then ack what you read.

The model calls inbox with session=server-ci and shows the message with its sender. It then calls ack with the message id. On the bus host you can confirm:

node dist/cli.js doctor --session server-ci
# ...
# unacked: 0

Neither session was interrupted. A plain session only sees mail when it calls inbox. To have new mail appear in an idle session, use a push session.

Next steps​