@mthines/reaper-mcp 0.6.0-beta.3.2 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +56 -6
- package/main.js +99 -2
- package/package.json +1 -1
- package/reaper/mcp_bridge.lua +3 -3
package/README.md
CHANGED
|
@@ -272,15 +272,65 @@ Processing decisions adapt to the genre:
|
|
|
272
272
|
| Orchestral | -23 to -16 | Preserve dynamics, hall reverb staging |
|
|
273
273
|
| Metal | -11 to -8 | V-scoop guitars, tight drums, 4-guitar wall |
|
|
274
274
|
|
|
275
|
+
## Autonomous Mode (Allow All Tools)
|
|
276
|
+
|
|
277
|
+
By default Claude Code asks permission for each MCP tool call. To let the mix agents work autonomously, add the REAPER tools to your allow list.
|
|
278
|
+
|
|
279
|
+
Add to your project's `.claude/settings.json` (or `~/.claude/settings.json` for global):
|
|
280
|
+
|
|
281
|
+
```json
|
|
282
|
+
{
|
|
283
|
+
"permissions": {
|
|
284
|
+
"allow": [
|
|
285
|
+
"mcp__reaper__get_project_info",
|
|
286
|
+
"mcp__reaper__list_tracks",
|
|
287
|
+
"mcp__reaper__get_track_properties",
|
|
288
|
+
"mcp__reaper__set_track_property",
|
|
289
|
+
"mcp__reaper__add_fx",
|
|
290
|
+
"mcp__reaper__remove_fx",
|
|
291
|
+
"mcp__reaper__get_fx_parameters",
|
|
292
|
+
"mcp__reaper__set_fx_parameter",
|
|
293
|
+
"mcp__reaper__list_available_fx",
|
|
294
|
+
"mcp__reaper__search_fx",
|
|
295
|
+
"mcp__reaper__get_fx_preset_list",
|
|
296
|
+
"mcp__reaper__set_fx_preset",
|
|
297
|
+
"mcp__reaper__play",
|
|
298
|
+
"mcp__reaper__stop",
|
|
299
|
+
"mcp__reaper__record",
|
|
300
|
+
"mcp__reaper__get_transport_state",
|
|
301
|
+
"mcp__reaper__set_cursor_position",
|
|
302
|
+
"mcp__reaper__read_track_meters",
|
|
303
|
+
"mcp__reaper__read_track_spectrum",
|
|
304
|
+
"mcp__reaper__read_track_lufs",
|
|
305
|
+
"mcp__reaper__read_track_correlation",
|
|
306
|
+
"mcp__reaper__read_track_crest",
|
|
307
|
+
"mcp__reaper__snapshot_save",
|
|
308
|
+
"mcp__reaper__snapshot_restore",
|
|
309
|
+
"mcp__reaper__snapshot_list",
|
|
310
|
+
"mcp__reaper__get_track_routing"
|
|
311
|
+
]
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
316
|
+
The format is `mcp__reaper__{tool_name}`. Once added, Claude Code will run these tools without prompting.
|
|
317
|
+
|
|
275
318
|
## CLI Commands
|
|
276
319
|
|
|
277
320
|
```bash
|
|
278
|
-
reaper-mcp # Start MCP server (default)
|
|
279
|
-
reaper-mcp serve # Start MCP server (stdio mode)
|
|
280
|
-
reaper-mcp setup # Install Lua bridge + JSFX into REAPER
|
|
281
|
-
reaper-mcp install-skills # Install AI knowledge into your project
|
|
282
|
-
reaper-mcp doctor # Verify everything is configured
|
|
283
|
-
reaper-mcp status # Check bridge connection
|
|
321
|
+
npx @mthines/reaper-mcp # Start MCP server (default)
|
|
322
|
+
npx @mthines/reaper-mcp serve # Start MCP server (stdio mode)
|
|
323
|
+
npx @mthines/reaper-mcp setup # Install Lua bridge + JSFX into REAPER
|
|
324
|
+
npx @mthines/reaper-mcp install-skills # Install AI knowledge + agents into your project
|
|
325
|
+
npx @mthines/reaper-mcp doctor # Verify everything is configured
|
|
326
|
+
npx @mthines/reaper-mcp status # Check bridge connection
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Or install globally for shorter commands:
|
|
330
|
+
|
|
331
|
+
```bash
|
|
332
|
+
npm install -g @mthines/reaper-mcp
|
|
333
|
+
reaper-mcp setup
|
|
284
334
|
```
|
|
285
335
|
|
|
286
336
|
## Claude Code Integration
|
package/main.js
CHANGED
|
@@ -963,7 +963,7 @@ import { fileURLToPath } from "node:url";
|
|
|
963
963
|
import { homedir as homedir2 } from "node:os";
|
|
964
964
|
|
|
965
965
|
// apps/reaper-mcp-server/src/cli.ts
|
|
966
|
-
import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
966
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
|
|
967
967
|
import { join as join2 } from "node:path";
|
|
968
968
|
function resolveAssetDir(baseDir, name) {
|
|
969
969
|
const sibling = join2(baseDir, name);
|
|
@@ -1013,6 +1013,86 @@ var REAPER_ASSETS = [
|
|
|
1013
1013
|
"mcp_correlation_meter.jsfx",
|
|
1014
1014
|
"mcp_crest_factor.jsfx"
|
|
1015
1015
|
];
|
|
1016
|
+
var MCP_TOOL_NAMES = [
|
|
1017
|
+
// project
|
|
1018
|
+
"get_project_info",
|
|
1019
|
+
// tracks
|
|
1020
|
+
"list_tracks",
|
|
1021
|
+
"get_track_properties",
|
|
1022
|
+
"set_track_property",
|
|
1023
|
+
// fx
|
|
1024
|
+
"add_fx",
|
|
1025
|
+
"remove_fx",
|
|
1026
|
+
"get_fx_parameters",
|
|
1027
|
+
"set_fx_parameter",
|
|
1028
|
+
// discovery
|
|
1029
|
+
"list_available_fx",
|
|
1030
|
+
"search_fx",
|
|
1031
|
+
// presets
|
|
1032
|
+
"get_fx_preset_list",
|
|
1033
|
+
"set_fx_preset",
|
|
1034
|
+
// transport
|
|
1035
|
+
"play",
|
|
1036
|
+
"stop",
|
|
1037
|
+
"record",
|
|
1038
|
+
"get_transport_state",
|
|
1039
|
+
"set_cursor_position",
|
|
1040
|
+
// meters
|
|
1041
|
+
"read_track_meters",
|
|
1042
|
+
"read_track_spectrum",
|
|
1043
|
+
// analysis
|
|
1044
|
+
"read_track_lufs",
|
|
1045
|
+
"read_track_correlation",
|
|
1046
|
+
"read_track_crest",
|
|
1047
|
+
// snapshots
|
|
1048
|
+
"snapshot_save",
|
|
1049
|
+
"snapshot_restore",
|
|
1050
|
+
"snapshot_list",
|
|
1051
|
+
// routing
|
|
1052
|
+
"get_track_routing",
|
|
1053
|
+
// midi
|
|
1054
|
+
"create_midi_item",
|
|
1055
|
+
"list_midi_items",
|
|
1056
|
+
"get_midi_notes",
|
|
1057
|
+
"insert_midi_note",
|
|
1058
|
+
"insert_midi_notes",
|
|
1059
|
+
"edit_midi_note",
|
|
1060
|
+
"delete_midi_note",
|
|
1061
|
+
"get_midi_cc",
|
|
1062
|
+
"insert_midi_cc",
|
|
1063
|
+
"delete_midi_cc",
|
|
1064
|
+
"get_midi_item_properties",
|
|
1065
|
+
"set_midi_item_properties",
|
|
1066
|
+
// media
|
|
1067
|
+
"list_media_items",
|
|
1068
|
+
"get_media_item_properties",
|
|
1069
|
+
"set_media_item_properties",
|
|
1070
|
+
"split_media_item",
|
|
1071
|
+
"delete_media_item",
|
|
1072
|
+
"move_media_item",
|
|
1073
|
+
"trim_media_item",
|
|
1074
|
+
"add_stretch_marker",
|
|
1075
|
+
"get_stretch_markers",
|
|
1076
|
+
"delete_stretch_marker"
|
|
1077
|
+
];
|
|
1078
|
+
function ensureClaudeSettings(settingsPath) {
|
|
1079
|
+
const allowList = MCP_TOOL_NAMES.map((t) => `mcp__reaper__${t}`);
|
|
1080
|
+
if (!existsSync(settingsPath)) {
|
|
1081
|
+
mkdirSync(join2(settingsPath, ".."), { recursive: true });
|
|
1082
|
+
const config = { permissions: { allow: allowList } };
|
|
1083
|
+
writeFileSync(settingsPath, JSON.stringify(config, null, 2) + "\n", "utf-8");
|
|
1084
|
+
return "created";
|
|
1085
|
+
}
|
|
1086
|
+
const existing = JSON.parse(readFileSync(settingsPath, "utf-8"));
|
|
1087
|
+
const existingAllow = existing?.permissions?.allow ?? [];
|
|
1088
|
+
const existingSet = new Set(existingAllow);
|
|
1089
|
+
const newTools = allowList.filter((t) => !existingSet.has(t));
|
|
1090
|
+
if (newTools.length === 0) return "unchanged";
|
|
1091
|
+
if (!existing.permissions) existing.permissions = {};
|
|
1092
|
+
existing.permissions.allow = [...existingAllow, ...newTools];
|
|
1093
|
+
writeFileSync(settingsPath, JSON.stringify(existing, null, 2) + "\n", "utf-8");
|
|
1094
|
+
return "updated";
|
|
1095
|
+
}
|
|
1016
1096
|
|
|
1017
1097
|
// apps/reaper-mcp-server/src/main.ts
|
|
1018
1098
|
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
@@ -1094,6 +1174,22 @@ async function installSkills() {
|
|
|
1094
1174
|
const count = copyDirSync(agentsSrc, globalAgentsDir);
|
|
1095
1175
|
console.log(`Installed Claude agents (global): ${count} files \u2192 ${globalAgentsDir}`);
|
|
1096
1176
|
}
|
|
1177
|
+
const localSettingsPath = join3(targetDir, ".claude", "settings.json");
|
|
1178
|
+
const localResult = ensureClaudeSettings(localSettingsPath);
|
|
1179
|
+
if (localResult === "created") {
|
|
1180
|
+
console.log(`Created Claude settings: ${localSettingsPath}`);
|
|
1181
|
+
} else if (localResult === "updated") {
|
|
1182
|
+
console.log(`Updated Claude settings with new REAPER tools: ${localSettingsPath}`);
|
|
1183
|
+
} else {
|
|
1184
|
+
console.log(`Claude settings already has all REAPER tools: ${localSettingsPath}`);
|
|
1185
|
+
}
|
|
1186
|
+
const globalSettingsPath = join3(globalClaudeDir, "settings.json");
|
|
1187
|
+
const globalResult = ensureClaudeSettings(globalSettingsPath);
|
|
1188
|
+
if (globalResult === "created") {
|
|
1189
|
+
console.log(`Created Claude settings (global): ${globalSettingsPath}`);
|
|
1190
|
+
} else if (globalResult === "updated") {
|
|
1191
|
+
console.log(`Updated Claude settings (global) with new REAPER tools: ${globalSettingsPath}`);
|
|
1192
|
+
}
|
|
1097
1193
|
const mcpJsonPath = join3(targetDir, ".mcp.json");
|
|
1098
1194
|
if (createMcpJson(mcpJsonPath)) {
|
|
1099
1195
|
console.log(`
|
|
@@ -1103,7 +1199,8 @@ Created: ${mcpJsonPath}`);
|
|
|
1103
1199
|
.mcp.json already exists \u2014 add the reaper server config manually if needed.`);
|
|
1104
1200
|
}
|
|
1105
1201
|
console.log("\nDone! Claude Code now has mix engineer agents, knowledge, and REAPER MCP tools.");
|
|
1106
|
-
console.log(
|
|
1202
|
+
console.log("All 48 REAPER tools are pre-approved \u2014 agents work autonomously.");
|
|
1203
|
+
console.log('\nTry: @mix-engineer "Please gain stage my tracks"');
|
|
1107
1204
|
console.log('Or: @mix-analyzer "Roast my mix"');
|
|
1108
1205
|
}
|
|
1109
1206
|
async function doctor() {
|
package/package.json
CHANGED
package/reaper/mcp_bridge.lua
CHANGED
|
@@ -1116,12 +1116,12 @@ function handlers.create_midi_item(params)
|
|
|
1116
1116
|
local track = reaper.GetTrack(0, track_idx)
|
|
1117
1117
|
if not track then return nil, "Track " .. track_idx .. " not found" end
|
|
1118
1118
|
|
|
1119
|
-
local item = reaper.CreateNewMIDIItemInProj(track, start_pos, end_pos)
|
|
1120
|
-
if not item then return nil, "Failed to create MIDI item" end
|
|
1121
|
-
|
|
1122
1119
|
reaper.Undo_BeginBlock()
|
|
1120
|
+
local item = reaper.CreateNewMIDIItemInProj(track, start_pos, end_pos)
|
|
1123
1121
|
reaper.Undo_EndBlock("MCP: Create MIDI item", -1)
|
|
1124
1122
|
|
|
1123
|
+
if not item then return nil, "Failed to create MIDI item" end
|
|
1124
|
+
|
|
1125
1125
|
-- Find the index of the new item on the track
|
|
1126
1126
|
local item_count = reaper.CountTrackMediaItems(track)
|
|
1127
1127
|
local new_idx = -1
|