Space Dust MCP
# Space Dust connector
Lets someone shape Space Dust presets by describing the sound they want, instead of by
turning knobs or editing files. They say "make the bass darker and give it more bite";
Claude reads the preset, changes the right parameters, and tells them what it did.
[Space Dust](https://github.com/gadalleore/Space_Dust_Synthesizer) is a subtractive
synthesiser plugin (VST3 / AU / standalone, built with JUCE). This is a companion, not part
of the plugin — install the synth first.
Works with the Space Dust you already have installed. Presets are plain XML files, so
nothing here needs the plugin's source code or a rebuild.
## Install
Requires [Space Dust](https://github.com/gadalleore/Space_Dust_Synthesizer) and
[uv](https://docs.astral.sh/uv/).
```bash
git clone https://github.com/jwang47/Space_Dust_Synthesizer_MCP.git
uv tool install ./Space_Dust_Synthesizer_MCP
```
Then add it to Claude Code:
```bash
claude mcp add space-dust -- spacedust-mcp
```
For the Claude desktop app, add it under Settings → Developer → Edit Config:
```json
{
"mcpServers": {
"space-dust": { "command": "spacedust-mcp" }
}
}
```
Restart Claude afterwards. Nothing leaves the machine — the server only reads and writes
files in the user's own preset folder.
## What the user can do
- *"What have I got in Space Dust?"* — lists their presets
- *"What's going on in Dub Mew Bass?"* — reads a preset back in plain language
- *"Make me a bass like that one but darker and punchier"* — creates a new preset
- *"Too muddy, back off the low end"* — adjusts what they're currently playing
- *"Actually, undo that"* — restores the previous version
- *"What's different between these two?"* — compares presets
Changes to the preset the plugin currently has loaded are picked up on their own within a
second, so the user can keep playing while iterating. A newly created preset still has to
be selected once from the preset menu.
Live adjustment needs a plugin build that includes `PresetHotReload` — it publishes the
current sound to `current.sdpreset` in the plugin's app-data folder and watches the loaded
preset for external edits. That folder is `~/Library/Application Support/Space Dust` on
macOS and `%APPDATA%\Space Dust` on Windows, matching `PresetManager::appDataFolder()`.
Against older builds every other tool still works; the user just re-selects the preset to
hear a change.
## Tools
| Tool | Purpose |
|---|---|
| `read_current_sound` | What the plugin is playing right now, no preset name needed |
| `adjust_current_sound` | Change that sound; the plugin applies it within a second |
| `list_presets` | Presets in the user's preset folder |
| `read_preset` | A preset's settings, grouped by section, defaults omitted |
| `list_parameters` | Search parameters, their ranges and defaults |
| `create_preset` | New preset from Init or from an existing one |
| `adjust_preset` | Change an existing preset in place, saving an undo point |
| `undo_preset` | Restore the version before the last change |
| `preset_history` | List saved earlier versions |
| `compare_presets` | Every setting that differs between two presets |
The server's instructions teach Claude the synth's signal flow and how to translate
musician language ("wobblier", "more space", "punchier") into parameter moves, so the
user never has to learn a parameter name.
## Safety rails
These exist because the model, not the user, is choosing the values:
- Unknown parameter ids are rejected with close matches, never silently ignored.
- Out-of-range numbers are clamped to the plugin's real range and reported.
- Switch and menu parameters only accept their actual values (`on`/`off`, `Low Pass`).
- Preset names can't contain path separators, so writes stay in the preset folder.
- `create_preset` refuses to overwrite an existing preset.
- Every `adjust_preset` snapshots the previous version first — up to 30 per preset, in
`~/Library/Application Support/Space Dust/history/`.
- Presets are always written with all 206 parameters. `APVTS::replaceState` leaves
omitted parameters at their current value, so a partial preset would inherit whatever
the plugin happened to have loaded.
## Keeping the schema current
Parameter ranges, defaults and choice names live in `data/schema.json`, generated by
parsing `createParameterLayout()` in the
[plugin source](https://github.com/gadalleore/Space_Dust_Synthesizer/blob/main/Source/PluginProcessor.cpp).
Regenerate it whenever the plugin's parameter list changes:
```bash
uv run python -m spacedust_mcp.source_parser /path/to/Source/PluginProcessor.cpp
```
The default path assumes the two repos sit side by side; `SPACE_DUST_SOURCE` overrides it.
End users never run this — they get the generated file in the package. Longer term the
plugin should export this itself at build time, so the two can't drift.
## Tests
```bash
uv run pytest
```
TDQS
Scored across 10 tools
Each tool has a clearly distinct purpose: listing vs reading presets, adjusting named presets vs the current sound, and separate tools for undo, history, and comparison. The descriptions explicitly disambiguate potentially similar pairs like adjust_preset and adjust_current_sound.
All tool names follow a consistent verb_noun snake_case pattern (e.g., list_presets, read_preset, adjust_current_sound). Verbs are semantically appropriate (list, read, create, adjust, undo, compare), and no mixed naming conventions are present.
At 10 tools, the set is well-scoped for a synth preset management server. Each tool covers a distinct capability without redundancy, and the count feels neither sparse nor bloated.
The core lifecycle of preset management is covered: list, read, create, adjust, undo, history, and compare. However, a delete operation is missing, and saving the current sound as a new preset would require a workaround, leaving minor gaps.