muster

module
v0.3.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 15, 2026 License: MIT

README ΒΆ

muster

A local coordination bus for coding agents.

muster lets coding-agent sessions in separate terminals send messages and hand tasks to each other. Any agent that can register an MCP server can join the bus β€” Claude Code and OpenAI Codex are the two it's tested with. Everything runs over a local unix socket with state in a local SQLite file; muster itself never calls a model.

  • Messages and tasks between sessions. One agent posts a "review this branch" task; a standing session in another terminal claims it, works it, and replies.
  • One static Go binary, three modes: a lazy-started daemon, a stdio MCP server each agent registers, and a CLI for you.
  • tmux-native wake β€” mail sets a mailbox flag (πŸ“¬<count>) on the recipient's tmux session; muster nudge is the only thing that types into a pane.

Landing page: muster.tools

Status

v0.2.2 β€” session identity (project-scoped agents, addressable labels, tmux-verified liveness), the @muster_inbox mailbox, and Codex autonomy on top of the v0.1.0 core (SQLite store, lazy daemon, MCP server, human CLI, notify/nudge wake). See releases for the changelog.

Setup

# 1. install the binary: download a prebuilt one from the releases page
#    (https://github.com/schuettc/muster/releases) and put it on your PATH,
#    or build from source (Go 1.22+; macOS or Linux β€” on Windows use WSL2):
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     # Claude Code
codex mcp add muster -- muster mcp              # Codex
# (any other MCP client: point it at `muster mcp` over stdio)

# 3. in each session, have the agent call register_agent once
#    (or add that instruction to your project's CLAUDE.md / AGENTS.md)

That's a working bus. Two optional layers, both in contrib/:

  • See the mailbox β€” two lines of tmux config render πŸ“¬<count> on tabs with unread mail (contrib/tmux-mailbox.conf).
  • Automate the lifecycle β€” session hooks (muster hook <event> <model>) auto-register agents on start and have them drain their own inbox at turn end (config for both harnesses in contrib/).

MCP mode

muster mcp runs muster as an MCP server over stdio, exposing the bus as tools any MCP client (Claude Code, Codex) can call. Register it once per tool:

# Claude Code
claude mcp add muster -s user -- muster mcp
# Codex
codex mcp add muster -- muster mcp

The tools, by what they do:

Group Tools Notes
Identity register_agent, list_agents join the bus once per session; see who's on it
Conversation send_message, reply, get_inbox, get_thread a message is a plain thread β€” no state, just an exchange
Work task_create, task_claim, task_transition a task is a thread with a lifecycle: open β†’ claimed β†’ needs_info | blocked β†’ completed | declined | cancelled. Claiming is atomic β€” two agents can't take the same task
Shared state kv_set, kv_get a key/value scratchpad both sides can read (an API contract, a port, a decision)

The MCP server talks to the local daemon (auto-started on first use).

Note: stdout is the MCP channel in this mode; muster writes all diagnostics to stderr.

CLI

Agents coordinate through the MCP tools above β€” the CLI is for you (and for hooks): commands you run from any shell to watch the bus and step in when you want to (they auto-start the daemon):

muster agents                              # who's registered
muster inbox <alias>                       # threads addressed to an agent
muster tasks <alias>                       # just the tasks for an agent
muster send <alias> "message"  --from me   # send a directed message
muster send --role reviewer "please look"  --from me   # to a role
muster send --broadcast "heads up"         --from me   # to everyone
Registering & liveness

Agents can self-register (so a shell hook can do it at session start):

muster register [alias] --role <r> --model <name>
muster deregister [alias]
muster gc                 # reap agents whose tmux session is gone

register captures the tmux pane automatically. Alias precedence: explicit arg β†’ $MUSTER_ALIAS β†’ tmux session name. --model is stored on the agent and tunes muster nudge's submit keystroke (claude and codex auto-submit; other values are typed without submitting).

muster agents shows each agent's project and live label:

  • project is derived from the tmux socket name when it follows a proj-<name> convention (one tmux server per project). On the default tmux server there's no project β€” everything shares one namespace, and the rest of muster works the same.
  • label is a name you give a session: run muster label backend inside it (or muster label --clear to remove it). Only deliberately-set labels are addressable; auto-generated values are shown parenthesized and are not. (Stored in a tmux session option β€” default @claude_task, override with $MUSTER_LABEL_OPTION.)
