Skip to main content
Glama

Hibiki

Hibiki is the agent inside your music editor, built for professionals. Talk to it about what you're working on, let it edit, arrange and mix alongside you, and bring the AI agents you already use. It runs in REAPER today.

Path

What

reaper_mcp/

MCP server (server.py stdio, http_server.py bearer HTTP) + bridge.lua, the Lua bridge that runs inside REAPER

panel/

Hibiki — chat panel docked in REAPER (ReaImGui) for Gamut, Codex and other ACP agents

reaper/__startup.lua

Starts the bridge and the chat panel whenever REAPER launches

gateway/

Agent gateway: one local API for the panel in front of Gamut and ACP agents (Codex, …)

scripts/

Remote-host bootstrap (Cloudflare Tunnel) and hot-swap deploy of the bridge — see docs/remote-host.md

ci

MCP client  --stdio JSON-RPC-->  reaper_mcp/server.py  --JSON mailbox-->  reaper_mcp/bridge.lua (inside REAPER)

Fourteen grouped tools. Multi-step edits go through batch; anything else through reaper_call / run_lua. Track index -1 is the master. Time is project quarter notes. Call status first; on a new project pass detail=true for arrangement facts (time signature, length in beats, markers, MIDI vs audio) — not chords. midi cc is CC and program change; item import takes a path on the REAPER host; project save writes without a dialog (pass path if the project is unsaved). midi get omits default fields; batch slots are the inner result or {error}.

Just want the MCP? For Claude Desktop, Claude Code or Cursor with no panel, no gateway and no background services, see MCP only.

Install (macOS)

  1. REAPER first. Download it from reaper.fm, drag it to Applications and open it once. The package (and hibiki setup) refuses to install on a Mac without REAPER.

  2. Hibiki. Download Hibiki-<version>.pkg from Releases and open it. The package brings its own Python, so it doesn't need the Xcode command line tools. To upgrade, install a newer package.

  3. Restart REAPER. The Hibiki panel opens docked on the right; click the agent name at its top to pick a provider and model.

  4. Connect an agent — Gamut or a CLI agent: see Connect an agent.

The package isn't signed yet. If macOS says it can't verify the developer, open System Settings → Privacy & Security and click Open Anyway.

What it sets up for the logged-in user (hibiki setup runs the same steps; safe to re-run):

Piece

Where

Lua bridge, Hibiki panel

<REAPER resource path>/Scripts/reaper_mcp_bridge.lua, Scripts/Hibiki/

ReaImGui (if missing, pinned + sha256-checked), and its imgui.lua shim

<REAPER resource path>/UserPlugins/, Scripts/ReaTeam Extensions/API/

Startup hook: starts both with REAPER

a marked block in Scripts/__startup.lua; your own lines stay

MCP over HTTP on 127.0.0.1:8787 (bearer in ~/.config/reaper-mcp/token, 0600)

LaunchAgent com.hibiki.reaper-mcp

Agent gateway on 127.0.0.1:47892

LaunchAgent com.hibiki.agent-gateway

MCP registration

Gamut (as REAPER), plus Claude Desktop, Claude Code and Cursor when they're installed

hibiki doctor                         # what's installed, what's running, what's wrong
hibiki recover                        # restart the MCP + gateway, drop stuck panel streams (REAPER untouched)
hibiki connect gamut|claude-desktop|claude-code|cursor [--remove]
hibiki agents add codex claude kimi   # ACP agents for the panel (Node goes in ~/.local/node)
hibiki watchdog on|off                # relaunch REAPER after crashes, for an unattended Mac
hibiki stop                           # turn the background services off; they stay off after login
hibiki start                          # turn them back on (setup does too)
hibiki update                         # newer release on GitHub? (--channel stable|dev, --json; dev builds default to dev)
hibiki update --install               # download it, verify its sha256, open the installer (you finish it); source clones: git pull
hibiki uninstall [--purge]            # --purge also deletes tokens and gateway config
hibiki use dev [--path ~/reaper-mcp]  # testing unreleased code: run everything from a git checkout (no admin)
hibiki use release                    # back to the installed package
hibiki use [status] [--json]          # which one is live: release version, or checkout path @ commit

