MCP — driving FaustWave from external clients
The Model Context Protocol (MCP) is the open standard for "LLMs talking to applications." FaustWave exposes its action registry as an MCP server. That means you can hook FaustWave up to any MCP client — Claude Desktop, a custom script, a CI job, another AI tool — and drive the IDE from outside.
The same surface the in-app AI Assistant uses. Same actions, same input schemas, same trace into the Activity log. Different transport, that's all.
What it's for
Three real use cases:
- Claude Desktop driving FaustWave — pull up Claude, ask it to build a DSP, it drives FaustWave via MCP. Same as the in-app Assistant, but you're outside the FaustWave window.
- Automation scripts — render N variations of a DSP with different param sweeps, batch-import a sample folder, regenerate sequencer patterns from an external composer. Headless-friendly via daemon mode.
- Authoring tutorials + content — the very manual you're reading is being written + published via MCP. The loop: open a markdown editor module via
documents.add,editor.source.setthe content,documents.save, build the pack,hub.version.upload. See § Authoring this manual via MCP below.
Connecting Claude Desktop
The Claude Desktop config file lives at:
| Platform | Path |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
Add a FaustWave entry under mcpServers:
{
"mcpServers": {
"faustwave": {
"command": "<path-to-faustwave>",
"args": ["--mcp"],
"env": {}
}
}
}
Restart Claude Desktop. You should see a "🛠 faustwave" indicator in Claude's tool palette next to your message bar; clicking it reveals the action catalog.
The tool catalog
When the MCP client connects, FaustWave publishes its actions as tools. Roughly:
- ~130 actions total in the registry.
- Hot-path tools (a curated subset of the highest-frequency ones) are exposed directly with their full schemas so clients see them at first glance:
dsp.compile,dsp.run,dsp.stop,dsp.node.*,builder.graph.connect/disconnect,midi.note.play,sequencer.play/stop/step.set,master.volume.set,transport.play/stop,recorder.start/stop/toggle,routing.list/connect/disconnect, etc. palette.runis the meta-action — exposes the FULL catalog. To call any action that isn't a hot-path tool, you callpalette.run { action_id, input }.
The split exists because of the MCP 128-tool soft cap — Anthropic's API rejects more than 128 published tools in a single context. Hot-path tools are the high-frequency ones that benefit from inline schemas; everything else lives behind palette.run. Current publishing decision: ~22 hot-path tools + palette.run + palette.list + palette.describe = 25 published, well under the cap.
Discovery — find what you need
Three meta-actions FaustWave always publishes:
| Action | Purpose |
|---|---|
palette.list | Browse the full catalog. Defaults to category summaries. Pass category for a focused list. Pass search for substring matches. Pass all: true for everything. |
palette.describe | Full input_schema + description + examples for up to 10 action ids at a time. |
palette.run | Invoke any action by id with structured input. Validates against the schema; rejects unknown ids with a friendly error. |
Pattern: when you want to do something — say, add reverb:
1. palette.list { search: "reverb" } → candidate actions
2. palette.describe { action_ids: ["master.fx.slot.add"] } → input_schema + examples
3. palette.run { action_id: "master.fx.slot.add", input: { … } }
This is the dance the in-app Assistant does internally on every turn. External clients (Claude Desktop included) do the same.
Hard-required module_id on DSP-Builder actions
A discipline rule: every DSP-Builder action requires an explicit module_id input. No implicit fallback to "the currently active Builder."
The reason is a time-of-check / time-of-use race. Before the rule, an AI mid-task could call builder.graph.node.add and FaustWave would silently target whatever Builder was active in the user's UI at the moment of dispatch. User switches tabs mid-AI-task → next AI action lands on the WRONG Builder. The symptom (AI's work appearing in a different file) is hard for the user to spot because the AI's reply still reads coherent.
Closed by the rule: module_id is required, the schema rejects the call without it, and the error path lists the available Builder ids so the AI self-corrects:
{
"error": "Module id is required. Available Builders: builder-mq2dtphb-8ygb (\"test-slice-c\"), builder-mq2du5g5-coyr (\"untitled\")"
}
A pre-existing sequencer exception is grandfathered — sequencer actions take an optional instance_id with active-fallback. Lower-frequency surface; sequencers are typically created once per project and switched between rarely, so the race window is empirically tiny.
Activity surfaces every call
activity.recent { limit?, surface?, outcome?, text? } returns the most-recent action invocations across MCP, palette, and AI surfaces. Filter to see only what YOU did via MCP:
{ "action_id": "activity.recent", "input": { "surface": "mcp", "limit": 20 } }
For a session-history view, this is the source of truth. The in-app Activity rail panel reads from the same store, so you and the user see the same thing.
Daemon mode — headless FaustWave
For server-side use or scripted batch work, boot FaustWave with the --daemon flag (or set FAUSTWAVE_DAEMON=1). Behaviour:
- No visible window. Tray icon for stop/quit control.
- Full audio + MCP run.
- MCP force-starts.
- Persistence + project state work as normal.
Use case: a batch job that opens a project, sweeps a Builder's params, records 20 takes, and exits.
Daemon mode is a deliberate "FaustWave-as-service" surface — not for everyday use, but the door is open for the socket-API track and the "open alternative to controller second-tracks" use case.
Building your own MCP client
If Claude Desktop is too heavyweight (or you want CI integration), write a thin client. The protocol is open + documented at modelcontextprotocol.io. FaustWave's server is a standard MCP implementation — no FaustWave-specific extensions.
Roughly:
- Spawn FaustWave as a child process with
--mcp(or connect to a running daemon). - Send a
tools/listrequest to discover the published tools. - Send
tools/callrequests with{ name, arguments }to invoke. - Process the response stream.
Languages with established MCP SDKs include TypeScript / JavaScript (official), Python (official), and a growing community list. Pick whichever fits your stack.
Authoring this manual via MCP — the live loop
The book you're reading is the canonical live-loop demo:
- Open a markdown editor module in the IDE via
documents.add { ref: "asset:assets/<chapter file>.md" }(orfile_pathwith an absolute OS path to import an external file). - Edit —
editor.source.set { module_id, source: "<new content>" }(or just type in the editor surface). - Save —
documents.save { module_id }writes to the file path. - Build the pack —
node docs/books/build-books.mjsconcatenates the pack's.mdfiles into_build/<slug>.mdwith H1 → H2 demotion so each chapter becomes one Book section. - Publish a new version —
hub.version.upload { item_id, kind: "book", file_path: "<built bundle>", changelog }. - Reinstall locally —
hub.install { item_id }to pull v(n+1) into the local KB.
Four to six MCP calls per chapter update. The dance is fast enough that "write a paragraph, see it rendered" is a 10-second loop. The manual writes itself via the actions it documents.
Authoring chains — not just one-shot
The Book Reader supports chained tutorial actions in section YAML blocks. Each step's return value can be saved with save_as: <var>; downstream steps reference {{var.path}} to thread results through. Every playable chain in this manual uses the same primitive — launched from the Reader, the chain runs through api.actions.run with status badges, inline result chips, and a Reset button. See FaustWave — Hub § 1 for the book content shape and any section's actions: block in this manual for examples.
Where to go from here
- § 1 (The AI Assistant) — the in-app equivalent of what you do from Claude Desktop.
- § 2 (The Command Palette) — the human-side surface to the same registry.
- FaustWave — Hub § 3 — the publish + install workflows that the live-loop hits over MCP.
- FaustWave — Reference § MCP actions — the full hot-path catalog.