Skip to main content
Glama

Muster

license

Muster launches instructed Codex, Claude Code, or OpenCode agents on this machine. A session returns an address only after its runtime is reachable. A task runs once, captures output, and never advertises a peer address.

Live launch verification: Codex and Claude both launched and answered their initial prompts without terminal interaction. OpenCode 1.18.31 passed the loopback API and local-provider protocol checks. Claude requires a directory already trusted by the operator. The automated suite uses fake runtimes, not real models.

Install

npm install -g @brutalsystems/muster
muster --version

Publishing a release does not touch an installed copy: muster --version keeps reporting the old version until you update it.

npm update -g @brutalsystems/muster

If 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.

An 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.

Related MCP server: pokeclaw

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.

Requires Node 22.12+ (tested with 24.16), TypeScript 5, Codex 0.155.1, Claude Code 2.1.267, and OpenCode 1.18.31 or newer. Newer OpenCode releases must retain the CLI and loopback HTTP API used by Muster. Terminal drivers use tmux or node-pty. Process discovery currently requires a POSIX host with ps and lsof; the terminal interface itself is platform-neutral. The macOS Terminal driver is an unavailable v1 stub.

Before launching a Claude session, open Claude normally in the target directory and complete its workspace-trust review yourself, then exit that setup session. This is a one-time prerequisite for each directory Claude requires you to trust. Muster never accepts trust prompts or changes trust settings. An untrusted directory can block startup; Muster times out and cleans up that launch.

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 coldfire-local/qwen3-30b-a3b
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.

For readable terminal output, add --format human to run, list, stop, or doctor:

muster run codex --prompt 'Review this project' --format human
muster list --format human
muster stop THREAD_OR_SESSION_OR_RUN_ID --format human

Human output keeps full IDs and shows directory, host, state, and relevant attach/output/stop commands with actual IDs. pty sessions are labeled as not watchable or attachable. --format json is explicit JSON; omitting the flag still returns JSON. Put Muster options before any -- RUNTIME_OPTIONS. output always prints captured task text and does not accept --format. MCP tools retain their existing JSON responses.

Human output uses subtle colors in interactive terminals: green for idle or running, yellow for busy or starting, gray for ended states and field labels, red for failures or nonzero exit codes, and cyan for follow-up commands. IDs and paths retain the normal text color. Set NO_COLOR=1 to disable colors; piped output and TERM=dumb are always uncolored. JSON never includes colors.

run accepts an optional -- followed by runtime arguments. The normal allowlist is --model / -m, plus Claude's --effort and OpenCode's --agent and --variant. Unknown options, bundled short options, config injection and raw permission overrides are refused, even with allow_dangerous_flags enabled. Use Muster's normalized permission flags. Prompt strings are always passed as one literal argument. Codex and Claude launches and OpenCode tasks put that value after --; OpenCode sessions use the dedicated --prompt value.

OpenCode inherits the provider and model definitions from its normal user and project configuration, so configured local OpenAI-compatible providers such as coldfire-local/qwen3-30b-a3b remain available. Muster never rewrites those files. Put runtime options after --, as in the local-model example above.

muster run opencode --prompt 'Review this project'
muster run opencode --prompt 'Build a plan' -- --model coldfire-local/qwen3-30b-a3b
muster run opencode --kind task --prompt 'Summarize the tests'
muster run opencode --mcp tincan --permissions auto --sandbox workspace-write --prompt 'Coordinate'

Terminal lifetime

Add --open to display the launched session in a new Terminal.app window on macOS:

muster run codex --open --prompt "Review this project" --format human
muster run claude --open --terminal ghostty --prompt "Review this project" --format human
muster run opencode --open --terminal iterm2 --prompt "Review this project" --format human
muster run codex --open --terminal iterm2 --prompt "Review this project" --format human

MCP run accepts open: true. This requires tmux and selects it when the host is auto; explicit pty hosts and tasks are rejected. Detached launch remains the default. --terminal auto|terminal|iterm2|ghostty requires --open; omitted or auto uses Terminal.app. MCP accepts the same terminal values. Explicit choices never silently fall back. iTerm2 and Ghostty must be installed as iTerm.app or Ghostty.app in /Applications or ~/Applications. The host remains tmux. Successful results include terminal_opened: true and the resolved terminal (a launch event, not a live window-status check). Closing the Terminal window leaves the session running; use muster stop <id> to stop it. Terminal.app and iTerm2 may require macOS Automation permission. Ghostty opens a separate app instance that exits when its last window closes; that instance disables saved-window restoration so previous tabs and windows are not duplicated. It uses the Ghostty macOS launch interface. Terminal.app creates the requested window before activation to avoid also opening a default shell window on startup. iTerm2 uses its documented scripting interface. If the launch request to the viewer fails, Muster stops the launched session and returns an error.

Auto-selection tries tmux, then pty. Every peer includes host, capabilities and attach_hint. Watchability is separate from the runtime's idle/busy state.

  • tmux: each agent has its own session on the dedicated muster tmux server. Opening or exiting one agent does not switch another agent's viewer. Watchable and attachable; survives the CLI or MCP server exiting. Use the returned attach hint to reconnect to that agent.

  • pty: not watchable or attachable. The CLI prints the peer record and stays running to own the terminal. Ctrl-C stops it. MCP-owned pty sessions stop when the MCP server disconnects. There is no persistent pty daemon.

  • task: a per-run worker captures stdout/stderr and exit status after the launching CLI exits. It supervises one task, with no retry or restart behavior.

list refreshes live session metadata and shows ended runs distinctly. A timeout or startup failure cleans the process tree and host window, logs failure, and returns an error instead of a peer record.

Each OpenCode session owns a separate HTTP server bound to 127.0.0.1 on a Muster-selected port. Muster verifies that the listener belongs to the launched process tree, stores its server_url and durable session_id, and never attaches to an existing personal OpenCode server. list refreshes the session through that endpoint; stop aborts it best-effort and still performs authoritative process-tree cleanup. The URL is local control metadata, not a public address. OpenCode sessions otherwise use the same tmux/pty, viewer, list, stop, and human output behavior described above; OpenCode tasks use the same detached output and exit-status lifecycle as other tasks.

Configuration and permissions

Muster reads ~/.muster/config.toml once at startup and never writes it. Missing configuration uses these defaults:

host = "auto"
launch_timeout_sec = 30
max_concurrent = 4
permissions = "deny"
sandbox = "read-only"
allow_dangerous_flags = false
default_mcp = []

Choose sandbox = "workspace-write" yourself when agents should edit files. full-access and permissions = "bypass" require allow_dangerous_flags = true. The old config spelling danger-full-access remains accepted as an alias.

Per-launch --permissions and --sandbox override these config defaults. The same named fields are accepted by MCP run. Both session and task launches support them:

muster run codex --permissions auto --sandbox workspace-write \
  --prompt 'Implement the change' --format human
muster run claude --permissions auto --sandbox workspace-write \
  --prompt 'Implement the change' --format human

Muster permissions

Codex translation

Claude Code translation

OpenCode translation

deny (default)

Approval policy never

Permission mode dontAsk

Deny write, shell, task, external-directory, web, and unselected MCP operations

auto

--approve-for-me

Permission mode auto

--auto with explicit deny rules

bypass

Bypass approvals and sandbox

Permission mode bypassPermissions

Allow supported operations

deny refuses actions that would require approval; it does not prohibit tools already allowed by the sandbox or permission rules. auto delegates permission review to the runtime and may still reject an action; it is not blanket approval. Auto mode requires workspace-write in Muster because the Codex preset selects that sandbox. Explicitly select it; Muster never widens a read-only request. Bypass requires full-access; combinations claiming a sandbox while bypassing it are refused. deny can be combined with any authorized sandbox setting.

full-access disables the runtime command sandbox and requires operator-owned config authorization even without bypass. Muster never writes that config. Config defaults apply to subsequent launches; overrides apply to one launch. Resolved permissions and sandbox are returned in records, shown in human output, persisted for listing, and written in the pre-launch log. Old records without those fields remain readable; their settings are not guessed.

The runtimes' enforcement differs: Codex reviews sandbox escalation requests; Claude's classifier reviews tool permission requests while its Bash sandbox is separate. Auto-mode availability and decisions remain subject to runtime, model, account, and managed policy. These fields describe Muster's resolved launch settings, not a continuous attestation of remote policy or user changes. See Codex auto-review and Claude permission modes.

OpenCode permissions are tool policy, not an OS-level filesystem sandbox. Muster's read-only OpenCode policy denies editing, shell, subagent, external-directory, web, and MCP operations except explicitly selected MCP tools; it does not claim kernel-enforced isolation. Auto still requires workspace-write, and bypass still requires authorized full-access.