Addressing

Any command that takes a target β€” send, nudge, inbox, tasks β€” accepts a target of the form <alias|label|proj:label>:

  • an alias (the tmux session name, globally unique): muster nudge muster-2
  • a label, resolved within your current project: muster send frontend "…"
  • a qualified label to cross projects: muster send timewalk:frontend "…"

A bare label never silently crosses projects; if it's ambiguous or only exists elsewhere, muster errors and lists the proj:label candidates.

Notifications & nudging

When bus activity is addressed to an agent, muster sets @muster_inbox on its tmux session to that agent's unread count. It never types into a pane, and unlike a transient bell the flag persists until the agent reads its inbox (get_inbox), which clears it. tmux doesn't display the option by default β€” add the two render lines from contrib/tmux-mailbox.conf to see πŸ“¬<count> on the tab title and status bar.

To actively poke an agent to act now:

muster nudge <alias>              # types "check your inbox" into the agent's pane and submits
muster nudge <alias> --no-submit  # type only; don't press Enter

Nudge submits for both Claude Code (immediate Enter) and Codex (a short delayed Enter β€” Codex treats an Enter bundled with pasted text as part of the paste). Other model types are typed without submitting.

Hooks (optional)

Registration and inbox-draining can be driven by session lifecycle hooks instead of typed by hand:

  • SessionStart β†’ muster register β€” every session joins the bus on start.
  • Stop (turn end) β†’ if the session has unread muster mail, the hook tells the agent to drain its inbox and reply, autonomously.
  • SessionEnd (Claude Code) β†’ muster deregister; muster gc covers the rest.

The muster binary is its own hook β€” point your harness at muster hook <event> <model> (e.g. muster hook Stop claude). Copy-paste config for both Claude Code and Codex is in contrib/.

License

MIT Β© Court Schuett

Directories ΒΆ

Path Synopsis
cmd
muster command
Command muster is the entrypoint for the muster coordination bus.
Command muster is the entrypoint for the muster coordination bus.
internal
client
Package client talks to the muster daemon, spawning it if needed.
Package client talks to the muster daemon, spawning it if needed.
clock
Package clock provides a test-overridable millisecond clock.
Package clock provides a test-overridable millisecond clock.
daemon
Package daemon serves the muster store over a unix socket.
Package daemon serves the muster store over a unix socket.
humancli
Package humancli implements muster's operator subcommands (agents, inbox, send, tasks) that read/drive the bus from a plain shell.
Package humancli implements muster's operator subcommands (agents, inbox, send, tasks) that read/drive the bus from a plain shell.
mcpserver
Package mcpserver exposes muster's daemon operations as MCP tools over stdio.
Package mcpserver exposes muster's daemon operations as MCP tools over stdio.
mustertest
Package mustertest provides shared test helpers for muster.
Package mustertest provides shared test helpers for muster.
nudge
Package nudge delivers an operator-triggered "check your inbox" prompt into an agent's tmux pane via send-keys.
Package nudge delivers an operator-triggered "check your inbox" prompt into an agent's tmux pane via send-keys.
paths
Package paths resolves muster's on-disk locations.
Package paths resolves muster's on-disk locations.
proto
Package proto defines the daemon wire protocol: newline-delimited JSON.
Package proto defines the daemon wire protocol: newline-delimited JSON.
store
Package store is muster's SQLite persistence layer.
Package store is muster's SQLite persistence layer.
tmuxenv
Package tmuxenv is muster's single point of contact with tmux from outside the daemon: capturing the current pane's identity, deriving the project from the per-project socket, checking session liveness, and reading the session label.
Package tmuxenv is muster's single point of contact with tmux from outside the daemon: capturing the current pane's identity, deriving the project from the per-project socket, checking session liveness, and reading the session label.
wake
Package wake delivers best-effort "notify" signals to agents' tmux sessions by setting/clearing a per-session tmux option (which the operator's status bar surfaces).
Package wake delivers best-effort "notify" signals to agents' tmux sessions by setting/clearing a per-session tmux option (which the operator's status bar surfaces).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL