Files
ableton-mcp/README.md
T
valknar 7260e9c43d Add comprehensive README with full tool reference and setup guide
Covers installation of AbletonOSC, Claude Desktop config, all 124 tools
across 9 categories, listener usage, architecture overview, example
prompts, and troubleshooting tips.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 21:09:46 +02:00

403 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ableton-mcp
A full-featured [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server that gives AI assistants (Claude, etc.) complete control over Ableton Live via [AbletonOSC](https://github.com/ideoforms/AbletonOSC).
## Overview
**ableton-mcp** bridges AI assistants and Ableton Live by exposing **124 MCP tools** covering every major area of the Live API: transport control, track mixing, clip launching and editing, MIDI note manipulation, device parameter control, scene management, view selection, and real-time property listeners.
The server communicates with Ableton Live via [AbletonOSC](https://github.com/ideoforms/AbletonOSC) — a MIDI Remote Script that runs inside Live and exposes its internal API over OSC/UDP.
```
Claude (AI) ──MCP tools──▶ ableton-mcp ──OSC/UDP──▶ AbletonOSC ──Live Object Model──▶ Ableton Live
```
---
## Requirements
- **Ableton Live 11 or later**
- **Python 3.10+** (tested with 3.10.6 via pyenv)
- **AbletonOSC** installed as a MIDI Remote Script (see below)
---
## Installation
### 1. Install AbletonOSC in Ableton Live
1. Download or clone [AbletonOSC](https://github.com/ideoforms/AbletonOSC)
2. Copy the `AbletonOSC` folder into your Ableton User Library Remote Scripts directory:
- **Windows:** `%USERPROFILE%\Documents\Ableton\User Library\Remote Scripts`
- **macOS:** `~/Music/Ableton/User Library/Remote Scripts`
3. Restart Ableton Live
4. Open **Preferences → Link, Tempo & MIDI → MIDI** and set one of the Control Surface slots to **AbletonOSC**
AbletonOSC will now listen on **UDP port 11000** and reply on **port 11001**.
### 2. Install ableton-mcp
```bash
# Clone the repo (rename the folder after cloning)
git clone https://github.com/your-user/ableton-mcp
cd ableton-mcp
# Create and activate a virtual environment
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
# Install
pip install -e .
```
### 3. Configure Claude Desktop
Add the server to your Claude Desktop configuration file:
**Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
```json
{
"mcpServers": {
"ableton": {
"command": "C:\\path\\to\\ableton-mcp\\.venv\\Scripts\\ableton-mcp.exe"
}
}
}
```
Restart Claude Desktop. The Ableton Live tools will appear automatically when a Live session is open.
---
## Configuration
All settings can be overridden via environment variables:
| Variable | Default | Description |
|---|---|---|
| `ABLETON_HOST` | `127.0.0.1` | AbletonOSC host address |
| `ABLETON_SEND_PORT` | `11000` | Port to send OSC commands to Live |
| `ABLETON_RECEIVE_PORT` | `11001` | Port to receive OSC replies from Live |
| `ABLETON_TIMEOUT` | `5.0` | Query timeout in seconds |
Example (Claude Desktop config with custom port):
```json
{
"mcpServers": {
"ableton": {
"command": "C:\\path\\to\\.venv\\Scripts\\ableton-mcp.exe",
"env": {
"ABLETON_TIMEOUT": "10.0"
}
}
}
}
```
---
## Tool Reference
### System (7 tools)
| Tool | Description |
|---|---|
| `system_test_connection` | Ping AbletonOSC; returns `{connected, latency_ms}` |
| `system_get_version` | Get Ableton Live version `{major, minor}` |
| `system_get_cpu_usage` | Get average CPU process usage (0.01.0) |
| `system_show_message` | Display a message in the Ableton status bar |
| `system_get_log_level` | Get current AbletonOSC log level |
| `system_set_log_level` | Set log level: `debug` / `info` / `warning` / `error` / `critical` |
| `system_reload_api` | Hot-reload all AbletonOSC modules |
---
### Song / Transport (48 tools)
#### Playback
| Tool | Description |
|---|---|
| `song_get_state` | Full snapshot: tempo, is_playing, loop, time sig, track/scene counts, groove, link, scale… |
| `song_start_playing` | Start playback from current position |
| `song_stop_playing` | Stop playback |
| `song_continue_playing` | Resume without resetting to start |
| `song_stop_all_clips` | Stop all active clips |
| `song_tap_tempo` | Send a tap-tempo pulse |
#### Tempo & Time
| Tool | Description |
|---|---|
| `song_get_tempo` / `song_set_tempo` | Get/set BPM (20300) |
| `song_get_time` / `song_set_time` | Get/jump playhead position in beats |
| `song_get_time_signature` / `song_set_time_signature` | Get/set numerator + denominator |
#### Loop
| Tool | Description |
|---|---|
| `song_get_loop` | Get `{loop, loop_start, loop_length}` |
| `song_set_loop` | Set on/off, start, and length (beats) |
#### Metronome, Quantization & Groove
| Tool | Description |
|---|---|
| `song_get_metronome` / `song_set_metronome` | Toggle metronome |
| `song_set_quantization` | Clip trigger quantization (0=none … 13=1/32) |
| `song_set_midi_recording_quantization` | MIDI recording quantization |
| `song_set_groove` | Global groove amount (0.01.0) |
#### Recording
| Tool | Description |
|---|---|
| `song_set_arrangement_overdub` | Enable/disable arrangement overdub |
| `song_set_session_record` | Enable/disable session record |
| `song_set_punch_in` / `song_set_punch_out` | Punch in/out |
| `song_trigger_session_record` | Toggle session record |
| `song_capture_midi` | Capture incoming MIDI into a new clip |
| `song_re_enable_automation` | Re-enable overridden automation |
#### Edit
| Tool | Description |
|---|---|
| `song_undo` / `song_redo` | Undo/redo |
#### Tracks
| Tool | Description |
|---|---|
| `song_get_tracks` | List all tracks with index and name |
| `song_create_audio_track` | Create audio track at index |
| `song_create_midi_track` | Create MIDI track at index |
| `song_create_return_track` | Create return/aux track |
| `song_delete_track` / `song_delete_return_track` | Delete track |
| `song_duplicate_track` | Duplicate a track |
#### Scenes
| Tool | Description |
|---|---|
| `song_get_scenes` | List all scenes with index and name |
| `song_create_scene` / `song_delete_scene` / `song_duplicate_scene` | Scene CRUD |
| `song_capture_and_insert_scene` | Capture session state as a new scene |
#### Cue Points
| Tool | Description |
|---|---|
| `song_get_cue_points` | List all cue points |
| `song_jump_to_cue` | Jump to cue by index or name |
| `song_add_or_delete_cue` | Toggle cue at current playhead |
| `song_set_cue_name` | Rename a cue point |
#### Scale & Link
| Tool | Description |
|---|---|
| `song_set_root_note` | Set root note (0=C … 11=B) |
| `song_set_scale_name` | Set scale name e.g. `"Major"`, `"Dorian"` |
| `song_set_ableton_link` | Enable/disable Ableton Link |
| `song_export_structure` | Export full session structure to JSON file |
---
### Tracks (19 tools)
| Tool | Description |
|---|---|
| `track_get_info` | All track properties: name, volume, pan, mute, solo, arm, type, color, monitoring, meter slots, device count |
| `track_set_volume` | Volume (0.0=−∞, 0.85≈0 dB, 1.0=+6 dB) |
| `track_set_pan` | Panning (1.0=left, 0.0=center, +1.0=right) |
| `track_set_mute` | Mute / unmute |
| `track_set_solo` | Solo / unsolo |
| `track_set_arm` | Arm / disarm for recording |
| `track_get_send` / `track_set_send` | Get/set send level to a return track |
| `track_set_name` | Rename a track |
| `track_set_color` | Set track color by palette index (069) |
| `track_stop_clips` | Stop all clips on a track |
| `track_set_monitoring` | Monitoring state: 0=Auto, 1=In, 2=Off |
| `track_set_fold` | Fold/unfold a group track |
| `track_get_clips` | List session clips: index, name, length, color |
| `track_get_arrangement_clips` | List arrangement clips: index, name, length, start_time |
| `track_get_devices` | List devices: index, name, type, class_name |
| `track_get_meter` | Output meter levels: left, right, level |
| `track_delete_device` | Remove a device from the chain |
| `track_get_available_input_routing_types` | List available input routing options |
| `track_set_input_routing_type` / `track_set_output_routing_type` | Set I/O routing |
---
### Clips (19 tools)
| Tool | Description |
|---|---|
| `clip_fire` | Launch a clip |
| `clip_stop` | Stop a playing clip |
| `clip_get_info` | All clip properties: name, length, playing state, loop, markers, pitch, gain, launch mode, warp, color |
| `clip_set_name` | Rename a clip |
| `clip_set_color` | Set clip color by palette index (069) |
| `clip_set_gain` | Set clip gain in dB |
| `clip_set_muted` | Mute/unmute a clip |
| `clip_set_looping` | Enable/disable loop |
| `clip_set_loop_points` | Set loop start + end in beats |
| `clip_set_markers` | Set start + end markers in beats |
| `clip_set_pitch` | Transpose: semitones (48 to +48) and cents (50 to +50) |
| `clip_set_warp_mode` | Warp mode: 0=Beats, 1=Tones, 2=Texture, 3=Re-Pitch, 4=Complex, 5=Complex Pro |
| `clip_set_warping` | Enable/disable warping |
| `clip_set_launch_mode` | Launch mode: 0=Trigger, 1=Gate, 2=Toggle, 3=Repeat |
| `clip_set_launch_quantization` | Per-clip launch quantization (014) |
| `clip_set_legato` | Enable/disable legato mode |
| `clip_duplicate_loop` | Double loop length by duplicating content |
| `clip_get_notes` | Get MIDI notes (filterable by pitch range + time range) |
| `clip_add_notes` | Add MIDI notes: `[{pitch, start, duration, velocity, mute}, …]` |
| `clip_remove_notes` | Remove MIDI notes by pitch/time range |
---
### Clip Slots (7 tools)
| Tool | Description |
|---|---|
| `clip_slot_get_info` | Slot state: has_clip, is_playing, is_triggered, will_record, is_group_slot |
| `clip_slot_fire` | Trigger a slot (launches clip or starts recording if empty) |
| `clip_slot_stop` | Stop a slot |
| `clip_slot_create_clip` | Create a new empty MIDI clip with a given length in beats |
| `clip_slot_delete_clip` | Delete the clip in a slot |
| `clip_slot_duplicate_to` | Copy clip from one slot to another |
| `clip_slot_set_stop_button` | Enable/disable the stop button for a slot |
---
### Scenes (7 tools)
| Tool | Description |
|---|---|
| `scene_fire` | Launch a scene by index |
| `scene_fire_selected` | Launch the currently selected scene |
| `scene_get_info` | All scene properties: name, color, tempo, tempo_enabled, time sig, is_empty, is_triggered |
| `scene_set_name` | Rename a scene |
| `scene_set_color` | Set scene color by palette index (069) |
| `scene_set_tempo` | Override tempo for a scene (with enable toggle) |
| `scene_set_time_signature` | Override time signature for a scene |
---
### Devices (6 tools)
| Tool | Description |
|---|---|
| `device_get_info` | Device info: name, type (audio_effect / instrument / midi_effect), class_name, num_parameters |
| `device_get_parameters` | All parameters: index, name, value, min, max, is_quantized |
| `device_get_parameter` | Single parameter: name, value, value_string (display value) |
| `device_set_parameter` | Set a parameter value (normalized 0.01.0) |
| `device_set_parameters_bulk` | Set multiple parameters in one call: `[{index, value}, …]` |
| `device_map_midi_cc` | Map a MIDI CC to a device parameter |
---
### View / Selection (5 tools)
| Tool | Description |
|---|---|
| `view_get_selection` | Current selection: selected_track, selected_scene, selected_clip, selected_device |
| `view_set_selected_track` | Select a track in the Ableton UI |
| `view_set_selected_scene` | Select a scene in the Ableton UI |
| `view_set_selected_clip` | Select a clip in the Ableton UI |
| `view_set_selected_device` | Select a device in the Ableton UI |
---
### Real-time Listeners (3 tools)
Subscribe to property changes from Ableton Live and poll them at any time.
| Tool | Description |
|---|---|
| `listener_start` | Register a listener for a property; returns the OSC response address |
| `listener_stop` | Unregister a listener |
| `listener_get_events` | Drain queued events (up to `max_events`); each event is a list of OSC args |
**Supported objects and properties:**
| object_type | property_name | Notes |
|---|---|---|
| `song` | `beat` | `[beat_number, beat_index, bar, song_time]` per beat |
| `song` | `is_playing` | `[0/1]` |
| `song` | `tempo` | `[bpm]` |
| `song` | `current_song_time` | `[beats]` |
| `view` | `selected_track` | `[track_index]` |
| `view` | `selected_scene` | `[scene_index]` |
| `track` | any read/write property | requires `track_index` |
| `clip` | any read/write property | requires `track_index` + `clip_index` |
| `clip_slot` | any property | requires `track_index` + `clip_index` |
**Example usage with Claude:**
> "Watch the beat and tell me the bar number every 4 bars"
> Claude calls `listener_start("song", "beat")`, then periodically `listener_get_events("song", "beat")`
---
## Example Prompts
```
Play the song from bar 3 at 128 BPM with the metronome on.
Create a 4-bar MIDI clip on track 0, slot 1, and add a C minor chord
(C3, Eb3, G3) on beats 1 and 3 with velocity 90.
Set every device on track 2 to a random-ish sound:
randomize all parameters whose name contains "Filter".
Loop scene 4 forever: set scene 4's clips to looping and fire the scene.
Solo track 3, mute tracks 1 and 2, and set track 3's reverb send to 0.4.
Name all empty scenes "—" and delete any track with no clips.
```
---
## Architecture
```
src/ableton_mcp/
├── server.py # FastMCP app; registers all tool modules
├── osc_client.py # Thread-safe OSCClient singleton
│ # cmd() fire-and-forget
│ # query() synchronous request/response
│ # start_listener() / drain_listener() real-time events
├── config.py # Port/host/timeout from env vars
└── tools/
├── song.py # Transport, tempo, loop, scenes, tracks, cues, scale, Link
├── track.py # Mixing, routing, devices list, meter
├── clip.py # Playback, MIDI notes, pitch, warp, loop, launch
├── clip_slot.py # Slot-level create/fire/delete/duplicate
├── scene.py # Scene fire, tempo/time-sig overrides
├── device.py # Parameter get/set (individual + bulk), MIDI CC mapping
├── view.py # Selected track/scene/clip/device
├── system.py # Connectivity, version, CPU, status bar, logging
└── listener.py # Real-time property change subscriptions
```
**OSC communication** uses `python-osc` directly against AbletonOSC's full 200+ endpoint API. The `OSCClient` singleton runs a `ThreadingOSCUDPServer` on the receive port in a daemon thread. Queries use `threading.Event` for synchronous blocking with configurable timeout. Listeners store events in per-address `collections.deque` instances for thread-safe polling.
---
## Troubleshooting
**`system_test_connection` returns `connected: false`**
- Confirm AbletonOSC is enabled in Ableton → Preferences → Control Surfaces
- Make sure a Live project is open (AbletonOSC only activates with an open set)
- Check that no firewall is blocking UDP 11000/11001 on localhost
**Timeout errors on queries**
- Increase `ABLETON_TIMEOUT` env var (default 5 s)
- Some properties (e.g. `song_get_state`) issue many sequential OSC queries; slow machines may need a higher timeout
**`No module named 'ableton_mcp'`**
- Make sure you installed with `pip install -e .` inside the correct `.venv`
- The Claude Desktop config `command` path must point to the `.venv` executable, not the system Python
---
## License
MIT