muster
This is a read-only Muster MCP server for inspecting Muster-owned runs and reading task output.
List sessions and tasks, optionally filtered by
kind(sessionortask), including host capabilities.Read captured output from a task run by its required
id.It cannot launch, stop, title, open, or otherwise modify sessions/tasks.
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., "@musterRun a Codex session to review the authentication flow"
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
Launch coding agents on your machine, under containment you chose, and get back an address you can actually reach.
Muster starts Claude Code, Codex and OpenCode sessions on your behalf. You say what the agent may do; Muster arranges it, verifies the session is genuinely alive, and hands you a durable address for it. If a session never becomes reachable, you get a diagnosis naming what stopped it — not a process that looks fine and isn't.
It is the launching half of a small family: Muster starts agents, tincan lets them message each other, birddog watches what they do.
What it's for
Running more than one agent, deliberately. One session reviewing while another builds; a task that runs once and captures its output; an agent launched under a separate account so its work never touches your own configuration. Muster is the part that makes those launches repeatable, contained and addressable instead of a terminal tab you have to remember.
A session returns an address only after its runtime is reachable. A task
runs once, captures output, and never advertises a peer address.
Related MCP server: LightsOut
What makes it different
Containment is two separate questions, and both are answered. Whether the agent stops to ask you, and what it may touch — the second enforced by the OS, not by asking nicely. Every launch records which of the two it actually got.
A session is only reported ready when it is reachable. Muster asks each runtime in its own language — a session record, an RPC call, an HTTP endpoint — and does not confuse "the process started" with "the agent is listening".
It refuses instead of guessing. An unrecognised flag, a contradictory pair of options, an identity belonging to a different runtime: all errors, before anything is started. Nothing half-launched is left behind.
Other machines can ask, within limits you set. An enrolled caller launches inside a profile's ceiling — the directories it may use, the strongest containment it may request. Configuration is the grant; the request never widens it.
Every claim here was measured. Runtime behaviour is established by driving the real programs and recording what they did — see Verification. Where a finding later proved wrong, the correction is in the release notes rather than quietly edited away.
Claude requires a directory already trusted by the operator, or
--options auto-approve-path. The automated suite uses fake runtimes, not real
models; behaviour against real ones is verified by hand and recorded in
RELEASE_NOTES.md.
Quick start
# Allow the install scripts: muster's postinstall builds node-pty, and npm
# skips install scripts by default — silently, so the pty host fails later.
npm install -g --allow-scripts=@brutalsystems/muster,node-pty @brutalsystems/muster
# A session: an agent you can reach, addressed once it is genuinely alive.
muster run claude --prompt 'Review this project' --cwd .
# A task: runs once, captures output, advertises nothing.
muster run codex --kind task --prompt 'Summarise the failing tests' --read-only
muster output <id>
# Knowing it has finished: block on it, or have muster run a command then.
muster wait <id> --timeout 30m
muster run codex --kind task --prompt 'Review' --on-exit 'notify "$MUSTER_STATE"'
# What is running, and stopping it.
muster list --format human
muster stop <id>
# Show a session in a terminal: terminal, iterm2, ghostty, or one you define
# under [open.apps] in config.toml (see docs/launching.md).
muster run claude --prompt 'Review this project' --open kittyA Claude launch with no containment flag opens exactly as you would open it
by hand in that profile and folder. It gets your rules and CLAUDE.md, your
permissions, hooks, status line, plugins, MCP servers and settings env.
Muster adds nothing and replaces nothing. The one thing it refuses is a profile
whose default permission mode is bypass. Codex and OpenCode stay read-only by
default.
When you want muster's guarantee instead, seal the launch. A sealed launch runs on muster's own settings in place of the profile's, so it loads no rules or CLAUDE.md:
Flag | The agent asks before acting | What it may touch |
| always | nothing on disk |
| no | its cwd, except |
| no | everything |
--unrestricted removes the sandbox and needs allow_dangerous_flags in
config. --level read|work|open is the older spelling of the same three and
still works.
Claude asks to trust a directory the first time. That is a one-time review you
do yourself — or --options auto-approve-path, which records it for you after
checking the directory ships no hooks. See
Claude workspace trust.
Requirements
Node 22.12+ (tested on 24.16), and a POSIX host with ps and lsof.
Terminals use tmux or node-pty. The OS sandbox is seatbelt, so kernel-enforced
containment is macOS only; everywhere else enforcement reports what was
actually applied rather than pretending.
Then whichever agents you mean to launch, installed and logged in. Verified against Claude Code 2.1.274, Codex 0.155.1 and OpenCode 1.18.31 or newer — a newer OpenCode must keep the CLI and loopback HTTP API Muster uses. What that verification covers is in Verification.
Documentation
hosts, terminals, lifetimes, repeated requests | |
containment, config file, remote callers | |
running as a named account | |
the one-time dialog, and the two gates behind it | |
output formats, runtime pass-through | |
tools for launched agents, and Muster's own MCP server | |
what is tested, what is checked by hand |
Use with Claude Code
Install the plugin. Its
musterskill teaches a Claude session to use Muster well: choosing a kind and level, reaching and stopping what it launched, and the traps. It also brings Muster's MCP server, read-only (list,output), started withnpxat the release the plugin came from. Both are versioned with Muster, so they describe and run the same release.claude plugin marketplace add BrutalSystems/muster claude plugin install muster@musterOr, inside a session,
/plugin marketplace add BrutalSystems/musterand then/plugin install muster@muster.The plugin's server needs Node 22.12+ with
npxon PATH. On macOS and Windows, node-pty loads a prebuilt binary. On Linux,npxbuilds node-pty from source the first time, which needs Python,makeand a C++ compiler; without them, use the global install and step 2 instead.Or register the MCP server yourself, when you want launch authority or a server that runs your global
muster:muster mcp installIt is read-only by default too.
muster mcp install --allow-launchaddsrun,stop,titleandopen, and every session in that profile can then launch and stop sessions.muster mcp statusshows which you have. Use the plugin's server or this one, not both: see plugin or registration. Details: MCP installation.Restart Claude Code (or start a new session) to load it.
Keeping it up to date
Publishing a release does not touch an installed copy: muster --version keeps
reporting the old version until you update it.
npm update -g @brutalsystems/musterIf which muster resolves to a version-manager shim (for example
~/.asdf/shims/muster), run that update under the Node the shim resolves to and
reshim afterwards — asdf reshim nodejs — or the shim keeps pointing at the old
binary.
The plugin, and the server it pins, update with the marketplace:
claude plugin marketplace update muster
claude plugin update muster@musterAn MCP server starts once at session startup, so an agent session that already has Muster loaded keeps running the old binary until that session restarts. Updating on disk is not enough; restart the session too.
Build and run locally
npm run check is the local gate: it builds, runs the suite, then packs and
verifies the tarball — the same scripts/check-tarball.mjs the CI packing job
runs, so the two cannot disagree about what "verified" means. npm test alone
does not pack anything, so tarball drift is green locally and red on push.
It is not everything CI does: CI additionally runs the suite across the Node
version matrix, and the contract suite runs only on release. Passing check is
necessary rather than sufficient.
Beyond the runtime requirements above, building needs TypeScript 5. The terminal interface itself is platform-neutral; the macOS Terminal driver is an unavailable v1 stub.
npm ci
npm run build
node dist/muster.js run codex --prompt 'Review the authentication flow'
node dist/muster.js run claude --prompt 'Summarize the project' --host tmux
node dist/muster.js run opencode --prompt 'Review this project'
node dist/muster.js run opencode --prompt 'Build a plan' -- --model local-provider/qwen3-30b
node dist/muster.js run codex --kind task --prompt 'Explain the test layout'
node dist/muster.js run opencode --kind task --prompt 'Summarize the tests'
node dist/muster.js list
node dist/muster.js list --format human
node dist/muster.js list --kind task
node dist/muster.js output RUN_ID
node dist/muster.js stop THREAD_OR_SESSION_OR_RUN_ID--prompt is required and cannot be blank. --cwd defaults to the current
working directory. --kind defaults to session. All commands except output
emit JSON; output prints the captured task output. stop also accepts an
unambiguous peer name or canonical address, refusing ambiguity with candidates.
Use the durable ID to stop a session whose runtime has renamed it.
License and releases
MIT © 2026 BrutalSystems. See LICENSE. Vendored Tin Can code retains source attribution and its MIT notice.
Publishing is tag-driven and runs in GitHub Actions over OIDC trusted
publishing, with no stored npm token. A bare git push publishes nothing; a
version tag is what triggers publish.yml. That workflow validates a RELEASE_NOTES.md section for
the version being published, so write the notes under ## Unreleased as you do
the work and commit them normally. Cutting the release is then one command:
git commit -am "<the change, including its notes under ## Unreleased>"
npm version patch -m "%s — <what changed>"npm version runs the version hook, which stamps ## Unreleased into
## <version> — <date> and stages it, then bumps, commits and tags; the
postversion hook pushes the commit and tag together. If there is no
## Unreleased section, or it is empty, the stamp refuses — before a tag
exists, rather than in CI after one has been pushed.
RELEASING.md covers versioning, package inspection, publication, and release notes in full. Changes to the shared address format require an explicit contract update; Muster never independently fixes the frozen naming behavior.
Available Tools
2 toolslistList sessions and tasksBRead-only
List Muster-owned sessions and tasks, including host capabilities.
| Name | Required | Description | Default |
|---|---|---|---|
| kind | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false, so the safety profile is covered. The description adds useful scope by saying results are Muster-owned and include host capabilities. However, it does not describe ordering, pagination, or whether the list is exhaustive, leaving some behavioral gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no redundant phrasing. Every element, including the ownership scope and host-capability inclusion, adds useful information. There is no structural waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
This is a simple list tool with one optional enum parameter and annotations covering safety. The description states the resource and scope, but it omits parameter behavior, return-shape detail, and sibling-tool guidance. It is minimally adequate but has clear gaps for an agent deciding exactly how to call it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the description never mentions the 'kind' parameter. It does not explain that 'kind' filters between sessions and tasks, nor what happens when it is omitted. The enum values are self-explanatory, but the description does not compensate for the missing schema documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: listing Muster-owned sessions and tasks. It also adds that host capabilities are included, which clarifies scope. It does not explicitly distinguish this tool from the sibling 'output', but the resource is clear enough to identify the operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives no guidance on when to use this tool versus the sibling 'output', nor does it state any exclusions or prerequisites. Usage is only implied by the verb 'List'. An agent must infer the appropriate context without help from the description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
outputRead task outputBRead-only
Read captured output from a task run.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=false. The description adds that the output is 'captured' from a task run, clarifying that this reads stored output rather than streaming or live data. It does not explain truncation, permissions, or error behavior, but for a simple read-only tool this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single front-loaded sentence with no wasted words. It is appropriately sized for a simple read operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a low-complexity read-only tool with annotations and one required parameter, the description is minimally viable. It is missing explicit id semantics and any note about the return format, but the tool name and title carry much of that meaning.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, and the single required parameter 'id' is undocumented. The description implies the id identifies a task run, but it never explicitly states what the id is, its format, or how to obtain it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Read') and resource ('captured output from a task run'), making the core purpose clear. It does not differentiate itself from the sibling tool 'list', but an agent can still understand what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no explicit guidance on when to use this tool versus the sibling 'list', nor any prerequisites or exclusions. The usage is only implied by the verb 'Read'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
3 tool updates
v3.0.0- Removed
run - Removed
stop - Removed
title
2 tool updates
v1.2.0- Changed
run3 fields changed- changed
Input schema / properties / idleTimeout / descriptionPrevious value: -"Stop this tmux session after the given inactivity, as 90s/30m/4h, or 'off'. Defaults to 30m. Refused for tasks and for pty or macos-terminal hosts, which do not outlive their parent."New value: +"Stop this tmux session after the given inactivity, as 90s/30m/4h, or 'off'. Off by default. Refused for tasks and for pty or macos-terminal hosts, which do not outlive their parent." - added
Input schema / properties / optionsAdded value: +{ + "description": "Muster-side launch options. auto-approve-path records the launch directory as trusted in the profile the agent will use, so its one-time dialog does not block the launch; refused for a runtime with no trust gate, and refused if the directory ships hooks or MCP servers. accept-bypass-warning accepts Claude's one-time Bypass Permissions warning for a bypass launch (level open); refused for other runtimes and without bypass permissions. Not expressible remotely.", + "items": { + "enum": [ + "auto-approve-path", + "accept-bypass-warning" + ], + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / titleAdded value: +{ + "description": "Terminal title for this tmux session, shown by any terminal attached to it. Defaults to the session's name and runtime once it is reachable; the agent's own title is shown instead only with [session] title_from_agent. Control characters are stripped and it is capped at 100 characters. Refused for tasks and for pty or macos-terminal hosts.", + "type": "string" +}
- Added
title
1 tool update
v0.9.1- Changed
run2 fields changed- added
Input schema / properties / idleTimeoutAdded value: +{ + "description": "Stop this tmux session after the given inactivity, as 90s/30m/4h, or 'off'. Defaults to 30m. Refused for tasks and for pty or macos-terminal hosts, which do not outlive their parent.", + "type": "string" +} - added
Input schema / properties / ttlAdded value: +{ + "description": "Stop this tmux session the given duration after launch regardless of activity, as 90s/30m/4h, or 'off'. Off by default.", + "type": "string" +}
1 tool update
v0.7.21- Changed
run1 field changed- changed
Input schema / properties / model / descriptionPrevious value: -"PROVIDER/MODEL, overriding the configured [opencode] model. OpenCode only."New value: +"Model for the launch. A bare model id for claude and codex; PROVIDER/MODEL for opencode, where it overrides the configured [opencode] model. Recorded on the run and reported by `list`."
1 tool update
v0.7.14- Changed
run6 fields changed- added
Input schema / properties / identityAdded value: +{ + "description": "A named identity created by `muster setup-identity`; the agent runs as that account instead of inheriting the ambient environment. A non-local requester is bounded by its profile's identities.", + "pattern": "^[a-zA-Z0-9_-]+$", + "type": "string" +} - added
Input schema / properties / levelAdded value: +{ + "description": "A spelling of a legal permissions/sandbox pair: read is deny + read-only, work is auto + workspace-write, open is bypass + full-access. Naming a level and either flag is an error.", + "enum": [ + "read", + "work", + "open" + ], + "type": "string" +} - added
Input schema / properties / modelAdded value: +{ + "description": "PROVIDER/MODEL, overriding the configured [opencode] model. OpenCode only.", + "minLength": 1, + "type": "string" +} - added
Input schema / properties / pluginAdded value: +{ + "description": "Configured OpenCode plugin names. Omit for session defaults; [] disables all. OpenCode only.", + "items": { + "pattern": "^[a-zA-Z0-9_-]+$", + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / projectAdded value: +{ + "description": "A project named in config.toml, used instead of cwd. Naming both is an error.", + "pattern": "^[a-zA-Z0-9_-]+$", + "type": "string" +} - added
Input schema / properties / requestKeyAdded value: +{ + "description": "Caller-owned identity for this launch. Repeating it returns the launch it already produced instead of starting another; repeating it with different parameters is refused.", + "maxLength": 200, + "minLength": 1, + "type": "string" +}
1 tool update
v0.7.8- Changed
run4 fields changed- added
Input schema / properties / mcpAdded value: +{ + "description": "Configured MCP server names. Omit for session defaults; [] disables all. Tasks have no defaults.", + "items": { + "pattern": "^[a-zA-Z0-9_-]+$", + "type": "string" + }, + "type": "array" +} - added
Input schema / properties / openAdded value: +{ + "description": "Open the tmux session in a terminal viewer (macOS only).", + "type": "boolean" +} - changed
Input schema / properties / runtime / enumPrevious value: -[ - "codex", - "claude" -]New value: +[ + "codex", + "claude", + "opencode" +] - added
Input schema / properties / terminalAdded value: +{ + "description": "Viewer app; requires open. Auto uses Terminal.app.", + "enum": [ + "auto", + "terminal", + "iterm2", + "ghostty" + ], + "type": "string" +}
4 tool updates
v0.3.0- First observed
list - First observed
output - First observed
run - First observed
stop
TDQS
Scored across 2 tools
The two tools have distinct purposes: list enumerates sessions/tasks/host capabilities, while output reads captured output from a task run. There is little overlap, though the generic name 'list' is broad enough that an agent may need to inspect the description to know what it lists.
Both tool names are single lowercase verbs, so the naming style is internally consistent. However, they are very generic and do not follow a descriptive verb_noun pattern, which reduces predictability.
Two tools is thin for a server that appears to manage sessions, tasks, and task output. It sits at the borderline where the surface feels underpowered for the apparent domain.
The server exposes only listing and output-reading, with no tools for creating, starting, updating, or deleting tasks/sessions. These are significant gaps that will likely cause agents to hit dead ends in core workflows.
Maintenance
Related MCP Connectors
Start and manage Reason cloud coding agents, projects and sessions from any MCP client.
A paid remote MCP for OpenAI Codex agent coordination MCP, built to return verdicts, receipts, usage
Hosted MCP memory and agent control plane for durable conversations, jobs, and operations.
Scoped agent execution. Server-side credentials, policy, budgets and verifiable receipts.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.4MIT
- FlicenseNot gradedqualityAmaintenanceAgent orchestration system that runs coding-agent sessions (Claude Code, Codex) with policy mediation and exposes tools via MCP.-
- FlicenseNot gradedqualityCmaintenanceMCP server for programmatic lifecycle management of Claude Code sessions, supporting list, create, read, send, fork, wait, and interrupt operations.1 npm1-
- FlicenseNot gradedqualityBmaintenanceEnables MCP hosts like Claude Code and Codex to spawn, manage, and interact with persistent, reusable Pi coding-agent sessions, supporting task dispatch, status checks, and session lifecycle control.2 npm-