reaper-mcp
The reaper-mcp server provides comprehensive control over the REAPER DAW via an MCP interface, exposing tools (all prefixed with reaper_) that enable an LLM or any MCP client to:
Project & Transport: Get project info (name, length, tempo, cursor position, transport state, track count); set tempo; play, stop, pause, and record; move the edit cursor; set/clear time selections; enable/disable looped playback; render the project to disk using last-used render settings.
Track Management: List, create, rename, and delete tracks; get/set volume (dB), pan, mute, solo, and arm state; set record input; set automation mode (trim/read/touch/write/latch/etc.).
Master Track: Get/set master track volume and pan.
FX / Plugin Management: List installed FX plugins (VST2/VST3/CLAP/JS/AU) with filtering; add/remove FX on tracks; enable or bypass FX; list/set FX parameters by index or name; list and switch FX presets.
Automation: Add envelope points for track volume, pan, or any FX parameter with configurable interpolation shapes (linear, bezier, square, etc.); clear envelopes.
MIDI & Media Items: List media/MIDI items on a track; insert empty MIDI items; add individual MIDI notes (pitch, velocity, channel, timing); delete media/MIDI items; insert existing audio/MIDI files from disk.
Routing: List, add, remove, and set volume on track sends.
Markers & Regions: List, add, and delete markers and regions; navigate the edit cursor to a marker.
Mix Analysis: Analyze a rendered or quick-exported audio file for DSP metrics (LUFS, loudness range, peak, crest factor, clipping, per-band EQ balance, stereo width/correlation); optionally get AI-powered feedback via Gemini with reference track comparison.
Escape Hatch: Execute any REAPER action by numeric command ID for functionality not explicitly wrapped as a dedicated tool.
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., "@reaper-mcp list my installed synths"
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.
reaper-mcp
An MCP server that gives Claude Code (or any MCP client) full control of Reaper.
Claude can:
List every VST/VST3/CLAP/JS/AU plugin you have scanned
Add plugins to tracks, set parameters, and pick presets
Move volume faders, pan, mute, solo (track and master)
Write automation envelopes (track volume/pan or any FX parameter)
Set up track sends / routing
Create/rename/delete tracks; create/delete media & MIDI items and write MIDI notes (one at a time or a whole part in one batch call)
Insert existing media files — audio samples/loops or
.midclips — onto a track from diskAdd markers and regions; set the time selection and toggle looping
Arm tracks and drive the transport (play / stop / record)
Render the project using the last-used render settings
Trigger any Reaper action by command ID (escape hatch)
All 55 tools are namespaced with a reaper_ prefix (e.g. reaper_create_track) so they
don't collide with other MCP servers. Read tools accept a response_format argument
(markdown for humans, json for machines).
How it works
Claude Code ──stdio──▶ reaper-mcp server ──TCP 127.0.0.1:8765──▶ Reaper bridge ReaScript
(MCP) (this package) (runs inside Reaper)The bridge is a Python ReaScript that lives inside Reaper. It opens a non-blocking
TCP listener and polls it from reaper.defer so the DAW UI never freezes.
Every mutation is wrapped in Undo_BeginBlock / Undo_EndBlock, so anything Claude does
is a single undo step.
Related MCP server: reaper-mcp-server
Prerequisites
Reaper installed (default location:
C:\Program Files\REAPER (x64)\)Python ReaScript enabled in Reaper. Open Options → Preferences → Plug-ins → ReaScript and point "Custom path to Python dll" at your Python install (e.g.
C:\Users\<you>\AppData\Local\Programs\Python\Python311\). Restart Reaper. The page should sayPython loaded successfully.Python 3.10+ on your host machine for the MCP server itself.
Install
cd "C:\Users\tommy\Desktop\CODING STUFF\reaper-mcp"
py -m venv .venv
.\.venv\Scripts\Activate.ps1
pip install -e .Launch the bridge inside Reaper
Copy
reaper_scripts\reaper_mcp_bridge.pyinto%APPDATA%\REAPER\Scripts\.In Reaper: Actions → Show action list → ReaScript: Load → pick the file → Run.
You should see
[reaper-mcp] bridge listening on 127.0.0.1:8765in the ReaScript console.
Optional: in the action list, right-click the loaded action and "Add to toolbar", so you can start the bridge with one click. To make it auto-start with Reaper, install SWS Extension and use SWS: Set startup action.
Wire it up to Claude Code
Add to your Claude Code MCP config (%APPDATA%\Claude\claude_desktop_config.json for Claude Desktop, or ~/.claude.json / project settings for Claude Code):
{
"mcpServers": {
"reaper": {
"command": "C:\\Users\\tommy\\Desktop\\CODING STUFF\\reaper-mcp\\.venv\\Scripts\\python.exe",
"args": ["-m", "reaper_mcp.server"]
}
}
}Restart Claude Code. Verify with the reaper_ping tool — it should return Reaper's version.
Try it
Ask Claude things like:
"List every synth I have installed." →
reaper_list_installed_fxfiltered to instruments"Make a new track called 'Bass', drop Serum on it, and switch to the first preset." →
reaper_create_track→reaper_add_fx_to_track→reaper_list_fx_presets→reaper_set_fx_preset"Automate the volume of track 1 to fade in over the first 4 seconds." →
reaper_add_envelope_point× 2"Send track 2 to a reverb bus and pull the send down 6 dB." →
reaper_add_send→reaper_set_send_volume_db"Drop a 2-bar MIDI clip on track 3 and write a C major chord." →
reaper_insert_midi_item→reaper_add_midi_notes(all 3 notes in one call)"Mark the chorus at 32 seconds." →
reaper_add_marker"Arm track 1 and start recording." →
reaper_set_track_record_arm→reaper_transport_record
Configuration
Env var | Default | Effect |
|
| Where the MCP server looks for the bridge |
|
| Bridge TCP port (set on both sides if you change it) |
Troubleshooting
could not reach Reaper bridge— the bridge script isn't running. Re-load it via the action list. Check Reaper's ReaScript console for errors.Python ReaScript not loadedin Reaper — point Preferences → Plug-ins → ReaScript at a Python install of the same bitness (Python 3.x x64 for Reaper x64) and restart.could not add FX 'X' (not found?)— callreaper_list_installed_fxand copy the exact name (including theVST3:/VST3i:prefix). Reaper matches by exact suffix.Preset name doesn't match — some plugins expose presets as
.fxpfiles in%APPDATA%\REAPER\presets\vst-<plugin>\. Callreaper_list_fx_presetsto see what Reaper actually sees.Automation doesn't seem to do anything — set the track to
readmode:reaper_set_track_automation_mode(idx, "read").
Adding new capabilities
To add a tool:
Write an
h_<method>handler inreaper_scripts/reaper_mcp_bridge.pyand register it inHANDLERS.Add a
@mcp.tool(name="reaper_<verb_noun>", annotations={...})wrapper inreaper_mcp/server.pythat calls_call("<method>", ...). Validate inputs withAnnotated[type, Field(...)]andEnumtypes, give read tools aresponse_formatargument, and let failures raise (do not return an error dict —_callraises so FastMCP reports it as anisErrorresult).Re-load the bridge script in Reaper (Actions list → ReaScript: Load) and restart the MCP server in Claude Code.
The method-name string is the contract between the two files and must match exactly on both sides.
Evaluations
evaluations/reaper_eval.xml holds read-only eval questions (mcp-builder Phase 4) for checking that an
LLM can drive the server. See evaluations/README.md for how to run them and verify answers against a
live project.
Available Tools
53 toolsreaper_add_envelope_pointA
Insert one automation point on a track volume/pan or FX-parameter envelope.
Tip: if the envelope can't be obtained, set the track to read mode first
via reaper_set_track_automation_mode(track_index, 'read').
Inputs: track_index (required), target (required), time_sec (required), value (required), +4 more.
reaper_add_fx_to_trackA
Add an FX to the end of a track's chain.
Returns {track_index, fx_index, name}. If the plugin can't be found the
call fails — re-check the exact string via reaper_list_installed_fx.
Inputs: track_index (required), fx_name (required), show_ui.
reaper_add_markerA
Add a project marker at a time. Returns {id, is_region, position_sec}.
Inputs: position_sec (required), name.
reaper_add_midi_noteB
Insert a single MIDI note into an existing MIDI item on a track.
Inputs: track_index (required), item_index (required), pitch (required), start_sec (required), +3 more.
reaper_add_regionA
Add a project region spanning [start, end] seconds. Returns {id, is_region, position_sec}.
Inputs: start_sec (required), end_sec (required), name.
reaper_add_sendA
Create a send from one track to another. Returns the new send's index.
Inputs: src_track_index (required), dest_track_index (required).
reaper_analyze_mixARead-onlyIdempotent
Analyze a rendered mix: local DSP measurements + AI listening feedback.
Two layers. Local DSP (numpy/pyloudnorm) measures the trustworthy numbers — integrated LUFS, loudness range, sample peak, crest factor, clipped samples, per-band frequency balance, and stereo correlation/width/balance. Then (unless include_ai=false) Gemini is given BOTH the audio file and those measurements and returns grounded mix/master feedback with concrete REAPER fixes.
Requires the optional deps: pip install -e .[analyze], and GEMINI_API_KEY in the
environment for the AI layer. Pass a reference_path to compare against a pro track.
This reads files and calls an external API; it never modifies the Reaper project.
Inputs: audio_path (required), focus, reference_path, include_ai, +2 more. Returns: result
reaper_analyze_projectAIdempotent
One-call mix check: quick-export the master mix, then analyze it.
This is the convenient path — no need to pre-configure the render dialog or pass a file. It tells Reaper to render the master mix to a temp file (reusing your project's render codec, e.g. WAV), measures it with local DSP (LUFS, peak, crest, per-band balance, stereo width), then — unless include_ai=false — uploads a small compressed proxy plus those measurements to Gemini for grounded feedback.
Requires the optional deps (pip install -e .[analyze]) and GEMINI_API_KEY for the
AI layer. For best results set the project's render source to 'Master mix' and format
to a single audio file. Writes a temp render but does not modify the project.
Inputs: focus, reference_path, bounds, include_ai, +2 more. Returns: result
reaper_clear_envelopeADestructiveIdempotent
Delete every point on an envelope. Same target semantics as reaper_add_envelope_point.
Inputs: track_index (required), target (required), fx_index, param.
reaper_clear_time_selectionAIdempotent
Clear the project time selection.
Inputs: no named parameters.
reaper_create_trackA
Insert a new track. Returns the new track's state including its assigned index.
Inputs: name, position.
reaper_delete_itemADestructive
Delete a media/MIDI item from a track. Later item indices shift down by one.
Inputs: track_index (required), item_index (required).
reaper_delete_markerADestructiveIdempotent
Delete a project marker or region by its id.
Inputs: marker_id (required), is_region.
reaper_delete_trackADestructive
Delete the track at the given index. This is destructive and shifts later indices down by one.
Inputs: track_index (required).
reaper_get_master_trackARead-onlyIdempotent
Return the master track's volume (dB), pan, mute state, and FX count.
Inputs: response_format. Returns: result
reaper_get_project_infoARead-onlyIdempotent
Return the current project's name, length, tempo, cursor position, transport state, and track count.
Returns a dict: {name, length_sec, tempo_bpm, cursor_sec, playing, paused, recording, track_count}.
Inputs: response_format. Returns: result
reaper_get_track_stateARead-onlyIdempotent
Return name, volume (dB), pan, mute/solo/arm, and FX count for a single track.
Inputs: track_index (required), response_format. Returns: result
reaper_goto_markerAIdempotent
Move the edit cursor to a marker by its id.
Inputs: marker_id (required).
reaper_insert_midi_itemA
Create an empty MIDI item on a track spanning [start, end] seconds.
Returns {item_index, position_sec, length_sec}. Add notes with
reaper_add_midi_note.
Inputs: track_index (required), start_sec (required), end_sec (required).
reaper_list_fx_paramsARead-onlyIdempotent
List an FX's parameters with current value, min, and max.
Returns a list of {index, name, value, min, max}. Parameter values are
plugin-native (often normalised 0..1) — read min/max before setting.
Inputs: track_index (required), fx_index (required), response_format. Returns: result
reaper_list_fx_presetsARead-onlyIdempotent
List every preset available for an FX instance, plus the current selection.
Returns {count, current_index, presets:[{index, name}]}.
Inputs: track_index (required), fx_index (required), response_format. Returns: result
reaper_list_installed_fxARead-onlyIdempotent
List every FX plugin Reaper has scanned (VST2/VST3/CLAP/JS).
Reads Reaper's own scan-cache files directly (no bridge round-trip). Use
this to find the exact fx_name string to pass to reaper_add_fx_to_track.
Each item: name (pass this to add_fx, e.g. "VST3i: Serum (Xfer Records)"),
kind (VST/VSTi/VST3/VST3i/CLAP/CLAPi/JS), is_instrument (bool), filename.
Result is paginated. The response wraps the page in
{total, count, offset, has_more, next_offset, items}.
Inputs: name_filter, instruments_only, limit, offset, +1 more. Returns: result
reaper_list_itemsARead-onlyIdempotent
List the media/MIDI items on a track.
Each entry: {index, position_sec, length_sec, muted, take_name}. Item
index is 0-based within the track and is what the item tools expect.
Inputs: track_index (required), response_format. Returns: result
reaper_list_markersARead-onlyIdempotent
List all project markers and regions.
Each entry: {index, is_region, position_sec, region_end_sec, name, id}.
id is the marker/region's displayed number — pass it to delete/goto tools.
Known limitation: name may come back empty even when a marker has a name.
REAPER's Python ReaScript build does not marshal the name out-parameter of
EnumProjectMarkers, so names set via reaper_add_marker/reaper_add_region show
in Reaper's UI but can't be read back here. Identify markers by position/id.
Inputs: response_format. Returns: result
reaper_list_sendsARead-onlyIdempotent
List the sends originating from a track.
Each entry: {send_index, dest_track_index, dest_track_name, volume_db, pan, muted}.
Inputs: track_index (required), response_format. Returns: result
reaper_list_track_fxARead-onlyIdempotent
List FX on a track with each FX's index, name, current preset, enabled state, and param count.
FX index is 0-based within the track's chain and is what the other FX
tools expect.
Inputs: track_index (required), response_format. Returns: result
reaper_list_tracksARead-onlyIdempotent
List all tracks with index, name, volume (dB), pan, mute/solo/arm state, and FX count.
Track index is 0-based and is the value every other track tool expects.
Inputs: response_format. Returns: result
reaper_pingARead-onlyIdempotent
Check that the Reaper bridge is alive and report Reaper's version.
Call this first when anything fails — a clean response confirms both the MCP server and the in-Reaper bridge script are running and reachable.
Returns: {pong: bool, reaper_version: str}.
Inputs: response_format. Returns: result
reaper_remove_fxADestructive
Remove an FX from a track's chain. Indices of later FX shift down by one.
Inputs: track_index (required), fx_index (required).
reaper_remove_sendADestructive
Remove a send from a track. Later send indices shift down by one.
Inputs: track_index (required), send_index (required).
reaper_rename_trackAIdempotent
Rename a track. Returns the updated track state.
Inputs: track_index (required), name (required).
reaper_render_projectA
Render the project to disk using Reaper's most recent render settings.
This reuses whatever output path, bounds, and format were last configured in Reaper's Render dialog — set those up once manually first. Writes a file but does not modify the project.
Inputs: no named parameters.
reaper_run_actionADestructive
Trigger any Reaper action by numeric command ID (Main_OnCommand).
The escape hatch for actions not yet wrapped as dedicated tools. Look up IDs in Reaper's Actions list (right-click an action → Copy selected action command ID). Marked destructive because arbitrary actions can do anything.
Inputs: command_id (required).
reaper_set_cursorAIdempotent
Move the edit cursor to a time in seconds. Returns the resulting cursor position.
Inputs: time_sec (required), move_view.
reaper_set_fx_enabledAIdempotent
Enable or bypass an FX (enabled=False bypasses it without removing it).
Inputs: track_index (required), fx_index (required), enabled (required).
reaper_set_fx_paramAIdempotent
Set an FX parameter by index or name. Returns {param_index, value, min, max}.
Inputs: track_index (required), fx_index (required), param (required), value (required).
reaper_set_fx_presetAIdempotent
Switch an FX to a preset by name or by index.
Provide exactly one of preset_name or preset_index. Use
reaper_list_fx_presets to discover valid values.
Inputs: track_index (required), fx_index (required), preset_name, preset_index.
reaper_set_loop_enabledAIdempotent
Enable or disable looped playback (repeat over the time selection).
Inputs: enabled (required).
reaper_set_master_volume_dbAIdempotent
Set the master track's volume fader in dB.
Inputs: db (required).
reaper_set_send_volume_dbAIdempotent
Set the level of a track send in dB.
Inputs: track_index (required), send_index (required), db (required).
reaper_set_tempoAIdempotent
Set the project tempo in BPM. Returns the resulting tempo.
Inputs: bpm (required).
reaper_set_time_selectionAIdempotent
Set the project time selection (the loop/render range) to [start, end] seconds.
Inputs: start_sec (required), end_sec (required).
reaper_set_track_automation_modeAIdempotent
Set a track's automation mode (trim/read/touch/write/latch/latch_preview).
Set to 'read' for written envelopes to play back.
Inputs: track_index (required), mode (required).
reaper_set_track_muteAIdempotent
Mute or unmute a track. Returns the updated track state.
Inputs: track_index (required), mute (required).
reaper_set_track_panAIdempotent
Set a track's pan. Returns the updated track state.
Inputs: track_index (required), pan (required).
reaper_set_track_record_armAIdempotent
Arm or disarm a track for recording. Returns the updated track state.
Inputs: track_index (required), armed (required).
reaper_set_track_record_inputAIdempotent
Set a track's record input (audio channel or encoded MIDI input).
Inputs: track_index (required), input (required).
reaper_set_track_soloAIdempotent
Solo or un-solo a track. Returns the updated track state.
Inputs: track_index (required), solo (required).
reaper_set_track_volume_dbAIdempotent
Set a track's volume fader in dB. Returns the updated track state.
Inputs: track_index (required), db (required).
reaper_transport_pauseAIdempotent
Pause the transport, keeping the cursor where it is.
Inputs: no named parameters.
reaper_transport_playAIdempotent
Start playback from the edit cursor.
Inputs: no named parameters.
reaper_transport_recordA
Start recording on all armed tracks.
Inputs: no named parameters.
reaper_transport_stopAIdempotent
Stop the transport.
If Reaper is recording, the call is refused unless force=true — this
avoids ending a take without the user's go-ahead. Ask the user first, then
retry with force=true.
Inputs: force.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 53 tools
Each tool has a clear, distinct purpose. Even similar tools like reaper_add_marker and reaper_add_region are differentiated by region spanning a range. Descriptions provide enough detail to avoid confusion.
All tools follow the verb_noun pattern with 'reaper_' prefix. Naming is perfectly consistent across the entire set.
53 tools is high but justified for a DAW control server covering many aspects (tracks, FX, sends, automation, transport, etc.). It's slightly above the ideal range but still well-scoped without redundancy.
Covers most core DAW operations: track management, FX, sends, automation, MIDI, markers, transport, analysis, render. Minor gaps like item editing (split, move) or detailed MIDI editing are missing but not critical for basic workflows.
Related MCP Connectors
Remote MCP server for audio stem separation, denoise, reverb, and MIDI export.
MCP server for Producer/Riffusion AI music generation
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Shared memory MCP server for Claude Code, Codex, Gemini CLI and Cursor. Cited, editable.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that exposes REAPER digital audio workstation functionality through a clean API interface, enabling programmatic control of 169+ REAPER operations across track management, MIDI editing, effects, automation and more.88MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets language models interact with the Reaper DAW1MIT
- FlicenseNot gradedqualityDmaintenanceMCP server for controlling Renoise via OSC. Lets Claude compose music by writing patterns, triggering notes, and controlling playback.4-
- AlicenseBqualityDmaintenanceThis MCP server enables AI assistants to control a live REAPER DAW instance, including transport, tracks, FX, MIDI, media, markers, rendering, and project state, with an escape hatch for arbitrary ReaScript commands.40MIT