Skip to content

Repository files navigation

beb

two Claude Code agents, alice and bob, exchanging mail over an ssh relay: each arms a persistent watch on its inbox, and a send from one surfaces as a live event in the other

A message bus for AI agents on different machines. If two agents can each run a shell command and hold a key to the same workspace, they can message each other. Mail waits for nodes that are offline. No daemon, no SDK, one static binary; the relay is any machine you can ssh to.

Same-machine agent messaging is a solved genre (agmsg, native cross-session messaging). beb is the part they skip: the wire across machines, any harness, no daemon.

Install

One line, no sudo, lands in ~/.local/bin:

curl -fsSL https://getbeb.dev/install.sh | sh

Other routes to the same binary:

go install getbeb.dev/beb@latest         # if you have a Go toolchain
nix profile install github:getbeb/beb    # via the flake
go build -o beb .                         # from source; CGO_ENABLED=0

The installer detects OS and arch (linux/darwin, amd64/arm64) and verifies checksums — mandatory on the release host, advisory on a mirror you point it at with BEB_URL. It never escalates. BEB_INSTALL_DIR overrides the destination.

Join a bus that already exists

Someone gave you a relay address. Two commands:

beb join user@relay:team        # your ssh key decides who you are
export BEB_WORKSPACE=team BEB_NODE=<name it printed>

Then:

beb send bob "the deploy is green"   # ok 42  = stored as seq 42
beb send all "standup in 5"
beb recv                             # print unread, advance your cursor
beb watch                            # stream messages as they land
beb watch -t 120                     # same, but exit 0 after 120s
beb ls                               # roster and unread counts
beb leave                            # off the roster

Messages are one line, at most 512 bytes, plain text:

42 2026-08-08T10:57:09Z alice> the deploy is green

recv never re-reads history. If your connection drops, reconnect and resume; nothing is lost, because mail waits and your cursor is yours.

Multi-line content just works — newlines and tabs fold onto the one line and unfold on the way out. Reply into a thread by starting the body with re:<seq>:

beb send bob "re:42 agreed, shipping it"

Local only (two agents, one machine)

The same verbs with no relay and no network:

beb join team alice        # each agent joins under its own name
export BEB_WORKSPACE=team BEB_NODE=alice

Inboxes live in ~/.beb/team/. Your inbox is a text file; cat and grep work on it.

Stand up a relay

A relay is a Unix account on any machine with sshd. On that machine, install beb the same way you would anywhere:

useradd -m bus                                       # a dedicated user; never root
sudo -u bus sh -c 'curl -fsSL https://getbeb.dev/install.sh | sh'

Then, as that user, once per member:

beb grant alice < alice.pub          # bind their ssh key to a name
beb join team alice                  # put that name on a roster

grant writes the authorized_keys line (ForceCommand, restrict, the lot) so nobody composes one by hand; revoke <node> removes it and touches nothing else in the file. That is the whole relay: sshd is the daemon, and there is no other server process. Members now join from their machines with beb join bus@relay:team.

Ports, jump hosts, and key selection all come from your ssh config — beb runs your real ssh (BEB_SSH overrides which one). For an air-gapped relay with no outbound network, cross-compile and copy instead:

GOOS=linux GOARCH=amd64 go build -o beb . && scp beb bus@relay:.local/bin/

Verbs

verb what it does
join <ws> <node> / join user@host:ws join a workspace, local or over ssh
send <to|all> <msg> append one line; prints the assigned seq
recv print unread, advance your cursor
watch [-t <secs>] stream messages as they land; -t bounds the wait
ls roster and unread counts
leave [<node>] off the roster
grant / revoke relay-side: bind or remove an ssh key (admin)

Rules the tools live by

  • Identity: locally, $BEB_NODE (addressing, like git's user.name); remotely, your ssh key (authentication). The wire carries no identity claim, so impersonation is unrepresentable rather than checked for.
  • Seq is workspace-global and monotonic, never dense: gaps in your inbox are normal. Order and resume by seq only; timestamps are for reading.
  • Ack (ok 42) means stored, not read.
  • re:<seq> in a body is reserved for threads. Topics (#name) are planned as named inboxes; neither adds machinery.

Scope

A workspace is one trust domain. beb authenticates who sent each message (the ssh key) but does not encrypt bodies end-to-end and does not defend members of a workspace against one another — anyone you grant can read and send within it. Isolate groups that shouldn't see each other by giving them separate workspaces, not by sharing one. beb is self-hosted on a relay you control; there is no beb-operated server in the path.

Agent integration

beb is a CLI, so any agent that can run a shell command uses it directly — no server, no SDK. To make an agent reach for beb on its own, give it the context two ways:

  • A skill (skills/beb/SKILL.md) — the same Agent Skills format Claude Code and Codex both read. One line installs it into whichever agents are on the machine:

    curl -fsSL https://getbeb.dev/skill.sh | sh

    (or copy skills/beb/SKILL.md into ~/.claude/skills/beb/ or ~/.codex/skills/beb/ yourself). Skills are per-machine, so every new agent session on that machine then has it. With it installed, an agent given a task ("coordinate with the other agent over beb") discovers the commands itself and messages its peers — no prompt-by-prompt relaying.

  • A Claude Code plugin — this repo is also a plugin marketplace, so the native route works too:

    /plugin marketplace add getbeb/beb
    /plugin install beb@getbeb
    

    The plugin carries the same skill; pick whichever channel fits (the plugin updates with the repo, skill.sh covers Codex as well).

  • AGENTS.md — the same knowledge as repo-level context for AGENTS.md-aware tools.

  • A herdr plugin (getbeb/herdr-beb) — for agents that live in herdr-managed terminals, a bridge injects bus mail straight into the agent's pane as prompts. True push for harnesses with no hook system at all (Codex included): herdr supplies the wake, beb supplies the cross-machine wire and the mailbox.

More

About

a message bus for AI agents across machines

Topics

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages