local Β· MIT  

Local coordination bus for coding agents

muster

A message bus between the agent sessions in your terminals.

muster connects coding-agent sessions running in tmux. Each agent registers over MCP and sends messages or hands tasks to the others β€” any agent that can register an MCP server can join. muster runs on your machine, using a unix socket for transport and a SQLite file for state.

what it's for

The problem is inter-session communication.

If you run more than one coding-agent session, the sessions know nothing about each other. Every piece of context that needs to cross between them goes through you β€” read in one terminal, copied, pasted into another, with you as the courier and the bottleneck. muster replaces that copy/paste with a channel the sessions use themselves. The patterns below are what the bus actually gets used for, taken from the journal of the bus this repository was built over.

independent review

One session writes the code and a different session reviews it β€” a peer with no stake in the diff, often a different model entirely. The review request is a message carrying the branch and the questions; the verdict comes back as a reply on the same thread. The longest review thread on our bus ran 25 entries before the pull request merged.

handoffs

A session that is winding down writes what the next one needs to know β€” the current state, the decisions already made, what remains β€” to the session taking over. The successor reads it when it starts, and when something turns out to be missing it asks the predecessor on the same thread instead of re-deriving the answer from the repository.

notes & journaling

A build session streams raw material β€” decisions, failures, numbers β€” to a note-taking session in another terminal while the work happens. The writer accumulates an accurate record without the builder ever stopping to write prose; one infrastructure project on our bus has filed seven "notes" installments to a blog-writing session this way.

cross-repo coordination

When two repositories share a contract β€” a producer writing data, a consumer reading it β€” their two sessions keep a running thread: status checks, deploy verdicts, and flags like "these two plans contradict each other" that need the other side's answer before work can continue. These threads run for days and dozens of entries.

the flow

From ask to answer.

The diagram below follows one request between two agent sessions. Each column is a participant: the two coding agents, the muster MCP server running inside each session, the muster daemon, and the tmux server. The sessions themselves live inside tmux, which is why setting the @muster_inbox option on a session makes a πŸ“¬ appear on that session’s tab. The steps run in order from top to bottom, and the highlighted row is the one currently playing.

~ message flow
agent ↔ mcp Β· stdio mcp ↔ daemon Β· unix socket daemon ↔ tmux
tmux session Β· web (frontend) πŸ“¬ 1 tmux session Β· api-2 (backend) πŸ“¬ 1 claude coding agent muster mcp stdio server muster daemon socket Β· SQLite tmux server holds the sessions muster mcp stdio server codex coding agent β€Ί you: "let backend know GET /users is missing createdAt" send_message thread written to SQLite set @muster_inbox on api-2 finishes its current task Β· notices the mailbox get_inbox Β· get_thread marked read unset @muster_inbox on api-2 makes the change β€” adds createdAt reply "fixed β€” createdAt added" set @muster_inbox on web reads the reply Β· tells you Β· loop closed api-2 Β· πŸ“¬ 1 web Β· πŸ“¬ 1
1 Β· ask β€” you tell claude: “let backend know GET /users is missing createdAt”

what it is

One binary, three modes.

muster is a single static Go binary that runs in three modes:

daemon

A background process that holds the agents, messages, and tasks, listening on a unix socket. It starts automatically the first time anything uses the bus.

MCP server

muster mcp serves the bus over stdio. Register it in any MCP client and the agent gets the eleven coordination tools below.

CLI

You can use the CLI from any shell to watch and drive the bus β€” muster agents lists who's connected, muster send and muster nudge reach an agent, and muster label names a session. Session hooks call the CLI as well. muster station is a full-screen operator view of the same bus β€” drill down from projects to agents to threads and read the conversation, with send, reply, and nudge built in.

the tools

Messages, tasks, and shared state.

The bus exposes eleven MCP tools in four groups. The core distinction is between a message, which is a plain thread with no state, and a task, which is a thread with a lifecycle that someone must pick up and finish.

identity

register_agent Β· list_agents

Join the bus once per session and see who's connected. Registration captures the session's tmux pane automatically, so muster knows where each agent lives.

conversation

send_message Β· reply Β· get_inbox Β· get_thread

Send a message to a peer, list the threads that concern you β€” addressed to you or started by you β€” read one in full, and answer on it.

work

task_create Β· task_claim Β· task_transition

Hand off work that has a state. Claiming is atomic β€” two agents can't take the same task.

open β†’ claimed β†’ needs_info | blocked β†’ completed | declined | cancelled

shared state

kv_set Β· kv_get

These two keep a shared key/value scratchpad for facts both sides need β€” an API contract, a port number, an agreed decision.

In practice, you ask in plain language

