sublevel
Sublevel is an MCP server that lets Claude steer a Live set's low end toward a genre/reference target by measuring, planning, applying, verifying, and undoing changes—plus bass design, reference management, monitoring, mastering checks, and project scaffolding.
Session & targeting:
session,set_target(genre/reference/artist/favorites/file),find_references,add_reference,finishline(acceptance bands from finished records).Measurement & analysis:
measure,compare,readiness(club-floor checks),mastering_check,detect_key,read_notes,find_kicks,find_bass_patches,samples,project_reference.Mix mapping & monitoring:
map_mix,mixmap,monitor(periodic read-only readouts).Planning & guarded writing:
plan,apply(measure/verify/keep-or-revert),iterate(measure-plan-apply loop),verify,automate.Bass design & placement:
design_bass(headless Vital or in-Live search),deliver_patch,write_bassline,place_sample.Project setup:
scaffold,prepare_track(device chains on roles/tracks).Safety & history:
undo,revert_all,ab(A/B bypass),rate,history(change log with verdicts).Job control:
job(poll long-running operations),cancel.
Provides a Max for Live device and panel that runs the same low-end measurement, targeting, fixing, A/B, undo, and change-log workflow inside Ableton Live, with every action going through the same guarded engine as the MCP tools.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@sublevel compare my kick and bass to a Tech House reference and tell me what's missing"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Sublevel
A reference-matching low-end fixer for Ableton Live: an MCP server Claude drives and a Max for Live device on the master, both over one engine, backed by a corpus of 798 analyzed electronic tracks.
Mixing low end without accurate monitoring is guessing. Everything below about 150Hz is inaudible on laptop speakers and misrepresented on consumer headphones. Sublevel replaces the ear with measurement where measurement works, and says how confident it is by placing every number against records you actually listen to.
What makes it trustworthy
There is not a single invented threshold in this repo. A mix is not "thin" because a diff crossed -3dB; it is thin because it sits below p10 of tracks in its own genre. Every claim carries its percentile so it can be checked.
sub vs body: you -3.42dB (p8), reference 3.92dB (p82), -7.34dB.
Kick has punch but no weight underneath it.The corpus is scoped by genre, because the genres genuinely differ - House carries about 2dB less sub relative to kick body than Tech House or Minimal, and that is not a rounding artifact.
Related MCP server: Ableton Cookbook MCP
Status
Built and verified on a real set: measurement core, 798-track corpus with
section-aware finish-line profiles, genre-scoped calibration, the low-end and
club-ready planners, the guarded engine (measure, apply, verify, keep or
revert, with undo and A/B), headless Vital patch design, bassline writing,
the MCP server (36 tools) and the Max for Live panel. ARCHITECTURE.md has
the phase table; 251 tests, including the architecture rules, pass.
Needs you, once, in Live: python -m sublevel install-remote-script, then
select AbletonMCP as a Control Surface (Preferences > Link, Tempo & MIDI;
Input and Output both None) and restart Live.
Setup
python3.13 -m venv .venv
.venv/bin/pip install -e ".[dev]"
.venv/bin/python -m pytestThe MCP server is registered for this project in .mcp.json (python -m sublevel mcp). See ARCHITECTURE.md for the v2 layout and the tool contracts.
The Max for Live device
The same loop from inside Live, without Claude: aim at a genre or a record, measure, fix the low end, A/B, undo, read the changes.
.venv/bin/python -m sublevel m4l build # writes Sublevel.amxd into Live's User Library
.venv/bin/python -m sublevel serve # the HTTP shim the panel talks to, on 127.0.0.1:8766Drop Sublevel.amxd on the master (it passes audio through). The device is
a web view over surfaces/m4l/ui.html; every button is a POST to
/api/<tool> that calls the same function the MCP tool does, so the panel
cannot do anything Claude cannot, and nothing Claude cannot undo. The panel
and the MCP server each hold their own session and share the one Remote
Script socket: run one at a time.
Rebuilding the calibration
python -m sublevel.corpus extract ~/Downloads/beatport_tracks_* --out calibration/corpus.json
python -m sublevel.calibration build calibration/corpus.json
python -m sublevel.calibration show calibration/thresholds.json --genre "Tech House"Extraction is resumable and keyed by content hash, so re-running skips what is already analyzed. 798 tracks takes about 14 minutes on 5 workers.
MCP tools
The agent-facing surface (python -m sublevel mcp). Long operations return
a job id; poll with job.
tool | what it does |
| the open set: tracks, chains, target, budget, bypass state, jobs |
| genre / reference / artist / favorites / file; acceptance bands from the drop of finished records |
| loop-aligned capture; distance and gaps to the target; the club floor |
| which track owns which band |
| pure plan, guarded write, the loop; goals |
| the undo stack, the A/B bypass, what it sounded like, the change log |
| read-only readout every N bars while you play |
| what the master's limiter and compressors are contributing |
| the sample library and preset bank against the target's kick and bass |
| design a bass toward the reference (Vital offline, or a rack in Live in place) and put it on the bass track |
| the key, a clip's notes, a bassline under the kick, clip automation |
| the corpus and the named library |
Sound design
.vital presets are plain JSON with human-named parameters, and pedalboard
renders Vital offline, so the measurement engine doubles as a fitness function:
write a patch, render a note, measure, adjust - about 200 candidates a minute,
entirely headless, with only the winner going into Live. Targeting a real
tech-house bass preset from Vital's init patch converges in ~25 seconds.
Corpus percentiles are deliberately not used here. They describe finished, mastered records; a solo'd bass patch judged against them would produce nonsense with a confident percentile attached.
Safety
Sublevel writes to Live through exactly one path, Engine.apply, and every
write is measured before and after. A move is kept only if the objective
improved without costing kick punch, crest, mono compatibility or headroom;
otherwise it is put back. Every kept and reverted move is appended to
calibration/changes.jsonl with device, parameter, old value, new value, the
reason, the proposal it came from and the verdict. undo, revert_all and
the ab bypass are always available.
Two notes on the Ableton bridge:
The Remote Script Live runs is the upstream ableton-mcp script, patched and vendored at
src/sublevel/live/remote_script/. Upstream binds to0.0.0.0; the vendored copy binds to127.0.0.1.The third-party
abletonMCP server in.mcp.jsonhas telemetry that records the originating prompt and an opt-in dataset upload. It is registered withDISABLE_TELEMETRY=1; consent is yours to give.
What it does not do
It does not judge groove, sound design, arrangement, or whether a record is good. It speaks with confidence about sub, weight, punch, width and dynamics - the parts monitoring problems hide - and reports midrange as context rather than instruction, because most midrange problems are masking and arrangement, where the fix is removing a layer and no analyzer can tell you that.
Notes on the corpus
All 798 tracks are 320kbps MP3. That is transparent in the bottom two octaves,
so sub, punch, dynamics and mono correlation are trustworthy. It is not
transparent at the extremes: codec reconstruction overshoots sample peaks
(every track in this corpus reads above 0dBTP), and everything is lowpassed
around 20kHz. true_peak_db and the high band are marked advisory
wherever they surface, and are never presented as calibrated fact.
Available Tools
36 toolsabC
A/B by ear: bypass=true writes back every kept move's old value (the set as it was); bypass=false puts sublevel's moves back in. The undo stack is untouched.
Inputs: bypass (required). Returns: result
add_referenceA
Ingest a local audio file into the reference library (and optionally tag it as a favourite so set_target(kind="favorites") uses it).
Inputs: path (required), name, favorite. Returns: result
applyA
Write a proposal to Live. With verify (default) it measures before and after and keeps the moves only if the objective improved without costing punch, crest, mono or headroom; otherwise it puts them back. Runs as a job: poll job(job_id). dry_run only runs the policy filter.
Inputs: proposal_id (required), verify, dry_run. Returns: result
automateB
Write automation for one device parameter into a session clip as steps: points = [{"time": beats, "value": v}, ...]. Needs the extended Remote Script.
Inputs: track (required), device (required), points (required), parameter (required), +2 more. Returns: result
cancelB
Stop a running job between steps.
Inputs: job_id (required). Returns: result
compareA
Compare a measurement (default: the latest) with the target: per-axis gaps to the acceptance band, the 20-320Hz curve error per band, and what each gap means in plain words.
Inputs: measurement_id. Returns: result
deliver_patchA
Put a designed Vital candidate into Live: written as an AU preset, loaded
onto the "Sublevel Bass" track (or track) with a 4-beat clip at the root note.
Inputs: candidate_id (required), track. Returns: result
design_bassA
Design a bass patch toward the target's bass profile (or a few words such as "deep round tight"). backend "vital": offline search, then deliver_patch loads it into Live. backend "live": searches the instrument on the "Sublevel Bass" track in place (creating the track with a Drift bass if missing) by writing its macros, firing a clip and recording. Runs as a job.
Inputs: note, brief, steps, passes, +1 more. Returns: result
detect_keyC
The key: from the notes of a clip (the bass track's, or track's) when
there are enough, else from the last capture's audio, else the reference's.
Inputs: slot, track. Returns: result
find_bass_patchesB
Rank the Vital preset bank against the target's bass profile (sub/body, brightness, sustain). Seeds for design_bass.
Inputs: n. Returns: result
find_kicksA
Rank every kick one-shot on the machine against the target's kick profile
(fundamental, decay, click, sub/body); pack narrows to one library. Needs a
target with a profile (a reference, or a genre with the finish line built).
Inputs: n, pack. Returns: result
find_referencesD
Records to aim at. like: nearest neighbours of a named track. character: words such as "heavy sub, tight punch, pumping".
Inputs: n, like, genre, character. Returns: result
finishlineA
What a finished record measures in the drop, for a genre / family / tempo band (default: the current target's scope): acceptance bands per axis, kick and bass profiles, arrangement, pump. From the deep corpus.
Inputs: scope. Returns: result
historyB
The change log for this set: every write with old/new value, reason, proposal id and verdict (kept / reverted / undone / rated).
Inputs: limit. Returns: result
iterateB
The loop: measure, plan, apply, verify, repeat until the goal is met or the policy's round cap. goal: "lowend" or "club_ready". Runs as a job.
Inputs: goal, track, rounds. Returns: result
jobA
Poll a job: status, progress lines after since, and the result when done.
Inputs: job_id (required), since. Returns: result
map_mixA
Work out which track owns each band by pulling each one 12dB down in turn and re-measuring the master from the same bar. Needed before the planner can correct the low-end curve on the tracks that carry it. Live must be playing with the loop brace on. Runs as a job (one capture per track).
Inputs: seconds, only_tracks. Returns: result
mastering_checkA
Bypass the master's limiter / compressors, measure, restore, and say what they contribute: loudness added, crest and punch lost, whether the level is earned by the mix or borrowed from the ceiling. Runs as a job.
Inputs: no named parameters. Returns: result
measureA
Record the mix from the top of the loop and measure it: the low-end axes, dynamics, stereo, resonances, and the club-readiness floor. Live must be playing with the loop brace on. Returns a measurement id for compare().
Inputs: bars, section. Returns: result
mixmapB
The stored mix map for this set: per track, how much of each band it carries.
Inputs: no named parameters. Returns: result
monitorA
A live readout while you play: every interval_bars, capture (without
seeking) and report distance and gaps against the target. Read-only.
action "start" returns a job id whose progress lines are the readout;
"stop" cancels it. windows=0 runs until stopped.
Inputs: action, windows, interval_bars. Returns: result
place_sampleB
Put an audio file into Live: a new audio track (or track) gets a clip
in slot with the sample. Logged like any other change.
Inputs: path (required), slot, track. Returns: result
planA
Plan moves toward the target without touching Live. goal: "lowend" steers the low end into the target's band; "club_ready" fixes whatever the club floor failed (mono, headroom, resonances, loudness, plus the low-end axes). track: force the moves onto one track index instead of the mix map's owner. Returns a proposal id for apply(), the moves, anything refused, and the devices it would need added.
Inputs: goal, track. Returns: result
prepare_trackB
Give a track the chain finished projects put on its role (kick: Saturator, Drum Buss, EQ Eight; bass: Saturator, EQ Eight, Glue; master: Glue, Saturator, EQ Eight, Limiter, Utility). role is read from the track name unless given. Adds only what is missing, in order, at the end of the chain.
Inputs: track (required), role, dry_run. Returns: result
project_referenceB
What finished projects are built like: with no name, the profile across all indexed .als files (what sits on kicks, basses, buses and the master, tempo, length); with a name, that project's tracks and chains.
Inputs: name. Returns: result
rateA
Record what a kept proposal sounded like: verdict "good" or "bad", with an optional note. Goes into the change log next to the numbers.
Inputs: verdict (required), proposal_id (required), note. Returns: result
readinessB
The club floor on a measurement (default: latest): seven pass/fail checks plus the DJ-mixer boost test, each with its consequence and the fix.
Inputs: measurement_id. Returns: result
read_notesD
The notes of a MIDI clip.
Inputs: track (required), slot. Returns: result
revert_allC
Put every parameter sublevel changed in this session back.
Inputs: no named parameters. Returns: result
samplesA
What the sample index holds: one-shots per kind, and the packs the kicks
come from. Build or refresh it with python -m sublevel samples index.
Inputs: no named parameters. Returns: result
scaffoldA
Set an empty project up like a finished one: tempo, KICK / BASS / DRUMS / PERC / SYNTHS / VOCALS / FX tracks with the device chains finished projects put on each role, two returns, and the master chain (Glue, Saturator, EQ Eight, Limiter, Utility). dry_run lists it; dry_run=false builds it. Groups have to be made by hand afterwards - the Remote Script cannot create them.
Inputs: dry_run. Returns: result
sessionA
What sublevel knows about the open Live set: tracks and their device chains, the current target, budget spent, whether sublevel's moves are bypassed, open proposals and running jobs. Call this first.
Inputs: no named parameters. Returns: result
set_targetB
Choose what the mix is steered toward.
kind: "genre" (value = genre name, or blank for the session's best guess), "reference" (value = a record name from the library or corpus, e.g. "Eating Glue"), "artist" (value = artist name; median of their corpus tracks), "favorites" (median of references tagged favourite), "file" (value = path). Returns the target's acceptance ranges (p25-p75) per axis and any warning that the chosen record is an outlier for its genre.
Inputs: kind, genre, value. Returns: result
undoB
Undo the last n kept proposals (most recent first).
Inputs: n. Returns: result
verifyA
Re-measure now and compare with the baseline taken before the first apply.
Inputs: no named parameters. Returns: result
write_basslineA
A bassline that sits under the kick: root from the reference's bass (or the
key, or root as a MIDI pitch), kick grid from a drum clip or the last capture.
style: sub_hold, rolling_offbeat, follow_kick, two_note. dry_run shows the
piano roll; dry_run=false writes it to slot slot of the bass track (created
if missing) or track, replacing what is there.
Inputs: bars, root, slot, style, +2 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 36 tools
Tools are grouped into clear functional clusters—reference, measurement, mixing moves, and job control—and most have distinct resource-action purposes. The measurement family (measure/compare/verify/monitor) and revert family (undo/revert_all/ab) could be confused, but their scopes are different enough that a careful agent should select correctly.
Most actions use an imperative verb_target pattern and information tools are named as plain nouns (session, history, samples, mixmap), which is a consistent semantic convention. A few bare verbs or abbreviations like ab, job, and rate break the pattern slightly, but the all-snake_case style keeps it predictable.
At 36 tools, this is well beyond the 25-tool 'too many' threshold, making the surface heavy even for a broad DAW-assistant domain. Several tools could be consolidated into grouped subcommands—especially the measurement, reference, and job-related tools—without losing clarity.
The set covers the full workflow: references and target selection, measurement and comparison, planning/apply/iterate, undo and history, plus creative helpers like bassline writing, patch design, and project scaffolding. Minor gaps like reference-library removal/editing exist, but core workflows are complete with no dead ends.
Related MCP Connectors
Pay-per-query x402 business intelligence on Base, settled in USDC via the native 402 payment flow.
On-chain security and market intelligence for trading agents on Base.
Base token safety: one-call verdict, risk score, rug check, holders, momentum. x402 + free demo.
Base token risk (honeypot sim), prices, balances, Basenames, tx data. Pay-per-call in USDC via x402.
Related MCP Servers
- AlicenseNot gradedqualityBmaintenanceEnables AI-assisted electronic music production in Ableton Live, with built-in genre theory for indie dance, tech house, melodic techno, and house music.8GPL 3.0
- AlicenseNot gradedqualityDmaintenanceBridges AI assistants with Ableton Live, enabling real-time control, offline project analysis, version tracking, and rack/preset parsing for music production workflows.MIT
- AlicenseBqualityDmaintenanceEnables AI-powered music production in Ableton Live through natural language, with tools for composition, arrangement, mixing, and sound design.52MIT
- AlicenseAqualityBmaintenanceStyle-aware auto-mixing and mastering for Ableton Live, providing tools for analysis, preview rendering, and release checks.1048 PyPI3MIT