
Ableton Live
- 4 installs
- 14 repo stars
- Updated June 3, 2026
- othmanadi/loophole
Helps with ai & agent building tasks during AI-assisted development.
About
ableton-live is a Claude Code skill for ai & agent building. It helps solo builders move faster with AI-assisted coding.
- ableton-live
- AI & Agent Building
- AI-coding skill
Ableton Live by the numbers
- 4 all-time installs (skills.sh)
- Ranked #13,348 of 16,546 AI & Agent Building skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/othmanadi/loophole --skill ableton-liveAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 14 |
| Last updated | June 3, 2026 |
| Repository | othmanadi/loophole ↗ |
What it does
Helps with ai & agent building tasks during AI-assisted development.
Files
ableton-live (alias: loophole)
A thin developer-experience layer for the Loophole Bridge, the MCP server that controls Ableton Live 12 over the official Extensions SDK. This skill closes the loop between "the bridge is installed" and "the agent uses it well." It does three things and nothing more.
It never talks to Live directly. It does not embed tool logic, re-implement the bridge, or import any bridge or SDK code. The bridge is the only thing that touches the Live Object Model. Every Live operation in this skill is a call to one of the bridge's MCP tools.
What this skill does
1. `/doctor` runs five prerequisite checks (Live running, extension installed, Node version, bridge port reachable, token present) and prints a PASS or a specific FIX line for each, then one verdict. See doctor.md. It never auto-runs /setup. 2. `/setup` reads the port and bearer token the extension wrote to bridge.json, then emits the correct MCP client config for Claude Code, Claude Desktop, or Cursor. It never invents a port or token. See setup.md. 3. Recipes are reusable snippets for common Live edits, each a named sequence of real bridge tool calls. See recipes/: humanize-midi, build-arrangement, batch-rename, chord-from-prompt.
How the pieces connect
flowchart LR
U["User intent"] --> SK["ableton-live skill"]
SK --> DOC["/doctor: 5 checks"]
SK --> SET["/setup: write client config"]
SK --> REC["recipes: tool sequences"]
DOC -. "reads" .-> BJ["bridge.json"]
SET -. "reads" .-> BJ
REC --> BR["Loophole Bridge (MCP tools)"]
BR --> LIVE["Ableton Live 12 Suite"]
classDef accent fill:#E9A23B,stroke:#9A6A1A,color:#160F02,font-weight:bold;
class BR accentThe skill reads bridge.json (for /doctor and /setup) and issues MCP tool calls (for recipes). It does not reach past the bridge.
The bridge tools the recipes use
The recipes reference only these registered MCP tools. No recipe invents a tool.
| Tool | Read or write | What it does |
|---|---|---|
live_get_song_overview | read | tempo, scale, grid, track and scene counts, track names with ids |
live_find_track | read | resolve a track name or substring to a stable track id |
live_list_clips | read | list a track's session slots (with empties) and arrangement clips, each with an id |
live_get_notes | read | read all MIDI notes from one clip |
live_set_tempo | write | set the Set tempo in BPM |
live_set_track_props | write | set a track's name, mute, solo, or arm in one undo step |
live_set_notes | write | replace all MIDI notes in one clip in one undo step |
live_create_track | write | create one empty MIDI or audio track |
live_create_midi_clip | write | create an empty MIDI clip in a session clip slot |
live_set_param | write | set one device parameter by its id |
live_insert_device | write | insert a built-in Live device on a track |
live_render_track | write | render a track's pre-FX audio over a beat range to a WAV |
The one-undo rule (read before running any recipe)
Each bridge mutation is its own transaction, so each tool call is one undo step. This is per call, not per recipe. A recipe that calls live_set_notes once is one undo. A recipe that renames three tracks calls live_set_track_props three times and is three undo steps. A recipe that creates a clip and then fills it (live_create_midi_clip then live_set_notes) is two undo steps, because the bridge cannot create and populate inside one transaction. Each recipe states its own undo count. Do not promise a whole recipe reverts in a single undo.
Beta limits the recipes inherit
These come from the bridge and extensions, not from the skill, and the recipes state them where they apply:
- MIDI notes only. No automation, MIDI CC, clip gain, or routing API in this beta.
live_create_midi_cliptargets session clip slots, not the Arrangement timeline. There is no Arrangement-write tool in the bridge. For a real Session-to-Arrangement build in one undo, the Session-to-Song extension (a.ablx) does that, not this skill.live_insert_deviceis built-in Live devices only (no third-party or VST).live_render_trackis pre-FX and practical for audio tracks.- Scale and tempo are read from the Set; the recipes do not guess a key. Assume 4/4 unless a scene signature is read.
- User-invoked only.
/doctor
Check every prerequisite for the Loophole Bridge and print exactly what is missing plus the one action that fixes it. Run all five checks, never assume a dependency, and never proceed to /setup on your own. The user runs /setup themselves once /doctor reads ready.
This procedure reads bridge.json and probes the local bridge port. It does not import bridge code and does not talk to Live directly. The only Live read is one MCP tool call in check 4.
Where bridge.json lives
The extension writes bridge.json into its own storageDirectory on first activation. That path is assigned by the Extension Host, so resolve it rather than hardcoding it: ask the user for the storage directory Live reports for the Loophole extension, or check the path the extension logged. The file shape is:
{
"port": 8420,
"token": "<base64url-bearer>",
"transport": "http",
"url": "http://127.0.0.1:8420/mcp"
}The port is one of 8420 to 8429 (the bridge probes that range and binds the first free port). Read port and token from this file; never invent either.
The five checks
| # | Check | How | FIX line on failure |
|---|---|---|---|
| 1 | Live 12.4.5b Suite is running | Confirm an Ableton Live process is up; check 4 (the port responding) is the strong signal | "Open Ableton Live 12 Suite (beta build 12.4.5b)." |
| 2 | The extension is installed and active | bridge.json exists in the extension storageDirectory | "Install the Loophole extension .ablx in Live, Settings, Extensions, then restart Live." |
| 3 | Node >= 24.14.1 | run node --version and compare | "Update Node to >= 24.14.1." |
| 4 | Bridge port reachable | read port from bridge.json, then GET http://127.0.0.1:<port>/mcp with header Authorization: Bearer <token>; expect a valid MCP response, not a connection refusal | "Live is running but the bridge did not answer on <port>. Restart Live, and check that no other app holds the port." |
| 5 | Token present | bridge.json contains a non-empty token | "No token in bridge.json. Reinstall or restart the extension to regenerate it." |
Notes on the checks:
- Check 1 and check 4 reinforce each other. Live's host owns the bridge process, so a port that answers on check 4 is the strongest proof Live is up with the extension active. If check 4 passes, check 1 passes.
- Check 3 floor is Node 24.14.1 (the repo
.nvmrc). Live's own host already satisfies this; the check matters on the client side if a stdio shim is in play. - Check 4 is the one Live touch. It is a single read-only HTTP probe of the bridge's
/mcpendpoint with the bearer token frombridge.json. Treat any 2xx or a well-formed MCP/JSON-RPC response as PASS. A connection refused or a timeout is the FIX case. A 401 means the token inbridge.jsondoes not match what the bridge expects: tell the user to restart the extension so the file and the running bridge agree.
Output format
Print a compact table, one row per check, each marked PASS or FIX with the FIX line inline. Then print a single verdict:
Loophole /doctor
1. Live 12 Suite running ............ PASS
2. Extension installed (bridge.json) PASS
3. Node >= 24.14.1 .................. PASS
4. Bridge port reachable (8420) ..... PASS
5. Token present .................... PASS
Verdict: ready. Run /setup to wire your MCP client.When something fails, show the FIX line on that row and a count in the verdict:
Loophole /doctor
1. Live 12 Suite running ............ PASS
2. Extension installed (bridge.json) FIX: Install the Loophole extension .ablx in Live, Settings, Extensions, then restart Live.
3. Node >= 24.14.1 .................. PASS
4. Bridge port reachable ............ FIX: bridge.json not found, so the port is unknown. Resolve check 2 first.
5. Token present .................... FIX: No token in bridge.json. Reinstall or restart the extension to regenerate it.
Verdict: 3 checks failing. Fix them top to bottom, then re-run /doctor.Fix top to bottom: check 2 (the file) gates checks 4 and 5, since both read bridge.json. Do not run /setup from here. When the verdict reads ready, tell the user they can run /setup.
Recipe: batch rename tracks
Rename several tracks consistently from a rule: add a prefix, apply a naming scheme, or clean up placeholder names. Reads the current names, computes each new name, then applies them one track at a time.
This recipe calls bridge MCP tools only. It does not import bridge code or touch Live directly.
Inputs
pattern, the renaming rule, e.g. "prefix every drum track with DRUM\_", or "Title Case every track name", or "rename Audio 1..4 to Kick, Snare, Hat, Perc".- Optional: a subset filter, if only some tracks should change.
Tool sequence
1. live_get_song_overview to read every track's current name and id in one call. For a subset, live_find_track with { query } resolves a name or substring to matching track ids. 2. Compute each new name from the rule (no tool call). Build the old to new mapping. Skip tracks whose name would not change. 3. For each track that changes, live_set_track_props with { trackId, props: { name: "<new name>" } }. One call per track.
If the change is large, print the old to new mapping and confirm with the user before step 3.
Undo
One undo step per track. Renaming three tracks is three live_set_track_props calls, so three undo steps, one per track. This recipe is not a single undo. If the user wants to revert all of them, they undo once per renamed track.
Notes and limits
live_set_track_propssets name, mute, solo, and arm. This recipe usesnameonly, but you can batch other props in the same call (still one undo per call).- A stale
trackId(the track was deleted or its index shifted) returnsSTALE_REFERENCE; re-runlive_get_song_overviewfor fresh ids. - For content-aware MIDI clip naming, Ableton's own RNMR does that better. This recipe renames tracks, not clip contents.
live_get_song_overviewandlive_find_trackare read-only, so you can preview the full mapping before any write.
Recipe: build arrangement
Sketch a song structure from a Session full of loops: survey what is there, plan a section order, and optionally stage the sections as MIDI clips in Session view.
This recipe calls bridge MCP tools only. It does not import bridge code or touch Live directly.
What the bridge can and cannot do here
The bridge has no Arrangement-write tool. live_create_midi_clip targets Session clip slots, not the Arrangement timeline, and there is no tool that places clips on the Arrangement. So this recipe does two honest things: it plans the arrangement, and it can stage sections in Session view. It does not write the Arrangement timeline.
For the real Session-to-Arrangement build (recreating clips on the Arrangement at the right bars, named, colored, with cue points, in one undo), use the Session-to-Song extension (a .ablx from the Loophole Kit). That runs inside Live with SDK access this skill does not have. This recipe is the lightweight planner around it.
Inputs
- A target structure, e.g. "Intro 8, Verse 16, Chorus 16, Bridge 8, Outro 8".
- Optional: which existing Session clips map to which section.
Tool sequence (plan, read-only)
1. live_get_song_overview. Read tempo, the track list, and the scene count. 2. For the key tracks, live_list_clips with { trackId } to see which Session clips exist and their ids. 3. Propose a section order, referencing clips by id, and describe how each section lays out in bars. Present this to the user. Mutate nothing yet.
Optional: stage sections in Session view (mutating)
If the user wants the sections staged as empty clips to fill (in Session view, not the Arrangement):
4. live_list_clips to find empty session slots (kind: "empty", with slotId). 5. For each section, live_create_midi_clip with { slotId, lengthBeats } (bars times beats per bar; assume 4/4 unless a scene signature is read). 6. Optionally live_set_notes to fill a created clip, and live_set_track_props to name the track.
Undo
Counts per tool call, not per recipe. The plan path (steps 1 to 3) writes nothing, so there is nothing to undo. In the optional staging path, each live_create_midi_clip, each live_set_notes, and each live_set_track_props is its own undo step. Staging five sections is at least five undo steps, more if you fill or rename. This recipe does not revert in a single undo. The single-undo Arrangement build is what the Session-to-Song extension provides.
Notes and limits
- No Arrangement timeline write in this skill. Session view staging plus the planner only. Point the user at the Session-to-Song extension for the Arrangement build.
live_create_midi_clipon an occupied slot returnsSDK_REJECTED; pick an empty slot.- The plan path is fully read-only, so the user can approve the structure before anything is created.
Recipe: chord from prompt
Turn a text request ("warm Fm7 to Bbm7 loop", "four-bar I-V-vi-IV in the Set's key") into MIDI chords written to a clip, staying in the key already set in Live. Reads the Set's scale and tempo, builds the voicings in the model, then writes them.
This recipe calls bridge MCP tools only. It does not import bridge code or touch Live directly.
Inputs
- A chord request in words: the progression, the feel, the length in bars.
- Either an existing MIDI
clipIdto write into, or a target session slot to create one in.
Tool sequence
1. live_get_song_overview. Read scale (root note, scale name, intervals), tempo, and the track list. Use the scale so the chords stay in the key the user already set; do not guess a key. 2. If you need a clip:
live_list_clipswith{ trackId }to find an empty session slot (kind: "empty", with aslotIdliketrack:2/clipslot:4).live_create_midi_clipwith{ slotId, lengthBeats }(bars times beats per bar; assume 4/4 unless a scene signature is read). It returns the newclipId.
3. Build the chord notes in the model (no tool call): pick chord roots from the progression, voice each chord as note pitches within the Set's scale intervals, set each note's startTime and duration from the bar positions, and choose velocities. Keep pitches in 0 to 127. 4. live_set_notes with { clipId, notes }, the full chord array.
Undo
Counts per tool call, not per recipe:
- Writing into an existing clip is one undo step (one
live_set_notes). - Creating a clip and then filling it is two undo steps:
live_create_midi_clipis one,live_set_notesis another. The bridge cannot create and populate a clip in the same transaction, so this is two undos by design.
State the count to the user so they know how many times to undo.
Notes and limits
- The chord voicing logic lives in the model, not in a tool. The tools read the scale and write the notes; you decide the voicings.
live_create_midi_cliptargets session clip slots, not the Arrangement timeline. If the slot is occupied it returnsSDK_REJECTED; pick an empty slot fromlive_list_clips.- Stay within the Set's scale intervals from
live_get_song_overviewto keep chords in key. If no scale is set, ask the user for a key rather than guessing. - MIDI only. No automation or CC in this beta.
Recipe: humanize MIDI
Take a stiff, quantized MIDI clip and nudge it so it feels played: small shifts to note timing, with optional velocity and probability variation. Reads the notes, transforms them in the model, writes the whole array back.
This recipe calls bridge MCP tools only. It does not import bridge code or touch Live directly.
Inputs
clipId, the clip to humanize, e.g.track:2/clipslot:4/clip. Get it fromlive_list_clipsif you only have a track.amount, how far to nudge timing, in beats, e.g.0.02(subtle) to0.08(loose). Stay well under one grid cell so the feel stays musical.- Optional: vary velocity by a few units, and set
probabilityslightly below 1 on some notes for a living pattern.
Tool sequence
1. live_get_notes with { clipId }. Read the current notes (each has pitch, startTime, duration, and optional velocity, probability). 2. Transform the array in the model (no tool call): for each note, shift startTime by a small random amount within plus or minus amount beats, clamped so it never goes below 0. Optionally vary velocity within 1 to 127, and set probability a little below 1 on some notes. Keep the note count and pitches unchanged; move timing, velocity, and probability only. 3. live_set_notes with { clipId, notes }, passing the full transformed array. This replaces every note in the clip.
Undo
One undo step. live_set_notes is a single bridge mutation, so one Ctrl/Cmd-Z reverts the whole humanize.
Notes and limits
- MIDI clips only.
live_set_noteson an audio clip returns aWRONG_TYPEerror; pick a MIDI clip id fromlive_list_clips. - The result is random within the bounds you set: run it twice and you get two different feels, which is the point.
- Timing, velocity, duration, and probability are the only fields in play. No automation, MIDI CC, or audio in this beta.
- The bridge clamps pitch and velocity to 0 to 127 on write, so an out-of-range value is rejected the way Live would reject it.
- Read-only first:
live_get_noteschanges nothing, so you can inspect the clip before deciding whether to write.
/setup
Read the port and bearer token the extension wrote to bridge.json, then write the correct MCP client config for the user's client. This procedure never invents a port or token. If bridge.json is absent, stop and tell the user to run /doctor first.
/setup reads a file and emits a client config. It does not import bridge code and does not talk to Live. The only Live touch is the verify step at the end, which is one read-only bridge tool call the user runs in their client.
Step 1: read bridge.json
Resolve the extension storageDirectory (the path Live reports for the Loophole extension), then read bridge.json:
{
"port": 8420,
"token": "<base64url-bearer>",
"transport": "http",
"url": "http://127.0.0.1:8420/mcp"
}Take port, token, and url straight from this file. The examples below use 8420 and <token-from-bridge.json> as placeholders; substitute the real values you read. If the file is missing, the bridge is not running or the extension is not installed: stop and tell the user to run /doctor, do not guess a port or mint a token.
Step 2: emit the client config
Ask which client the user runs (or detect it from context), then emit only that block.
Claude Code (preferred)
Add the HTTP transport and attach the bearer token as a header:
claude mcp add --transport http loophole http://127.0.0.1:8420/mcp \
--header "Authorization: Bearer <token-from-bridge.json>"
claude mcp list # verify "loophole" is listed--header is the current flag for attaching the Authorization header on an HTTP transport. Confirm it against the installed CLI version (claude mcp add --help) before running, since the flag name can change between releases.
Claude Desktop
Patch the config file, then fully quit and reopen Claude Desktop (closing the window is not enough; the server list is read on launch):
- Windows:
%APPDATA%\Claude\claude_desktop_config.json - macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
{
"mcpServers": {
"loophole": {
"transport": "http",
"url": "http://127.0.0.1:8420/mcp",
"headers": { "Authorization": "Bearer <token-from-bridge.json>" }
}
}
}If mcpServers already exists, add the loophole key alongside the others rather than replacing the object. After saving, quit Claude Desktop completely and reopen it.
Cursor
Write the same mcpServers block to .cursor/mcp.json in the project (or ~/.cursor/mcp.json for all projects):
{
"mcpServers": {
"loophole": {
"transport": "http",
"url": "http://127.0.0.1:8420/mcp",
"headers": { "Authorization": "Bearer <token-from-bridge.json>" }
}
}
}Step 3: verify it worked
Confirm the wiring against the live bridge:
1. Live 12.4.5b Suite is running with the Loophole extension installed (so the bridge answers). If unsure, run /doctor. 2. loophole appears in the client's MCP server or tool list (claude mcp list in Claude Code; the tools panel in Desktop or Cursor after the restart). 3. Run one read-only tool: call live_get_song_overview. It returns the Set tempo and the real track names with ids. If you see your actual track names, the bridge is wired and working.
If the tool list is empty or the call errors, the token is wrong or stale (re-read bridge.json and re-emit the config), or the bridge is not running (/doctor). The token is per install: if the extension regenerated it, the file and the running bridge must agree, so re-read the file after any reinstall or restart.