# 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 **160+ MCP tools** covering the full AbletonOSC API: transport, mixing, clips, MIDI notes, devices, scenes, return tracks, browser, groove pool, view navigation, and real-time listeners. The server communicates with Ableton Live via 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+** - **AbletonOSC** installed as a MIDI Remote Script --- ## Installation ### 1. Install AbletonOSC in Ableton Live 1. 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` 2. Restart Ableton Live 3. Open **Preferences → Link, Tempo & MIDI → MIDI** and set one of the Control Surface slots to **AbletonOSC** AbletonOSC listens on **UDP port 11000** and replies on **port 11001**. ### 2. Install ableton-mcp ```bash git clone https://github.com/your-user/ableton-mcp cd ableton-mcp python -m venv .venv .venv\Scripts\activate # Windows # source .venv/bin/activate # macOS/Linux pip install -e . ``` ### 3. Configure Claude Code Add to `~/.claude/settings.json`: ```json { "mcpServers": { "ableton-mcp": { "command": "C:\\path\\to\\ableton-mcp\\.venv\\Scripts\\ableton-mcp.exe", "args": [] } } } ``` Restart Claude Code. Tools appear automatically when a Live session is open. --- ## Configuration | Variable | Default | Description | |---|---|---| | `ABLETON_HOST` | `127.0.0.1` | AbletonOSC host address | | `ABLETON_SEND_PORT` | `11000` | Port to send OSC to Live | | `ABLETON_RECEIVE_PORT` | `11001` | Port to receive OSC from Live | | `ABLETON_TIMEOUT` | `5.0` | Query timeout in seconds | --- ## Tool Reference ### System (5 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` | Average CPU process usage (0.0–1.0) | | `system_show_message` | Display a message in the Ableton status bar | | `system_reload_api` | Hot-reload all AbletonOSC modules | --- ### Song / Transport (38 tools) #### Playback | Tool | Description | |---|---| | `song_get_state` | Full snapshot: tempo, is_playing, loop, time sig, track/scene/return counts, groove | | `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 (20–300) | | `song_get_time` / `song_set_time` | Get/jump playhead position in beats | | `song_jump_by` | Move playhead by ±N beats relative to current position | | `song_jump_to_next_cue` | Jump to next cue point | | `song_jump_to_prev_cue` | Jump to previous cue point | | `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.0–1.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 & Scenes | Tool | Description | |---|---| | `song_get_tracks` | List all tracks with index and name | | `song_get_return_tracks` | List all return tracks with index and name | | `song_create_audio_track` / `song_create_midi_track` / `song_create_return_track` | Create tracks | | `song_delete_track` / `song_delete_return_track` / `song_duplicate_track` | Delete/duplicate tracks | | `song_get_scenes` | List all scenes with index and name | | `song_create_scene` / `song_delete_scene` / `song_duplicate_scene` | Scene CRUD | #### Cue Points | Tool | Description | |---|---| | `song_get_cue_points` | List all cue points `{index, name, time}` | --- ### Tracks (19 tools) | Tool | Description | |---|---| | `track_get_info` | All properties: name, volume, pan, mute, solo, arm, type, color, monitoring, 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` / `track_set_solo` / `track_set_arm` | Mute/solo/arm | | `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 (0–69) | | `track_stop_clips` | Stop all clips on a track | | `track_set_monitoring` | Monitoring: 0=Auto, 1=In, 2=Off | | `track_set_fold` | Fold/unfold a group track | | `track_get_clips` | Session clips: index, name, length, color, is_playing | | `track_get_arrangement_clips` | Arrangement clips: index, name, length, start_time | | `track_get_devices` | Devices: index, name, type, class_name, can_have_chains | | `track_get_meter` | Output meter: level, left, right, peak_left, peak_right | | `track_delete_device` / `track_duplicate_device` | Remove/duplicate device | | `track_get_input_routing` | Current input type + channel + available options | | `track_set_input_routing_type` / `track_set_input_routing_channel` | Set input routing | | `track_get_output_routing` | Current output type + channel + available options | | `track_set_output_routing_type` / `track_set_output_routing_channel` | Set output routing | --- ### Return Tracks (11 tools) | Tool | Description | |---|---| | `return_track_get_info` | All properties: name, mute, solo, color, volume, panning | | `return_track_set_volume` / `return_track_set_panning` | Volume/pan | | `return_track_set_mute` / `return_track_set_solo` | Mute/solo | | `return_track_set_name` / `return_track_set_color` | Rename/recolor | | `return_track_get_send` / `return_track_set_send` | Inter-return sends | | `return_track_get_meter` | Output meter: level, left, right | | `return_track_get_devices` | List devices on the return track | --- ### Clips (31 tools) #### Playback & Properties | Tool | Description | |---|---| | `clip_fire` / `clip_stop` | Launch/stop a clip | | `clip_get_info` | All properties: name, length, playing state, loop, markers, pitch, gain, launch mode | | `clip_set_name` / `clip_set_color` | Rename/recolor | | `clip_set_gain` | Clip gain in dB | | `clip_set_muted` | Mute/unmute | | `clip_set_looping` / `clip_set_loop_points` | Enable loop and set start/end | | `clip_set_markers` | Set clip start/end markers | | `clip_set_pitch` | Transpose: semitones (−48…+48) and cents (−50…+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` | 0=Trigger, 1=Gate, 2=Toggle, 3=Repeat | | `clip_set_launch_quantization` | Per-clip quantization (0–14) | | `clip_set_legato` | Enable/disable legato | | `clip_set_velocity_amount` | Scale note velocities (0.0–1.0) | | `clip_set_ram_mode` | Enable/disable RAM mode for audio clips | | `clip_duplicate_loop` | Double loop by duplicating content | | `clip_quantize` | Quantize MIDI notes (quantization enum + strength 0.0–1.0) | #### MIDI Notes | Tool | Description | |---|---| | `clip_get_notes` | Notes filtered by pitch/time range: `{pitch, start, duration, velocity, mute}` | | `clip_get_notes_extended` | Extended notes with note_id, release_velocity, probability | | `clip_add_notes` | Add notes: `[{pitch, start, duration, velocity, mute}, …]` | | `clip_apply_note_modifications` | Modify existing notes by note_id | | `clip_remove_notes` | Remove notes in pitch/time range | #### Automation Envelopes | Tool | Description | |---|---| | `clip_get_automation_envelope` | Get breakpoints `{time, value}` for a device param | | `clip_create_automation_envelope` | Create envelope for a device param | | `clip_clear_envelope` | Clear one param's envelope | | `clip_clear_all_envelopes` | Clear all envelopes in a clip | #### Warp & Groove | Tool | Description | |---|---| | `clip_get_warp_markers` | Warp markers: `{beat_time, sample_time}` | | `clip_get_groove` / `clip_set_groove` | Get/assign groove by name | --- ### Clip Slots (7 tools) | Tool | Description | |---|---| | `clip_slot_get_info` | State: has_clip, is_playing, is_triggered, will_record, is_group_slot | | `clip_slot_fire` / `clip_slot_stop` | Trigger/stop a slot | | `clip_slot_create_clip` | Create empty MIDI clip with given length in beats | | `clip_slot_delete_clip` | Delete the clip in a slot | | `clip_slot_duplicate_to` | Copy clip to another slot | | `clip_slot_set_stop_button` | Enable/disable slot stop button | --- ### Scenes (9 tools) | Tool | Description | |---|---| | `scene_fire` | Launch a scene by index | | `scene_fire_as_selected` | Fire scene respecting follow actions | | `scene_get_info` | All properties: name, color, tempo, time sig, is_empty, is_triggered | | `scene_get_num_clips` | Number of clips in the scene | | `scene_get_clip_slots` | Per-slot occupancy: `{slot_index, has_clip}` | | `scene_set_name` / `scene_set_color` | Rename/recolor | | `scene_set_tempo` | Override tempo (with enable toggle) | | `scene_set_time_signature` | Override time signature | --- ### Devices (15 tools) | Tool | Description | |---|---| | `device_get_info` | Name, type, class_name, num_parameters, is_active | | `device_get_is_active` / `device_set_is_active` | Get/set bypass state | | `device_get_parameters` | All params: index, name, value, min, max, default_value, is_quantized | | `device_get_parameter` | Single param: name, value, min, max, default_value, value_string | | `device_set_parameter` | Set a parameter value (0.0–1.0 normalized) | | `device_set_parameters_bulk` | Set multiple params: `[{index, value}, …]` | | `device_randomize_macros` | Randomize rack macro knobs | | `device_get_chains` | Rack chains: index, name, num_devices, device names | | `device_get_drum_pads` | Drum Rack pads: index, name, note, mute, solo | | `device_set_drum_pad_mute` / `device_set_drum_pad_solo` | Mute/solo a drum pad | | `device_chain_get_parameter` | Get a param value inside a rack chain | | `device_chain_set_parameter` | Set a param value inside a rack chain | --- ### View / Navigation (8 tools) | Tool | Description | |---|---| | `view_get_selection` | Selected track, scene, clip, and device | | `view_get_focused_document_view` | Active view name (e.g. `'Session'`, `'Arranger'`) | | `view_set_selected_track` | Select a track | | `view_set_selected_scene` | Select a scene | | `view_set_selected_clip` | Select a clip | | `view_show_clip_detail` | Show clip detail panel | | `view_show_device_detail` | Show device detail panel | | `view_focus_browser` | Focus the browser panel | --- ### Browser (6 tools) | Tool | Description | |---|---| | `browser_get_items` | List items in a category: `audio_effects` / `instruments` / `midi_effects` / `samples` / `sounds` / `clips` / `packs` / `plugins` | | `browser_load_item` | Load an item into the selected track/slot (pass path parts as args) | | `browser_preview_item` | Preview a sample or preset | | `browser_stop_preview` | Stop browser preview playback | | `browser_get_hotswap_target` | Name of device targeted for hotswap | | `browser_begin_hotswap` | Begin hotswap mode for a device | --- ### Groove Pool (3 tools) | Tool | Description | |---|---| | `groove_get_all` | List all groove names in the groove pool | | `groove_get_amount` | Get groove intensity (0.0–1.0) by name | | `groove_set_amount` | Set groove intensity (0.0–1.0) by name | --- ### 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 | | `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 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. Load a reverb from the browser onto the first return track and set the wet/dry to 50%. Get all drum pad names on track 0's Drum Rack, then mute every pad that isn't a kick or snare. Solo track 3, set its reverb send to 0.4, and watch the output meter until it clips. Set the groove pool's first groove to 80% intensity and assign it to all clips on track 1. ``` --- ## 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 ├── track.py # Mixing, routing, devices list, meter ├── clip.py # Playback, MIDI notes, pitch, warp, loop, launch, envelopes ├── clip_slot.py # Slot-level create/fire/delete/duplicate ├── scene.py # Scene fire, info, clip slots, tempo/time-sig overrides ├── device.py # Parameters (individual + bulk), chains, drum pads ├── return_track.py# Return/aux track mixing and devices ├── browser.py # Content library browsing, load, preview, hotswap ├── groove.py # Groove pool listing and amount control ├── view.py # Selected track/scene/clip, panel navigation ├── system.py # Connectivity, version, CPU, status bar └── listener.py # Real-time property change subscriptions ``` --- ## Troubleshooting **`system_test_connection` returns `connected: false`** - Confirm AbletonOSC is enabled in Preferences → Control Surfaces - A Live project must be open (AbletonOSC only activates with an open set) - Check that no firewall blocks UDP 11000/11001 on localhost **Timeout errors** - Increase `ABLETON_TIMEOUT` env var (default 5 s) - `song_get_state` issues many sequential queries; slow machines may need 10 s+ **`No module named 'ableton_mcp'`** - Install with `pip install -e .` inside the correct `.venv` - The MCP config `command` path must point to the `.venv` executable --- ## License MIT