Muse Code (Meta)
TL;DR:
npm install -g @agenticcontrolplane/muse-code
MUSE_EXPERIMENTAL_PLUGINS=1 muse plugins install "$(npm root -g)/@agenticcontrolplane/muse-code" --scope user
MUSE_EXPERIMENTAL_PLUGINS=1 muse plugins approve acp
From the next session, every tool call Muse Code makes flows through your ACP workspace before it runs. Already ran the installer? It detects Muse Code and installs the plugin for you.
Muse Code is in beta with breaking changes promised — the plugin tracks it, and this page records the sharp edges we’ve hit.
Why a plugin behind a flag
Meta’s docs describe a muse hooks CLI and a .muse/hooks.json file. The shipped 0.2.1 binary doesn’t expose that CLI, and a project hooks.json is silently ignored. What is wired is a native plugin system, gated behind the MUSE_EXPERIMENTAL_PLUGINS flag: hooks register as capabilities of a plugin (.muse-plugin/plugin.json), installed and trusted via muse plugins install / approve. The flag gates only the management CLI — once approved, the hooks fire in ordinary unflagged sessions.
We wrote up the full reverse-engineering in the launch post. The short version: this package is a Muse native plugin bundle, and the three commands above install and approve it.
How it works
| Muse event | ACP endpoint | What happens |
|---|---|---|
PreToolUse |
POST /govern/tool-use |
allow / ask / deny before the tool runs |
PermissionRequest |
POST /govern/tool-use |
a policy deny settles Muse’s own approval prompt; anything else lets it proceed |
PostToolUse |
POST /govern/tool-output |
output scanning; a server block becomes feedback the model sees |
Stop |
— | one session receipt with a deep link to the session timeline |
The wire contract is Claude Code’s hook schema — snake_case payload in, a camelCase hookSpecificOutput decision back. Every path above was verified against Muse Code’s own muse plugins hook test runner, and the PreToolUse deny path against the live production gateway.
Credentials: Muse clears the environment
Muse Code runs hooks with a cleared environment. That’s a deliberate hardening choice — and it means an exported ACP_BEARER_TOKEN does not reach the hook. The plugin reads its credential from a file instead:
~/.acp/credentials— written once by the installer, free up to 5 agents.
Optional operational overrides live in ~/.acp/config.json:
{
"govern_base": "https://govern.agenticcontrolplane.com",
"agent_tier": "interactive",
"check_timeout_ms": 4000,
"shadow": "off"
}
Failure posture
An unreachable control plane must never brick your session, and must never be mistaken for a live one:
- Interactive sessions fail open, loudly — the call proceeds, a
systemMessagewarns[ACP] ⚠ UNGOVERNED, and a lapse line lands in~/.acp/lapse.log. - Unattended runs fail closed —
CI,MUSE_HEADLESS, an explicitagent_tier, or apermission_modeofnevermarks a run as unattended; policy that can’t be consulted stays blocked. - Policy denies are unaffected either way — the posture only covers the inability to ask the policy.
Sharp edges
- Experimental flag.
muse plugins install/approverequireMUSE_EXPERIMENTAL_PLUGINS=1. The installed hooks run without it; only the management commands need it. Expect this to converge on the documentedmuse hooksCLI in a later beta. - Hooks run outside the sandbox. Muse executes hook commands directly through your shell, outside the OS sandbox, with a cleared environment as the only hardening. That’s why the plugin has zero dependencies — see the control model for the full picture.
- Beta churn. 0.2.1 promises breaking changes. If an install command changes shape, this page is where we’ll record it.
Uninstall
MUSE_EXPERIMENTAL_PLUGINS=1 muse plugins reject acp
npm uninstall -g @agenticcontrolplane/muse-code
Source and issues: github.com/agentic-control-plane/muse-code-acp-plugin.