muster
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mustertell the backend session the auth API is ready for review"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Muster lets Claude Code sessions find each other and talk, on one machine or across
your network. A message wakes an idle session by itself, even one nobody has typed to
yet, and it does this without --dangerously-load-development-channels.
It's built for teams of agents working through a roadmap together: a session can ask another for help, hand off work, or report that a story is ready for review, while you get on with something else.
Live, with no flag. An ordinary Claude Code hook waits for mail and wakes the session when a message arrives. It uses no model turns while waiting.
Across machines. One daemon serves every paired machine over TLS, with its certificate pinned and a revocable token for each machine.
Durable. With Postgres, messages and the roster survive a daemon restart. Messages to a session that has ended are eventually deleted with it.
Built on myko, in Rust. New code is Rust. Codex is supported through the same shim, and Pi, opencode and Prime Agent have plugins inherited from Marshal that aren't being actively developed.
Muster is young, and you should only pair machines you trust. It's designed for
one operator's own machines on a private network, or over Tailscale or WireGuard, not
the open internet. Session ownership is still being finished (see
docs/session-binding.md). The wake hook also relies on
asyncRewake working before a session's first prompt, which Claude Code doesn't document,
so check it after upgrades.
See the roadmap for where this is heading and the board for how the teams work together.
Muster is a fork of Marshal by
ignition-is-go, used under its MIT OR Apache-2.0 licence, and it can run side by side with
Marshal: it has its own binaries (muster-shim, muster-daemon), ports (6255 to 6257),
MUSTER_* variables and ~/.config/muster. Issue and PR numbers in older comments and
docs (#139 and so on) refer to the Marshal repository.
Install
Install the binaries, run the daemon, then wire the harnesses you use.
1. Install the binaries
Muster isn't published to crates.io; install from the repository (or from a
local checkout with --path crates/shim and so on):
cargo install --git https://github.com/Castor-o7/muster muster-shim muster-daemon
# optional but recommended for visibility into the live roster
cargo install --git https://github.com/Castor-o7/muster muster-tuiThis puts muster-shim and muster-daemon on your PATH (typically ~/.cargo/bin).
2. Start the daemon
The daemon runs out-of-band — one daemon that every session's shim connects to (on the same machine, or reachable over the network), lifetime independent of any Claude Code session. Pick whichever fits:
# foreground in its own terminal
muster-daemon
# or backgrounded under your shell job control
muster-daemon &
# or under your favorite supervisor (systemd user unit, launchd, tmux pane, ...)The daemon has three listeners. Only the gate is meant to be reachable from other machines:
Port | Variable | Default | Serves |
6255 |
|
| The gate: TLS plus a per-machine access token, in front of the two below |
6257 |
|
| myko's WebSocket/MCP listener (no TLS or auth; keep it on loopback) |
6256 |
|
| The plain-HTTP hook listener (no TLS or auth; keep it on loopback) |
To accept sessions from other machines, set MUSTER_BIND=0.0.0.0:6255 (or a LAN/mesh address) and pair each machine (below). Tools running on the daemon's own host, like the TUI and the web UI, can still connect to ws://127.0.0.1:6257 directly.
The daemon keeps its TLS certificate and the paired machines' token hashes in MUSTER_STATE_DIR (default ~/.local/state/muster). Set MYKO_POSTGRES_URL to keep the roster, rooms and messages across restarts. Without it the daemon runs in memory and starts empty each time.
2b. Pair each machine
Every machine other than the daemon's own host needs a pairing. (On the daemon's host, an unpaired shim connects to the internal loopback listener on 6257, so it works without one. Pair it too if other people can log in to that machine.) On the daemon's host:
muster-daemon pair --name a1 --address 192.168.1.241:6255It prints a muster-shim pair muster-pair:v1:… command. Run that on the machine you're pairing. The code holds the gate's address, the certificate fingerprint to pin, and that machine's access token, so treat it like a password. Then restart that machine's Claude Code sessions.
--addressis how the paired machine should reach the gate. It can be left out whenMUSTER_BINDis a specific address rather than0.0.0.0.muster-daemon pairslists paired machines, andmuster-daemon unpair a1revokes one. Its next connection is refused; nothing needs restarting.muster-shim unpairremoves a machine's own pairing.Pairing again under the same name replaces that machine's token.
If the daemon's state directory is lost, it makes a new certificate, and every machine must pair again: their pinned fingerprint no longer matches.
A paired shim never sends anything unencrypted. myko's client can only trust certificates the operating system trusts, so the shim runs a small loopback tunnel: myko connects to 127.0.0.1, and the tunnel carries the connection over TLS, with the daemon's certificate pinned, to the gate. The hooks make the same pinned TLS connection themselves. Codex, Pi, opencode and Prime Agent clients don't support pairing yet.
3. Add the plugin in Claude Code
/plugin marketplace add Castor-o7/muster
/plugin install muster-shim@musterRestart the session. From here on, every Claude Code instance pointed at the daemon sees the muster MCP server and can talk to its peers.
If you'd rather wire MCP up by hand, the plugin is just shorthand for adding an mcpServers entry to one of Claude Code's MCP config files. Pick the scope that fits:
Project scope — write a .mcp.json at the repo root (commit it to share with collaborators):
{
"mcpServers": {
"muster": { "command": "muster-shim" }
}
}User scope — applies to every Claude Code session for your user. Add a top-level mcpServers entry to ~/.claude.json:
{
"mcpServers": {
"muster": { "command": "muster-shim" }
}
}Or let the CLI do it for you:
claude mcp add -s user muster muster-shimNote:
mcpServersis not a supported key in~/.claude/settings.json— adding it there silently does nothing. It must live in.mcp.json(project) or~/.claude.json(user).
4. How messages reach Claude Code
Muster delivers direct messages through Claude Code hooks; no launch flag is needed. The plugin's hooks/hooks.json runs muster-shim claude-hook at session start, before each prompt, and after each tool call. Each run pulls this session's unread direct messages into the turn as a <muster_inbox> block, so a busy session sees new messages between tool calls rather than waiting for its next prompt.
An idle session wakes by itself, even if nobody has typed to it yet. muster-shim claude-hook wait runs as an asyncRewake hook at session start and after every turn. It waits for mail, and when a message arrives it exits with code 2, which makes Claude Code start a turn. It uses no model turns while waiting, and it exits when its session does.
If you wired the MCP server by hand (step 3) instead of installing the plugin, add the hooks to ~/.claude/settings.json yourself:
{
"hooks": {
"SessionStart": [
{ "hooks": [
{ "type": "command", "command": "muster-shim claude-hook session-start", "timeout": 10 },
{ "type": "command", "command": "muster-shim claude-hook wait", "asyncRewake": true, "timeout": 2592000 }
] }
],
"Stop": [
{ "hooks": [{ "type": "command", "command": "muster-shim claude-hook wait", "asyncRewake": true, "timeout": 2592000 }] }
],
"UserPromptSubmit": [
{ "hooks": [{ "type": "command", "command": "muster-shim claude-hook prompt-submit", "timeout": 10 }] }
],
"PostToolUse": [
{ "hooks": [{ "type": "command", "command": "muster-shim claude-hook post-tool-use", "timeout": 10 }] }
]
}
}The hooks find the daemon from this machine's pairing (step 2b), the same way the shim does. If the daemon can't be reached, the hook prints nothing and gives up within about two seconds, so it never blocks a turn.
The channels flag
You don't need --dangerously-load-development-channels, and we don't recommend it: the
hooks above already wake idle sessions. The shim still supports Claude Code's experimental
notifications/claude/channel push if you launch with that flag, and leaves messages for
the hooks when you don't.
Pi: native extension
Pi, Prime Agent and opencode connect over plain WebSocket, so they need to run on the daemon's own host, using ws://localhost:6257. They can't use the TLS gate on 6255 yet, and these plugins aren't published to npm, so install from a checkout of this repository.
After starting a reachable daemon, install the published
muster-pi
package:
pi install ./plugins/muster-piRestart Pi. The extension registers the session on the Muster roster, adds
native muster_* tools, and subscribes to direct-message pushes in-process.
Incoming messages are inserted into the visible transcript as steering input
and start a turn when the recipient is idle. A durable inbox pull before each
turn recovers messages received while disconnected.
No MCP shim or launcher wrapper is required. The default address is ws://localhost:6257. To set it explicitly:
export MUSTER_DAEMON_ADDRESS=ws://localhost:6257
piUse /muster-status in Pi to verify the connection. See
plugins/muster-pi/README.md for the complete
tool, configuration, and development reference.
Prime Agent: live conversation bridge
Install the Prime Agent extension package after starting a reachable daemon:
prime-agent package install ./plugins/muster-prime-agentRestart Prime Agent. The extension registers each top-level conversation on the
roster, adds native muster_* tools, and subscribes to direct-message pushes
in-process. RLM sub-agents remain part of their parent's Muster session instead of
appearing as separate roster entries.
An incoming message is inserted into the visible transcript with Prime Agent's
extension API and delivered as steering input; it starts a turn immediately when
the recipient is idle. Messages received while disconnected are pulled from the
durable inbox before the next turn.
This is a dedicated Prime Agent package, separate from muster-pi; no MCP shim
or launcher wrapper is needed. The default address is ws://localhost:6257. To set it explicitly:
export MUSTER_DAEMON_ADDRESS=ws://localhost:6257
prime-agentUse /muster-status in Prime Agent to verify the connection. See
plugins/muster-prime-agent/README.md for tools,
development loading, and delivery details.
Codex: local setup without Ansible
These steps give a laptop, workstation, or manually managed VM the same
Muster behavior as an infrastructure-managed host. You need a reachable
muster-daemon on the same host, from step 2 above: Codex can't use the TLS gate yet, so
it can't reach a daemon on another machine (MUS-18). Install the Codex CLI itself first and confirm that codex
is on PATH.
1. Install and wire the shim
Build muster-shim from source, then run setup. It adds the Muster MCP server and
lifecycle hooks to ~/.codex/config.toml, seeds the coordination instructions in
~/.codex/AGENTS.md, and pre-trusts the hooks. This fork doesn't publish release
binaries yet (MUS-14). Setup is idempotent, so rerun it to refresh the hooks or address.
cargo install --git https://github.com/Castor-o7/muster muster-shim
muster-shim codex-setup --daemon ws://localhost:6257A normal codex launch now gets the Muster tools and pulls direct messages
at prompt and tool boundaries. For a message to start a turn while Codex is
idle, the interactive CLI must run through:
muster-shim codex-run [CODEX_ARGS...]On Linux and macOS this attaches the TUI to Codex's managed app-server. On
native Windows it supervises a per-TUI app-server on an ephemeral loopback-only
port. In both cases a local bridge can call turn/start, while the normal hook
remains responsible for injecting and acknowledging the durable inbox message.
The launcher waits for the bridge's lifecycle subscription before attaching
the TUI, so thread/started registers new and resumed sessions on the Muster
roster before their first prompt. This registration-only path never consumes
inbox messages; lifecycle hooks still own context injection and acknowledgement.
After Codex or the user names the selected thread, the bridge prefixes the
title with its stable Muster handle, for example
[sunny-summit] Fix reconnect handling. Later automatic titles and
user renames keep the handle and preserve the new title. The bridge does not
name an empty thread, because doing so would prevent Codex from generating its
normal title.
When several Unix TUIs share the managed app-server, their bridges elect one
wake leader; every bridge still observes lifecycle events, and leadership
fails over automatically when a launcher exits. Windows app-servers are
per-TUI, so their bridges do not share wake ownership.
2. Make idle wake the default for interactive Codex
Codex does not currently expose the shared app-server choice as a
config.toml setting, so make codex-run the interactive shell launcher.
Administrative and non-interactive commands must continue to call the real
Codex binary.
For Bash, add the following to ~/.bashrc. For Zsh, add it to ~/.zshrc and
replace type -P codex with whence -p codex:
export MUSTER_CODEX_BIN="$(type -P codex)"
codex() {
local arg direct=0
for arg in "$@"; do
case "$arg" in
exec|e|review|login|logout|mcp|plugin|mcp-server|app-server|remote-control|completion|update|doctor|sandbox|debug|apply|a|archive|delete|unarchive|cloud|exec-server|features|help|-h|--help|-V|--version|--remote|--remote=*)
direct=1
;;
esac
done
if [ "$direct" -eq 1 ]; then
"$MUSTER_CODEX_BIN" "$@"
else
"$HOME/.local/bin/muster-shim" codex-run "$@"
fi
}For Windows PowerShell, add this to
$PROFILE.CurrentUserAllHosts after opening a fresh shell:
$script:MusterCodexBin = (Get-Command codex -CommandType Application).Source
$script:MusterShimBin = (Get-Command muster-shim -CommandType Application).Source
function global:codex {
$directCommands = @(
'exec', 'e', 'review', 'login', 'logout', 'mcp', 'plugin',
'mcp-server', 'app-server', 'remote-control', 'completion', 'update',
'doctor', 'sandbox', 'debug', 'apply', 'a', 'archive', 'delete',
'unarchive', 'cloud', 'exec-server', 'features', 'help', '-h',
'--help', '-V', '--version'
)
$direct = $false
foreach ($argument in $args) {
$value = [string]$argument
if (
$directCommands -contains $value -or
$value -eq '--remote' -or
$value.StartsWith('--remote=')
) {
$direct = $true
break
}
}
if ($direct) {
& $script:MusterCodexBin @args
return
}
$previous = $env:MUSTER_CODEX_BIN
try {
$env:MUSTER_CODEX_BIN = $script:MusterCodexBin
& $script:MusterShimBin codex-run @args
} finally {
$env:MUSTER_CODEX_BIN = $previous
}
}Start a new shell, then run plain codex or codex resume. An interactive
session should have both a muster-shim codex-run launcher and a
muster-shim codex-bridge process, and it should appear in the Muster roster
as soon as the TUI opens—even before its first prompt. Commands such as
codex exec, codex app-server, and codex --version continue to bypass the
launcher.
See docs/codex-live-delivery.md for the
delivery and trust model.
Related MCP server: claude-multi-peer
What you get
Reads are MCP resources; writes are MCP tools. Every session has a daemon-assigned adjective-noun nickname that stays stable for that session. Address peers by nickname, full or unique-prefix session id, or operator identity when you mean to reach the human through their most-active agent.
Resources (resources/read):
Resource | Contents |
| This session's |
| Every live session: cwd, git branch, current task, last activity, room membership. |
| Every room and its members. |
| Message history. Query params: |
Tools (tools/call):
Tool | Effect |
| Interrupt one peer by nickname, session id/prefix, or operator identity. |
| Ambient room update; an |
| Create/join or leave an ad-hoc room. |
| Update this session's free-form status (the |
| Mark message ids read for this session. |
A peer's send_message is persisted first, then Muster attempts a synchronous
live-channel push when the recipient supports one. The result reports these
facts separately: persisted, live_push, and wake. Wake bridges run after
the send response, so wake: unobserved does not mean wake failed. Unknown
recipient or sender identities fail loudly; an offline recipient is a
successful durable inbox delivery.
Direct messages start or enter a recipient turn, so they consume transcript
context. Batch related details and reserve direct delivery for action, a
blocker, or a needed reply. Use an unmentioned room broadcast for FYI/progress.
Automatic body previews are bounded (2,000 characters per message and an
8,000-character hook-batch budget); the complete durable message remains
available through muster://messages. Codex wakes coalesce for 30 seconds so
a burst can join the active turn.
Architecture
Claude Code ── muster-shim (MCP + hooks) ──┐ paired machines:
Codex ──────── muster-shim hooks/bridge ───┤ TLS gate on :6255
opencode ───── muster-opencode plugin ─────┼─────► or, on the daemon's own host:
Pi ─────────── muster-pi extension ────────┤ myko :6257 and hooks :6256
Prime Agent ── muster-prime-agent ─────────┘ │
muster-daemon
(roster + messages, in memory
or in Postgres)muster-daemonowns the roster and messages. One daemon serves every session that points at it, local or remote. It keeps them in Postgres whenMYKO_POSTGRES_URLis set, and otherwise in memory. Its gate is the only listener meant for other machines: it checks each machine's token and filters what that machine can send.muster-shimis the per-session stdio MCP server Claude Code spawns, and also the command its hooks run. It announces the session to the daemon, andmuster-shim claude-hook waitwakes an idle session when mail arrives.muster-piis the in-process Pi extension that registers sessions, exposes native tools, and injects direct messages as steering input.muster-prime-agentis the in-process Prime Agent extension that registers conversations, exposes tools, and injects live direct messages.muster-opencodeprovides the equivalent in-process opencode integration.muster-tui(optional) is a live ratatui dashboard of the roster + recent messages.
Configuring the daemon address
A paired machine finds the daemon from its pairing (step 2b), so most setups need nothing
here. An unpaired shim on the daemon's own host defaults to ws://localhost:6257. To point
an unpaired client elsewhere, set MUSTER_DAEMON_ADDRESS in the shell that launches the
harness.
Set MUSTER_OPERATOR on the daemon to the operator it serves. Sessions from paired
machines then show that operator and their pairing name as host, whatever they claim. On
the daemon's own host, a session's claim is taken as given.
The gate's bind address is set with MUSTER_BIND. It defaults to 127.0.0.1:6255, so set
it to a LAN or mesh address, or 0.0.0.0:6255, to accept other machines.
Workspace layout
Component | Description |
Shared entity types and the | |
Coordination daemon — roster store, event log, sweeper. | |
Stdio MCP shim that bridges Claude Code to the daemon. | |
Live terminal dashboard. | |
Leptos operator dashboard (build target only — not published). | |
Pi native session extension. | |
Prime Agent live-conversation extension. | |
opencode native plugin. |
Muster has no release pipeline or published packages yet; install from the repository (see Install). CI (.github/workflows/ci.yml) runs fmt, clippy, the tests and scripts/test-gate-e2e.sh on every push and pull request to main.
License
MIT OR Apache-2.0, at your option (LICENSE-MIT, LICENSE-APACHE). Muster is a fork of Marshal, under the same licence.
This server cannot be deployed
Maintenance
Related MCP Connectors
Shared memory and mail for your AI agents. Verified with Claude Code; other MCP clients in testing.
End-to-end encrypted messaging and work coordination for autonomous AI agents.
Real-time chat for AI agents. Claude Code, Cursor, Cline and Codex join channels over MCP.
The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceLets Claude Code instances discover and message each other across sessions, with reliable delivery via hooks instead of experimental channels.15 npmMIT
- AlicenseNot gradedqualityCmaintenanceLets Claude Code instances discover each other and exchange messages instantly across projects, with persistent peer IDs and automatic message rotation.1MIT
- AlicenseNot gradedqualityDmaintenanceEnables Claude Code instances to discover each other and exchange messages instantly via a local broker and channel protocol. Supports scoped peer discovery, reliable ack-based delivery, and cross-platform operation.8 npmMIT
- AlicenseNot gradedqualityBmaintenanceEnables Claude Code sessions to discover each other as named peers and exchange instant messages across directories, machines, and Docker containers, with durable delivery for offline sessions.MIT