reaper-mcp-mac
reaper-mcp-mac
An MCP server that lets an AI assistant drive a live REAPER session on macOS — create tracks, write MIDI, add FX, control transport — in real time.
Claude (MCP client) ──stdio──► reaper-mcp-mac (Node/TS) ──file IPC──► Lua bridge inside REAPERNode/TypeScript server + a Lua ReaScript bridge that runs inside REAPER. They talk over file-based IPC (JSON request/response files in a shared folder) — no sockets, no extensions, no LuaSocket. Reliable and dependency-free.
Why this shape
REAPER embeds a native Lua interpreter with the complete ReaScript API, but only inside its own process — Node can't call it directly. So the bridge is Lua (mandatory), and the MCP server is Node (talks to Claude). The two halves exchange atomic JSON files: the server writes request_<id>.json, the Lua defer loop executes it and writes response_<id>.json.
Requirements
macOS, REAPER 7.x (developed against 7.79)
Node.js 18+ (tested on 24)
Install
cd reaper-mcp
npm install
npm run build1. Install the Lua bridge into REAPER
./scripts/install_bridge.shThis copies lua/mcp_bridge.lua to ~/Library/Application Support/REAPER/Scripts/reaper_mcp_bridge.lua and offers to auto-start it on REAPER launch.
2. Start the bridge inside REAPER
If you chose auto-start: restart REAPER.
Otherwise (or right now, without restarting): in REAPER →
Actions→Show action list…→New action…→Load ReaScript…→ selectScripts/reaper_mcp_bridge.lua→ then select it in the list and click Run.
A ReaScript console appears showing [reaper-mcp-mac] bridge started. The bridge then runs quietly via a defer loop until REAPER closes.
3. Verify the round-trip
npm run smokeExpected: a _ping with REAPER's version, the project state, and a track count. If it times out, the bridge isn't running inside REAPER (see step 2).
Use with an MCP client
Point your MCP client at the built server. Example (Claude Desktop claude_desktop_config.json):
{
"mcpServers": {
"reaper": {
"command": "node",
"args": ["/Users/atticus/Documents/code/atticusofsparta/reaper-mcp/dist/index.js"]
}
}
}For Claude Code:
claude mcp add reaper -- node /Users/atticus/Documents/code/atticusofsparta/reaper-mcp/dist/index.jsTools
Tool | Purpose |
| Confirm the bridge is alive; returns REAPER version |
| Tempo, length, play state, track list |
| Set project BPM |
| Save the project |
| Add / remove tracks |
| Track properties (volume in dB) |
| New MIDI item, positioned in beats |
| Insert notes (beats, pitch, velocity, channel) |
| FX chain management |
| Read/write FX parameters |
| play / stop / pause / record |
| Move edit cursor (seconds) |
| Bounce the master to a 24-bit WAV (time selection or whole project) |
| Escape hatch: call any ReaScript function by name |
The escape hatch
reaper_call exposes the entire ReaScript API generically: {"func":"CountTracks","args":[0]}. Pointers returned by the API come back as "handle:N" strings (valid within the session) and can be passed back as args to chain calls. Dedicated tools are preferred where they exist, but this means the server is never blocked on a missing wrapper.
Configuration
REAPER_MCP_BRIDGE_DIR— override the shared IPC folder (must match on both sides).REAPER_MCP_TIMEOUT— per-call timeout in ms (default 15000; raise for very large MIDI inserts).
Layout
lua/mcp_bridge.lua # runs inside REAPER: JSON codec, handle registry, dispatch, defer loop
src/bridge.ts # file-IPC client (serialized calls, atomic writes, stale purge)
src/index.ts # MCP server entry (stdio)
src/tools/ # tool definitions by domain
src/smoke.ts # direct bridge round-trip test
scripts/install_bridge.shLimitations & notes
Handles (
handle:N) are per-session; they reset when REAPER restarts.The bridge services requests at REAPER's defer cadence (~30–60/sec), so batch bulk work (insert many notes in one
reaper_add_midi_notescall) rather than looping single calls.File-based IPC only; a socket transport could be added later for lower latency.
Credit
Architecture (Lua bridge + external server, file IPC, generic dispatch) is informed by the prior Python projects Aavishkar-Kolte/reaper-daw-mcp-server and shiehn/total-reaper-mcp. This is an independent macOS Node/TypeScript implementation.