reaper-mcp
This server lets you control a live REAPER DAW instance from an AI assistant (like Claude), enabling full project manipulation and automation.
Transport Control — Play, stop, pause, record, seek to any position, set tempo (BPM), and retrieve current play state.
Track Management — Add, remove, rename, and list tracks; control volume (dB), pan, mute, solo, and color (RGB).
FX/Plugin Control — Add (VST, VST3, AU, JS), remove, enable/bypass FX on tracks; get and set normalized parameter values.
MIDI — Create empty MIDI items on tracks; add notes with specified pitch, velocity, channel, and timing.
Media Items — Split, move, glue selected, or render selected items in place (destructively applies FX).
Markers & Regions — Add project markers and named regions at specified positions/durations.
View & Navigation — Zoom to selected items, scroll arrange view to a time position, set horizontal zoom level (px/sec).
Project & Rendering — Save project, undo last action, render project (with optional output path override).
Status & Diagnostics — Check REAPER version, resource/project paths, track count, play state, bridge connection, and running processes.
Arbitrary ReaScript Execution — Execute any custom Lua code directly inside REAPER for full access to the reaper.* API, or run any native REAPER action by command ID.
Provides tools for controlling Audacity's transport (play/stop/pause/record), track management (add/remove/rename/list), per-track volume/pan/mute/solo, and render/export via Audacity's mod-script-pipe.
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 add a track named Bass"
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.
dawmcp
A comprehensive MCP for Digital Audio Workstations (DAWs).
It connects Claude to a live, running DAW instance - controlling transport, tracks, FX, and rendering - through a DAW-agnostic tool surface, with a per-DAW adapter behind it.
Architecture
Claude <--stdio--> dawmcp (Rust, rmcp, --daw=reaper|audacity) --> DawBackend trait --> adapter
|
dawmcp-reaper (file IPC --> reaper_bridge.lua --> reaper.* API)
dawmcp-audacity (mod-script-pipe named pipes/FIFOs --> Audacity)dawmcp-core defines DAW-agnostic traits (Transport, Tracks, Fx,
Render, Project, Status) so the same MCP tools work over any DAW that
implements them. DAW-specific concepts that don't generalize (REAPER's
run_reascript escape hatch, Audacity's lack of a persistent FX chain) live
only in that adapter, not in the shared core. dawmcp-server picks which
adapter to serve via --daw=reaper (default) or --daw=audacity; .mcp.json
registers both as separate MCP server entries so Claude can connect to
either (or both) at once.
The REAPER adapter (crates/dawmcp-reaper) talks to REAPER the same way the
original Python implementation did: the server writes one JSON request file
per call into a bridge directory, lua/reaper_bridge.lua picks it up on its
next reaper.defer() tick (REAPER's UI frame rate, ~16-33ms round trip) and
writes a JSON response back - no REAPER extensions required. See
docs/ARCHITECTURE.md for the full design writeup and
why this is file IPC rather than a socket.
The Audacity adapter (crates/dawmcp-audacity) talks to Audacity's built-in
mod-script-pipe module (named pipes on Windows, FIFOs on Linux/Mac) - every
command it sends is verified against Audacity's own source, not assumed.
Audacity must have mod-script-pipe enabled once yourself (Edit > Preferences
Modules) - dawmcp won't flip that on for you, since it's a security-relevant setting Audacity's own docs warn about (any program can then control Audacity with no notification).
Related MCP server: reaper-reapy-mcp
Status
The Rust workspace has full REAPER tool parity with the original Python
implementation, verified against a real running REAPER instance (the Python
package has been removed; git log has its history). The Audacity adapter
covers transport (play/stop/pause/record), track add/remove/rename/list,
per-track volume/pan/mute/solo, and render/export - also verified against a
real Audacity install's process/path discovery on this machine. Not yet
supported for Audacity (by design, not by omission - see
AGENTS.md for why): seeking/tempo/transport-state queries, FX,
and per-track color.
Requirements
Rust (stable toolchain, via
rustup)REAPER (tested on 6.x/7.x) for the REAPER adapter, and/or Audacity (3.x) for the Audacity adapter - use either or both. REAPER needs no extensions. Audacity needs
mod-script-pipeenabled once yourself: Edit > Preferences > Modules > setmod-script-pipeto "Enabled", then restart Audacity.
Setup
Run build.bat (double-click it, or
cargo build --releaseyourself), which buildsdawmcpand installs REAPER's bridge for every detected REAPER install.Point Claude Code (or Claude Desktop) at it -
.mcp.jsonin this repo already registers both:{ "mcpServers": { "reaper": { "command": "<path-to-this-repo>/target/release/dawmcp" }, "audacity": { "command": "<path-to-this-repo>/target/release/dawmcp", "args": ["--daw=audacity"] } } }For REAPER: on every launch,
dawmcpauto-detects and installslua/reaper_bridge.lua(plus the default project and startup hook, see below) into every REAPER install it finds, idempotently, before serving. No separate setup script or manual Actions-list step needed. Pass--no-installto skip this and just serve.If REAPER is already open when
dawmcpfirst installs the startup hook, it won't retroactively start the bridge this session - either fully quit and reopen REAPER, or load it once manually: Actions -> Show action list -> New action -> Load ReaScript..., selectreaper_bridge.lua, then Run it. You should see the small status window appear (see "Status window" below).
Useful standalone commands (no MCP client needed):
dawmcp --status # diagnostics for every detected DAW: installs found? reachable?
dawmcp --install-bridge # install/update the REAPER bridge for every detected REAPER, then exit
dawmcp --daw=audacity # serve Audacity's tools instead of REAPER'sIf a REAPER tool call errors with "bridge heartbeat not found or stale",
the bridge script isn't currently running in REAPER (REAPER was closed, the
script was stopped, or it crashed) - reload/rerun it via the Actions list.
If an Audacity tool call errors with "could not open Audacity's
mod-script-pipe", either Audacity isn't running or mod-script-pipe isn't
enabled (see Requirements above). Call the daw_status tool for
diagnostics either way.
Default project
reaper_project/default.RPP is a blank,
track-less project checked into this repo (generated by REAPER itself, not
hand-authored, so its file format is guaranteed valid). dawmcp copies it
into REAPER's resource path as reaper-mcp-default.RPP and adds a
reaper.Main_openProject(...) call to the same __startup.lua block that
installs the bridge, so REAPER opens this clean project automatically on
every launch instead of whatever it would otherwise default to.
Status window
Once the bridge is running, a small status window appears in REAPER, docked by default (not floating). It shows:
"Status: ON" - the bridge has no on/off toggle; once loaded it runs for as long as REAPER is open, independent of whether this window is open
Green "Active" if a request was processed in the last ~3 seconds, gray "Idle" otherwise, plus a running request count
A quick reference list of available tool domains
Tool overview
DAW-agnostic tools (dawmcp-core's DawBackend trait), backed by whichever
adapter is active (--daw=reaper, the default, or --daw=audacity):
Domain | Tools | Audacity support |
Status |
| yes |
Transport |
| play/stop/pause/record only - no verified seek, tempo, or state query |
Tracks |
| all but |
FX |
| not supported - Audacity has no persistent per-track FX chain like REAPER's |
Render |
| yes, via |
Project |
| yes ( |
REAPER-only tools (no cross-DAW equivalent, exposed via dawmcp-reaper's
inherent methods rather than the shared trait):
Domain | Tools |
MIDI |
|
Items |
|
Markers |
|
View |
|
Actions |
|
Compose |
|
Escape hatch |
|
These REAPER-only tools return a clear error if called against
--daw=audacity instead of silently doing nothing.
Development
cargo build
cargo test --workspaceLicense
Licensed under the MIT License.
Available Tools
40 toolsfx_addA
Add an FX/plugin (VST/VST3/AU/JS by name, e.g. 'ReaEQ' or 'VST3: Pro-Q 3 (FabFilter)') to the end of a track's FX chain. Returns the new fx_index.
Inputs: fx_name (required), track_index (required).
fx_get_paramC
Get a normalized (0.0-1.0) parameter value from a track's FX.
Inputs: fx_index (required), param_index (required), track_index (required).
fx_listB
List all FX on a track's FX chain with their index, name, and enabled state.
Inputs: track_index (required).
fx_removeB
Remove the FX at fx_index from a track's FX chain.
Inputs: fx_index (required), track_index (required).
fx_set_enabledC
Bypass (False) or enable (True) an FX on a track.
Inputs: enabled (required), fx_index (required), track_index (required).
fx_set_paramC
Set a normalized (0.0-1.0) parameter value on a track's FX.
Inputs: value (required), fx_index (required), param_index (required), track_index (required).
install_bridgeA
Copy reaper_bridge.lua into the detected REAPER Scripts folder(s). This does not start it -- REAPER must load it once via its Actions list (or you can set it to run on startup).
Inputs: no named parameters.
item_glue_selectedA
Glue all currently selected media items into one item each (per track).
Inputs: no named parameters.
item_moveB
Move the media item on a track that starts at item_start_sec to new_start_sec.
Inputs: track_index (required), new_start_sec (required), item_start_sec (required).
item_render_in_place_selectedB
Render selected items in place (applies FX/pitch/rate destructively to new item).
Inputs: no named parameters.
item_splitC
Split the media item on a track that starts at item_start_sec, at split_at_sec.
Inputs: track_index (required), split_at_sec (required), item_start_sec (required).
marker_addB
Add a project marker at the given position in seconds.
Inputs: position_sec (required), name.
midi_add_itemA
Create an empty MIDI item on a track spanning start_sec to end_sec. Returns nothing useful yet to reference the item by -- use midi_add_note with the same track/time range, which locates the item itself.
Inputs: end_sec (required), start_sec (required), track_index (required).
midi_add_noteB
Add a MIDI note to the MIDI item on a track that starts at item_start_sec. note_start_sec/note_end_sec are absolute project time in seconds. pitch is 0-127 (60 = middle C), velocity is 1-127.
Inputs: pitch (required), velocity (required), track_index (required), note_end_sec (required), +3 more.
project_saveB
Save the current project.
Inputs: no named parameters.
project_undoA
Undo the last action in REAPER.
Inputs: no named parameters.
reaper_infoA
Get REAPER version, resource path, current project path, track count, and play state.
Inputs: no named parameters.
reaper_statusA
Report REAPER installs found, running REAPER processes (with PIDs), and whether the reaper_bridge.lua socket bridge is reachable. Call this first when diagnosing connection issues.
Inputs: no named parameters.
region_addC
Add a project region spanning start_sec to end_sec.
Inputs: end_sec (required), start_sec (required), name.
render_projectA
Render the project using its current render settings. If output_path is given, it overrides the configured render output file path first.
Note: rendering can take time (up to 60 seconds depending on project length).
Inputs: output_path.
run_reascriptA
Execute arbitrary Lua code inside REAPER's ReaScript environment (full access to the reaper.* API) and return its result as a string. Use this for anything not covered by a dedicated tool -- e.g. advanced routing, item editing, or calling ReaScript functions with no wrapper yet. Be precise: this runs with the same permissions as any ReaScript.
Inputs: code (required).
track_addA
Insert a new track, optionally at a specific 0-based index (default: end of track list) and with a given name.
Inputs: name, index.
track_listA
List all tracks in the current project with name, mute/solo state, volume (dB), and pan.
Inputs: no named parameters.
track_removeC
Delete the track at the given 0-based index.
Inputs: track_index (required).
track_renameB
Rename the track at the given 0-based index.
Inputs: name (required), track_index (required).
track_set_colorA
Set a track's color using 0-255 RGB components.
Inputs: b (required), g (required), r (required), track_index (required).
track_set_muteC
Mute or unmute a track.
Inputs: mute (required), track_index (required).
track_set_panB
Set a track's pan, from -1.0 (full left) to 1.0 (full right).
Inputs: pan (required), track_index (required).
track_set_soloB
Solo or unsolo a track.
Inputs: solo (required), track_index (required).
track_set_volume_dbB
Set a track's volume fader in dB (0 = unity gain).
Inputs: db (required), track_index (required).
transport_get_stateA
Get current play state, cursor position (seconds), and tempo.
Inputs: no named parameters.
transport_pauseB
Pause playback.
Inputs: no named parameters.
transport_playA
Start playback from the current edit cursor position.
Inputs: no named parameters.
transport_recordA
Arm and start recording.
Inputs: no named parameters.
transport_seekC
Move the edit cursor to an absolute position in seconds.
Inputs: position_sec (required).
transport_set_tempoC
Set the project tempo in beats per minute.
Inputs: bpm (required).
transport_stopB
Stop playback/recording.
Inputs: no named parameters.
view_scroll_toA
Scroll the arrange view so the given position (seconds) is visible.
Inputs: position_sec (required).
view_set_arrange_zoomB
Set the arrange view's horizontal zoom level, in pixels per second.
Inputs: pixels_per_sec (required).
view_zoom_to_selectionA
Zoom the arrange view horizontally to fit the currently selected item(s).
Inputs: no named parameters.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 40 tools
Each tool targets a distinct action on a specific resource (e.g., transport_play vs transport_pause, fx_add vs fx_list). Even the two info tools (reaper_info, reaper_status) serve different diagnostic purposes. No ambiguity or overlap exists.
All tools follow a consistent verb_noun or domain_verb_noun pattern with underscores (e.g., track_add, fx_set_param, transport_stop). The only outlier is install_bridge, but it still follows the verb_noun convention. No mixing of styles.
With 40 tools, this server is well beyond the typical 3-15 range for a well-scoped server. While REAPER is a complex DAW, the granularity could be reduced (e.g., combining transport tools into a single tool with actions). The high count makes it heavy for an MCP server.
Core operations for tracks, FX, transport, and items are covered, but notable gaps exist (e.g., deleting markers/regions, editing MIDI notes beyond adding, managing sends/receives). The run_reascript tool partially mitigates this by allowing arbitrary code, but the dedicated tool surface is incomplete.
Maintenance
Related MCP Connectors
Remote MCP server for audio stem separation, denoise, reverb, and MIDI export.
MCP server for Producer/Riffusion AI music generation
Nifty's MCP server — exposes tasks, projects, messages, and files as tools for AI agents.
MCP server for progressive tool usage at any scale (see https://klavis.ai)
Related MCP Servers
- AlicenseBqualityBmaintenanceA Model Context Protocol server that enables AI agents to create fully mixed and mastered tracks in REAPER DAW, supporting project management, MIDI composition, audio recording, and mixing automation.61185MIT
- AlicenseCqualityCmaintenanceEnables AI assistants to control REAPER DAW via the Model Context Protocol, including track, FX, MIDI, and audio operations.4790MIT
- AlicenseCqualityAmaintenanceA comprehensive MCP server that enables AI assistants to control REAPER DAW for mixing, mastering, MIDI composition, and full music production workflows with 130 tools.1872,076 PyPI104MIT
- AlicenseNot gradedqualityDmaintenanceAn MCP server that lets language models interact with the Reaper DAW1MIT