The concurrency cap is shared by separate CLI/MCP processes, including pending launches. Settings apply to both kinds; tasks are read-only by default.

Codex defaults to an explicit sandbox and never-ask approval policy. Muster enumerates and explicitly disables inherited MCP servers, enables only the selected operator definitions, then verifies the effective server selection. Hooks, plugins, app connectors, automatic skill-MCP installation and external notifications are disabled for the child. Unknown MCP names that cannot be addressed safely are refused.

Claude's built-in tools default to enabled. Unless full access is selected, its command sandbox is enabled, requires availability, and forbids unsandboxed retries. File-writing tools and sandbox writes are denied in read-only mode; default permissions use dontAsk so an unattended child does not auto-grant escalations. User/project settings and MCP servers are not inherited. Detected managed policy is refused because the CLI cannot prove that inline settings override it. Enterprise remote policy can arrive after startup; this v1 is not an enterprise policy-enforcement layer. Claude permissions and its command sandbox are different mechanisms; neither claim implies that every external tool is OS-sandboxed.

OpenCode keeps normal provider/model configuration and launches with --pure unless plugins are selected, which disables inherited external plugins. Providers declared under [opencode.provider] and a model named by [opencode] model or --model are supplied in the same verified overlay, so a launch does not depend on the operator's own OpenCode configuration; provider definitions merge with any the child resolves for itself rather than replacing them. Secrets belong in api_key_env_var, read from the launching environment, not in config.toml. Before launch, Muster inspects the effective OpenCode configuration, disables every inherited MCP server and tool family, enables only the selected Muster definitions, and fails closed if a higher-precedence managed policy prevents that isolation from being proven.

These child restrictions prevent automatically propagating spawn authority. External tools are enabled only through the operator configuration and launch selection described below. Codex and Claude runtime inboxes remain reachable from an external Tin Can even when they have no MCP tools of their own. An OpenCode session is reachable as a Tin Can peer only when the Tin Can plugin is selected with --plugin; the plugin, not the MCP server, is what advertises the session to other runtimes. No user-level runtime configuration is rewritten, and workspace-trust dialogs are never accepted automatically.

Launch intent is fsynced to ~/.muster/launches.jsonl before a runtime starts; ready/failure outcomes follow. The log contains the full prompt, cwd, requester, runtime, kind and host. Registry and task outputs also live under ~/.muster, with private file permissions. An abandoned registry.lock fails closed: verify no Muster operation is running before removing that directory. There is no automatic time-based lock theft.

Optional tools for launched agents

MCP servers are optional. Muster does not require or install Tin Can (or any other MCP server). Register only servers you want launched agents to use in ~/.muster/config.toml. For example, to use an already-installed Tin Can:

# Optional personal defaults for sessions. Omit to keep launches MCP-free.
default_mcp = ["tincan"]

[mcp_servers.tincan]
command = "tincan"
tools = ["peers", "send_peer", "message_log"]
required = false

Then any runtime can use it:

muster run codex --mcp tincan --prompt 'Coordinate with the other agent'
muster run claude --mcp tincan --prompt 'Coordinate with the other agent'
muster run opencode --mcp tincan --permissions auto --sandbox workspace-write \
  --prompt 'Coordinate'
muster run codex --no-mcp --prompt 'Work without external tools'

A plugin is named either by path or by an npm specifier, never both. A path becomes a file URL; a specifier is passed through untouched for OpenCode to resolve and install:

[plugins.tincan]
npm = "@brutalsystems/tincan-opencode"

[plugins.local-thing]
path = "~/.config/opencode/plugin/local-thing.ts"

Prefer npm where the plugin is published — but not because it avoids a stale copy. Both routes keep one. A copied file goes stale in silence: the package updates, the copy does not, and the old code keeps running against whatever it was built for. A specifier keeps its copy somewhere less obvious. OpenCode resolves the specifier once, writes a generated package.json pinning the resolved version alongside a lockfile, and caches that under the range it was asked for:

~/.cache/opencode/packages/@brutalsystems/tincan-opencode@latest

Publishing a new version does not change that directory and nothing warns, so the stale plugin keeps running and keeps reporting. Deleting it forces re-resolution on the next launch:

rm -rf ~/.cache/opencode/packages/@brutalsystems/tincan-opencode@latest