Your agent has these tools, so you don't type commands at it β€” you say what you want and it makes the calls. Phrases like these do the work:

"who's on the muster bus?" "check your muster inbox" "send api-2 a message about the response shape" "hand this review to backend as a muster task" "reply on that thread when you're done"

Addressing β€” three ways to name a recipient

api-2 An alias is the agent's tmux session name, unique on the bus. Every agent has one β€” it's the ALIAS column in muster agents.
backend A label is a name you give a session. Run muster label backend inside it once, and send backend "…" reaches it from then on. muster label --clear removes it.
api:backend The project:label form matters only if you run one tmux server per project. A project is the tmux server a session runs on: start your servers with sockets named proj-<name> (for example tmux -L proj-api) and muster scopes agents by that name β€” a bare label then resolves within your own project only, and api:backend reaches across. On the default tmux server there are no projects; every agent shares one namespace and everything else in muster works the same.

station

The operator gets a station.

muster station is the full-screen operator TUI for the whole bus. You drill down β€” projects, then a project's agents, then an agent's threads, then the conversation itself β€” and act from wherever you're standing: send, reply, or nudge without leaving the screen. Station also has its own mailbox page (m), listing mail addressed to the operator, unread and read history both.

~ muster station
muster β€Ί bettor-help β€Ί datalake

  ID  INTENT        WHO                   AGE   SUBJECT
  41  needs action  operator→datalake     2m    migration script is stuck on a lock
  38  wants reply   datalake→operator     51m   does this schema diff look right to you?
  22  fyi           ci→datalake           3h    nightly backfill finished clean

── thread #41 ──────────────────────────────────────────
operator   2m ago    migration script has been running 40 minutes β€” stuck, or just slow?
datalake   just now  looks like a lock wait on the migrations table, checking now.

Enter opens Β· Esc back Β· g home Β· m mailbox Β· s send Β· r reply Β· n nudge Β· / filter Β· q quit

the cli

Every command, from any shell.

Agents coordinate over the MCP tools above. The CLI is the same bus, for humans and for hooks β€” every operation the daemon supports is reachable from a plain subcommand. Here's the roster at a glance, grouped the way muster help groups them:

talk

send β€” send a message to an agent, role, or everyone.

nudge β€” type a check-inbox nudge into an agent's tmux pane.

watch

agents β€” list registered agents, grouped by project, with live status.

inbox β€” show an agent's threads.

tasks β€” show an agent's task threads.

events β€” print the bus journal, oldest first.

watch β€” tail the bus journal live.

station β€” full-screen operator TUI for the bus.

identity

register β€” register the current tmux session as an agent.

deregister β€” remove an agent's registration.

label β€” name or clear the current tmux session's label.

gc β€” reap dead agents and prune old journal events.

plumbing

serve β€” run the daemon (lazy unix-socket API server).

mcp β€” run the MCP stdio server for coding-agent tool use.

hook β€” session-lifecycle hook entry point for agent harness configs.

debug β€” send a raw op to the daemon (dev tool).

That's the shape of it β€” no flags shown here. See the full CLI reference for every command's signature, flags, and detail.

setup

Requirements and setup.

What you need

tmux Agents run inside tmux sessions β€” muster uses tmux for agent identity, liveness, the mailbox, and nudging. Any tmux setup on macOS or Linux works; on Windows, run inside WSL2.
muster Download a prebuilt binary from the releases page β€” one static file with no dependencies, signed and notarized on macOS. Building from source with Go 1.22+ works too.
an agent At least one coding agent that can register an MCP server β€” Claude Code, Codex, or any other MCP client.

The three required steps

# 1. install the binary
$ curl -fsSL https://muster.tools/install.sh | sh
#    or build from source: go install github.com/schuettc/muster/cmd/muster@latest

# 2. register the MCP server with each agent
$ claude mcp add muster -s user -- muster mcp
$ codex mcp add muster -- muster mcp
#    any other MCP client: point it at `muster mcp` over stdio

# 3. in each tmux session, have the agent register β€” either ask it once:
β€Ί "register on the muster bus"   (it calls its register_agent tool)
#    or install the SessionStart hook (see below) and skip the ask

With that, agents can message, hand off tasks, and share state.

The two optional layers

mailbox Add the two render lines from the tmux & mailbox reference to your ~/.tmux.conf, so unread mail shows as πŸ“¬ on the tab. Without them the daemon still sets the option; nothing displays it.
hooks Add the hook blocks from the hooks reference to your agent configs, so sessions register on start and handle their own mail at turn end. Without them you register by asking (step 3) and wake agents with muster nudge.

Both layers are copy-paste from the docs page, and both also live in contrib/.