AbletonMCP
# AbletonMCP
Control Ableton Live from Claude Code via the Model Context Protocol (MCP).
Create/edit tracks, control plugins (Waves, FabFilter, iZotope, any VST), fire clips, edit MIDI notes, capture audio — all through natural language.
## Architecture
```
Claude Code
↓ MCP Protocol (stdio)
mcp_server/ ← Python MCP server (this project)
↓ HTTP JSON (localhost:9001)
AbletonMCP/ ← Ableton Remote Script (Python, runs inside Ableton)
↓ Live Python API
Ableton Live
```
---
## Requirements
- Ableton Live 10, 11, or 12 (any edition)
- Python 3.11+ (for the MCP server)
- Claude Code CLI
---
## Installation
### Step 1 — Install the Ableton Remote Script
Copy the `AbletonMCP/` folder into Ableton's MIDI Remote Scripts directory:
| OS | Path |
|----|------|
| **Windows** | `C:\Users\<you>\Documents\Ableton\User Library\Remote Scripts\` |
| **macOS** | `/Users/<you>/Music/Ableton/User Library/Remote Scripts/` |
Result: `Remote Scripts/AbletonMCP/__init__.py` should exist.
### Step 2 — Enable in Ableton
1. Open Ableton Live
2. Go to **Preferences → Link, Tempo & MIDI**
3. Under **Control Surface**, select `AbletonMCP` in any available slot
4. No Input/Output device required — leave them as `None`
5. Check Ableton's Log file (`Help → Show Log File`) and confirm you see:
```
[AbletonMCP] AbletonMCP started on port 9001
```
### Step 3 — Install the MCP Server
```bash
cd ableton-mcp
pip install -e .
```
For audio capture support (optional):
```bash
pip install -e ".[audio]"
```
### Step 4 — Configure Claude Code
Add to your Claude Code MCP config (`~/.claude/claude_desktop_config.json` or via `claude mcp add`):
```json
{
"mcpServers": {
"ableton": {
"command": "python",
"args": ["-m", "mcp_server.main"],
"cwd": "/path/to/ableton-mcp"
}
}
}
```
Or using the Claude Code CLI:
```bash
claude mcp add ableton python -m mcp_server.main --cwd /path/to/ableton-mcp
```
### Step 5 — Verify
In Claude Code, ask:
```
Get the current Ableton session state
```
If Ableton is open with AbletonMCP loaded, you'll see tempo, tracks, etc.
---
## Running Tests
Tests run without Ableton (using a mock bridge server):
```bash
pip install -e ".[dev]"
pytest tests/ -v
```
All 51 tests should pass.
---
## Features & Tools
### Session / Transport
| Tool | Description |
|------|-------------|
| `get_session` | Tempo, time signature, playback state, loop settings, track/scene counts |
| `set_tempo` | Set BPM (60–200) |
| `set_time_signature` | Set numerator and denominator (e.g. 3/4, 7/8) |
| `play` | Start playback |
| `stop` | Stop playback and return to position 0 |
| `continue_playback` | Continue from current position |
| `toggle_record` | Toggle session record mode |
| `set_loop` | Enable/disable loop with optional start and length in bars |
| `set_metronome` | Toggle click track |
### Mixer (Master)
| Tool | Description |
|------|-------------|
| `get_mixer` | Master volume, master pan, cue volume, crossfader |
| `set_master_volume` | 0.0 (silent) → 1.0 (0dB) → 1.26 (+2dB) |
| `set_crossfader` | -1.0 (A) → 0.0 (center) → 1.0 (B) |
### Tracks
| Tool | Description |
|------|-------------|
| `list_tracks` | All audio, MIDI, and return tracks |
| `get_track` | Full track details by index |
| `create_track` | Create audio, MIDI, or return track |
| `update_track` | Name, volume, pan, mute, solo, arm, color |
| `delete_track` | Remove track permanently |
| `duplicate_track` | Copy track to next position |
| `get_sends` | All send levels for a track |
| `set_send` | Set send level to a return track |
**Track colors** accepted as name strings: `red`, `orange`, `yellow`, `green`, `cyan`, `blue`, `purple`, `pink`, `white`, `gray` — or as integer Ableton color ID.
### Clips
| Tool | Description |
|------|-------------|
| `list_clips` | All clip slots for a track (empty and filled) |
| `get_clip` | Clip details: name, length, loop points, warp mode |
| `create_clip` | Create MIDI clip in a slot with given length |
| `update_clip` | Name, loop start/end, looping, warp mode, gain |
| `delete_clip` | Remove clip from slot |
| `fire_clip` | Launch clip (equivalent to clicking launch button) |
| `stop_clip` | Stop playing clip on track |
| `get_notes` | All MIDI notes: pitch, start, duration, velocity |
| `add_notes` | Add MIDI notes to a clip |
| `clear_notes` | Remove all notes from a clip |
**MIDI note format:**
```json
{"pitch": 60, "start": 0.0, "duration": 0.5, "velocity": 100, "mute": false}
```
- `pitch`: MIDI note number (0–127, middle C = 60)
- `start`: position in beats from clip start
- `duration`: note length in beats
- `velocity`: 0–127
### Devices / Plugins
Works with **Ableton native devices** (Reverb, Compressor, Operator, Wavetable, etc.) and **any installed VST/AU plugin** (Waves, FabFilter, iZotope, Native Instruments, Serum, Vital, etc.).
| Tool | Description |
|------|-------------|
| `list_devices` | All devices in a track's device chain |
| `get_device` | Device info + all parameters with values and ranges |
| `add_device` | Add device by name (searches Ableton browser) |
| `enable_device` | Bypass or enable a device |
| `delete_device` | Remove device from chain |
| `list_parameters` | All parameters: name, value, min, max, display string |
| `set_parameter_by_index` | Set parameter by its index number |
| `set_parameter_by_name` | Set parameter by name (case-insensitive) |
| `load_preset` | Load a preset by name from Ableton's browser |
**Plugin examples:**
```
add_device(track_index=0, device_name="FabFilter Pro-Q 3")
add_device(track_index=1, device_name="Wave s SSL E-Channel")
add_device(track_index=2, device_name="iZotope Ozone 10")
add_device(track_index=0, device_name="Serum")
add_device(track_index=0, device_name="Compressor") # Ableton native
```
**Parameter editing examples:**
```
set_parameter_by_name(track_index=0, device_index=0, param_name="Threshold", value=-18.0)
set_parameter_by_name(track_index=0, device_index=1, param_name="Band 1 Gain", value=3.0)
```
### Scenes
| Tool | Description |
|------|-------------|
| `list_scenes` | All scenes with name and color |
| `get_scene` | Scene details |
| `create_scene` | Add new scene |
| `update_scene` | Name, color, tempo (per-scene), time signature |
| `delete_scene` | Remove scene and all its clips |
| `fire_scene` | Launch all clips in scene row |
### Audio
| Tool | Description |
|------|-------------|
| `get_audio_devices` | List audio devices (find virtual routing device name) |
| `analyze_track` | Track signal info: volume, pan, device chain state |
| `export_track` | Export track to WAV (see note below) |
| `start_audio_capture` | Begin recording from virtual audio device |
| `stop_audio_capture` | Stop capture and save WAV; returns RMS, peak, duration |
**Audio capture setup (virtual routing):**
1. Install a virtual audio device:
- Windows: [VB-Cable](https://vb-audio.com/Cable/)
- macOS: [BlackHole](https://github.com/ExistingHuman/BlackHole)
2. In Ableton, route your master output to the virtual device
3. Use `get_audio_devices` to find the exact device name
4. Use `start_audio_capture(device_name="CABLE Output (VB-Audio Virtual Cable)")`
5. Play in Ableton
6. Use `stop_audio_capture(output_path="~/my_recording.wav")` to save + analyze
**Note on export:** Ableton's Python API does not expose the export/render dialog programmatically. The recommended workflow is virtual routing capture or using Ableton's built-in export (File → Export Audio/Video) for offline rendering.
---
## Usage Examples
### Natural language in Claude Code
```
Create a new MIDI track called "Bass" at index 2 with a FabFilter Pro-Q 3 plugin,
then add a 4-bar clip in slot 0 with a C major chord (C4, E4, G4) at beat 0 with duration 2 beats.
```
```
Set the tempo to 128 BPM, enable the loop from bar 1 to bar 9, then fire scene "Chorus".
```
```
List all parameters of the Compressor on track 0 and set the threshold to -12 dB and ratio to 6:1.
```
```
Duplicate track 1, mute the original, and add a Waves SSL E-Channel to the duplicate.
```
---
## Project Structure
```
ableton-mcp/
├── AbletonMCP/ # Ableton Remote Script (install in Ableton)
│ ├── __init__.py # Entry point, create_instance()
│ ├── bridge_server.py # HTTP server thread (port 9001)
│ ├── api_handler.py # URL routing
│ └── live_api/
│ ├── session.py # Transport, tempo, loop, mixer
│ ├── tracks.py # Track CRUD, sends
│ ├── clips.py # Clip + MIDI note management
│ ├── devices.py # Plugin add/remove/parameter control
│ ├── scenes.py # Scene management
│ └── audio.py # Audio capture via virtual routing
├── mcp_server/ # MCP Server (Claude talks to this)
│ ├── main.py # Server entry point
│ ├── bridge_client.py # HTTP client to AbletonMCP
│ └── tools/
│ ├── session_tools.py
│ ├── track_tools.py
│ ├── clip_tools.py
│ ├── device_tools.py
│ ├── scene_tools.py
│ └── audio_tools.py
├── tests/
│ ├── mock_bridge/server.py # Simulates Ableton for offline testing
│ ├── conftest.py
│ ├── test_session.py
│ ├── test_tracks.py
│ ├── test_clips.py
│ ├── test_devices.py
│ └── test_scenes.py
└── pyproject.toml
```
---
## Troubleshooting
**"Cannot connect to Ableton bridge at localhost:9001"**
- Confirm AbletonMCP is selected in Ableton Preferences → Control Surfaces
- Check Ableton's log file for `[AbletonMCP] started on port 9001`
- Make sure no firewall blocks localhost:9001
**Plugin not found when using `add_device`**
- Plugin must be installed and scanned by Ableton (Preferences → Plug-Ins)
- Use the exact name as it appears in Ableton's browser
- VST3 plugins are preferred over VST2 when both are installed
**"Parameter X not found"**
- Use `get_device` or `list_parameters` first to see exact parameter names
- Parameter names are case-insensitive but must otherwise match exactly
**Tests fail**
- Run `pip install -e ".[dev]"` first
- Tests do not require Ableton — they use a mock bridge server
- Ensure port 9002 is free (used by mock server during testing)
---
## Known Limitations
- **Device reordering**: Ableton's Python API does not support moving devices within a chain. Delete and re-add in desired order.
- **Direct WAV export**: Ableton's API cannot trigger the export dialog programmatically. Use virtual routing capture or Ableton's built-in export.
- **Return track deletion**: Not supported via API (Ableton limitation).
- **Audio clips**: MIDI note editing only applies to MIDI clips. Audio clips support loop/warp settings only.
- **Plugin browser search**: Uses Ableton's browser tree traversal. Very large plugin collections may be slow to search on first use.
TDQS
Scored across 120 tools
Most tools have clearly distinct purposes, but some overlap exists, such as multiple automation-related tools (add_automation_points, create_automation, automate_mixer) and several analysis tools (analyze_mix, analyze_track, analyze_wav_file_tool). Detailed descriptions mitigate confusion, keeping ambiguity low for an experienced agent.
Tools predominantly follow a verb_noun snake_case pattern (e.g., list_tracks, create_clip, set_tempo). Minor inconsistencies like 'add_automation_points' vs 'create_automation' and the use of 'setup_sidechain' instead of 'set_sidechain' slightly disrupt uniformity, but the overall scheme is clear and predictable.
With 120 tools, the server is excessively large for most use cases. While Ableton Live is complex, this number overwhelms typical workflows and includes many highly specialized tools (e.g., set_chain_pan, mute_chain) that feel redundant. A more focused set of ~30-50 tools would be more coherent.
The toolset covers virtually every aspect of Ableton Live, including session management, clip and device manipulation, automation, routing, mixing analysis, MIDI generation, audio capture, and project lifecycle (save/undo). Only minor gaps like groove settings or advanced warp modes are missing, making it exceptionally comprehensive.