Muster passes the specifier through untouched, so pin a version where the staleness should be deliberate and visible in config rather than implicit in a cache. OpenCode keys a pinned specifier to its own directory, leaving the @latest copy alone:

[plugins.tincan]
npm = "@brutalsystems/tincan-opencode@0.7.1"

A specifier needs the package to declare an entry point OpenCode's loader actually reads. It looks for exports["./server"] and falls back to main; it does not read exports["."]. A package declaring only the latter is fetched, its package.json is read, the session runs — and the plugin never executes, with nothing logged. If a specifier-named plugin appears to do nothing, check the package's entry points before looking anywhere else.

Either way, confirm what is actually loaded. muster doctor checks every path-configured plugin against the package it came from:

muster doctor --format human
tincan @brutalsystems/tincan-opencode
  Status: stale — copy predates 0.7.2, published 2026-09-21
  Path: /Users/you/.config/opencode/plugin/tincan.ts

1 stale plugin. Replace path with npm = "@brutalsystems/tincan-opencode" in [plugins.tincan], or re-copy the file.

The copied file carries no version of its own, so the check compares its mtime against the registry's publish time for the current release. That means a file re-copied recently reads as current even when its contents are old: doctor under-reports and never cries wolf. It exits 1 when anything is stale, and an unreachable registry is reported as such rather than failing the command.

Muster knows the packages for the plugins it ships with. Name anything else, or override the default, with published:

[plugins.mine]
path = "~/src/mine.ts"
published = "@acme/mine-opencode"

Plugins named by npm are not checked: they keep no copy of their own, and clearing OpenCode's cache above is that remedy instead. For what a running session loaded rather than what is on disk, the records still carry the version:

grep plugin_version ~/.tincan/peers/opencode/ses_*.json
tincan --version

Registering Muster itself is the one case to think twice about. A definition whose command runs muster mcp gives every session that selects it run, list, stop and output — launch authority, held by an agent rather than by you. Put it in default_mcp and every session muster launches can launch more, which is the propagation the child restrictions above exist to prevent; max_concurrent caps simultaneous launches but does not stop a tree forming. Nothing in Muster refuses this, so the restraint has to be yours. If you want an orchestrating agent, give exactly that one session an explicit --mcp muster and leave default_mcp alone. See "MCP installation" below for the same stance applied to a runtime's own shared configuration.

--mcp NAME is repeatable and replaces personal defaults. --no-mcp clears them and cannot be combined with --mcp. MCP run takes mcp: ["tincan"]; mcp: [] disables all servers. Omitted selection uses default_mcp for sessions. Tasks have no defaults, but accept an explicit selection.

Definitions support either command plus optional args, env, and env_vars for stdio, or url plus optional bearer_token_env_var for Streamable HTTP. tools is a required nonempty list of exact tool names. Use env_vars and bearer_token_env_var to reference credentials in the launch environment; credentials are not written to launch logs. HTTP OAuth setup shared across runtimes, plugin/app tools, MCP resources and prompts are outside this interface. Server and tool names must contain only letters, digits, underscores or hyphens. Relative stdio commands run from the requested working directory; prefer an absolute executable path or a command on PATH.

Before agent launch, Muster initializes each selected server and checks its tool catalog. No tool is called during preflight. An explicit --mcp selection is required: a missing server, missing credential, or missing configured tool fails that launch. Defaults are optional unless their definition sets required = true; an unavailable optional default is skipped with mcp_warnings. Each preflight is bounded by startup_timeout_sec (default 10, maximum 60) and the launch deadline. JSON results and list report selected logical names in mcp; human output shows MCP: and any warnings. These describe launch configuration, not continuous server health.

Codex receives isolated definitions, using a fresh runtime name when an inherited server has the same name, and its native tool allowlist. Claude receives a private Muster stdio connection that filters both tool discovery and calls; newly added upstream tools cannot bypass the selection. Only selected tools are preapproved. OpenCode disables inherited definitions and tool families in its verified per-launch overlay, then enables only selected definitions. A launch that selects MCP servers omits the wildcard * permission entry and names the built-in tools it denies instead: in OpenCode a * entry suppresses MCP tools outright, and an explicit allow for the tool does not restore them. The built-in list is fixed, so a tool added by a future OpenCode release would not be denied by it; launches that select no MCP server keep the wildcard. With no plugins selected it also uses --pure and pins an empty plugin list, so inherited plugins do not enter the child process. Selecting a plugin with --plugin necessarily relaxes that: OpenCode merges project-local plugin discovery into any non-empty plugin list, so the child also loads whatever plugins the target repository ships. It globs both spellings — .opencode/plugin and .opencode/plugins — so auditing only one of them misses half of what a repository can load. Select plugins only for repositories trusted with that. Claude connection specifications are stored with owner-only permissions under ~/.muster/mcp, removed on stop, task completion, or when list observes an ended session. MCP server access is separate from filesystem sandbox permissions: a selected external tool may have its own write or network capabilities.

