MCP (Model Context Protocol) server for SuperCollider integration with Claude Code.
- Connect to a running SuperCollider server (scsynth)
- Load SynthDefs reliably with automatic disk-write pattern
- Play synths with custom parameters and timing
- Execute code - run arbitrary SuperCollider code
- Validate syntax - check code for errors without executing (tree-sitter + sclang fallback)
- Analyze audio - real-time pitch, timbre, and amplitude monitoring
- Compare sounds - capture references and compare against them
- Debug - access server logs and error messages
- SuperCollider installed
- SuperCollider.app running with server booted (
Server.local.boot) - uv for Python package management
cd sc-repl-mcp
uv syncclaude mcp add sc-repl -- uv run --directory /path/to/sc-repl-mcp python sc_repl_mcp.pyOr add to ~/.claude/settings.json:
{
"mcpServers": {
"sc-repl": {
"command": "uv",
"args": ["run", "--directory", "/path/to/sc-repl-mcp", "python", "sc_repl_mcp.py"]
}
}
}| Tool | Description |
|---|---|
sc_connect |
Connect to SuperCollider server |
sc_status |
Get server status (CPU, synths, groups) |
sc_play_sine |
Play a sine wave test tone |
sc_play_synth |
Play any SynthDef with parameters |
sc_load_synthdef |
Load a SynthDef reliably |
sc_eval |
Execute arbitrary SuperCollider code |
sc_validate_syntax |
Check code syntax without executing |
sc_free_all |
Free all running synths |
sc_start_analyzer |
Start audio analysis |
sc_stop_analyzer |
Stop audio analysis |
sc_get_analysis |
Get pitch/timbre/amplitude data |
sc_get_onsets |
Get detected onset/attack events |
sc_get_spectrum |
Get frequency spectrum data |
sc_capture_reference |
Save current sound as reference |
sc_compare_to_reference |
Compare current sound to reference |
sc_list_references |
List saved sound references |
sc_delete_reference |
Delete a saved reference |
sc_analyze_parameter |
Analyze how a parameter affects sound |
sc_get_logs |
View server log messages |
sc_clear_logs |
Clear log buffer |
You: Connect to SuperCollider and create a metallic bell sound
Claude: [uses sc_connect, sc_load_synthdef, sc_play_synth]
Claude Code <--stdio/JSON-RPC--> sc-repl MCP <--OSC--> scsynth (port 57110)
|
+--persistent--> sclang (code execution)
The server uses OSC (Open Sound Control) to communicate directly with scsynth. A persistent sclang process handles code execution, SynthDef loading, and OSC forwarding.
After sc_connect, a persistent sclang process stays running. This makes sc_eval and sc_load_synthdef much faster (~10ms vs 2-5s) by avoiding class library recompilation on each call. State persists within the session.
You can run multiple MCP server instances connecting to the same SuperCollider server by configuring different ports for each instance:
# Instance 1 (default ports)
SC_REPLY_PORT=57130 SC_SCLANG_PORT=57122 uv run python sc_repl_mcp.py
# Instance 2
SC_REPLY_PORT=57131 SC_SCLANG_PORT=57123 uv run python sc_repl_mcp.py
# Instance 3
SC_REPLY_PORT=57132 SC_SCLANG_PORT=57124 uv run python sc_repl_mcp.pyOr in ~/.claude/settings.json:
{
"mcpServers": {
"sc-repl-1": {
"command": "uv",
"args": ["run", "--directory", "/path/to/sc-repl-mcp", "python", "sc_repl_mcp.py"],
"env": {"SC_REPLY_PORT": "57130", "SC_SCLANG_PORT": "57122"}
},
"sc-repl-2": {
"command": "uv",
"args": ["run", "--directory", "/path/to/sc-repl-mcp", "python", "sc_repl_mcp.py"],
"env": {"SC_REPLY_PORT": "57131", "SC_SCLANG_PORT": "57123"}
}
}
}All instances share the same scsynth audio engine, so sounds from any instance go to the same output.
The sc_validate_syntax tool uses a hybrid approach:
- tree-sitter (fast, ~5ms) - Primary validation using a SuperCollider grammar
- sclang compile() (accurate, ~200ms) - Fallback when tree-sitter unavailable
The tree-sitter grammar must be compiled before first use:
uv run python scripts/build_grammar.pyRequires: git, C compiler (gcc/clang)
The tree-sitter grammar has some false positives with advanced SC syntax:
| Pattern | Status | Workaround |
|---|---|---|
arr[i % 8] |
False positive | var idx = i % 8; arr[idx] |
Out.ar(0, sig ! 2) |
False positive | Out.ar(0, sig.dup(2)) |
`[freqs, amps] |
False positive | Use variable: var spec = [f,a]; Klank.ar(spec) |
These patterns are valid SuperCollider and will execute correctly - the validator just can't parse them.
See CLAUDE.md for detailed usage guidance when working with Claude Code.