hibiki use dev records the checkout in ~/.config/reaper-mcp/mode.json and runs the checkout's setup with the package's Python, so the LaunchAgents, the bridge and the panel come from the checkout; every hibiki command (including the panel's Recover and update) then runs the checkout's code. Restart REAPER to load the new bridge and panel. hibiki update --install refuses in dev mode, and installing a package switches back to release.

From a clone instead (the LaunchAgents then run from the clone, so keep it; re-run after git pull):

git clone https://github.com/yiw190/hibiki.git ~/hibiki
sh ~/hibiki/install.sh                # WITH_AGENTS=1 also adds Codex, Claude Code and Kimi

Related MCP server: reaper-reapy-mcp

Install (Windows)

Release candidate: tested in CI on Windows Server, not yet on a desktop REAPER. Windows 10 1803+ (64-bit).

  1. REAPER first. Download the 64-bit installer from reaper.fm, install it and open REAPER once. The installer (and hibiki setup) refuses to install on a PC without REAPER.

  2. Hibiki. Download Hibiki-<version>-setup.exe from Releases and run it. It installs for your Windows user only (%LOCALAPPDATA%\Programs\Hibiki, no administrator rights), brings its own Python and adds hibiki to your PATH. To upgrade, run a newer installer; to remove, use Settings → Apps.

  3. Restart REAPER. Same as on macOS: the panel opens docked on the right.

  4. Connect an agent — see Connect an agent.

The installer isn't signed yet: if SmartScreen stops it, click More info → Run anyway.

Differences from macOS: the REAPER resource path is %APPDATA%\REAPER; instead of LaunchAgents one background supervisor (hibiki run, windowless) keeps the MCP and the gateway running, started at logon from HKCU\...\CurrentVersion\Run; logs are in %LOCALAPPDATA%\Hibiki\logs; Open in Claude Code / Kimi opens a cmd window; the watchdog is macOS only. From a clone: py -m reaper_mcp setup (Python 3.9+).

Connect an agent (step 4)

The panel talks to an agent; Hibiki doesn't ship one. Pick either route — or both, they show up side by side in the panel's Agent settings → Provider.

Route A — Gamut (desktop app, agents with skills, dashboards, connected accounts):

  1. Download Gamut — macOS (Apple Silicon) · Windows · all releases (source, gamut.so).

  2. Open it and sign in with your Gamut account. Gamut sets up its own agent containers and models; your own API keys (Anthropic, OpenRouter, Bedrock, OpenAI) are optional.

  3. Create an agent.

  4. In the Hibiki panel pick Gamut and the agent under Agent details. Gamut gives MCP servers to agents one by one, so the panel offers Enable REAPER for until that agent has it (one click; it also registers the MCP in Gamut if setup ran before Gamut was installed). From a terminal instead: hibiki connect gamut --agent "<name>" (or --all-agents, or no flag to pick from a list).

Route B — a coding-agent CLI (each uses its own login / subscription): click Install next to it on the panel's "Connect an agent" card or in Agent settings → Provider — it installs Node and the CLI into ~/.local/node (no admin rights) and loads it without a restart — then Connect to log in once. The REAPER MCP is wired in automatically.

Agent

Package

Login

Claude Code

@agentclientprotocol/claude-agent-acp

your Claude login

Codex

@agentclientprotocol/codex-acp

ChatGPT / OpenAI

Kimi

@moonshot-ai/kimi-code

kimi.ai or kimi.com (one button each)

MiniMax

@minimax-ai/code

global or mainland account (one button each)

Grok

@xai-official/grok

browser sign-in; SuperGrok or X Premium+ (beta)

Gemini

@google/gemini-cli

Google sign-in in the browser; Google AI Pro / Ultra

Copilot

@github/copilot

copilot login (device code) in Terminal; Copilot Pro / Pro+

Same from a terminal: hibiki agents add claude kimi minimax grok gemini copilot codex. Not one-click yet: Qwen Code (ACP only offers an OpenAI-compatible API key set through environment variables) and DeepSeek (its harness's ACP server is automation-only; DeepSeek models work through an ACP agent such as OpenCode with an API key).

MCP only

On macOS or Windows, from a clone:

git clone https://github.com/yiw190/hibiki.git ~/hibiki
sh ~/hibiki/install.sh --mcp-only     # Windows: python -m reaper_mcp setup --mcp-only

What it does:

  • Installs the bridge and a startup hook that starts it with REAPER.

  • Registers the MCP in Claude Desktop, Claude Code and Cursor, if they're installed.

  • Nothing else: no panel, no background services, no token.

Keep the cloned folder: those apps run reaper_mcp/server.py from it. Check the install with hibiki doctor --mcp-only.

Gamut needs the full install instead: it reaches REAPER through the background HTTP service, which this mode leaves out.

For other MCP clients or operating systems, see the next section.

Manual setup (any MCP client, any OS)

python3 -m reaper_mcp install-bridge

Then in REAPER: Actions → Load ReaScript → reaper_mcp_bridge.lua → Run. It starts silently (no console window); hibiki doctor shows the bridge version and heartbeat. Set REAPER_MCP_DEBUG=1 to log to the ReaScript console.

MCP client config (any client that runs stdio servers):

{
  "mcpServers": {
    "reaper": {
      "command": "python3",
      "args": ["/absolute/path/to/hibiki/reaper_mcp/server.py"]
    }
  }
}

On Windows use native Python, not WSL (they don't share the mailbox).

REAPER_MCP_IPC_DIR     mailbox override (must match on both sides)
REAPER_MCP_TIMEOUT     default 10s
REAPER_MCP_DEBUG=1     Lua request log

Mailbox: ~/Library/Application Support/reaper-mcp/ipc on macOS, %APPDATA%/reaper-mcp/ipc on Windows, $XDG_DATA_HOME/reaper-mcp/ipc on Linux. Time is beats. Indices are 0-based.

Hibiki panel (macOS, Windows)

Needs ReaImGui ≥ 0.10 and an agent: Gamut or one of the CLI agents (see Connect an agent). The panel talks to the agent gateway on 127.0.0.1:47892; for Gamut it uses the desktop app's local REST + SSE API (127.0.0.1:47891), the same one Gamut's own UI uses.

The installer puts it in place. By hand: 1. Copy panel/Hibiki.lua, panel/context.lua, panel/markdown.lua and panel/studio.lua to <REAPER resource path>/Scripts/Hibiki/ (and panel/Hibiki_Meter.jsfx to <REAPER resource path>/Effects/Hibiki/), then Actions → Load ReaScript and run Hibiki.lua. 2. Optional: run panel/restart_apply.sh while REAPER is open and quit REAPER — it docks the panel on the right, binds Cmd+L to toggle it, and relaunches REAPER.

What it does: the header shows the agent and the model in effect (Gamut, Claude Code, Kimi, …); click it for Agent settings, a Routing-style window with the provider, the Gamut agent, model / effort / mode, the context switch and the live REAPER selections; the clock lists recent chats, + starts one. For Claude Code and Kimi, Open in … reopens the chat in the agent's own CLI in Terminal. Replies stream with a markdown renderer; tool calls collapse into one line per run. Every message carries a [REAPER context] block: project, tempo, cursor and nearby markers, then each selection kind — time selection, razor areas, tracks, items, MIDI notes, envelope, FX — with how long ago it was set and, for time/razor ranges, the chord markers and what plays there. Pills above the input show the same selections, newest first. Enter sends, Shift+Enter is a newline. Drag to select message text and Cmd+C to copy. Attach files with + File or by dropping them on the panel: they're uploaded to the agent (Gamut's upload-file; for ACP agents the gateway stores them and sends images as image blocks) and listed in the message as [Attached files:] (for Gamut, whose copies live in the agent's container, followed by the files' paths on the REAPER host, which item import needs). A Gamut agent's questions, secrets, script runs and approvals are answered in the panel; connecting an account or MCP server, uploading a requested file, a browser step or computer use opens that chat in Gamut (superagent://agent/<slug>/sessions/<id>). Scrolling follows Gamut's own follow engine. Chinese/Japanese IME: ReaImGui passes keys to both the IME and ImGui, so the panel undoes ImGui's half of Backspace / arrows / Esc / Enter while a composition is open and shows the pending pinyin under the input.

Gamut's local API has no auth in desktop mode and listens on all interfaces. Block port 47891 in the macOS firewall if the Mac is on a network you don't trust.

Around the chat (panel/studio.lua)

  • Version history. After every agent reply that changed the project, a copy of it (saved or not; Main_SaveProjectEx to another path leaves the open project's path and dirty state alone) goes to <project folder>/.hibiki/history/<name>/<stamp>.RPP.gz with a line in index.jsonl: about 40 KB each, no media, the newest 200 kept. Each version is titled with the reply's own first sentence; hover lists what changed. The bridge knows what changed because it runs every request that can change the project in one undo block labelled Hibiki <reply>: <what changed> and lists the changes in ExtState Hibiki/receipts; for run_lua and raw API calls it diffs the project before and after (tracks, volume, pan, mute, FX added / removed / bypassed / offline, items, lanes, sends, tempo), and a first-line -- comment titles the script. Agent settings → Version history: Current (with Save version when it isn't in the history yet), then the 10 newest versions with the time to the second and Go to, which saves Current as a version first, then makes this tab that version.

  • Measure playback. Hibiki_Meter.jsfx sits on the master's monitoring FX (never rendered) and writes a frame every 100 ms of playback to gmem Hibiki: LUFS-M/S (BS.1770 K-weighting), 4× oversampled true peak, sample peak, correlation, side vs mid and eight mid bands. The next message's context gets the last playback: bars, gated LUFS-I, the loudest LUFS-S and true peak with their bar.beat, correlation minimum, band levels and a per-bar LUFS-M / true-peak row. Switch it in Agent settings → Context → Measure playback.

  • Audition rack. An agent offers audible alternatives (sounds, parts, effects; not levels) preferably as fixed lanes of one track tagged P_EXT:hibiki_lanes = "<group>" (one lane playing, lane names as labels), or by tagging tracks P_EXT:hibiki_var = "<group>/<n>" (one unmuted) or FX on one track with P_EXT:hibiki_fxvar lines "<group>/<n>\t<fx GUID>" (one enabled). The panel shows a row of numbered buttons per group above the input with the playing variant's name. Click or press 1–9 (panel focused) to switch (no undo point); when stopped, a click also loops the time selection, which the agent sets to the section where the variants differ, so a click is a listen. Hover = the loudness each variant measured while it played. Keep n deletes the other variants and their tags in one undo step.

  • Ears. With a time selection or razor area, Ears renders it from the master (≤ 30 s, 24-bit WAV in the panel's private folder, your render settings restored afterwards), reads REAPER's LUFS-I / LUFS-S max / true peak, runs hibiki ears (stdlib spectrum: 1/3-octave mid and side, tilt, bands over/under the tilt, stereo, level over time → .png + .md) and attaches the picture, the summary and the audio to your next message.

  • Agent rules. /remember <rule> saves a line to your rules.md (/remember off: <id> switches a convention off). Agent settings → Context → Agent rules shows N defaults (M off) · K yours; Edit opens defaults.md and rules.md. See Rules for agents.

Rules for agents

Every agent gets one text: Hibiki conventions from your defaults.md followed by your rules from rules.md, both in ~/.config/hibiki/brain/ (HIBIKI_BRAIN overrides the folder; the same path on Windows, under your profile).

  • defaults.md starts as a copy of the shipped brain/defaults.md (general know-how such as one DLSMusicDevice per project, never rendering onto an existing file), made by hibiki setup or the first read. It is yours: rewrite or delete any rule. Rules are bullets with a stable id, - [single-dls] ....

  • On every install or upgrade, hibiki setup merges the new shipped file in per id: a rule you left untouched gets the new text, one you edited keeps your wording, one you deleted stays deleted, a new id is added at the end; lines without an id are never touched (brain/.defaults-state.json remembers what was last shipped). hibiki rules reset <id> (or --all) brings the shipped text back.

  • rules.md is free text, one rule per line (/remember <rule> in the panel adds one). It also understands off: <id> (leave a default out) and [<id>] <text> (replace its text), but editing defaults.md is simpler. <!-- comments --> are not sent.

  • Delivered two ways: the MCP server appends the composed text to its initialize instructions (read at every session start, so edits apply to the next chat without a restart; Gamut agents and any MCP client see it), and the gateway writes it into AGENTS.md, CLAUDE.md and GEMINI.md in the ACP agents' working folder (a marked block; your own text in those files stays) before each new chat. Capped at 12,000 characters.

  • hibiki rules prints what agents get, hibiki rules --path the rules.md path, hibiki rules edit [defaults|mine] opens both files (or one), hibiki rules off <id> / on <id> toggle a default from rules.md. The panel's Agent rules → Edit opens both files.

Start with REAPER

The installer merges reaper/__startup.lua into <REAPER resource path>/Scripts/__startup.lua as a marked block. It starts the MCP bridge and opens the chat panel on every launch, registering either script if REAPER doesn't know it yet.

Agent gateway: Codex, Claude Code, Kimi, … in the same panel

gateway/agent_gateway.py is a small local server (127.0.0.1:47892, stdlib Python) that the panel talks to first. It proxies Gamut agents unchanged and adds ACP agents — Codex via @agentclientprotocol/codex-acp, Claude Code via @agentclientprotocol/claude-agent-acp, Kimi Code CLI (kimi acp), and anything else that speaks ACP — under the same API. Subscriptions work: Codex logs in with ChatGPT, Claude Code reuses the local claude login, Kimi's login button opens kimi login (device code) in Terminal. An agent's loginVariants turn its terminal login into one button per variant, each appending its args to the login command (the Kimi entry ships kimi.ai = --region global and kimi.com = --region mainland-cn). Each ACP session gets this repo's MCP server, so every backend can drive REAPER. The panel shows model / effort / mode pickers for both kinds (Gamut's model catalog, ACP config options), permission buttons when an ACP agent asks before a tool call, and a login button when the agent needs one. If the gateway isn't running the panel falls back to Gamut directly. Every request except /health needs Authorization: Bearer <token> from ~/.config/agent-gateway/token (created with mode 0600 on first start; the panel reads it). Docker and Lima forward host.docker.internal / host.lima.internal to the Mac's loopback, so without the token any container on the Mac could start a host agent.

hibiki agents add codex claude kimi   # Node (~/.local/node) + the ACP adapters, restarts the gateway
python3 gateway/test_gateway.py                   # fake Gamut + fake ACP agent, no network

Agents are listed in ~/.config/agent-gateway/config.json (acp: [{slug, name, command, env, cwd}], mcpServers: [...]). Transcripts of ACP sessions are kept in ~/.config/agent-gateway/sessions/. hibiki agents add installs each adapter at a pinned npm version with install scripts off (MiniMax keeps them: its SQLite binding and ripgrep are fetched by them).

An ACP agent starts on first use (a message, its config, or /status?probe=<slug>; probe=1 only checks that the binary is there and returns the last-known login state). After 10 minutes with no running turn and no open stream (AGENT_GATEWAY_IDLE, seconds) the gateway stops it and the MCP servers it started; the next message restarts it and reloads the chat.

Gamut desktop on the same Mac: install.sh registers the MCP as http://localhost:8787/mcp (no tunnel). Agent running somewhere else and need to reach REAPER over the internet? See docs/remote-host.md.

Troubleshooting

hibiki recover (also the Recover button in the panel's settings) restarts the MCP front and the gateway (their ACP agents go with it), kills leftover panel stream curls, puts back a missing bridge script / panel / token, waits up to 10 s for both services and reports the bridge heartbeat. It never touches REAPER: a stale heartbeat means REAPER is busy or hung, and the watchdog restarts a hung one. --json prints {"ok", "steps": [{"name", "ok", "detail"}]}; exit 0 when the MCP and the gateway answer. hibiki doctor lists everything else.

Security notes

  • The HTTP front (127.0.0.1:8787) refuses to start with a bearer shorter than 32 characters; hibiki setup and scripts/macos-host-bootstrap.sh generate one with a CSPRNG when none is given.

  • Exposed through a Cloudflare tunnel, the bearer is the only gate in front of run_lua, i.e. a shell on the Mac. Only run the tunnel while an agent outside the Mac needs it, and put a Cloudflare Access policy (service token or identity) in front of the tunnel hostname so requests are filtered before they reach the Mac.

Tools

status transport track midi fx send item envelope project render action reaper_call run_lua batch

Behaviour worth knowing (all optional parameters; older calls work unchanged):

  • status also returns any_solo (REAPER's own solo state, which can differ from a track's I_SOLO), master_mute and dirty.

  • render runs action 40101 (set all media online) first (media_online=false skips it), refuses when a target file already exists (REAPER's overwrite prompt would block the bridge) and when tracks are soloed (allow_solo=true, or solo_indices / mute_indices to solo/mute tracks for this render only; they are restored afterwards). It returns files: [{path, bytes, length_sec, peak_db, lufs_i}] and warnings (near-silent, file not written, master muted, stems that came out as the master). measure=false skips the loudness scan.

  • fx set takes formatted instead of value: the value as the plugin shows it (-18 for dB, 4 for 4:1, inf, or a label such as 3.2k). It searches the display text and returns the formatted value it actually set.

  • send add|update take mode (post_fader / pre_fader / pre_fx) and src_channel / dst_channel, the first channel of a stereo pair counted from 0 (dst_channel=2 = channels 3/4, a compressor's sidechain input). The destination track gets more channels if it needs them.

  • envelope get|set take unit=db for volume-type envelopes. set turns an inactive (ACT 0) envelope back on and rejects points that have no value.

  • run_lua takes timeout (seconds, default 10, at most 600). Errors quote the failing source line. REAPER is frozen while a snippet runs, so start long host commands in the background and poll their log.

  • Every call that can change the project is one undo point labelled Hibiki <reply>: <what changed> (a batch is one point for all its calls, with no rollback: stop_on_error=true skips the rest after a failure); see Version history.

  • A reply works on the project tab that was in front when it first changed something: if another tab comes to the front, writes and renders are refused (from the panel, until the reply ends; without the panel the first refusal re-pins to the new tab).

  • status always returns cursor_beats, time_selection, selected tracks (selected) and selected_items; detail=true adds tempo_map (tempo and meter changes).

  • item arranges: split (at_beats), delete, duplicate (an unpooled copy), and update with left_edge_beats (trim the start, content stays put), dest_track_index, active_take, fade_in_sec / fade_out_sec and fade_*_shape. Item indices follow position, so list again after a move.

  • envelope get|set take start_beats / end_beats: set then replaces only the points in that range.

  • transport goto moves the edit cursor to position_beats or a marker/region (number or name); transport returns position_sec and position_beats.

  • render takes format (wav with bit_depth 16 / 24 / 32 float, or mp3 at 320 kbps) for that render only. fx params takes filter; midi get_cc reads CC, program and pitch bend.

  • run_lua's timeout stops a snippet that is still running Lua (what it did until then stays done); a call blocked inside REAPER (ExecProcess, a render, a dialog) can't be stopped.

  • One REAPER serves the mailbox: a second REAPER's bridge waits until the first one's heartbeat goes stale, and a request is claimed by renaming it, so it never runs twice.

Tests

python3 tests/test_server.py                         # MCP server + fake bridge, versions in step
uv run --with lupa python tests/test_bridge_lua.py   # bridge.lua against a fake ReaScript API
uv run --with lupa python panel/test_panel.py   # chat panel events, sends and cards, fake reaper/ImGui
python3 gateway/test_gateway.py                      # agent gateway against fake Gamut + fake ACP agent
python3 tests/test_suite.py                          # setup / doctor / connect / uninstall on a fake HOME
python3 tests/test_ears.py                           # `hibiki ears` on synthetic WAVs
uv run --with lupa python scripts/check_syntax.py    # every .lua compiles under Lua 5.4, every .sh parses

CI runs all of these on every push: the Python suites on 3.9 (the macOS host's /usr/bin/python3) and 3.12.

None of these need REAPER. The Lua-based ones need lupa (CI installs it).

Contributing

See CONTRIBUTING.md. Report security issues privately: SECURITY.md.

License

MIT

Available Tools

14 tools
actionB

Run a REAPER Main_OnCommand by numeric command id.

Inputs: command_id (required).

batchA

Many operations in one IPC hop and one undo point. Each call is {func, args} or {func: 'run_lua', code, timeout} or {func, arguments} for a grouped tool name (track/midi/fx/...). Each slot is the inner result, or {error}. There is no rollback: by default one failure does not abort the rest; stop_on_error=true skips the slots after the first failure ({skipped: true}). Handles from earlier calls work later.

Inputs: calls (required), stop_on_error.

envelopeA

Track envelopes. action: list | get | set. name is REAPER envelope name (Volume, Pan, Mute, ...). set replaces all points, or with start_beats / end_beats only the points in that range (ends included; every new point must lie inside it); get with a range returns only those points. value is the envelope's value; Volume is linear gain (1.0 = 0 dB, 0.5 = -6 dB), also on fader-scaled envelopes. unit=db reads/writes volume-type envelopes (Volume, Trim Volume, send Volume) in dB. set re-activates an envelope left inactive (ACT 0).

Inputs: action (required), track_index (required), name, unit, +4 more.

fxB

Track FX. action: list | add | params | set | delete | bypass | move | preset. params takes filter (case-insensitive part of the parameter name) to list only matching ones. track_index -1 is the master. set takes value 0..1 (REAPER normalized) or formatted: the value as the plugin displays it (number in its unit, e.g. -18 for dB, 4 for 4:1, 120 for ms; or a label like "3.2k"), resolved by searching the display text. set returns the formatted value actually set.

Inputs: action (required), track_index (required), param, value, +7 more.

itemA

Media items on a track. action: list | update | import | split | delete | duplicate. Times are beats except fade_in_sec / fade_out_sec (seconds, REAPER native). update: gain_db, fades and fade_*_shape, loop, mute, position_beats (move), length_beats (trim the end), left_edge_beats (trim or extend the start; the content stays in place), dest_track_index (move to another track; returns the new indices), active_take. list shows take name, source file and take count. split cuts at at_beats (inside the item) and returns the pieces' item_indices. delete takes item_index or item_indices. duplicate copies the item (unpooled) to position_beats (default: right after it), optionally on dest_track_index. import uses a path already on the REAPER host; as_new_track=true makes new tracks. Item indices follow position, so re-list after edits that move items.

Inputs: action (required), loop, mute, path, +16 more.

midiB

MIDI on a track item. Times are absolute project beats. action: create_item | add | get | replace | update | delete | cc | get_cc. replace rewrites the whole take in one undo step; add only appends. cc inserts CC (cc+value) or program change (program) via ccs[]; get_cc reads CC, program and pitch_bend back in that shape. get omits index (use array offset), channel if 0, muted/selected if false.

Inputs: action (required), track_index (required), ccs, muted, +9 more.

projectB

Project-level edits. action: tempo | time_signature | time_selection | marker | save. save with path creates missing folders and writes a copy (no dialog); an untitled project adopts that path. save without path needs an already-named project.

Inputs: action (required), bpm, name, path, +7 more.

reaper_callB

Call any ReaScript function by name. Pointers come back as {"__handle":"hN"} and can be passed back in. Example: func=CountTracks args=[0].

Inputs: func (required), args.

renderA

Render. No undo. Long timeout. bounds: project | time_selection | custom | items. Default: the master mix. stems=true renders the selected tracks as stems instead (pass track_indices to select them). path is the output folder; the file name comes from pattern. Sets all media online (action 40101) first unless media_online=false. Refuses when a target file already exists (REAPER's overwrite prompt would hang the bridge) and when tracks are soloed (pass allow_solo=true, or solo_indices / mute_indices to solo/mute tracks for this render only; they are restored afterwards). Returns files [{path, bytes, length_sec, peak_db, lufs_i}] and warnings (near-silent, missing file, master muted); measure=false skips the loudness scan. format wav (bit_depth 16 | 24 | 32 = float) or mp3 (320 kbps) sets the file type for this render only; without it the project's render format is used.

Inputs: path, stems, bounds, format, +12 more.

run_luaA

Run a Lua snippet inside REAPER (reaper in scope). Use return to send a value. Best for multi-step work that would otherwise be many round-trips. Errors carry the failing line. timeout (seconds, default 10, max 600): a snippet still running Lua after it is stopped with an error (what it did until then stays done); a call blocked inside REAPER (ExecProcess, a render, a dialog) can't be stopped. REAPER is frozen while it runs, so start long host commands in the background (io.popen('cmd > log 2>&1 &')) and poll instead.

Inputs: code (required), timeout.

sendB

Track sends. action: list | add | delete | update. track_index is the source (-1 master). dest_index is the destination track. add/update take volume_db, pan, mute, mode (post_fader | pre_fader | pre_fx) and channel routing: src_channel / dst_channel = first channel of the stereo pair, 0-based (dst_channel 2 = channels 3/4, a compressor's sidechain input; the destination's channel count is raised to fit).

Inputs: action (required), track_index (required), pan, mode, +6 more.

statusA

Check the Lua bridge and return project tempo, play state, cursor_beats, tracks (selected=true on selected ones), time_selection {start_beats, end_beats} when there is one, selected_items [{track_index, item_index}], any_solo, master_mute and dirty (unsaved changes). Call first; clear a lingering solo before rendering. detail=true adds arrangement facts (time signature at the start, tempo_map of tempo/meter changes, length in beats, markers, MIDI vs audio per track) without guessing chords.

Inputs: detail.

trackB

Track operations. action: list | add | delete | update | bus. update uses name, volume_db, pan (-1..1), mute, solo. bus creates a submix named name and routes source_indices through it (their direct send to the master/parent is turned off).

Inputs: action (required), pan, mute, name, +4 more.

transportB

Playback control. action: play, stop, pause, record, toggle_repeat, goto_start, goto (edit cursor to position_beats, or to a marker/region by number or name; moves playback too when playing). Returns play_state, position_sec and position_beats.

Inputs: action (required), marker, position_beats.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.5/5.0

    Scored across 14 tools

    Disambiguation3/5

    Resource tools (track, item, midi, fx, envelope, send, project, transport, render) are mostly distinct, but four generic escape hatches—action, reaper_call, run_lua, and batch—all execute arbitrary commands and could easily be misselected. The descriptions offer guidance on when to use each, but the boundaries between 'run a Main_OnCommand', 'call a ReaScript function', 'run a Lua snippet', and 'batch these together' remain fuzzy.

    Naming Consistency4/5

    All names are lowercase snake_case and predominantly resource-oriented nouns, which makes the set readable and predictable. Minor deviations: a few generic names (action, status, batch) and a couple of verb forms (render, run_lua) break the pure noun convention.

    Tool Count4/5

    14 tools is within a reasonable scope for a DAW control server covering tracks, items, MIDI, FX, envelopes, sends, rendering, and project settings. The count is slightly inflated by redundant abstraction layers (action/reaper_call/run_lua/batch) that could arguably be consolidated.

    Completeness4/5

    Coverage is broad: arrangement state, transport, MIDI, FX, items, envelopes, sends, routing buses, project tempo/markers, rendering, and raw escape hatches. Minor gaps remain—no explicit undo/redo control, limited take management beyond active_take, and marker/region lifecycle is only partially exposed (creation via project, deletion unclear).

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      B
      quality
      D
      maintenance
      An MCP server that enables users to control and edit REAPER projects through a Python-based interface and a Lua bridge. It supports managing tracks, controlling transport, manipulating MIDI and audio items, and adjusting FX parameters within the digital audio workstation.
      57
      GPL 3.0
    • A
      license
      B
      quality
      D
      maintenance
      This 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.
      40
      MIT