MCP installation

Installed deliberately, in the one session that should hold spawn authority — never at user scope.

Muster exposes run, list, stop, and output over stdio. No arguments or mcp starts the server. Diagnostics go to stderr, never protocol stdout. Schemas match the CLI (args is the array of optional runtime arguments).

For a single Codex session, use per-invocation configuration:

codex -c 'mcp_servers.muster.command="node"' \
  -c 'mcp_servers.muster.args=["/absolute/path/to/muster/dist/muster.js","mcp"]'

For a single Claude session:

claude --mcp-config '{"mcpServers":{"muster":{"command":"node","args":["/absolute/path/to/muster/dist/muster.js","mcp"]}}}'

Do not add Muster to ~/.codex/config.toml, Claude's user-scope MCP registry, or another shared configuration that grants launch authority to every agent. The same applies to Muster's own [mcp_servers]: a definition that runs muster mcp, selected by default_mcp, grants that authority to every session Muster launches.

Tin Can compatibility

Muster has no Tin Can build or runtime dependency. Each tool implements the written address contract independently. Vendored mechanics carry source-commit headers and the original MIT license in TINCAN_LICENSE.

Addresses belong to running sessions and can expire or collide. Store thread_id / session_id, and re-resolve through Tin Can's peers before sending instead of caching a launch address. Canonical IDs are not unique keys.

One OpenCode behaviour is worth knowing if you deliver to a session yourself rather than through Tin Can. A message posted to the v2 /api/session/{id}/prompt of a TUI-hosted session is admitted with a 200 and an admittedSeq, schedules a turn, and then dies with ModelUnavailableError naming the session's own model — while the TUI resolves that same model in the same process. A session hosted by opencode serve does not do this, and the v1 /session/{id}/prompt_async route does not either. Tin Can 0.6.0 delivers over v1, so nothing here depends on the v2 path.

The failure is silent from the caller's side: a success response, nothing written into the session, and the only trace a line in OpenCode's own log. The investigation, what it did and did not establish, and why it was not filed upstream are recorded in CONTRACT_PROVENANCE.md. The frozen cases intentionally preserve Tin Can's known naming defects.

Codex idle means reachable and not known to be busy, not guaranteed free. The querying app-server can report notLoaded for a live thread; Muster maps that to idle. Claude state comes from its session registry.

OpenCode peers expose a durable session_id and loopback-only server_url so a future Tin Can adapter has a stable integration seam. Tin Can does not yet send to OpenCode through Muster: choosing native OpenCode messaging versus A2A, and updating Tin Can for that transport, are explicitly deferred follow-up work.

Verification

npm test
npm run build
npm run test:contract

The ordinary suite requires tmux, node-pty, POSIX ps/lsof, and Python 3 for real file locks in the fake Codex executable. It uses isolated runtime homes and no model APIs. It skips the four explicitly invoked compatibility cases.

The verified contract baseline is Tin Can 0.6.4. The suite spawns an installed binary as an MCP subprocess, compares durable IDs, and verifies delivery to fake runtimes through both terminal hosts. A missing binary or missing durable field fails the test. For reproducible verification, install that exact release outside Muster:

contract_dir=$(mktemp -d)
npm install --prefix "$contract_dir" --no-save @brutalsystems/tincan@0.6.4
MUSTER_TINCAN_BIN="$contract_dir/node_modules/.bin/tincan" npm run test:contract

Verification uses the published 0.6.4 release installed in an isolated temporary directory. No Tin Can source edits are made. Fixture version metadata alone does not indicate address-format drift: compare the case arrays. Those arrays cover naming only, not peer-list membership or state semantics. Upgrades require separate compatibility verification; passing fixture hashes alone does not establish compatibility. The tests locate the launched peer by canonical ID and compare its durable ID; they do not assert a total peer count, exclude same-runtime peers, or assert Tin Can's busy state. CONTRACT_PROVENANCE.md records both types of integrity checks.

