SuperCollider Pilot — structured agent driver for SuperCollider — includes the scctl CLI and an MCP transport.
Wraps the SuperCollider sclang interpreter as Pilot, a single-session local driver with a matching CLI and MCP transport. Pilot keeps one active local session, returns structured results, exposes recovery actions, and keeps raw SuperCollider output alongside machine-readable state.
- Cross-platform
sclangdiscovery (macOS, Windows, Linux, plusPATHfallback) - Single-session driver runtime with explicit state:
engine_missing -> idle -> booting -> ready -> busy -> degraded -> stopping -> stopped - Structured results for every action:
success,state,phase,session_id,recoverable,error_kind,summary,raw_output, plus optionalsession,artifact, andcompliance - Recovery surface:
sc_stop,sc_reset,sc_reboot,sc_reclaim - Pilot MCP tools:
sc_check,sc_status,sc_health,sc_eval,sc_run_file,sc_logs,sc_render,sc_render_nrt,sc_stop,sc_reset,sc_reboot,sc_reclaim - CLI commands:
check,status,health,eval,run,logs,render,render-nrt,stop,reset,reboot,reclaim - Workflow surface:
plan-workflow,run-probe,summarize-session,candidate-action,memory-summary - Governance surface:
prepare-handoff,audit-session, plus matching MCP tools for managed agent loops - Realtime draft render flow that boots, records, verifies WAV output, and tears the session down cleanly
- Final-quality NRT render flow with capability-aware engine selection and WAV metadata capture
- Vitest coverage for protocol helpers, runtime, Pilot routing, CLI behavior, and optional live smoke
| Dependency | Version |
|---|---|
| Node.js | 22+ |
| SuperCollider | 3.13+ (sclang on PATH or default install location) |
Default sclang locations:
| Platform | Path |
|---|---|
| macOS | /Applications/SuperCollider.app/Contents/MacOS/sclang |
| Windows | C:\Program Files\SuperCollider\sclang.exe |
| Linux | /usr/bin/sclang or /usr/local/bin/sclang |
git clone https://github.com/Bayern99/supercollider-pilot.git
cd supercollider-pilot
npm install
npm run buildVerify SuperCollider is reachable:
node dist/cli.js checkExpected output when installed: structured JSON with success, state, and summary.
Optional global install:
npm link
scctl checkMost teams use Pilot from a consumer workspace (music app, research repo, etc.) by pointing an Agent at the MCP server. You do not need to vendor this repository into your application code.
| What | Must live in the consumer workspace? | Notes |
|---|---|---|
Pilot binary (dist/mcp/server.js, scctl) |
No | Install anywhere; reference absolute path in MCP config |
| Archive + governed marker | Yes | Written under the Agent workspace root: .scctl/archive/, .scctl/governed-role |
KB (docs/superpowers/kb/) |
For meaningful handoff | Loaded from consumer cwd; missing files → empty kb_snapshot |
Agent skills (.agents/skills/scctl-*) |
Recommended | Copied or linked; not loaded automatically with MCP alone |
| IDE hooks | Optional hard layer | Consumer .cursor/hooks.json + scripts from this repo |
Pilot runs as separate OS processes (Node MCP server + sclang / scsynth when rendering). It does not run inside your app server. Idle MCP overhead is small; rendering uses local CPU/RAM. Add .scctl/ to .gitignore.
One-shot consumer setup:
/absolute/path/to/supercollider-pilot/scripts/bootstrap-consumer-project.sh /absolute/path/to/your-projectCopies KB, roles, .agents/skills/scctl-*, hooks, and Cursor hook config into the consumer workspace. Then add MCP (below). Details: docs/guides/consumer-bootstrap.zh-CN.md.
Agents should use MCP, not shell CLI, for governed loops: native tool calls, persistent sclang session, and optional beforeMCPExecution hooks. Use CLI for operators, smoke tests, and CI scripts.
Human-oriented walkthrough (Chinese): docs/guides/governed-pilot-tutorial.zh-CN.md
New consumer project (checklist + bootstrap script): docs/guides/consumer-bootstrap.zh-CN.md
Operator reference: docs/operator-runbook.md · 中文版
# Check engine reachability
node dist/cli.js check
# Inspect current session state
node dist/cli.js status
node dist/cli.js health
# Evaluate inline code
node dist/cli.js eval "{ SinOsc.ar(440, 0, 0.05) }.play;"
# Run a .scd file
node dist/cli.js run path/to/script.scd
node dist/cli.js run path/to/script.scd --task-tag sc-probe
# Inspect logs from the active session
node dist/cli.js logs --tail 500
# Record a .scd file to WAV
node dist/cli.js render path/to/script.scd -o /tmp/out.wav -d 5
node dist/cli.js render path/to/script.scd -o /tmp/out.wav -d 5 --task-tag sc-audio-generation
# Final-quality NRT render from an absolute .scd path
node dist/cli.js render-nrt /absolute/path/to/final-nrt.scd -o /tmp/final.wav
node dist/cli.js render-nrt /absolute/path/to/final-nrt.scd -o /tmp/final.wav --engine supernova --sample-format double
# Recovery actions
node dist/cli.js reset
node dist/cli.js reboot
node dist/cli.js reclaim
# Workflow planning and probe execution
node dist/cli.js plan-workflow --context '{"task_tag":"sc-probe","goal":"inspect a new timbral direction"}'
node dist/cli.js run-probe --spec '{"mode":"run_file","path":"/absolute/path/to/probe.scd","task_tag":"sc-probe"}'
node dist/cli.js summarize-session --input '{"session_id":"session-1","task":"probe a texture","outcome":"mixed","preserved_items":["slow envelope contour"],"failures":["render clipped"],"notes":["keep the modulation shape"]}'
node dist/cli.js candidate-action --input '{"session_id":"session-1","action":"create_draft","candidate_id":"cand-1","name":"grain-cloud-a","source_probe_id":"probe-1","summary":"promising density"}'
node dist/cli.js memory-summary --limit 10 # recent session window, not record count
# Governed handoff and audit
node dist/cli.js prepare-handoff --input '{"task_id":"task-1","task_tag":"sc-audio-generation","goal":"render a Zhou Yi texture study","requested_outcome":"explore"}'
node dist/cli.js audit-session --input '{"session_id":"session-1","task_tag":"sc-audio-generation"}'| MCP (default for Agents) | CLI (operators / scripts) | |
|---|---|---|
| Entry | Cursor, Claude Desktop, other MCP clients | node dist/cli.js … or scctl … |
| Session | Long-lived server reuses one ScDriver / sclang |
New Node process per invocation |
| Governed RBAC | Set SCCTL_GOVERNED_ROLE / SCCTL_FINAL_NRT in MCP env |
Same env vars on the command |
| IDE preflight hooks | Apply to MCP tool calls when configured | Do not apply to shell commands |
MCP-only setup (no env, no hooks, no skills) still exposes all tools but defaults to operator/debug behavior — raw runtime tools are not hard-blocked.
When SCCTL_GOVERNED_ROLE is set, the allowlist applies to the full CLI/MCP surface, not only raw runtime tools. Workflow and orchestration calls such as candidate-action, prepare-handoff, and audit-session are checked against the same role policy. Rejections use one contract on both transports:
{
"success": false,
"error_kind": "governance_violation",
"role": "builder",
"tool": "sc_candidate_action",
"allowed_tools": ["sc_run_probe"],
"forbidden_paths": ["sc_eval", "sc_run_file", "sc_render", "sc_render_nrt"],
"summary": "Governed role \"builder\" may not use \"sc_candidate_action\". ..."
}Start the Pilot MCP server (stdio transport):
node dist/mcp/server.jsClaude Desktop / Cursor — add to MCP config (use an absolute path to dist/mcp/server.js; cwd is the opened workspace):
{
"mcpServers": {
"supercollider-pilot": {
"command": "node",
"args": ["/absolute/path/to/supercollider-pilot/dist/mcp/server.js"],
"env": {
"SCCTL_GOVERNED_ROLE": "builder"
}
}
}
}Unset SCCTL_GOVERNED_ROLE for operator/debug. Optional governed hardening: copy .agents/skills/scctl-* and hook entries from hooks/hooks.json into the consumer workspace.
| Tool | Parameters | Description |
|---|---|---|
sc_check |
— | Verify engine discovery and interpreter reachability |
sc_status |
— | Return the current driver session snapshot |
sc_health |
— | Probe active-session health and server readiness |
sc_eval |
code (required) |
Evaluate inline code in the active session |
sc_run_file |
path (required), task_tag (optional) |
Read and evaluate a .scd file in the active session |
sc_logs |
tail (optional) |
Return the active session log buffer |
sc_render |
out (required), path or code, duration, task_tag (optional) |
Render a draft WAV and stop the session afterward |
sc_render_nrt |
path (required), out (required), duration, engine_preference, sample_format, task_tag (optional) |
Render a final-quality WAV through NRT from an absolute .scd source |
sc_stop |
— | Stop the active session |
sc_reset |
— | Clean the active session without discarding it |
sc_reboot |
— | Replace the active session with a fresh ready session |
sc_reclaim |
— | Recover from a degraded or ambiguous local session |
Additional governed workflow tools:
| Tool | Parameters | Description |
|---|---|---|
sc_plan_workflow |
spec or context |
Select a workflow and return prompts plus governed route/path expectations |
sc_run_probe |
spec (required) |
Validate and execute a ProbeSpec through ScDriver |
sc_summarize_session |
structured summary payload | Append a session summary record to archive |
sc_candidate_action |
structured lifecycle payload | Apply candidate lifecycle or review actions |
sc_memory_summary |
session_id, candidate_id, limit (all optional) |
Build a project-level memory summary from archive; limit means recent session window |
sc_prepare_handoff |
task envelope | Prepare manager / builder / critic packets plus KB snapshot |
sc_audit_session |
session_id (required), task_tag, candidate_id |
Audit a governed session and recommend the next step |
Default governed creation loop (see docs/operator-runbook.md):
prepare-handoff → run-probe → summarize-session → candidate-action / add_review → audit-session → memory-summary
plan-workflow now emits governed closure routes in selection.recommended_tools and canonical governed required steps in path_expectation.required_steps. Raw operator/debug hints stay in the runbook, not in planner payloads.
Successful audit-session appends a session_audit record to .scctl/archive/archive-events.jsonl.
| Task tag | Terminal action | Requires .scd source |
Requires render artifact | Requires review note |
|---|---|---|---|---|
sc-probe |
none | no | no | no |
sc-audio-generation |
render or render_nrt |
yes | yes | yes |
sc-render-review |
render or render_nrt |
no | yes | yes |
Canonical rules: docs/design/route-enforcement-rules.md and src/harness/policies.ts.
- Draft:
render/sc_render— fast iteration listens; session closes after render. - Final NRT:
render-nrt/sc_render_nrt— final-quality export; requires absolute NRT.scdsources (seesc/families/*/final-nrt.scd). - Tasks with
quality.render_tier: final_nrtcannot close through draft artifacts inaudit-session.
Typical operator/debug loop: sc_check → sc_status/sc_health → sc_eval or sc_run_file → sc_logs (on error) → sc_render → sc_reclaim or sc_stop.
- Use absolute paths for
.scdfiles and WAV output (no default cwd). - Keep application/domain logic out of SuperCollider — use
.scdfor SynthDefs, playback, and render snippets only. - The driver is single-session and local-first. Recovery is explicit; use
sc_reset,sc_reboot, orsc_reclaiminstead of guessing from raw logs alone. - CLI output is structured JSON. Raw SuperCollider output is preserved in
raw_output. runandrenderaccept optional task tags. When present, Pilot returns acomplianceblock that records route discipline, source kind, and artifact completeness.- Render artifacts now include verification metadata, so callers can distinguish “render flow ran” from “valid non-empty WAV was produced.”
checkandhealthnow report capability facts forsclang,scsynth,supernova, extension paths, Quarks paths, detectedsc3-plugins, and NRT availability.- Raw
sc_eval,sc_run_file, andsc_renderremain the operator/debug surface.sc_render_nrtis the explicit final-quality runtime surface. Managed creative workflows should default to the governed workflow tools above.
Documentation index: docs/README.md · 中文版
Quick links:
- governed-pilot-tutorial — usage flow and consumer bootstrap
- operator-runbook — operator/debug vs governed
- route-enforcement-rules — task tag policy
npm run build
node dist/cli.js check # expect structured JSON with success/state/summary
node dist/cli.js render fixtures/smoke/sine-play.scd -o /tmp/scctl-smoke.wav -d 2
test -s /tmp/scctl-smoke.wavIf smoke fails locally, see docs/smoke-troubleshooting.md.
Optional live integration suite:
npm run test:livenode play-music.js # Play a generated pentatonic pattern (~10s)
node record-music.js # Record output to ./music.wavPrompt → Agent (+ .agents/skills on demand)
→ Harness (SCCTL_GOVERNED_ROLE, hooks, completion-rules)
→ MCP or CLI → Pilot orchestration / workflow / runtime
→ sclang / scsynth + .scctl/archive
→ review loop (listening, critic, audit)
Agent client
│
▼
src/mcp/server.ts or src/cli.ts
│
├── orchestration / workflow (handoff, probe, audit)
└── ScDriver (src/runtime/driver.ts)
▼
SclangController → sclang → scsynth → audio
Key constraints:
- One active local session at a time
- Serial execution only — concurrent script runs are rejected
- Driver success/failure is decided from protocol completion plus raw SuperCollider error detection, not from free-form post text alone
- Shutdown sends
CmdPeriod.run; Server.killAll;then SIGKILL if needed
See docs/design/control-approach-notes.md for design background.
sc_eval runs arbitrary SuperCollider code with host filesystem and process access. Use only with trusted local Pilot/MCP clients. Do not expose the Pilot server on a network.
Details: SECURITY.md.
npm run typecheck
npm run build
npm test
npm run test:live # optional, requires local SuperColliderContributing: CONTRIBUTING.md.
ISC — see LICENSE.