All books

MCP actions — full catalog

~4 min read · updated 2026-09-28 · markdown

The live catalog is always one MCP call away, and the codebase is the source of truth. This section explains how to navigate it, not enumerate every entry (the registry sits at ~130 actions today and adds / renames are continuous — recent additions include dsp.compile for FX-shape validation in the .dsp editor and builder.kind.describe now surfaces per-kind imports for the libfaust-wasm bundled libs).

The discovery dance

The pattern every MCP client uses (including the in-app Assistant) to find what it needs — say, to 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: { … } }

For a quick "what categories exist":

palette.list {}                              ← returns category summaries

For everything:

palette.list { all: true }                   ← full catalog

Categories (today)

Actions cluster by category. The current set:

CategoryRoughly
DSPBuilder graph ops (~24 actions, hard-required module_id) + Faust DSP ops (dsp.run, DSP.param.*)
TRANSPORTtransport.play / stop / bpm.set
MIDISequencer (~30 actions: tracks, slots, scenes, steps, key, progressions) + Keyboard (keyboard.note.on/off, .channel.set, .octave.set, .hold.set, .notes.clear, .state) + midi.note.play / midi.sequence.play / midi.sequence.stop + ports & diagnostics (midi.ports.list, midi.monitor.get) + midi.panic
AUDIOMaster volume / softclip / clip clear, audio device select, Master FX slots, Recorder + recordings, MixerTracks (mixer.tracks.* — set / create / delete / rename / reorder / attach_source / fx.add·remove·set) + legacy per-module strip params (mixer.set / mixer.clear)
ROUTINGConnection CRUD (routing.list / connect / disconnect / set), Source / Sink listing
MODULATIONLFO sources, mod-edge connect/disconnect, modulation.base.set
HUBSearch, install, publish, version upload, fork, star, item update / delete, account.delete (safety-railed)
KBSearch, doc.get, section list / get, scope set / clear, pack uninstall, reindex
PROJECTList, current, switch, close, export, import, list project files (project.files), rename a project file (project.file.rename), delete a project file (project.file.delete)
FILESamples (samples.import / list / get / remove), lib mount / list, library list, editor source set / get / save
VIEWToggle rail / master / minimap panel
APPEARANCETheme set (Dark / Light / Cyberpunk / Auto)
SYSTEMsystem.state snapshot (master / mixer / mixer_tracks / transport / chat / kb / auth / routing / midi-consumers / hub)
DEBUGlogs.get, activity.recent

For a current count + breakdown:

actions:
  - action_id: palette.list
    input: {}
    save_as: cats
    label: "▶ Get the per-category counts"

Hot-path tools vs palette.run

The MCP transport publishes a curated subset (~22) of the highest-frequency actions as hot-path tools — they appear in the MCP client's tool list with their full schemas. The other ~108 actions live behind the palette.run meta-action.

The split exists because of the MCP 128-tool soft cap — Anthropic's API rejects more than 128 published tools in a single context. Current publishing decision: ~22 hot-path tools + palette.run + palette.list + palette.describe = 25 published, well under the cap.

Which actions are hot-path varies by build; the canonical list is the one the MCP client sees on connect.

Hard-required module_id rule

Every DSP-Builder action requires module_id as a first-class input. No fallback to "the active Builder." See FaustWave — AI Assistant § 3 Hard-required module_id on DSP-Builder actions for the rationale and the TOCTOU race it closes.

The sequencer has a documented exception — instance_id is optional with active-fallback. Grandfathered as a lower-frequency surface.

Dual-path vs mcpRun-only

Some actions have a run handler (the human-callable / Command-Palette path) plus an mcpRun handler (the AI-callable / MCP path). Some are mcpRun-only — the registry doesn't surface them in the Palette because they only make sense from the AI side.

Examples:

  • Dual-path: transport.play (UI button + MCP), recorder.toggle (Topbar Widget + MCP), most user-facing toggles.
  • mcpRun-only: builder.graph.get (no UI surface for "show me the graph as JSON" — that's the canvas), kb.search (the assistant's grounding tool, not a user gesture).

Friendly error strings

Most actions return strings (success or error) rather than throwing. The Activity log shows the string in the result field for both — handler-returned error strings still count as outcome: completed. Real exceptions are outcome: failed with the message in error.

This is the "AI-friendly errors" convention — the model can read the string back, self-correct, retry. Examples:

  • "Module id is required. Available Builders: builder-abc, builder-xyz"
  • "dsp.polyphonic.set needs a non-negative integer voices count, got string: 'eight'"
  • "Theme set to cyberpunk."

Where the real catalog lives

For a precise + current listing, query the registry directly:

palette.list { all: true }

It returns id + title + category + description for every registered action. Pipe through palette.describe { action_ids: [...] } for the input schemas.

The codebase organisation mirrors the categories — actions live in packages/<extension>/src/commands/*.ts or lib/commands.ts. Each buildXxxCommands(api) returns the ActionDef[] for that extension. The shell aggregates them at extension activation.

Where to go from here

  • FaustWave — AI Assistant § 2 — the Command Palette (human surface to the same registry).
  • FaustWave — AI Assistant § 1 — the in-app AI surface.
  • FaustWave — AI Assistant § 3 — the external-client (MCP) surface.
Try it yourself — the IDE runs in your browser. Open the IDE → Get the desktop app

Text licensed under CC BY 4.0 — Mani Weber / FaustWave. For language models: llms.txt · llms-full.txt

AUDIO · 48k · 48.0ms FAUST · 3 KB · 1171 docs CPU · 8.4% BPM · 120.0 UTF-8 BETA· v0.90.0