ableton12-mcp
MCP server for Ableton Live 12 enabling full DAW control (tracks, devices, mixer, clips, transport) and audio analysis via loopback capture, allowing LLMs to create, modify, and measure music in real time.
README
ableton12 — full-control MCP server for Ableton Live 12
A Python + uv MCP server that lets an LLM (Claude Code,
Claude Desktop, any MCP client) drive Ableton Live 12 through the Live Object Model —
and, uniquely, measure what it just made.
It is a drop-in superset of the upstream
ahujasid/ableton-mcp: it keeps the 16 original tools
(identical names, params and return values, so existing prompts/permissions keep working) and adds
everything upstream can't do — 62 tools in total:
- Device & instrument parameter control — read every parameter and actually change the tone: filter cutoff, oscillator type, reverb decay, macros, device bypass.
- Mixer — volume, pan, sends, mute, solo, arm, color. Addresses the master bus and return tracks, not just regular tracks.
- Tracks / clips / scenes / transport — create audio & return tracks, read & remove notes, loop settings, duplicate, delete, color, fire scenes, time signature, metronome, playhead.
- Session → Arrangement capture — record a Session scene into the Arrangement so Live's exporter (Arrangement-only) can render it.
- Ears — capture any single track (or the master / a return) to a WAV via a loopback device and
analyze it: LUFS, true peak, 10-band spectrum, spectral centroid, transient punch, stereo width.
Plus
compare_audiofor before/after A-B of a parameter change. This is what makes an autonomous measure → adjust → re-measure tuning loop possible instead of guessing. - Host automation (macOS) — launch Live, new Set, Save, Save As, open the Export dialog.
Scope: this repo is the MCP server + Remote Script only. The composition prompt-layer built on top of it (slash commands like
/clip,/master,/dial,/export) lives elsewhere; every tool here is usable from any MCP client on its own.
Architecture
Two halves talk over TCP localhost:9877 using 4-byte length-prefixed JSON frames:
LLM ⇄ (stdio) ⇄ ableton12 MCP server ⇄ (TCP 9877) ⇄ Remote Script (inside Live)
src/ableton12_mcp/ remote_script/AbletonMCP/
│
└─ ffmpeg + loopback device ─► WAV ─► analysis (numpy/scipy/pyloudnorm)
- MCP server (
src/ableton12_mcp/server.py): FastMCP server namedAbletonMCP. Each@mcp.tool()sends one command frame and returns the result._host.pydoes the macOS-level automation,_record.pythe loopback capture,_analysis.pythe audio metrics. - Remote Script (
remote_script/AbletonMCP/__init__.py): aControlSurfacerunning inside Live's embedded Python. A socket thread does pure I/O; every command — reads included — is marshaled onto Live's main thread viaschedule_message+ a reply queue (_run_on_main). That is the key correctness fix: upstream's device-parameter attempts crashed because reads ran off the main thread while writes ran on it.
Requirements
| Ableton Live 12 | the Remote Script targets Live 12's Object Model |
| macOS | required for host automation (launch_ableton, save_set*, open_export_dialog) and for loopback capture (avfoundation). The Live-control tools themselves are OS-agnostic. |
Python ≥ 3.10 + uv |
brew install uv |
| ffmpeg (optional) | needed by record_audio / record_and_analyze — brew install ffmpeg |
| BlackHole (optional) | loopback device for the "ears" — brew install blackhole-2ch |
Install
# 1. Clone and sync dependencies
git clone https://github.com/verove-jordan/ableton12-mcp.git
cd ableton12-mcp
uv sync
# 2. Install the Remote Script into Ableton's User Library
# (quit Live first; the script backs up any existing AbletonMCP install)
./install.sh
# 3. In Ableton: Settings → Link, Tempo & MIDI → Control Surfaces → pick "AbletonMCP"
# with Input = None and Output = None, then RESTART Ableton.
# The status bar should read: AbletonMCP (ableton12): listening on port 9877
# 4. Register the server with your MCP client — e.g. Claude Code, at user scope:
claude mcp add AbletonMCP -s user -- uvx --from "$(pwd)" ableton12
# Then run /mcp to connect and call the `health` tool to verify.
Generic MCP client config (Claude Desktop, .mcp.json, …) — use an absolute path:
{
"mcpServers": {
"AbletonMCP": {
"type": "stdio",
"command": "uvx",
"args": ["--from", "/absolute/path/to/ableton12-mcp", "ableton12"]
}
}
}
Only one process may bind port 9877 — make sure no old uvx ableton-mcp server is still running.
Optional: the "ears" (per-track capture)
record_audio records Live's output in realtime from a loopback audio input, so you need one:
brew install ffmpeg blackhole-2ch- Audio MIDI Setup → create a Multi-Output Device containing both your speakers/ headphones and BlackHole; set it as Live's output (Preferences → Audio) or the system output — that way you still hear playback while it is captured.
- macOS will prompt once for Microphone access for the app running the MCP server (capturing an audio input counts as mic use): System Settings → Privacy & Security → Microphone.
Capture is realtime — a window's wall-clock equals its musical length, so keep windows short (2–4 bars).
Optional: host automation permissions
save_set_as and open_export_dialog drive Live's menus with AppleScript keystrokes, which needs a
one-time Accessibility grant for the app running the MCP server (Terminal / iTerm / your editor):
System Settings → Privacy & Security → Accessibility. These routines are best-effort and depend on
the running Live version's dialog layout — always verify the resulting file on disk rather than
trusting the return value.
Tool catalog (62)
Session & transport: get_session_info, set_tempo, start_playback, stop_playback,
set_time_signature, set_metronome, set_song_position, get_transport, health.
Tracks: get_track_info, create_midi_track, create_audio_track, create_return_track,
set_track_name, delete_track, duplicate_track.
Mixer: set_track_volume, set_track_pan, set_track_send, set_track_mute,
set_track_solo, set_track_arm, set_track_color.
Devices & parameters: get_device_parameters, set_device_parameter, set_device_enabled,
delete_device, get_macros, set_macro.
Browser / loading: get_browser_tree, get_browser_items_at_path, load_instrument_or_effect,
load_drum_kit.
Clips: create_clip, add_notes_to_clip, get_clip_notes, remove_notes_from_clip,
set_clip_name, set_clip_loop, duplicate_clip, delete_clip, set_clip_color, fire_clip,
stop_clip.
Scenes: create_scene, fire_scene, set_scene_name, delete_scene.
Session → Arrangement capture: set_arrangement_record, set_clip_trigger_quantization,
capture_session_to_arrangement.
Metering: get_track_meter, get_master_meter (levels 0..1, only while playing).
Listening & analysis: record_audio, record_and_analyze, analyze_audio, compare_audio.
Host automation (macOS): launch_ableton, new_live_set, save_set, save_set_as,
open_export_dialog.
Addressing the master bus and return tracks
Track-scoped tools (get_track_info, load_instrument_or_effect, get_device_parameters,
set_device_parameter, set_device_enabled, delete_device, set_track_volume, set_track_pan,
get_track_meter, record_audio, …) take an optional track argument that overrides the
integer track_index:
track='master'→ the master bus (this is how you build a mastering chain),track='return:0'→ return track 0 (return:N), fed byset_track_send.
Plain integer track_index calls are unchanged.
Parameter value semantics (read this before "changing the tone")
get_device_parameters(track, device) returns each parameter with name, value, min, max,
is_quantized, value_items (enum labels) and display_value (e.g. "440 Hz", "Lowpass").
Always read before you write — ranges are device- and install-specific. Then
set_device_parameter:
- Continuous params: pass
valuein native units (within[min, max]), orvalue_normalized(0..1 →min + x*(max-min)). Values are clamped. - Quantized params (
is_quantized=true): passvalueas either the integer index or the exactvalue_itemslabel (case-insensitive), orvalue_normalizedto pick by fraction. - A parameter mapped to a macro reports
is_enabled=false; writes to it are skipped and the reply says so (applied=false). Change it through the macro (set_macro) instead.
Mixer ranges: volume is a fader position 0..1, not dB (~0.85 ≈ 0 dB, 1.0 ≈ +6 dB — the reply reports the resulting dB). Pan is −1..+1. Sends are 0..1.
Typical workflow: load_instrument_or_effect → get_device_parameters → set_device_parameter.
After structural edits (delete_track, create_*, delete_scene) re-read get_session_info,
because indices shift.
What analyze_audio returns
Peak/RMS dBFS, crest factor, clipping; LUFS (lufs_integrated, lufs_short_term_max,
lufs_range_lra) and true peak (true_peak_dbtp); a 10-band spectrum (spectrum_bands /
spectrum_bands_db) plus a legacy 4-band; brightness (spectral_centroid_hz,
spectral_rolloff_hz, spectral_flatness); transients (onset_strength, onset_rate_per_sec,
band_crest_db per band — low-band crest ≈ kick punch); stereo (stereo_correlation,
stereo_width, band_stereo_width); plus noise floor, DC offset and silence detection.
loudness_method flags whether pyloudnorm or the numpy fallback produced the LUFS figures.
compare_audio(a, b) turns two of those into per-metric deltas in human terms with a one-line
headline, suppressing sub-perceptual changes — the progress meter for a tuning loop.
Known limitation — no automation over time
The server can set a parameter to a static value, but it cannot write clip/device automation
envelopes, so moves that evolve across an arrangement (a filter opening over 16 bars, a
progressive L↔R pan sweep) are not directly authorable. Workarounds and the plan to close the gap
are in docs/AUTOMATION_TODO.md.
Debugging
- "Connection refused" / can't connect: Ableton isn't running, wasn't restarted after a script change, or the control surface isn't selected. Don't retry blindly — check those three.
- Confirm Live holds the port:
lsof -nP -iTCP:9877 -sTCP:LISTENshould showLive. If it shows apython/uvxprocess, a stale server has the port. - Remote Script logs:
~/Library/Preferences/Ableton/Live 12*/Log.txt— look forAbletonMCP (ableton12) ... initializingandlistening on port. Useself.log_message;print()from the script is invisible. - After editing the Remote Script you must restart Ableton (or re-select the control surface).
install.shclears__pycache__; thehealthtool reports the loaded version so you can confirm the new build is active.
Credits
API-compatible with, and inspired by, ahujasid/ableton-mcp.
Not affiliated with Ableton AG.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。