Spanreed
An inter-agent message bus for local Claude Code sessions. Run one Claude session per repo; let them coordinate.
Status: alpha. Published on PyPI (
spanreed-bus) and in daily use for single-host, multi-session coordination. Cross-host messaging (spanreed conjoin) is experimental — see Cross-host. Not yet on the official Claude Code marketplace.
Named after the spanreed: a paired magical writing tool from the Stormlight Archive that transmits text across vast distances. One side writes, the other side reads.
Install
Install the bus tooling from PyPI:
uv tool install spanreed-bus
Then launch claude in any directory and run these two slash commands at the prompt:
/plugin marketplace add Monkopedia/spanreed
/plugin install spanreed@spanreed
The MCP server (spanreed-mcp) and CLI (spanreed) need to be on $PATH for the plugin to find them — uv tool install handles this.
Developing on spanreed
For hacking on spanreed itself, install from a local clone:
git clone git@github.com:Monkopedia/spanreed.git
cd spanreed
uv tool install --editable .
Then in Claude Code, point the marketplace at your clone instead of GitHub:
/plugin marketplace add /absolute/path/to/spanreed
/plugin install spanreed@spanreed
Quickstart
Open two terminals, each in a different repo:
# Terminal A
cd ~/projects/repo-a && claude
# Terminal B
cd ~/projects/repo-b && claude
In terminal A, ask Claude to talk to the other session:
Ask agent at repo-b what version of Node it's using.
Claude in repo-A discovers the peer, sends the question, the peer answers, the answer comes back. The conversation is visible in both transcripts.
How it works
Two layers on Claude Code primitives:
- MCP server (
spanreed-mcp, per-session) exposes the bus API as typed tools: register, send, recv, list,wait_for_replywith timeout. - Plugin (auto-loaded) wires up a SessionStart hook for bus context, a Monitor for inbound wakeups, and points Claude at the MCP server.
State lives under ~/.claude/spanreed/ (registry + per-agent inboxes + per-session cursors). No central daemon — each session's MCP server is local and coordinates through shared files.
Read the full design in docs/architecture.md. Wire-format spec in docs/protocol.md.
Cross-host (experimental)
By default the bus is single-machine. To bridge two machines' buses, run on one host:
spanreed conjoin <other-host>
This opens a persistent SSH pipe to the peer and mirrors each side's agents into the other's list_agents (as agent-xxxx@host); messages addressed to a qualified id route across. It reconnects on its own if the pipe drops, and runs in the foreground until you stop it — supervision (start-on-boot, restart-on-crash) is left to you (wrap it in systemd/launchd/tmux).
Check it with spanreed list, whose PEERS section shows every bridge and when each last synced its registry. Read that before concluding a peer's agent is gone: registry sync and message transport are independent, so a bridge can carry mail while leaving the far side unaddressable, and list_agents looks identical in both cases. The list_peers MCP tool exposes the same records to agents.
Prerequisites: spanreed-bus ≥ 0.0.4 on both hosts, and key-based non-interactive SSH (it reconnects unattended, so it can't answer a password prompt). Full setup, the most common SSH gotcha (non-default key name), and how to update spanreed on a peer host: docs/cross-host.md. Design in docs/architecture.md.
Experimental and point-to-point only — no multi-hop routing or peer discovery yet.
Codex workers (experimental)
A Codex worker is a bus agent with no human attached: a long-lived process
that owns one codex app-server thread and turns inbound mail into Codex turns.
It needs codex on $PATH and a signed-in Codex; it does not need the
Claude Code plugin, since there is no Claude session involved.
Run the doctor first. It exercises the whole path once and writes a single self-contained log — send that file rather than a screenful:
spanreed codex --doctor --cwd ~/some/project
Then start a worker:
spanreed codex --name reviewer --cwd ~/some/project
--cwd is required and has no default. It is what the worker checks
approvals against and what it asks Codex to sandbox: approvals are
auto-approved inside it, any registered agent may wake the worker, and the bus
does not authenticate senders. What the sandbox then enforces depends on
--mode — under danger there is no sandbox at all. --mode picks the
confinement — workspace (default, writes confined to --cwd) or danger (no
sandbox at all, which warns on startup and on every turn).
Experimental, and specifically so. The protocol work is verified against
Codex's own schemas, and the failure paths are covered by fault-injection tests,
but the end-to-end path has been exercised against a stub rather than against a
live codex app-server on a machine where one is installed. Expect the doctor
to find things. See docs/architecture.md §"Codex
workers" for the design and
docs/findings.md for what was actually measured.
Update
The Python package and the plugin update independently:
uv tool upgrade spanreed-bus
For the plugin, inside Claude Code:
/plugin update spanreed@spanreed
Development
See docs/development.md for environment setup, running tests, and contribution conventions. The CLAUDE.md at the root captures the discipline rules — Claude sessions working on this repo should read it.
License
Metadata
Release files for spanreed-bus 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| spanreed_bus-0.2.0.tar.gz | 347.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| spanreed_bus-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 449.6 kB
Release files / spanreed_bus-0.2.0.tar.gz
| Download URL | spanreed_bus-0.2.0.tar.gz |
|---|---|
| Size | 347.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9001f78d1448b52d344c2105cbe7e5b4ae2ee72886fa14d474e192217ea9f6f1
|
|
BLAKE2b-256 checksum How to use checksums |
af7e13be802dd424a2d07a7dea47801c14059558c4cafb5003298fb2d7c103a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / spanreed_bus-0.2.0-py3-none-any.whl
| Download URL | spanreed_bus-0.2.0-py3-none-any.whl |
|---|---|
| Size | 101.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9a55e8f78573392615d8c492a239ddf4805f7eeaa616c588830feabb4888d136
|
|
BLAKE2b-256 checksum How to use checksums |
b120eda11c97b803ee632aae11e18aafac22db89a49ac95c4cac988f0440dede
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.15 {"installer":{"name":"uv","version":"0.12.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|