TwelveTake REAPER MCP
A TwelveTake Studios project.
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to control REAPER DAW for mixing, mastering, MIDI composition, and full music production workflows.
Version: 1.6.0
Why This Server
Workflow Automation, Not Just API Wrappers
Most MCP servers just wrap REAPER's API and call it a day. This one includes production workflow helpers that handle multi-step operations in a single call:
| Tool | What it does for you |
|---|---|
setup_sidechain_compression() | Creates send, routes to channels 3-4, configures ReaComp's detector input — complete sidechain setup in one call |
add_mastering_chain() | Adds ReaEQ → ReaComp → ReaEQ → ReaLimit to master track with proper signal flow |
add_parallel_compression() | Creates a bus track, sets up the send, adds compressor — NY-style compression ready to blend |
create_bus() | Creates a submix track and routes your specified tracks to it |
get_project_summary() | Returns track count, all track names/volumes/pans/FX, markers, regions, tempo, time signature — everything your AI needs in one call |
Zero Configuration
- File-based communication works immediately — no network setup, no ports to configure
- Stock REAPER Lua only — the bridge script has no dependencies, nothing extra to install in REAPER
- Copy the script, run it, connect your AI assistant
176 Tools Covering Real Production Needs
- Full FX control — add/remove plugins, get/set any parameter by index, manage presets, bypass
- FX parameter automation — automate any plugin knob (flanger depth, filter cutoff, etc.)
- Complete routing — sends, receives, sidechain routing to specific channel pairs
- Automation — create envelopes, add/edit points, set automation modes
- MIDI — create items, add notes individually or in batches, edit velocities
- MIDI editing — transpose, quantize with swing, humanize, snap to a scale, stretch, legato, strum, velocity ramps — each targetable by pitch range, beat window, or channel
- Audio items — import, split, duplicate, fade, position, mute
- Markers & regions — create, edit, navigate, render by region
Requirements
- REAPER (any recent version; full live suite green through REAPER 7.77)
- Python 3.8+ (for the MCP server)
- An MCP-compatible AI assistant
Installation
1. Install the Bridge Script in REAPER
The bridge script runs inside REAPER and handles communication with the MCP server.
- Copy
reaper_mcp_bridge.luato your REAPER Scripts folder:- Windows:
%APPDATA%\REAPER\Scripts\ - macOS:
~/Library/Application Support/REAPER/Scripts/ - Linux:
~/.config/REAPER/Scripts/
- Windows:
- In REAPER: Actions → Show action list → Load ReaScript
- Select
reaper_mcp_bridge.luaand click Run
You should see "REAPER MCP Bridge (File-based, Full API) started" in REAPER's console.
2. Install and Configure the MCP Server
The server is published on PyPI as twelvetake-reaper-mcp. The simplest path is to let your
MCP client launch it with uvx (or pipx) — nothing to install by hand.
Add it to your MCP client's configuration (e.g. .mcp.json, or your client's MCP settings):
{
"mcpServers": {
"reaper": {
"command": "uvx",
"args": ["twelvetake-reaper-mcp"]
}
}
}VS Code uses a top-level
serverskey with"type": "stdio"instead ofmcpServers.
To confirm the server starts on its own:
uvx twelvetake-reaper-mcp
# or: pipx run twelvetake-reaper-mcpIt waits quietly for a client to connect — press Ctrl+C to stop.
3. Verify
With REAPER open and the bridge running, ask your assistant "how many tracks are in my project?" — a number back means the server, bridge, and REAPER are all talking.
Run from source (for development)
To work on the server itself, run it from a clone instead of from PyPI. Install the dependencies:
pip install -r requirements.txt # or: pip install mcp httpxPoint your MCP client at the local script:
{
"mcpServers": {
"reaper": {
"command": "python",
"args": ["path/to/reaper_mcp_server.py"]
}
}
}Then check the connection with:
python test_connection.pyNix flake (optional)
If you use Nix, the repo ships a flake-based dev shell that provides Python 3.12 and creates/activates a virtualenv for you:
# Enter the dev shell manually
nix develop
# Or, with direnv, auto-activate on cd:
direnv allowThen install the dependencies as usual:
pip install -r requirements.txtThis pins the Python version and keeps dependencies isolated from your system.
Note: the
x86_64-linuxdev shell is tested and working. The macOS (Darwin) shells are provided but have not been tested — confirmation from a macOS user is welcome.
Communication Modes
The file-based bridge is the supported path — it is reliable and needs no extra setup. HTTP mode is deprecated (see below).
File-Based (Default, Recommended)
Uses JSON files for communication. More reliable, no network configuration needed. This is the only actively maintained path; all tools are guaranteed to work here.
MCP Server REAPER Bridge
│ │
├── writes request_N.json ────►│
│ ├── processes request
│◄── reads response_N.json ────┤Bridge directory: %APPDATA%\REAPER\Scripts\mcp_bridge_data
HTTP Mode (Deprecated)
Deprecated as of v1.2.1. The HTTP bridges (
reaper_web_server.lua/reaper_web_server.py) are kept for existing users but are no longer maintained and will not receive new tools. They may be removed in a future major release (v2.0). Use the file bridge instead.
Uses HTTP requests on localhost. Requires additional setup:
- Lua HTTP bridge: Requires LuaSocket (install via ReaPack → "sockmonkey")
- Python HTTP bridge: Requires Python enabled in REAPER preferences
# Set environment variable to use HTTP mode
REAPER_COMM_MODE=http python reaper_mcp_server.pyDefault port: 9000
Quick Start Examples
Basic Track Operations
"How many tracks are in my project?"
"Create a new track called 'Vocals'"
"Set track 0 volume to -6dB"
"Mute track 2"
"Solo the drums track"Mixing
"Add ReaComp to the bass track"
"Set up sidechain compression from the kick to the bass"
"Create a drum bus and route tracks 0-3 to it"
"Add a mastering chain to the master track"FX and Parameters
"What plugins are on track 0?"
"Get the parameters for the compressor on track 1"
"Set the threshold to -20dB"
"Bypass the EQ on the vocal track"MIDI Composition
"Create a 4-bar MIDI item on track 0"
"Add a C major chord at the start"
"Get all the notes in the MIDI item"
"Set the velocity of note 0 to 100"Transport and Navigation
"Play the project"
"Stop playback"
"Set the cursor to 30 seconds"
"Add a marker called 'Chorus' at the current position"Project Management
"What's the project tempo?"
"Set the tempo to 120 BPM"
"Save the project"
"Render to D:/Output/mix.wav"Tool Reference
Track Operations (23 tools)
| Tool | Description |
|---|---|
get_track_count() | Get total number of tracks (excluding master) |
get_track(index) | Get track info (name, volume, pan, mute, solo) |
get_all_tracks() | Get info for all tracks |
get_master_track() | Get master track info |
insert_track(index, name) | Create a new track |
delete_track(index) | Delete a track |
set_track_name(index, name) | Rename a track |
set_track_volume(index, db) | Set volume in dB |
set_track_pan(index, pan) | Set pan (-1 to 1) |
set_track_mute(index, mute) | Mute/unmute track |
set_track_solo(index, solo) | Solo/unsolo track |
set_track_phase(index, invert) | Invert phase |
set_track_width(index, width) | Set stereo width (0-2) |
set_track_color(index, r, g, b) | Set track color |
get_track_peak(index, channel) | Get current peak level (dB) |
get_track_peak_hold(index, channel) | Get held peak since last reset (dB) |
clear_all_peak_indicators() | Reset peak hold on all tracks |
get_track_master_send(index) | Get master/parent send state |
set_track_master_send(index, enabled) | Enable/disable master send |
set_track_as_folder(index, depth) | Set as folder parent/child |
arm_track(index, arm) | Arm for recording |
set_track_input(index, input) | Set record input |
set_track_monitor(index, mode) | Set monitor mode |
FX Operations (16 tools)
| Tool | Description |
|---|---|
track_fx_get_count(index) | Count FX on track |
track_fx_get_list(index) | List all FX with details |
track_fx_add_by_name(index, name, position?) | Add FX plugin (optionally at position) |
track_fx_move(index, fx_index, new_position) | Reorder FX in the chain |
track_fx_delete(index, fx_index) | Remove FX |
track_fx_get_name(index, fx_index) | Get FX name |
track_fx_get_enabled(index, fx_index) | Check if enabled |
track_fx_set_enabled(index, fx_index, enabled) | Enable/bypass FX |
track_fx_get_num_params(index, fx_index) | Count parameters |
track_fx_get_param_name(index, fx_index, param) | Get parameter name |
track_fx_get_param(index, fx_index, param) | Get parameter value |
track_fx_set_param(index, fx_index, param, value) | Set parameter value |
get_fx_presets(index, fx_index) | List available presets |
get_fx_preset(index, fx_index) | Get current preset |
set_fx_preset(index, fx_index, name) | Load preset |
save_fx_preset(index, fx_index, name) | Save current settings as preset |
ReaEQ Operations (5 tools)
Dedicated ReaEQ band control using REAPER's EQ-specific API, which handles ReaEQ's non-linear parameter curves (dB gain, log frequency, log Q) correctly.
| Tool | Description |
|---|---|
find_eq(track, instantiate?) | Find ReaEQ on a track (optionally add it) |
get_eq_bands(track, fx) | Read all ReaEQ bands with human-readable values |
set_eq_band(track, fx, bandtype, bandidx, paramtype, value, is_normalized?) | Set a band parameter (Hz, dB, or Q) |
get_eq_band_enabled(track, fx, bandtype, bandidx?) | Check whether a band is enabled |
set_eq_band_enabled(track, fx, bandtype, bandidx?, enabled?) | Enable/disable a band |
Take FX Operations (11 tools)
Per-take (per-item) FX, mirroring the track FX tools. Every take is addressed by
(track_index, item_index, take_index).
| Tool | Description |
|---|---|
take_fx_get_count(track, item, take) | Count FX on a take |
take_fx_get_list(track, item, take) | List all take FX with details |
take_fx_add_by_name(track, item, take, name) | Add FX plugin to a take |
take_fx_delete(track, item, take, fx) | Remove FX from a take |
take_fx_get_name(track, item, take, fx) | Get take FX name |
take_fx_get_enabled(track, item, take, fx) | Check if enabled |
take_fx_set_enabled(track, item, take, fx, enabled) | Enable/bypass take FX |
take_fx_get_num_params(track, item, take, fx) | Count parameters |
take_fx_get_param_name(track, item, take, fx, param) | Get parameter name |
take_fx_get_param(track, item, take, fx, param) | Get parameter value |
take_fx_set_param(track, item, take, fx, param, value) | Set parameter value |
T
…