add_markers_batch
Batch add markers/regions.
Args: markers: JSON array. Markers: {"position":0,"name":"Intro"}. Regions: {"start":0,"end":8,"name":"V1","is_region":true}. color optional: [r, g, b], each 0-255.
Drive REAPER from the conversation — write the MIDI, build the FX chains, mix and master to a style, bounce the stems.
LABSCO SUMMARY
Most DAW integrations stop at transport control — play, stop, record. This one opens the production surface: genre-tuned mix and master engines across 35 style profiles, a vocal-chop pipeline, drum and chord shorthand, sidechain and bus recipes, so a track can go from empty project to bounced stems in one conversation. Everything moves through a file-based bridge inside REAPER, which is why nothing is uploaded anywhere — and why REAPER has to be open with that script loaded before a single tool works.
A local bridge into REAPER. The assistant writes the notes, CC curves and arrangement itself and drives the DAW through a file-based Lua script running inside it, so the project, audio and MIDI never leave the machine.
Python 3.10 or newer, and REAPER 7 or newer already open. pip install xdarkzx-reaper-mcp gives you the reaper-mcp command; the repository's install.bat or install.sh does the same and also configures Claude Desktop and sets REAPER to auto-load the bridge. Either way REAPER needs reaper_scripts/reaper_mcp_server.lua running — it is not bundled into the PyPI package, and nothing works without it, because the server reaches REAPER through a file on disk and cannot launch it for you. No account, no key, no network calls. REAPER_MCP_PROFILE narrows the tool surface to composition, mixing, analysis or minimal for models that cap how many tools they accept, and the loudness, clipping and spectrum analysis tools need the optional analysis extra installed.
Follow the published steps — pip install xdarkzx-reaper-mcp
USE CASES
Create the tracks, write the chord progression and drum pattern from shorthand, then set the tempo and loop the section you are working on.
Run the mix engine for the style, add the bus recipes it calls for, then master to that style's loudness target.
Scan the folder for BPM, key and role in the filenames, settle on a common tempo, then load the stems onto tracks.
Run the chop pipeline for the style you want, or drive the primitives yourself — split at transients, pitch, reverse, duplicate.
Point the sidechain at the source and target with an amount, then read the routing back as a diagram to confirm it.
Detect what is installed, pin the preferred EQ and compressor per category, then build the chain from those.
Bounce the tracks to individual stems, or export the whole project to WAV or MP3 with its render metadata set.
Re-run the pipeline as a repair pass that preserves manual tweaks where it can.
Counted once with only startup setup. Other versions, modes or optional credentials may expose a different list.
add_markers_batchBatch add markers/regions.
Args: markers: JSON array. Markers: {"position":0,"name":"Intro"}. Regions: {"start":0,"end":8,"name":"V1","is_region":true}. color optional: [r, g, b], each 0-255.
analyze_chop_setInspect a list of chops and classify each by duration.
Pure-Python helper that calls item_get_info for each index and returns enriched per-chop info plus summary stats. Helps the AI pick which chops to use for which musical role without doing audio content analysis.
Duration classes: hit — < 150 ms (drum hit, consonant burst) staccato — 150-400 ms (short syllable, good for stutters) syllable — 400 ms-1 s (full syllable / word) sustain — > 1 s (phrase / vowel held)
Args: item_indices: JSON array of item indices. Up to 200 chops.
analyze_scoreDump current MIDI data: per-track notes, CCs, timing stats.
Use this to inspect what's in the project before editing, or to verify what you just inserted.
Args: tracks: JSON array of track indices e.g. [0,1,2], or "all". start_time: Start in seconds (default 0). end_time: End in seconds (-1 = project end).
arrange_chops_to_chord_tones[NICHE] Retune each chop to a chord tone.
⚠️ WARNING: This is NOT how professional vocal chops are made. Per-slice chord-tone retuning smears vocal formants and sounds unnatural. chop_pipeline uses uniform transpose instead, which is the correct default for EDM vocal chops.
This tool is kept for stylized experimental use (e.g., glitch / granular / heavily-processed chop effects where the pitched-up- demon-voice sound is the desired character). DO NOT use it as your default chop workflow.
Walks the chops in playback order. For each chop, determines which chord it falls within (based on its time position) and picks a chord tone according to layout. Applies the pitch shift via take_set_pitch.
Args: item_indices: JSON array of chop item indices (in playback order). Typically the chops list returned by item_split_at_transients. chord_progression: Chord names separated by commas, pipes, or dashes-with-spaces. E.g., "Cm7, Fm7, Bb7, Eb" or "Am - F - C - G". beats_per_chord: How many beats each chord lasts. Default 4 (one bar per chord at 4/4). bpm: Project tempo. Pass 0 to fetch from REAPER (extra round-trip). layout: How to pick a chord tone for each chop:
follow — cycle root → 3rd → 5th → root → 3rd → 5thascending — climb chord tones across each chordporter — root → 5th → octave → 5th → root (Porter Robinson)root — every chop = root of current chord source_root: Note name the source vocal is "in". Pitch shifts are computed relative to this. Default "C". If you don't know, leave as C; the result will still be musical relative to the chord changes, just not in absolute key.bounce_stemsRender the given tracks as individual audio stems (in-project).
Selects the tracks, then invokes REAPER's "Render tracks to stereo stem tracks" action (command ID 40892). Resulting stems are added to the project as new tracks.
IMPORTANT SIDE EFFECTS (undocumented by REAPER, confirmed by behavior):
track_set_mute(False) on them after this finishes.Requires REAPER 5.x or newer. For export to audio files on disk, use project_export_audio instead — this tool is for in-project stemming.
Args: track_indices: JSON array of track indices to stem, e.g. "[0,1,2]". output_dir: Reserved (not currently used — in-project stemming). format: Reserved (not currently used).
chop_pipelineEnd-to-end vocal-chop arrangement (redesigned for pro workflow).
Produces a contiguous, key-matched, professionally-structured chop arrangement on a new track. Follows researched EDM vocal-chop rules:
REQUIREMENT for clean pitch: set REAPER's per-item pitch-shift mode to "élastique Pro Soloist Monophonic" (Project Settings → Media Item Defaults, or per-take in Item Properties). Raw pitch shift without formant preservation destroys vocal character. The tool does not auto-set this (requires REAPER user config).
Modes:
slice-preserve (default): slice source at a 1/16 (or 1/8 / 1/32 per style) grid, reorder slices across bars for variation, apply ONE uniform pitch shift to all chops.melody: pick a central vowel offset in the source, write a chord-tone melody across bars (root/3rd/5th of each chord), capped at ±5 semitones from source. Requires chord_progression. Approximates the "one vowel + sampler + MIDI melody" workflow (Flume / Simpler / Quick Sampler).Args: vocal_item_index: Global 0-based index of the vocal item. chord_progression: Chord list (required for melody mode, optional for slice-preserve). E.g. "Fm, Ab, Bb, Fm". bpm: Project tempo. 0 = fetch from REAPER. bars: Length in bars. Default 4, max 32. style: One of future_bass, chillstep, porter, trap, mura_masa, odesza. Drives grid / stutter / layers. target_track_name: Name for the new track. mute_original: Mute the source vocal's track. Default True. source_key: Vocal's original musical key. Accepts Am, A minor, A, Ebm, etc. Default C. target_key: Track key to transpose TO. Empty = use root of first chord in chord_progression, or source_key if no progression given. mode: slice-preserve (default) or melody. See above. seed: Random seed for bar permutations. 0 = nondeterministic.
compose_arrangementBatch-insert MIDI from shorthand or JSON — guarded for small edits only.
Accepts either shorthand notation (e.g. 3|D3:2.5:65 E3:3.0:70|cc1:0-8:35-55) or a JSON tracks array: [{"track_index": N, "notes": [...], "ccs": [...]}].
All note/CC times (shorthand durations, JSON start/end) are RAW SECONDS, not beats or quarter-notes, and are independent of the project's tempo — there is no bpm parameter to set. If you need notes aligned to bars, get the real tempo from project_get_info first and convert yourself (seconds = beats * 60 / bpm). This differs from create_drum_pattern / create_chord_progression, which take quarter-notes and convert using the actual project BPM automatically — don't mix up the two conventions.
Blocked at >2 tracks or >30 total notes to prevent accidental mass inserts — for larger writes, call this repeatedly in smaller chunks, or use the batch MIDI tools directly.
Args: tracks: JSON tracks array or shorthand string. clear_existing: True to wipe target tracks before inserting.
configure_tracksBatch set volume_db, pan, color, mute, solo, name on multiple tracks.
Args: tracks: JSON array. Each: {"track_index":0, "volume_db":-3.0, "pan":-0.5, "color":[200,90,60], ...}. Only track_index required. color is [r, g, b], each 0-255 (not a {"r":..} object, not a hex string).
create_chord_progressionInsert a chord progression as voiced MIDI notes.
Accepts chords separated by commas, pipes, dashes, or newlines: "Cm7, Fm7, Bb7, Eb" or "Am - F - C - G" or "Dm | G | Em | A".
Supported qualities: maj, m/min, dim, dim7, aug, sus2, sus4, 6, m6, 7, m7, maj7, add9, 9, m9, maj9, 11, m11, 13, m13.
base_octave=4 places C as MIDI 60 (middle C). Each chord occupies chord_duration_qn quarter notes (default 4 QN = one bar at 4/4).
Pass item_index=-1 to auto-create a MIDI item positioned in the project at start_qn (e.g. bar 5 in 4/4 = start_qn=16.0). Building a multi-section arrangement on one track? Call this once per section with item_index=-1 each time and increasing start_qn — each call creates its own non-overlapping item at the right place, it does NOT append to a previous item.
Returns the item index, number of chords placed, and any that failed to parse.
create_drum_patternCreate a drum pattern from step-sequencer shorthand.
Each line of pattern is one drum lane. Characters map to GM drums: k=kick, s=snare, h=hi-hat closed, o=hi-hat open, c=crash, r=ride, t=mid tom, l=low tom, i=high tom, p=clap, b=rimshot. . or space = rest. Any unknown character is ignored.
Example — standard 16-step rock beat:
k...k...k...k... ....s.......s... h.h.h.h.h.h.h.h.
Defaults: 16 steps per bar = 1/16-note grid. channel=9 = GM drum channel. Pass item_index=-1 to auto-create a new MIDI item positioned in the project at start_qn (e.g. bar 5 in 4/4 = start_qn=16.0). Building a multi-section arrangement on one track? Call this once per section with item_index=-1 each time and increasing start_qn — each call creates its own non-overlapping item at the right place, it does NOT append to a previous item.
Returns the item index and number of notes inserted.
demo_edm_projectScaffold a minimal EDM test project with 7 tracks, ReaSynth on each, and 8 bars of MIDI.
Use this to verify engine_mix / engine_master / setup_sidechain actually work end-to-end: after this call, you should immediately be able to run:
engine_mix("melodic_dubstep") # applies EQ/comp/reverb/sidechain engine_master("melodic_dubstep") # master chain on master bus transport_play() # hear it
Tracks created: Kick Drum, Snare, Closed Hat, Sub Bass, Pad, Lead Synth, Vocal Chop. Each gets REAPER's stock ReaSynth (always available) + a simple 8-bar pattern.
Args: clean_first: Wipe existing MIDI + markers first (default True). bpm: Project BPM (default 140 — matches melodic_dubstep's half-time feel).
detect_common_bpmGiven a JSON array of file paths, return the most common BPM parsed from their filenames.
Useful after scan_audio_folder when the AI has narrowed down a set of candidate loops and wants to confirm they agree on tempo before setting the project BPM.
Args: file_paths: JSON array of absolute paths.
Returns: detected_bpm: the most common value (int), or None if none found. bpm_votes: full distribution of BPMs across the set. confidence: fraction of files that agreed with the winner. hint: a one-line next-step suggestion.
edit_sectionClear+replace notes/CCs in a time range. For CC-only fixes, use rewrite_cc instead.
Args: tracks: JSON array. Each: {"track_index":0, "notes":[...], "ccs":[...]}. Omit notes/ccs to just clear. Or "all". start_time: Range start in seconds. end_time: Range end in seconds. mode: "all" (default), "ccs_only", or "notes_only". trim_item: Shorten item to start_time (for cutting endings).
engine_fix_mixRescue a muddy / harsh / unbalanced mix with a single call.
Applies corrective EQ per track based on what the track sounds like (bass / vocal / lead / drum / other), classified by name (and by role if style is a known v2 catalog style).
Each track gets:
Plus optional master chain: bus glue comp + brick-wall limiter at -1 dB.
Call this when a mix sounds "stuffy" or "harsh" and you want a quick corrective pass before fine-tuning. Doesn't replace engine_mix — use this to fix something already mixed (poorly) by someone else.
Args: style: Optional v2 catalog style (e.g. melodic_dubstep) for better track classification via aliases. Empty = keyword fallback. include_master: Also apply the emergency master chain (default True).
engine_masterApply a professional mastering chain to the master bus for the given style.
Chain applied (in order): HP 25Hz → bus glue comp → tonal shelf EQ → stereo width → brick-wall limiter. Targets per-style LUFS and true-peak ceiling.
Auto-detects FabFilter Pro-L 2 / Pro-C 2 / Pro-Q 3; falls back to REAPER stock (ReaLimit / ReaComp / ReaEQ).
Supported styles: melodic_dubstep, big_room, future_bass, future_house, deep_house, tech_house, progressive_house, dubstep, trap, drum_and_bass, trance, modern_pop, dance_pop, indie_pop, rnb_pop, alt_rock, classic_rock, pop_rock, hard_rock, punk, post_rock, synthwave, lofi, ambient, hiphop, swing_jazz, jazz_fusion, latin_jazz, classical_chamber, cinematic_trailer, ambient_orchestral, classic_funk, motown_soul, neo_soul, disco_funk (35 total). Any other name falls through to the legacy per-instrument orchestral master chain.
Args: style: Style name from the catalog (required). clean: Remove previously added master FX before applying (default True).
engine_mixOne-click professional mix pipeline. Applies volume staging, pan, EQ, compression, reverb buses, and sidechain.
Two paths depending on the style:
Auto-detects FabFilter (Pro-Q 3, Pro-C 2, Pro-R) or falls back to REAPER stock (ReaEQ, ReaComp, ReaVerbate).
Args: style: Style name. For v2: melodic_dubstep, big_room, future_bass, modern_pop, alt_rock, swing_jazz, classical_chamber, classic_funk, etc. (35 total). Empty, or any name not in the v2 catalog, → legacy per-instrument path. clean: Remove existing mix FX before applying (default True).
envelope_add_pointsBatch-insert automation points into an envelope.
Point shape codes: 0=linear, 1=square, 2=slow start/end, 3=fast start, 4=fast end, 5=bezier. Tension -1 to +1 for curve skew.
Value units:
Args: track_index: Track. points: JSON array of {"time":s, "value":v, "shape":0, "tension":0}. envelope_name: Track envelope name (ignored with FX param). fx_index / param_index: Target FX param envelope (-1 for track env). create: If the envelope doesn't exist yet, create it (default True).
envelope_clear_rangeDelete all envelope points in a time range.
Args: track_index: Track. start_time: Range start in seconds (>= 0). end_time: Range end in seconds (> start_time). envelope_name: Track envelope name. fx_index / param_index: Target FX param envelope (-1 for track env).
envelope_get_pointsRead automation points from a track or FX parameter envelope.
Track envelopes: "Volume", "Pan", "Mute", "Width", "Volume (Pre-FX)", "Pan (Pre-FX)", "Width (Pre-FX)".
For FX param envelopes: pass fx_index and param_index (get these from fx_get_params). envelope_name is ignored when FX param is set.
Args: track_index: Track. envelope_name: Named track envelope (ignored if fx_index+param_index set). fx_index: FX slot index, -1 to target track envelope instead. param_index: FX parameter index, -1 to target track envelope instead. max_results: Cap on returned points (default 2000, prevents context blow-up).
fx_addAdd FX plugin to track. Prefer setup_fx_chain for batch operations.
The name is passed straight to REAPER's TrackFX_AddByName, which resolves it fuzzily. Plugin format cannot be selected: pass the bare name only. The display prefixes from fx_list_installed ("VSTi: ", "VST3i: ") are not format selectors — they are matched as part of the fuzzy string and silently resolve to whichever format REAPER prefers, normally VST3. REAPER's own "vst:"/"vst3:" prefixes and the raw .dll filename both fail outright with FX not found. So when a plugin is installed as both VST2 and VST3, fx_list_installed will list both but only one is reachable here.
Args: track_index: 0-based track index. fx_name: Bare plugin name (e.g. "ReaEQ", "ReaComp", "ARIA Player").
fx_disableBypass an FX plugin.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index.
fx_enableEnable an FX plugin.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index.
fx_get_chainGet FX chain for a track (names, enabled, presets, param counts).
Args: track_index: 0-based track index.
fx_get_instrumentFind VSTi instrument on track. Returns index + params, or -1 if none.
Args: track_index: 0-based track index.
fx_get_paramsGet all parameters of an FX plugin (names, values, formatted display).
Automatically filters out junk params (Internal, MIDI CC, unused FabFilter bands) to keep context size small.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index.
fx_get_presetGet current preset name and count.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index.
fx_list_installedList every FX plugin installed in REAPER, grouped by category.
Uses REAPER's EnumInstalledFX API. Returns:
all_installed: raw list of plugin names — capped at 150 unless full_list=True (power users can have 500+ installed; the best_* picks below already cover the decision the AI actually needs to make, so the raw list is capped by default to avoid dumping the whole catalog into context on every call)best_eq / best_compressor / best_reverb / best_limiter / best_deesser / best_gate / best_saturator / best_multiband / best_stereo: highest-ranked plugin per category that the user hasracks_detected: any rack-style plugins (StudioRack, PatchWork, Lion, Multipass, Snap Heap) — the MCP does NOT configure modules inside racks, so avoid routing auto-mixing through themuser_overrides: current contents of the preferences fileUse this BEFORE running mix pipelines to know what the user has. If the user has premium plugins (FabFilter, Waves, iZotope, Valhalla, Softube, etc.), prefer those over REAPER stock.
Args: category: Optional — filter output to a single category: "eq", "compressor", "limiter", "reverb", "deesser", "gate", "saturator", "multiband", "stereo". Empty returns full inventory. full_list: Return the complete all_installed list uncapped. Only needed if you're hunting for something the built-in category rankings don't cover.
fx_moveMove FX to different position in chain.
Args: track_index: 0-based track index. fx_index: Current FX index. new_index: Target position.
fx_navigate_presetStep to next/previous preset.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index. direction: 1=next, -1=previous.
fx_removeRemove FX from track chain.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index.
fx_renameRename an FX instance's display label (cosmetic — plugin unchanged).
Use to tag FX you've added yourself so later cleanup can find them without affecting other FX on the track. The mix engine uses this internally to prefix all its additions with "[MIX] ".
Args: track_index: 0-based track index. fx_index: FX slot within the chain. new_name: New display name. Max 1000 characters.
Requires REAPER 6.37+ (for TrackFX_SetNamedConfigParm with "renamed_name"). Older REAPER versions will error out cleanly.
fx_set_paramSet FX parameter by index. Prefer setup_fx_chain for batch operations.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index. param_index: 0-based parameter index. value: 0.0-1.0 normalized.
fx_set_param_by_nameSet FX parameter by name (fuzzy match).
Args: track_index: 0-based track index. fx_index: 0-based FX chain index. param_name: Parameter name or partial match. value: 0.0-1.0 normalized.
fx_set_presetLoad preset by name. Returns the resulting preset, not the parameters.
The name must match the plugin's own spelling. Some plugins report names padded to a fixed width (e.g. KORG TRINITY pads to 16 chars), and the padded form is what has to be passed. Take the name from fx_get_preset or fx_navigate_preset rather than from REAPER's presets/*.ini, which stores it trimmed.
If the preset does not actually change, this raises instead of reporting success.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index. preset_name: Preset name, exactly as the plugin reports it. include_params: Also return the plugin's full parameter list. Off by default — on large instruments that runs to tens of thousands of characters. Use fx_get_params when the parameters are what you actually want.
fx_show_uiOpen FX plugin UI window.
Args: track_index: 0-based track index. fx_index: 0-based FX chain index.
get_track_instrumentsList all tracks with detected VSTi names and item counts.
Call this before any composition work so you know which track holds which instrument. Each track's name and VSTi are returned so you can pick the right track index for MIDI insertion.
item_create_midiCreate an empty MIDI item on a track. Returns the item's global index.
Args: track_index: 0-based track index. position: Item start time in seconds (>= 0). length: Item length in seconds (> 0).
item_deleteDelete an item. Prefer items_apply for multiple.
Args: item_index: Item index.
item_duplicateCopy an item N times at fixed spacing.
Each copy is a full clone — same source, same take properties (pitch, playrate, FX, fades). Used for the Porter Robinson 1/16 stutter, EDM build-up risers, percussive vocal repeats.
With default spacing (0), copies are placed back-to-back at the original item's length. For tight stutters, pass a small spacing like 60/bpm/4 for 1/16-note repeats at the project's tempo.
Args: item_index: Global 0-based source item index. count: Number of copies to make. Range 1-100. spacing_sec: Time between copy starts in seconds. 0 = use item length (back-to-back). Default 0.
Returns the new clones with their item_index so the AI can manipulate them (pitch, fade, etc.) directly.
item_get_allGet all media items. Filter by track or -1 for all.
Each item includes source_file (full path) and source_filename (basename only) for audio items — the actual dragged-in media file name, e.g. from a Splice/sample-pack import. Sample vendors commonly embed BPM/key in the filename itself ("Karra_Vocal_Loop_120bpm_Cmin.wav"), which the take's editable name field does not reliably preserve. Both are "" for MIDI items or items with no source.
Args: track_index: Track filter (-1=all). max_results: Max items to return (default 200, hard ceiling 2000). A chop-heavy project can have hundreds of items — narrow with track_index if the result is truncated.
item_get_infoGet detailed info for one item.
Includes source_file/source_filename for audio items — see item_get_all for what these are and why they matter.
Args: item_index: Item index.
item_insert_mediaInsert audio/MIDI file into track.
Args: track_index: Target track index. path: Absolute file path. position: Insert position in seconds.
item_moveMove item to new position. Prefer items_apply for multiple.
Args: item_index: Item index. new_position: New start in seconds.
item_move_to_trackMove item to different track.
Args: item_index: Item index. dest_track_index: Destination track index.
item_selectSelect/deselect an item.
Args: item_index: Item index. selected: True=select. exclusive: Deselect others first.
item_set_fadeSet fade in/out. -1=unchanged. Prefer items_apply for multiple.
Args: item_index: Item index. fade_in: Seconds, 0 or more (-1=keep, max 60s). fade_out: Seconds, 0 or more (-1=keep, max 60s).
item_set_lengthSet item length. Prefer items_apply for multiple.
Args: item_index: Item index. length: Length in seconds.
item_set_muteMute/unmute item. Prefer items_apply for multiple.
Args: item_index: Item index. mute: True=mute.
item_set_volumeSet item volume in dB. Prefer items_apply for multiple.
Args: item_index: Item index. volume_db: dB (0=unity).
item_splitSplit item at position.
Args: item_index: Item index. position: Split point in seconds.
item_split_at_positionsSlice an item at a list of absolute project-time positions.
For grid-based or hand-picked chopping where transient detection isn't right. Pass positions in seconds; positions outside the item's range are silently ignored.
Args: item_index: Global 0-based item index. positions: JSON array of absolute project-time positions (seconds). Example: "[1.5, 2.0, 2.5, 3.0]".
Returns the resulting chops in playback order with their indices, positions, lengths, and offset relative to the original item start.
item_split_at_transientsSlice an audio item at every detected transient.
Uses REAPER's native transient detection (action 40310). Sensitivity is controlled by REAPER's project settings (Options → Preferences → Project → Item handling → Transient detection sensitivity), not by this tool — set it once in REAPER and it applies to every call.
Args: item_index: Global 0-based item index of the source audio item.
Returns: chops_created: number of new items created from the split. chops_total: total items now spanning the original time range. chops: list of {item_index, position, length, offset_in_original_sec} in playback order. The AI uses these indices to repitch / duplicate / reverse individual chops.
item_take_addAdd a new empty take to an item. Returns the new take's index.
Args: item_index: Global item index.
item_take_delete_activeDelete the currently active take from an item.
To delete a non-active take, first call item_take_set_active on it.
Args: item_index: Global item index.
item_take_listList all takes on an item with their active status.
Useful for vocal comping (multiple vocal passes as separate takes on one item) or alternate MIDI performances.
Args: item_index: Global item index.
item_take_set_activeSwitch which take plays back on an item.
Args: item_index: Global item index. take_index: 0-based take index (from item_take_list).
items_applyBatch set position/length/volume_db/mute/fade_in/fade_out, or delete, across many items in one call.
Args: entries: JSON array. Each: {"item_index":0, "volume_db":-3.0, "fade_in":0.05}. Or {"item_index":5, "delete":true}. Only item_index required. Non-delete changes apply first (in the order given); deletes apply last, in descending item_index order, regardless of input order — this avoids a delete shifting the indices of items processed later in the same batch. A bad item_index is recorded in the response's errors array and does not abort the rest of the batch.
load_loopsBatch-load audio loops into REAPER, auto-creating tracks by name.
For each entry in the JSON array, find the named track (or create it if missing) and insert the audio file at the given position. Optionally sets the project BPM first so the loops align with the grid.
Args: loops: JSON array of entries. Each entry is an object with:
Returns a summary with tracks created vs reused, loops loaded, and per-entry errors (missing files, invalid entries) so the AI can recover without blowing up the whole batch.
marker_addAdd marker. Prefer add_markers_batch for multiple.
Args: position: Seconds. name: Label. color_r: Red 0-255. color_g: Green 0-255. color_b: Blue 0-255.
marker_add_regionAdd region. Prefer add_markers_batch for multiple.
Args: start: Start seconds. end: End seconds. name: Label. color_r: Red 0-255. color_g: Green 0-255. color_b: Blue 0-255.
marker_deleteDelete marker/region. Prefer markers_apply for multiple.
Args: marker_index: Index from marker_get_all.
marker_editEdit marker/region. Prefer markers_apply for multiple, or to also edit a region's end/color.
Args: marker_index: Marker index. position: New seconds, must be >= 0, or -1 to keep current position. name: New name (None=keep).
marker_get_allGet all markers and regions. For just the region list plus a cheap project overview, prefer project_get_overview() instead.
marker_go_toMove cursor to marker.
Args: marker_number: 1-based marker number.
markers_applyBatch edit (name/position/start/end/color) or delete markers and regions in one call.
Args: entries: JSON array. Each: {"marker_index":0, "name":"Line 12"}. Region bounds: {"marker_index":5, "start":10.0, "end":14.5}. Point marker position: {"marker_index":2, "position":8.0}. Color: {"marker_index":7, "color":[200,90,60]} (0-255 each). Delete: {"marker_index":9, "delete":true}. Only marker_index required. start/end only apply to regions, position only to point markers — a mismatched field (e.g. start/end on a point marker) is silently ignored, not an error. Non-delete changes apply first (in the order given); deletes apply last, in descending marker_index order, regardless of input order — this avoids a delete shifting the indices of markers processed later in the same batch. A bad marker_index is recorded in the response's errors array and does not abort the rest of the batch.
midi_count_eventsCount notes, CCs, and sysex events in item.
Args: item_index: MIDI item index.
midi_delete_all_notesClear all notes from a MIDI item.
Args: item_index: MIDI item index.
midi_delete_ccDelete a CC event.
Args: item_index: MIDI item index. cc_index: CC event index.
midi_delete_noteDelete a note.
Args: item_index: MIDI item index. note_index: Note index.
midi_get_note_namesGet MIDI note number to name mapping (C4=60, etc.).
midi_get_notesGet notes in a MIDI item (capped at max_results to limit context size).
Args: item_index: MIDI item index. max_results: Max notes to return (default 500, hard ceiling 10000). Use midi_count_events for total count first if unsure.
midi_humanizeAdd random timing + velocity jitter to all notes in a MIDI item.
Makes programmed MIDI feel less mechanical. Typical values:
Args: item_index: Global item index of the MIDI item. timing_ms: Max random shift in milliseconds (each note ±timing_ms). 0 = off. velocity_amount: Max random velocity offset (each note ±amount). 0 = off.
midi_insert_ccInsert single CC event. For whole curves use the ccs array of rewrite_cc or compose_arrangement.
Args: track_index: 0-based track index. item_index: MIDI item index. channel: 0-15. cc_number: 0-127. cc_value: 0-127. position: Seconds.
midi_insert_noteInsert single note into existing item. For composing use compose_arrangement.
Args: item_index: MIDI item index. channel: 0-15. pitch: 0-127 (60=C4). velocity: 1-127. start_position: Start seconds. end_position: End seconds.
midi_insert_notes_batchBatch-insert notes into a MIDI item. Primary tool for writing MIDI.
Args: track_index: 0-based track index. item_index: MIDI item index on that track. notes: JSON array of {"pitch":60, "velocity":100, "start":0.0, "end":0.5, "channel":0}.
midi_insert_program_changeInsert a MIDI Program Change, optionally preceded by Bank Select.
This is how emulations of classic hardware switch sounds. Their program list is often inert through the FX preset selector while Program Change works — check with midi_list_programs which programs a track offers.
Bank Select (CC 0 / CC 32) is written before the Program Change when given, one tick apart so the order cannot be reordered away. Omit both for instruments with a single bank.
Args: track_index: 0-based track index. item_index: MIDI item index. channel: 0-15, 0-based (REAPER's UI shows 1-16). program: 0-127, 0-based (the UI usually shows 1-128). position: Seconds. Place it before the notes it should affect. bank_msb: Optional Bank Select MSB (CC 0), 0-127. bank_lsb: Optional Bank Select LSB (CC 32), 0-127.
midi_list_programsList the MIDI program names a track's instrument exposes.
Returns supplier (the plugin providing the list, null if none) and programs as {program, name} pairs, program numbers 0-based.
Names come back exactly as the plugin reports them, including any fixed-width padding, so they can be passed straight to fx_set_preset — unlike the names in REAPER's presets/*.ini, which are stored trimmed and will be rejected.
Whether a plugin honors a Program Change is a separate question from whether it publishes names here; some publish a full list and still only respond to the preset selector, or the other way round.
Args: track_index: 0-based track index.
midi_quantizeQuantize notes in a MIDI item to a time grid.
Grid math: for 120 BPM, a 16th note = 0.125s, 8th = 0.25s, quarter = 0.5s. At tempo T: grid_sec = (60 / T) * (4 / divisor). For 140 BPM 16ths: (60/140) * (4/16) = 0.107s.
Args: item_index: Global item index of the MIDI item. grid_seconds: Grid spacing in seconds (see above). strength: 0.0 (no quantize) to 1.0 (hard snap). 0.5 = pull halfway.
midi_select_notesSelect/deselect all notes in item.
Args: item_index: MIDI item index. select_all: True=select, False=deselect.
midi_set_item_extentsSet MIDI item boundaries in quarter notes.
Args: item_index: MIDI item index. start_qn: Start in quarter notes. end_qn: End in quarter notes.
midi_set_noteEdit existing note. -1 keeps current value.
Args: item_index: MIDI item index. note_index: Note index in item. pitch: 0-127 (-1=keep). velocity: 1-127 (-1=keep). start_position: Seconds (-1=keep). end_position: Seconds (-1=keep). channel: 0-15 (-1=keep).
midi_sortSort MIDI events by time.
Args: item_index: MIDI item index.
project_backupSave a snapshot copy to path WITHOUT changing this project's active file — unlike project_save_as, your next project_save still targets the original file. Use this before a risky/destructive change (wiping MIDI, deleting tracks, clean=True mix passes) to leave a recoverable copy of what existed beforehand.
Args: path: Absolute .rpp path for the backup copy.
project_export_audioRender project to audio file.
Args: path: Output file path. format: wav, mp3, ogg, flac, or aiff.
project_get_change_countCheap check for whether the project has changed since you last looked.
Returns a monotonically increasing counter that bumps on any edit. Compare against a value you saved earlier to decide whether you need to re-fetch heavier data (track_get_all, item_get_all) instead of blindly re-querying every turn.
project_get_infoGet project info (name, BPM, time sig, tracks, length, markers, render settings).
For post-production work, prefer project_get_overview() instead — one call for this plus the region list, change_count, and a selection summary, versus composing several calls yourself.
path is the recording/media directory (exists even for a brand new, never-saved project). file_path is the actual .rpp project file's path — empty string if this project has never been saved.
project_get_metadataGet project render metadata (title, author, album, comment, etc.).
These are the metadata fields REAPER embeds into rendered files (ID3/BWF/Vorbis/APE tags) and substitutes into render-filename templates ($title, $artist, ...). Reachable in the GUI via the Render dialog's Metadata section.
Note: REAPER's API exposes WHICH fields are set (the tag list), but not their VALUES — values are write-only via GetSetProjectInfo_String (verified on REAPER 7.78). The returned fields_set maps each known logical field to true when any of its tags is present; tags_present gives the raw tag list (e.g. ["ID3:TIT2", "VORBIS:TITLE"]).
project_get_notesGet the project notes/description text.
project_get_notes_infoGet the Title and Author fields of the Project Settings -> Notes tab.
These are the two single-line fields at the top of REAPER's Project Settings -> Notes tab — distinct from both the notes free-text area (project_get_notes / GetSetProjectNotes) and the render metadata (project_get_metadata, which feeds file tags and filename templates).
Unlike render metadata, both fields return their actual stored values (they are not write-only).
project_get_overviewOne cheap call for post-production awareness: counts, region list, change_count, and a selection summary.
Bundles what project_get_info + marker_get_all + project_get_change_count + selection_get_time + selection_get_selected_tracks + selection_get_selected_items would otherwise take 6 separate calls to assemble. The selection summary returns indices and counts only (not full track/item detail) to stay genuinely lightweight — call selection_get_selected_tracks/items directly if you need full detail on what's currently selected.
project_newCreate a new empty REAPER project. Returns the new project info.
project_openOpen .rpp project file.
Args: path: Absolute path to .rpp file.
project_redoRedo last undone action.
project_saveSave the current project. Returns project info confirming the save.
project_save_asSave project to new path. This project's active file becomes path going forward — subsequent project_save calls target it, not the original file. Use project_backup instead if you want a snapshot copy without switching your active file.
Args: path: Absolute .rpp path.
project_set_gridSet grid division (1.0=quarter, 0.5=eighth, 0.25=sixteenth).
Args: grid_division: Grid size in quarter notes.
project_set_metadataSet project render metadata fields. Non-empty fields are written.
Each field is written to every tag format REAPER can embed on render (ID3 for mp3/wav-bwf, VORBIS for flac/ogg, APE for mpc/wv) so the value survives regardless of the render format chosen later. Empty strings are ignored and leave any existing value for that field untouched. Setting a field again overwrites its previous value.
Args: title: Track / project title. author: Artist / author. album: Album name. comment: Free-form comment. genre: Genre. year: Year / date. track_number: Track number. composer: Composer. isrc: ISRC code. copyright: Copyright string.
project_set_notesSet the project notes/description text.
Args: notes: The text to set as project notes (max 100 KB).
project_set_notes_infoSet the Title and Author fields of the Project Settings -> Notes tab.
Non-empty fields are written; empty strings are ignored and leave any existing value untouched. At least one field must be non-empty.
Args: title: Project title (stored via the PROJECT_TITLE descriptor). author: Project author (stored via PROJECT_AUTHOR; this is the same value GetSetProjectAuthor() reads and writes).
project_set_ripple_modeSet REAPER's ripple edit mode.
In ripple mode, editing one item shifts everything after it (per-track or across all tracks). Critical for dialogue/podcast editing.
Args: mode: 0=off, 1=per-track ripple, 2=all-tracks ripple.
project_undoUndo last action.
reset_compositionUnlock compose_arrangement without deleting MIDI. Use wipe_all_midi to also delete.
rewrite_ccReplace CC automation in a time range, leaving notes untouched.
Write curves as explicit CC points — there are no curve templates. For a crescendo, insert a series of points with rising cc_value; the resolution is up to you (e.g. one point every half bar).
Args: tracks: JSON array. Each: {"track_index":0, "ccs":[{"cc_number":1, "cc_value":64, "position":0.0, "channel":0}]}. Or "all". position is in seconds. Entries missing any of cc_number/ cc_value/position are skipped silently, so a malformed array still reports success with ccs_inserted: 0 — check that count rather than the success flag. start_time: Range start in seconds. end_time: Range end in seconds.
scan_audio_folderWalk a folder for audio loops and parse metadata from filenames.
Returns every audio file (.wav, .mp3, .flac, .aif, .aiff, .ogg, .m4a) with BPM, musical key, and role (kick / bass / pad / lead / fx / …) extracted from the filename. Plus a summary of distributions so the AI can quickly decide on a target BPM / key before picking loops.
Args: path: Absolute folder path (e.g., D:/Music Production/Chillstep Express). recursive: Walk subfolders too. Default True. max_files: Stop after this many files. Default 500; max 5000.
Returns a structure with:
Files without parseable metadata are still listed; their fields are null. Pair with transport_set_bpm + load_loops to turn the selection into a working REAPER session.
script_listList ReaScripts (.lua/.eel only) found in REAPER's own Scripts folder.
Never scans anywhere else — this is hard-coded to REAPER's Scripts folder, not a caller-supplied path. Returns each script's path (relative to the Scripts folder — pass this straight to script_run) and description (parsed from an @description/@about header comment if present, empty string otherwise). Capped at 300 results; use filter (case-insensitive substring match against path only — not description) to narrow a larger install.
filter matches path, not description: description requires opening and reading the file, which only happens for scripts that already matched by path. Installs with large community script packs (a few thousand .lua files) would otherwise take minutes to filter. If you can't find a script by keyword, its path may not contain that keyword even though its description does — try a shorter/different substring or browse by folder instead.
Args: filter: Optional case-insensitive substring filter (matches path only).
script_runRun a ReaScript from REAPER's own Scripts folder and optionally read back a result.
script_path must be one of the relative paths script_list returned. Registers the script as a REAPER action if it isn't already (safe to call every time), runs it, then waits up to wait_seconds for the script to report a result via reaper.SetExtState("reaper_mcp_script_result", "last_result", <string>, false). Scripts that don't opt into this convention — including anything that hasn't finished running (e.g. a background/defer-based script) by the time wait_seconds elapses — come back with result_found: false.
This runs arbitrary local script code. Confirm with the user before calling this unless they've already given clear, specific instruction to run this exact script.
Args: script_path: Relative path from script_list, e.g. "MyScripts/foo.lua". wait_seconds: How long to wait for a result, 0-30. Default 5.0.
selection_deselect_all_itemsDeselect all media items.
selection_deselect_all_tracksDeselect all tracks.
selection_get_selected_itemsGet a list of all currently selected media items with their full info.
Just need to know which indices are selected, alongside other project state? project_get_overview() returns indices only (cheaper) as part of a combined read — use this tool instead when you need full detail (position, volume, fades, etc.) on each selected item.
selection_get_selected_tracksGet a list of all currently selected tracks with their full info.
Just need to know which indices are selected, alongside other project state? project_get_overview() returns indices only (cheaper) as part of a combined read — use this tool instead when you need full detail (name, color, volume, etc.) on each selected track.
selection_get_timeGet current time selection. If you also need track/item counts or the region list, project_get_overview() gets all of it in one call.
selection_select_all_itemsSelect all items.
selection_select_all_tracksSelect all tracks.
selection_set_loopSet loop points.
Args: start: Start seconds. end: End seconds.
selection_set_timeSet time selection.
Args: start: Start seconds. end: End seconds.
send_createCreate send between tracks. Prefer setup_routing for batch.
To create a MIDI-only send to a multi-timbral VSTi track, pass midi_source_channel and midi_dest_channel (0=all, 1-16). The send will carry MIDI on the specified channels. Audio on the send can be muted separately via send_set_mute.
Args: source_track: Source track index. dest_track: Destination track index. midi_source_channel: If set, enables MIDI routing. 0=all channels, 1-16=specific. Must be paired with midi_dest_channel. midi_dest_channel: Target channel on the destination track. 0=all, 1-16. Must be paired with midi_source_channel.
send_get_allGet all sends/receives on a track.
Args: track_index: Track index.
send_get_routing_diagramGet full project routing diagram (sends, receives, outputs).
send_removeRemove a send.
Args: track_index: Source track index. send_index: Send index.
send_set_midi_channelSet MIDI source/destination channel on an existing send.
Enables or changes MIDI routing on a track send. Use this to route MIDI from a source track to a specific channel on a multi-timbral VSTi (e.g. ARIA Player, Kontakt multi) on the destination track.
To disable MIDI on the send, set both channels to 31.
Args: track_index: Source track index. send_index: Send index to modify. midi_source_channel: Source MIDI channel. 0=all channels, 1-16=specific, 31=disabled. midi_dest_channel: Destination MIDI channel. 0=all, 1-16=specific, 31=disabled.
send_set_muteMute/unmute send.
Args: track_index: Source track. send_index: Send index. mute: True=mute.
send_set_panSet send pan.
Args: track_index: Source track. send_index: Send index. pan: -1.0 to 1.0.
send_set_volumeSet send volume.
Args: track_index: Source track. send_index: Send index. volume_db: dB (0=unity).
set_fx_preferencesSave user FX preferences — per-category plugin overrides.
Stored at %APPDATA%/reaper_mcp/fx_prefs.json (Windows) or ~/.reaper_mcp/fx_prefs.json (macOS/Linux). Mix pipelines consult this before auto-picking.
Args: preferences: JSON object mapping categories to plugin names, e.g. {"eq": "FabFilter Pro-Q 3", "compressor": "Waves SSL G-Master Buss Compressor", "reverb": "Valhalla VintageVerb", "limiter": "FabFilter Pro-L 2"}
Categories: eq, compressor, limiter, reverb, deesser, gate, saturator, multiband, stereo. Plugin names must match what REAPER reports (check fx_list_installed first).
setup_drum_busGroup drum tracks into a dedicated bus with a glue compressor.
This is a lighter-touch version of parallel compression — the bus is a full sub-mix of the drums, with gentle comp gluing them together rather than crushing them. Use this to control the drum group's overall level and apply shared processing (additional EQ, saturation) above it.
Args: source_tracks: JSON array of drum track indices, e.g. "[0,1,2,3]". bus_name: Display name for the drum bus. return_db: Bus output level (0 = unity, no change vs pre-bus). glue_threshold_db: Glue comp threshold (-10 to -14 typical). glue_ratio: Glue comp ratio (1.5-2.5 for gentle glue).
setup_effect_busCreate effect return bus (track + FX + sends) in one call.
Args: bus_name: Bus track name. fx_chain: JSON array of FX (same format as setup_fx_chain). sends_from: JSON array: [{"source_track":0, "volume_db":-6.0}]. bus_position: Track insert position (-1 = end). bus_volume_db: Bus volume in dB. bus_color: Optional JSON color "[r,g,b]".
setup_fx_chainBatch add/configure FX across tracks. Replaces many fx_add + fx_set_param calls.
Args: tracks: JSON array. Each: {"track_index":0, "fx_chain":[{"name":"ReaEQ", "params":{"Gain":0.5}, "preset":"..."}]}. fx_chain modes: "name" adds new, "fx_index" targets existing, "add_mode":"find_or_add" reuses. Params by name (fuzzy) or params_by_index. Values 0.0-1.0.
setup_parallel_compressionCreate a NY-style parallel compression bus and route source tracks to it.
Classic use: crush drums or vocals with a heavy compressor on a parallel bus, then blend the crushed signal back in subtly with the dry. Adds perceived density and power without destroying transients.
Args: source_tracks: JSON array of track indices to send to the parallel bus, e.g. "[0,1,2]". bus_name: Display name for the created bus track. send_db: Send level from each source to the bus (0 = unity). return_db: Bus output (return) level. -8 is a typical subtle blend. threshold_db: Compressor threshold. -24 to -30 for heavy crush. ratio: Compression ratio. 10:1 or higher for that "smashed" sound. attack_ms: Fast (1-3 ms) for tight pumping. release_ms: Medium (80-120 ms) typical.
setup_routingBatch create sends with optional volume/pan.
Args: sends: JSON array. Each: {"source_track":0, "dest_track":10, "volume_db":-6.0, "pan":0.0}.
setup_sidechainSet up sidechain compression: source pumps/ducks the target.
Creates an aux send from source→target on channels 3/4, sets the target track to 4 channels, finds-or-adds a compressor on the target, pin-maps channels 3/4 to the compressor's sidechain input pins, and configures the compressor for pumping character.
Use cases:
Args: source_track: Track whose signal drives the ducking (e.g. kick). target_track: Track that gets ducked (e.g. pad, bass). amount: 0.0 (subtle) to 1.0 (heavy pumping). Defaults to 0.7. Translates to threshold/ratio if those are not explicit. attack_ms: Comp attack. Fast (2-10ms) = tight pump. Default 5. release_ms: Comp release. 80-250ms for classic EDM pump. Default 180. ratio: Compression ratio. 0 = derive from amount. Typical 4:1 to 10:1. threshold_db: Threshold in dB. 0 = derive from amount. Typical -15 to -30. compressor_name: "ReaComp" (default), "FabFilter Pro-C 2", or any loaded compressor. fx_index: Use an existing FX by index on the target. -1 = find-or-add by name. send_db: Aux send level in dB (drives how hard the compressor reacts). 0 = unity.
Returns: {success, send_index, fx_index, compressor_name, threshold_db, ratio, ...}
setup_vocal_chainOne-call vocal-chain setup: HP + compressor + tonal EQ + plate reverb send.
Creates (or reuses) a dedicated plate reverb bus and sends the vocal track to it. Designed to give a polished broadcast-ready vocal with one call.
Chain applied in order on the vocal track:
hp_freqplate_send_db.Args: track_index: Track to process. hp_freq: High-pass cutoff in Hz. comp_threshold_db / comp_ratio: Compression settings. air_boost_db / mud_cut_db / harsh_cut_db: EQ amounts in dB. plate_bus_name: Bus track name (reused if exists). plate_send_db: Send level from vocal to the plate bus.
stack_chop_layersFor each chop, create overlay copies at parallel pitch intervals.
The classic "future bass / Porter Robinson" harmonized chop stack: each chop becomes a 3-voice cluster — original (root) + 5th (+7) + octave (+12).
Each layer is a clone placed at the EXACT same position as the source on the SAME track, with take_set_pitch applied. This means layers play simultaneously with the original.
Args: item_indices: JSON array of chop indices to stack. Up to 50. intervals_semitones: JSON array of pitch shifts to add. Default "[7, 12]" = perfect 5th + octave (the classic stack). For unison-only set to "[]" (no extra layers).
Note: stacking creates many overlapping items. Best applied to a SUBSET of chops (e.g., the standout chops in your sequence) rather than every chop, or REAPER's mixer will get crowded.
take_set_pitchPitch-shift a take by N semitones (no time change).
The core of "tune a chop to a chord tone". Pass positive values to shift up, negative for down. Range is roughly -60 to +60 (REAPER clamps extremes). Half-semitone values work (0.5, -1.25, etc.) for fine-tuning.
Pitch quality depends on REAPER's per-take pitch shift mode setting (Item Properties → Take pitch shift mode). For vocals, "Élastique Pro Soloist" preserves formants well. Set it once in REAPER's project defaults and it applies to every chop.
Args: item_index: Global 0-based item index. semitones: Pitch shift in semitones. Float. Default 0 (no change). take_index: 0-based take index, or -1 for the active take.
take_set_playrateTime-stretch a take by changing its playrate.
With preserve_pitch=True (default), audio plays slower/faster without changing pitch — useful for fitting a chop to a beat grid. With preserve_pitch=False, this becomes a vinyl-style speed change (faster = higher pitch).
After changing the rate, the item's visible length in the timeline does NOT auto-resize. Call item_set_length afterwards to match.
Args: item_index: Global 0-based item index. rate: Playback rate. 1.0 = normal, 0.5 = half speed, 2.0 = double. Range 0.05 to 16.0. preserve_pitch: Time-stretch without pitch change. Default True.
take_set_reversedReverse an item's audio.
Uses REAPER's "Item: Reverse items as new take" action — the new reversed take becomes the active one, the original take is kept (item now has 2 takes). To revert, switch back to the original take via item_take_set_active.
Useful for: reverse-cymbal-into-downbeat fills, breath-in vocal FX, glitchy chop reversals (Skrillex / Flume style).
Args: item_index: Global 0-based item index.
tempo_add_markerAdd a tempo and/or time-signature marker at a given time.
Args: position: Time in seconds (>= 0). bpm: New BPM at this marker. 0 = inherit from previous. time_sig_num: Numerator (e.g. 3 for 3/4). 0 = inherit. time_sig_denom: Denominator (e.g. 4 for 3/4). 0 = inherit. linear: True = smooth BPM ramp to the NEXT marker; False = instant change.
tempo_clear_allDelete every tempo/time-sig marker — resets the project to its base tempo.
Does NOT change the base BPM itself; use transport_set_bpm for that.
tempo_delete_markerDelete a tempo/time-sig marker by its index (from tempo_list_markers).
Args: index: 0-based marker index.
tempo_list_markersList all tempo + time-signature markers in the project.
Returns each marker's time, measure, beat, BPM, and time signature. Use this to see the project's tempo map before editing.
track_createCreate new track.
Args: index: Insert position (-1 = end). name: Optional track name.
track_deleteDelete a track.
Args: track_index: 0-based track index.
track_freezeFreeze a track to stereo audio (pre-fader render of FX + VSTi).
Uses REAPER action 41223. Freezing bypasses the live FX chain and plays back rendered audio — use when a track's VSTi or FX chain is CPU-heavy and you're done editing that part.
Call track_unfreeze to restore the original FX + MIDI state.
Args: track_index: 0-based track index.
track_get_allGet all tracks with properties (name, volume, pan, mute, solo, FX, items, routing).
Each track includes sample_filenames — the distinct audio file names actually dragged/imported onto that track (Splice, sample packs, etc.), not the track's own display name. Vendors commonly embed BPM/key in the filename itself, e.g. "Karra_Vocal_Loop_120bpm_Cmin.wav". Capped at 20 distinct names per track; empty if the track has no audio items.
track_get_infoGet detailed info for one track.
Includes sample_filenames — see track_get_all for what this is.
Args: track_index: 0-based track index.
track_get_mixer_stateGet mixer state for all tracks (volumes, pans, mutes, solos, sends).
track_get_peakRead instantaneous peak level from a track's meter (L + R channels).
Returns peak in both linear gain (0-1+) and dB (-144 to +12 or so). Only meaningful DURING playback — REAPER's meters only report when audio is passing through. Start playback, wait a moment, then read.
Useful for: checking if a track is clipping, comparing levels between tracks, verifying a mix isn't too hot.
Returns: {peak_l_db, peak_r_db, peak_max_db, peak_l_linear, peak_r_linear}
Args: track_index: 0-based track index.
track_renameRename a track.
Args: track_index: 0-based track index. name: New name.
track_selectSelect/deselect a track.
Args: track_index: 0-based track index. selected: True=select. exclusive: Deselect others first.
track_set_colorSet track color (RGB 0-255). Prefer configure_tracks for batch.
Args: track_index: 0-based track index. r: Red 0-255. g: Green 0-255. b: Blue 0-255.
track_set_folderSet folder state. 0=normal, 1=folder parent, -1=last in folder.
Args: track_index: 0-based track index. folder_depth: Folder depth value.
track_set_inputSet recording input. 0=none, 1-1024=mono, 1024+=stereo, 4096+=MIDI, -1=MIDI all.
Args: track_index: 0-based track index. input_index: Input channel index. Valid values: -1 (MIDI all inputs), or >= 0.
track_set_muteMute/unmute a track.
Args: track_index: 0-based track index. mute: True=mute, False=unmute.
track_set_panSet track pan. Prefer configure_tracks for batch.
Args: track_index: 0-based track index. pan: -1.0 (left) to 1.0 (right).
track_set_record_armArm/disarm track for recording.
Args: track_index: 0-based track index. arm: True=arm, False=disarm.
track_set_soloSolo/unsolo a track.
Args: track_index: 0-based track index. solo: True=solo, False=unsolo.
track_set_volumeSet track volume. Prefer configure_tracks for batch.
Args: track_index: 0-based track index. volume_db: Volume in dB (0=unity, -6=half).
track_template_applyApply a saved template to a track — replaces its FX chain + settings.
Args: name: Template name (from track_template_list). track_index: 0-based target track index.
track_template_deleteDelete a saved track template.
Args: name: Template name to delete.
track_template_listList all saved track templates.
track_template_saveSave a track's full state (FX chain, sends, volume/pan/color, automation) as a named template on disk.
Templates are stored at %APPDATA%/reaper_mcp/track_templates/<name>.template.
Args: track_index: 0-based track index to save. name: Template name (letters/digits/space/-_() only).
track_unfreezeUnfreeze a track, restoring its original FX chain and MIDI state.
Uses REAPER action 41644.
Args: track_index: 0-based track index.
transport_get_stateGet transport state (play/record status, position, BPM, time sig, repeat).
transport_pauseToggle pause.
transport_playStart playback.
transport_recordStart recording.
transport_set_bpmSet project tempo.
Args: bpm: BPM (20-999).
transport_set_playrateSet playback speed.
Args: rate: 0.25-4.0 (1.0=normal).
transport_set_positionSet cursor position.
Args: seconds: Position in seconds.
transport_set_time_signatureSet time signature.
Args: numerator: Beats per measure (1-32). denominator: Beat value (1,2,4,8,16,32).
transport_stopStop playback/recording.
transport_toggle_metronomeToggle metronome.
transport_toggle_repeatToggle repeat/loop mode.
wipe_all_midiWipe all MIDI items and reset composition state. Tracks can compose again after.
Only deletes items whose active take is MIDI — audio items on the same tracks are left untouched. On a full wipe (tracks omitted), also clears all markers and regions.
Args: tracks: JSON array of track indices e.g. "[0,1,2]", or empty for all.
BEFORE YOU INSTALL
173 tools when we connected. The documentation says 182 in some places and 180 in others. The 35 style profiles and 143 device presets are parameter values, not tools.
All 3 documented clients run the server on your machine.
CONTEXT COST
Rated by the size of the 173 tool definitions that ride along on every turn, not by how many there are
INSTALLATION
pip install xdarkzx-reaper-mcpDownload reaper_mcp_server.lua, the bridge script REAPER runs; it is not bundled into the PyPI package:
https://github.com/xDarkzx/Reaper-MCP/raw/main/reaper_scripts/reaper_mcp_server.luaIn REAPER: Actions → Show action list → Load ReaScript... → select reaper_mcp_server.lua → Run
Keep REAPER open with the script running while you use the server. A manual load lasts only for the current session, so re-run it from the action list after each restart, or follow the auto-start setup in the installation guide:
https://github.com/xDarkzx/Reaper-MCP/blob/main/docs/INSTALLATION.md{
"mcpServers": {
"reaper": {
"command": "reaper-mcp"
}
}
}