One-time live probes are separate from the automated suite. Both runtimes launched and answered an initial prompt with the versions listed above; Claude used a directory already trusted by its operator. npm test does not run real models.

License and releases

MIT © 2026 Mike Williams. 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

4 tools
listA

List Muster-owned sessions and tasks, including host capabilities.

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description must disclose behavioral traits. It describes the action as non-mutating ('List'), which implies a read-only operation, but it does not explicitly state there are no side effects, nor does it mention authentication requirements, pagination, or output format. 'Including host capabilities' hints at extra data, but no details are given. This is adequate for a simple list tool but not richly transparent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single concise sentence that front-loads the primary purpose ('List Muster-owned sessions and tasks') before adding the secondary detail about host capabilities. It contains no filler or repetition, and its brevity is appropriate for a tool with only one optional parameter.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's low complexity (one optional enum parameter, no output schema, no annotations), the description covers the main purpose but leaves gaps: it does not explain the 'kind' parameter's effect, nor does it describe the return structure. The phrase 'including host capabilities' suggests extra output but is undefined. For a simple list tool, this is moderately complete but not fully self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description does not explain the 'kind' parameter at all. The schema provides an optional enum of 'session' or 'task', but with 0% schema description coverage, the description should clarify how this parameter filters results. The overview says 'sessions and tasks' but not that 'kind' selects between them. This is a meaningful gap, as the parameter's role is left entirely to inference from the schema's enum values.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the operation: 'List Muster-owned sessions and tasks'. It uses a specific verb ('List') and names the resource, which distinguishes it from siblings like 'run', 'stop', and 'output'. The additional 'including host capabilities' makes the scope more specific without confusing the core purpose.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies usage: the agent should call this when it needs to enumerate existing sessions/tasks. However, it does not explicitly state when to use it over alternatives (e.g., before running or stopping), nor does it describe when not to use it. There is no mention of prerequisites or routing to siblings, leaving the agent to infer the use case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

outputC

Read captured output from a task run.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

C2.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden of behavioral disclosure. It only says 'Read', implying a non-mutating operation, but does not state whether the task must be finished, whether it blocks, what happens if the id is invalid, or what the output format is. The description is too sparse to convey essential behavioral traits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness2/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single short sentence, which is concise, but it is under-specified. It lacks essential context that should be present given the absence of annotations and parameter descriptions. The brevity works against the agent rather than aiding it, so it is not appropriately sized for the tool's needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a tool with one parameter, no annotations, and no output schema, the description is severely incomplete. It does not explain what the 'id' is, what 'captured output' means, how to obtain the output, or what the response will look like. An agent cannot reliably invoke this tool correctly based on the provided definition.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters1/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The input schema has a single required parameter 'id' with no description, and schema coverage is 0%. The description does not explain what 'id' refers to (presumably a task run ID) or how to obtain it. The agent has no information about the parameter's meaning, format, or constraints beyond a minLength of 1.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the verb 'Read' and the resource 'captured output from a task run', which distinguishes it from sibling tools like run, list, and stop. However, it is slightly vague about what 'captured output' includes (e.g., stdout, stderr, logs), so it does not fully specify the resource.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives such as list or run. It does not mention prerequisites like the task needing to be completed, nor does it contrast with siblings. The agent is left to infer usage context.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

runB

Launch an instructed agent. Sessions return only when reachable; tasks return a non-messageable run handle.

ParametersJSON Schema
NameRequiredDescriptionDefault
cwdNo
mcpNoConfigured MCP server names. Omit for session defaults; [] disables all. Tasks have no defaults.
argsNo
hostNo
kindNosession
openNoOpen the tmux session in a terminal viewer (macOS only).
promptYes
runtimeYes
sandboxNoDefaults to config (read-only). Full access requires config authorization.
terminalNoViewer app; requires open. Auto uses Terminal.app.
permissionsNoDefaults to config (deny). Auto requires workspace-write; bypass requires authorized full-access.

TDQS

