@mthines/reaper-mcp 0.1.3 → 0.2.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/main.js +74 -58
- package/package.json +2 -2
package/main.js
CHANGED
|
@@ -123,7 +123,7 @@ function registerProjectTools(server) {
|
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
// apps/reaper-mcp-server/src/tools/tracks.ts
|
|
126
|
-
import { z } from "zod";
|
|
126
|
+
import { z } from "zod/v4";
|
|
127
127
|
function registerTrackTools(server) {
|
|
128
128
|
server.tool(
|
|
129
129
|
"list_tracks",
|
|
@@ -168,7 +168,7 @@ function registerTrackTools(server) {
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
// apps/reaper-mcp-server/src/tools/fx.ts
|
|
171
|
-
import { z as z2 } from "zod";
|
|
171
|
+
import { z as z2 } from "zod/v4";
|
|
172
172
|
function registerFxTools(server) {
|
|
173
173
|
server.tool(
|
|
174
174
|
"add_fx",
|
|
@@ -236,7 +236,7 @@ function registerFxTools(server) {
|
|
|
236
236
|
}
|
|
237
237
|
|
|
238
238
|
// apps/reaper-mcp-server/src/tools/meters.ts
|
|
239
|
-
import { z as z3 } from "zod";
|
|
239
|
+
import { z as z3 } from "zod/v4";
|
|
240
240
|
function registerMeterTools(server) {
|
|
241
241
|
server.tool(
|
|
242
242
|
"read_track_meters",
|
|
@@ -270,7 +270,7 @@ function registerMeterTools(server) {
|
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
// apps/reaper-mcp-server/src/tools/transport.ts
|
|
273
|
-
import { z as z4 } from "zod";
|
|
273
|
+
import { z as z4 } from "zod/v4";
|
|
274
274
|
function registerTransportTools(server) {
|
|
275
275
|
server.tool(
|
|
276
276
|
"play",
|
|
@@ -337,7 +337,7 @@ function registerTransportTools(server) {
|
|
|
337
337
|
}
|
|
338
338
|
|
|
339
339
|
// apps/reaper-mcp-server/src/tools/discovery.ts
|
|
340
|
-
import { z as z5 } from "zod";
|
|
340
|
+
import { z as z5 } from "zod/v4";
|
|
341
341
|
function registerDiscoveryTools(server) {
|
|
342
342
|
server.tool(
|
|
343
343
|
"list_available_fx",
|
|
@@ -370,7 +370,7 @@ function registerDiscoveryTools(server) {
|
|
|
370
370
|
}
|
|
371
371
|
|
|
372
372
|
// apps/reaper-mcp-server/src/tools/presets.ts
|
|
373
|
-
import { z as z6 } from "zod";
|
|
373
|
+
import { z as z6 } from "zod/v4";
|
|
374
374
|
function registerPresetTools(server) {
|
|
375
375
|
server.tool(
|
|
376
376
|
"get_fx_preset_list",
|
|
@@ -406,7 +406,7 @@ function registerPresetTools(server) {
|
|
|
406
406
|
}
|
|
407
407
|
|
|
408
408
|
// apps/reaper-mcp-server/src/tools/snapshots.ts
|
|
409
|
-
import { z as z7 } from "zod";
|
|
409
|
+
import { z as z7 } from "zod/v4";
|
|
410
410
|
function registerSnapshotTools(server) {
|
|
411
411
|
server.tool(
|
|
412
412
|
"snapshot_save",
|
|
@@ -452,7 +452,7 @@ function registerSnapshotTools(server) {
|
|
|
452
452
|
}
|
|
453
453
|
|
|
454
454
|
// apps/reaper-mcp-server/src/tools/routing.ts
|
|
455
|
-
import { z as z8 } from "zod";
|
|
455
|
+
import { z as z8 } from "zod/v4";
|
|
456
456
|
function registerRoutingTools(server) {
|
|
457
457
|
server.tool(
|
|
458
458
|
"get_track_routing",
|
|
@@ -471,7 +471,7 @@ function registerRoutingTools(server) {
|
|
|
471
471
|
}
|
|
472
472
|
|
|
473
473
|
// apps/reaper-mcp-server/src/tools/analysis.ts
|
|
474
|
-
import { z as z9 } from "zod";
|
|
474
|
+
import { z as z9 } from "zod/v4";
|
|
475
475
|
function registerAnalysisTools(server) {
|
|
476
476
|
server.tool(
|
|
477
477
|
"read_track_lufs",
|
|
@@ -537,14 +537,17 @@ function createServer() {
|
|
|
537
537
|
}
|
|
538
538
|
|
|
539
539
|
// apps/reaper-mcp-server/src/main.ts
|
|
540
|
-
import {
|
|
541
|
-
import { join as
|
|
540
|
+
import { existsSync as existsSync2, mkdirSync as mkdirSync2 } from "node:fs";
|
|
541
|
+
import { join as join3, dirname } from "node:path";
|
|
542
542
|
import { fileURLToPath } from "node:url";
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
543
|
+
|
|
544
|
+
// apps/reaper-mcp-server/src/cli.ts
|
|
545
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, statSync, writeFileSync } from "node:fs";
|
|
546
|
+
import { join as join2 } from "node:path";
|
|
547
|
+
function resolveAssetDir(baseDir, name) {
|
|
548
|
+
const sibling = join2(baseDir, name);
|
|
546
549
|
if (existsSync(sibling)) return sibling;
|
|
547
|
-
return join2(
|
|
550
|
+
return join2(baseDir, "..", name);
|
|
548
551
|
}
|
|
549
552
|
function copyDirSync(src, dest) {
|
|
550
553
|
if (!existsSync(src)) return 0;
|
|
@@ -562,40 +565,64 @@ function copyDirSync(src, dest) {
|
|
|
562
565
|
}
|
|
563
566
|
return count;
|
|
564
567
|
}
|
|
565
|
-
function installFile(src, dest
|
|
568
|
+
function installFile(src, dest) {
|
|
566
569
|
if (existsSync(src)) {
|
|
567
570
|
copyFileSync(src, dest);
|
|
568
|
-
console.log(` Installed: ${label}`);
|
|
569
571
|
return true;
|
|
570
572
|
}
|
|
571
|
-
console.log(` Not found: ${src}`);
|
|
572
573
|
return false;
|
|
573
574
|
}
|
|
575
|
+
function createMcpJson(targetPath) {
|
|
576
|
+
if (existsSync(targetPath)) return false;
|
|
577
|
+
const config = JSON.stringify({
|
|
578
|
+
mcpServers: {
|
|
579
|
+
reaper: {
|
|
580
|
+
command: "npx",
|
|
581
|
+
args: ["@mthines/reaper-mcp", "serve"]
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}, null, 2);
|
|
585
|
+
writeFileSync(targetPath, config + "\n", "utf-8");
|
|
586
|
+
return true;
|
|
587
|
+
}
|
|
588
|
+
var REAPER_ASSETS = [
|
|
589
|
+
"mcp_bridge.lua",
|
|
590
|
+
"mcp_analyzer.jsfx",
|
|
591
|
+
"mcp_lufs_meter.jsfx",
|
|
592
|
+
"mcp_correlation_meter.jsfx",
|
|
593
|
+
"mcp_crest_factor.jsfx"
|
|
594
|
+
];
|
|
595
|
+
|
|
596
|
+
// apps/reaper-mcp-server/src/main.ts
|
|
597
|
+
var __dirname = dirname(fileURLToPath(import.meta.url));
|
|
574
598
|
async function setup() {
|
|
575
599
|
console.log("REAPER MCP Server \u2014 Setup\n");
|
|
576
600
|
const bridgeDir = await ensureBridgeDir();
|
|
577
601
|
console.log(`Bridge directory: ${bridgeDir}
|
|
578
602
|
`);
|
|
579
603
|
const scriptsDir = getReaperScriptsPath();
|
|
580
|
-
|
|
581
|
-
const reaperDir = resolveAssetDir("reaper");
|
|
582
|
-
const luaSrc =
|
|
583
|
-
const luaDest =
|
|
604
|
+
mkdirSync2(scriptsDir, { recursive: true });
|
|
605
|
+
const reaperDir = resolveAssetDir(__dirname, "reaper");
|
|
606
|
+
const luaSrc = join3(reaperDir, "mcp_bridge.lua");
|
|
607
|
+
const luaDest = join3(scriptsDir, "mcp_bridge.lua");
|
|
584
608
|
console.log("Installing Lua bridge...");
|
|
585
|
-
installFile(luaSrc, luaDest
|
|
609
|
+
if (installFile(luaSrc, luaDest)) {
|
|
610
|
+
console.log(` Installed: mcp_bridge.lua`);
|
|
611
|
+
} else {
|
|
612
|
+
console.log(` Not found: ${luaSrc}`);
|
|
613
|
+
}
|
|
586
614
|
const effectsDir = getReaperEffectsPath();
|
|
587
|
-
|
|
588
|
-
const jsfxFiles = [
|
|
589
|
-
"mcp_analyzer.jsfx",
|
|
590
|
-
"mcp_lufs_meter.jsfx",
|
|
591
|
-
"mcp_correlation_meter.jsfx",
|
|
592
|
-
"mcp_crest_factor.jsfx"
|
|
593
|
-
];
|
|
615
|
+
mkdirSync2(effectsDir, { recursive: true });
|
|
594
616
|
console.log("\nInstalling JSFX analyzers...");
|
|
595
|
-
for (const jsfx of
|
|
596
|
-
|
|
597
|
-
const
|
|
598
|
-
|
|
617
|
+
for (const jsfx of REAPER_ASSETS) {
|
|
618
|
+
if (jsfx === "mcp_bridge.lua") continue;
|
|
619
|
+
const src = join3(reaperDir, jsfx);
|
|
620
|
+
const dest = join3(effectsDir, jsfx);
|
|
621
|
+
if (installFile(src, dest)) {
|
|
622
|
+
console.log(` Installed: ${jsfx}`);
|
|
623
|
+
} else {
|
|
624
|
+
console.log(` Not found: ${src}`);
|
|
625
|
+
}
|
|
599
626
|
}
|
|
600
627
|
console.log("\nSetup complete!\n");
|
|
601
628
|
console.log("Next steps:");
|
|
@@ -608,43 +635,32 @@ async function setup() {
|
|
|
608
635
|
async function installSkills() {
|
|
609
636
|
console.log("REAPER MCP \u2014 Install AI Mix Engineer Skills\n");
|
|
610
637
|
const targetDir = process.cwd();
|
|
611
|
-
const knowledgeSrc = resolveAssetDir("knowledge");
|
|
612
|
-
const knowledgeDest =
|
|
613
|
-
if (
|
|
638
|
+
const knowledgeSrc = resolveAssetDir(__dirname, "knowledge");
|
|
639
|
+
const knowledgeDest = join3(targetDir, "knowledge");
|
|
640
|
+
if (existsSync2(knowledgeSrc)) {
|
|
614
641
|
const count = copyDirSync(knowledgeSrc, knowledgeDest);
|
|
615
642
|
console.log(`Installed knowledge base: ${count} files \u2192 ${knowledgeDest}`);
|
|
616
643
|
} else {
|
|
617
644
|
console.log("Knowledge base not found in package. Skipping.");
|
|
618
645
|
}
|
|
619
|
-
const rulesSrc = resolveAssetDir("claude-rules");
|
|
620
|
-
const rulesDir =
|
|
621
|
-
if (
|
|
646
|
+
const rulesSrc = resolveAssetDir(__dirname, "claude-rules");
|
|
647
|
+
const rulesDir = join3(targetDir, ".claude", "rules");
|
|
648
|
+
if (existsSync2(rulesSrc)) {
|
|
622
649
|
const count = copyDirSync(rulesSrc, rulesDir);
|
|
623
650
|
console.log(`Installed Claude rules: ${count} files \u2192 ${rulesDir}`);
|
|
624
651
|
} else {
|
|
625
652
|
console.log("Claude rules not found in package. Skipping.");
|
|
626
653
|
}
|
|
627
|
-
const skillsSrc = resolveAssetDir("claude-skills");
|
|
628
|
-
const skillsDir =
|
|
629
|
-
if (
|
|
654
|
+
const skillsSrc = resolveAssetDir(__dirname, "claude-skills");
|
|
655
|
+
const skillsDir = join3(targetDir, ".claude", "skills");
|
|
656
|
+
if (existsSync2(skillsSrc)) {
|
|
630
657
|
const count = copyDirSync(skillsSrc, skillsDir);
|
|
631
658
|
console.log(`Installed Claude skills: ${count} files \u2192 ${skillsDir}`);
|
|
632
659
|
} else {
|
|
633
660
|
console.log("Claude skills not found in package. Skipping.");
|
|
634
661
|
}
|
|
635
|
-
const mcpJsonPath =
|
|
636
|
-
if (
|
|
637
|
-
const mcpConfig = JSON.stringify({
|
|
638
|
-
mcpServers: {
|
|
639
|
-
reaper: {
|
|
640
|
-
command: "npx",
|
|
641
|
-
args: ["@mthines/reaper-mcp", "serve"]
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
}, null, 2);
|
|
645
|
-
copyFileSync("/dev/null", mcpJsonPath);
|
|
646
|
-
const { writeFileSync } = await import("node:fs");
|
|
647
|
-
writeFileSync(mcpJsonPath, mcpConfig + "\n", "utf-8");
|
|
662
|
+
const mcpJsonPath = join3(targetDir, ".mcp.json");
|
|
663
|
+
if (createMcpJson(mcpJsonPath)) {
|
|
648
664
|
console.log(`
|
|
649
665
|
Created: ${mcpJsonPath}`);
|
|
650
666
|
} else {
|
|
@@ -661,12 +677,12 @@ async function doctor() {
|
|
|
661
677
|
if (!bridgeRunning) {
|
|
662
678
|
console.log(' \u2192 Run "reaper-mcp setup" then load mcp_bridge.lua in REAPER');
|
|
663
679
|
}
|
|
664
|
-
const knowledgeExists =
|
|
680
|
+
const knowledgeExists = existsSync2(join3(process.cwd(), "knowledge"));
|
|
665
681
|
console.log(`Knowledge base: ${knowledgeExists ? "\u2713 Found in project" : "\u2717 Not installed"}`);
|
|
666
682
|
if (!knowledgeExists) {
|
|
667
683
|
console.log(' \u2192 Run "reaper-mcp install-skills" in your project directory');
|
|
668
684
|
}
|
|
669
|
-
const mcpJsonExists =
|
|
685
|
+
const mcpJsonExists = existsSync2(join3(process.cwd(), ".mcp.json"));
|
|
670
686
|
console.log(`MCP config: ${mcpJsonExists ? "\u2713 .mcp.json found" : "\u2717 .mcp.json missing"}`);
|
|
671
687
|
if (!mcpJsonExists) {
|
|
672
688
|
console.log(' \u2192 Run "reaper-mcp install-skills" to create .mcp.json');
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mthines/reaper-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "MCP server for controlling REAPER DAW — real-time mixing, FX control, and frequency analysis for AI agents",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
},
|
|
29
29
|
"dependencies": {
|
|
30
30
|
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
31
|
-
"zod": "^3.
|
|
31
|
+
"zod": "^4.3.6"
|
|
32
32
|
},
|
|
33
33
|
"engines": {
|
|
34
34
|
"node": ">=20.0.0"
|