B3.2/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden for behavioral disclosure. It does disclose return behavior (sessions return only when reachable, tasks return a non-messageable run handle), but it says nothing about side effects, permissions, asynchronous execution, resource consumption, or failure modes – significant gaps for a launch tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two efficient sentences: the first states the core purpose, the second adds the key behavioral distinction. No redundant words, and the most important scoping information is front-loaded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness1/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 11 parameters, no annotations, and no output schema, the description is far too sparse. It covers the launch intent and one behavioral nuance, but leaves parameter semantics, usage scenarios, safety profile, and return formats nearly completely undocumented, forcing the agent to infer too much from the schema alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is low at 45%, and the description adds no parameter-level meaning beyond the session/task kind distinction. Required parameters like runtime and prompt are left entirely to the schema, and optional fields like cwd, args, host, and sandbox are not explained in the description, failing to compensate for the schema's incomplete coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with 'Launch an instructed agent' – a specific verb and resource. It also distinguishes session versus task variants by their return semantics, clearly setting it apart from sibling tools list, output, and stop without needing their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when to use run (to launch an agent) and distinguishes when to choose session vs task, but it does not explicitly mention alternatives such as list for viewing existing runs or stop for terminating them, nor does it state any prerequisites or when not to use the tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

stopA

Stop a Muster-owned run by durable id or unambiguous peer name.

ParametersJSON Schema
NameRequiredDescriptionDefault
idYes

TDQS

A3.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full responsibility for behavioral disclosure. It only says 'Stop,' implying a mutating action, but does not disclose whether stopping is irreversible, what happens to the run's output, permission requirements, or idempotency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with no filler. Every part contributes: the action, the resource scope, and the accepted identifier forms.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple and the description covers the action and parameter semantics, so an agent can likely invoke it correctly. However, with no annotations and no output schema, it omits behavioral consequences and does not mention how to obtain the id or name, despite the sibling list tool existing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema has one required string id with no description (0% coverage). The description adds crucial meaning by explaining that id can be a durable id or an unambiguous peer name, which is not derivable from the schema. It does not define the formats, but it compensates well for the schema gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Description uses a specific verb ('Stop') and names the exact resource ('Muster-owned run'), plus the identifier forms accepted. It is clearly distinct from siblings run, list, and output.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this tool is for stopping an existing Muster-owned run and even states how to identify it, but it does not explicitly mention when not to use it or direct the agent to list for finding ids. Usage context is clear but alternatives are left implicit.

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.

  1. 1 tool updatev0.7.8
    • Changedrun4 fields changed
      • addedInput schema / properties / mcp
        Added 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"
        +}
      • addedInput schema / properties / open
        Added value: +{
        +  "description": "Open the tmux session in a terminal viewer (macOS only).",
        +  "type": "boolean"
        +}
      • changedInput schema / properties / runtime / enum
        Previous value: -[
        -  "codex",
        -  "claude"
        -]New value: +[
        +  "codex",
        +  "claude",
        +  "opencode"
        +]
      • addedInput schema / properties / terminal
        Added value: +{
        +  "description": "Viewer app; requires open. Auto uses Terminal.app.",
        +  "enum": [
        +    "auto",
        +    "terminal",
        +    "iterm2",
        +    "ghostty"
        +  ],
        +  "type": "string"
        +}
  2. 4 tool updatesv0.3.0
    • First observedlist
    • First observedoutput
    • First observedrun
    • First observedstop

TDQS

B3.3/5.0

Scored across 4 tools

Disambiguation5/5

Each tool maps to a distinct lifecycle action: run creates, list inspects, output retrieves results, and stop terminates. There is no meaningful overlap between any pair of tools.

Naming Consistency5/5

All tool names are single-word lowercase commands that read as direct actions: list, output, stop, run. The style is uniform and predictable, with no mixed conventions.

Tool Count5/5

Four tools is a well-scoped set for launching, inspecting, reading output from, and stopping runs. Each tool earns its place without redundancy or bloat.

Completeness3/5

The run/list/output/stop lifecycle covers tasks well, but sessions appear to be a distinct messageable concept while no send/message or session-specific interaction tool exists. This is a notable gap in the tool surface.

Maintenance

ActivityMaintained
ResponsivenessUnresponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    Wraps Claude Code as tools for MCP clients, enabling autonomous coding tasks via a 4-tool lifecycle with session management, async polling, and permission controls.
    4
    43 npm
    20
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables MCP clients to spawn and control Codex CLI and Claude Code sessions on the host machine, with session management and filesystem access.
    4
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables ISLI agents and MCP clients to dispatch natural-language coding and terminal tasks to a locally-installed Claude Code CLI, supporting both one-shot execution and persistent sessions with workspace and security controls.
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    Agent orchestration system that runs coding-agent sessions (Claude Code, Codex) with policy mediation and exposes tools via MCP.
    -