@mthines/reaper-mcp 0.1.2 → 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 +76 -54
- 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,10 +537,18 @@ 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
|
-
|
|
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);
|
|
549
|
+
if (existsSync(sibling)) return sibling;
|
|
550
|
+
return join2(baseDir, "..", name);
|
|
551
|
+
}
|
|
544
552
|
function copyDirSync(src, dest) {
|
|
545
553
|
if (!existsSync(src)) return 0;
|
|
546
554
|
mkdirSync(dest, { recursive: true });
|
|
@@ -557,39 +565,64 @@ function copyDirSync(src, dest) {
|
|
|
557
565
|
}
|
|
558
566
|
return count;
|
|
559
567
|
}
|
|
560
|
-
function installFile(src, dest
|
|
568
|
+
function installFile(src, dest) {
|
|
561
569
|
if (existsSync(src)) {
|
|
562
570
|
copyFileSync(src, dest);
|
|
563
|
-
console.log(` Installed: ${label}`);
|
|
564
571
|
return true;
|
|
565
572
|
}
|
|
566
|
-
console.log(` Not found: ${src}`);
|
|
567
573
|
return false;
|
|
568
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));
|
|
569
598
|
async function setup() {
|
|
570
599
|
console.log("REAPER MCP Server \u2014 Setup\n");
|
|
571
600
|
const bridgeDir = await ensureBridgeDir();
|
|
572
601
|
console.log(`Bridge directory: ${bridgeDir}
|
|
573
602
|
`);
|
|
574
603
|
const scriptsDir = getReaperScriptsPath();
|
|
575
|
-
|
|
576
|
-
const
|
|
577
|
-
const
|
|
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");
|
|
578
608
|
console.log("Installing Lua bridge...");
|
|
579
|
-
installFile(luaSrc, luaDest
|
|
609
|
+
if (installFile(luaSrc, luaDest)) {
|
|
610
|
+
console.log(` Installed: mcp_bridge.lua`);
|
|
611
|
+
} else {
|
|
612
|
+
console.log(` Not found: ${luaSrc}`);
|
|
613
|
+
}
|
|
580
614
|
const effectsDir = getReaperEffectsPath();
|
|
581
|
-
|
|
582
|
-
const jsfxFiles = [
|
|
583
|
-
"mcp_analyzer.jsfx",
|
|
584
|
-
"mcp_lufs_meter.jsfx",
|
|
585
|
-
"mcp_correlation_meter.jsfx",
|
|
586
|
-
"mcp_crest_factor.jsfx"
|
|
587
|
-
];
|
|
615
|
+
mkdirSync2(effectsDir, { recursive: true });
|
|
588
616
|
console.log("\nInstalling JSFX analyzers...");
|
|
589
|
-
for (const jsfx of
|
|
590
|
-
|
|
591
|
-
const
|
|
592
|
-
|
|
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
|
+
}
|
|
593
626
|
}
|
|
594
627
|
console.log("\nSetup complete!\n");
|
|
595
628
|
console.log("Next steps:");
|
|
@@ -602,43 +635,32 @@ async function setup() {
|
|
|
602
635
|
async function installSkills() {
|
|
603
636
|
console.log("REAPER MCP \u2014 Install AI Mix Engineer Skills\n");
|
|
604
637
|
const targetDir = process.cwd();
|
|
605
|
-
const knowledgeSrc =
|
|
606
|
-
const knowledgeDest =
|
|
607
|
-
if (
|
|
638
|
+
const knowledgeSrc = resolveAssetDir(__dirname, "knowledge");
|
|
639
|
+
const knowledgeDest = join3(targetDir, "knowledge");
|
|
640
|
+
if (existsSync2(knowledgeSrc)) {
|
|
608
641
|
const count = copyDirSync(knowledgeSrc, knowledgeDest);
|
|
609
642
|
console.log(`Installed knowledge base: ${count} files \u2192 ${knowledgeDest}`);
|
|
610
643
|
} else {
|
|
611
644
|
console.log("Knowledge base not found in package. Skipping.");
|
|
612
645
|
}
|
|
613
|
-
const rulesSrc =
|
|
614
|
-
const rulesDir =
|
|
615
|
-
if (
|
|
646
|
+
const rulesSrc = resolveAssetDir(__dirname, "claude-rules");
|
|
647
|
+
const rulesDir = join3(targetDir, ".claude", "rules");
|
|
648
|
+
if (existsSync2(rulesSrc)) {
|
|
616
649
|
const count = copyDirSync(rulesSrc, rulesDir);
|
|
617
650
|
console.log(`Installed Claude rules: ${count} files \u2192 ${rulesDir}`);
|
|
618
651
|
} else {
|
|
619
652
|
console.log("Claude rules not found in package. Skipping.");
|
|
620
653
|
}
|
|
621
|
-
const skillsSrc =
|
|
622
|
-
const skillsDir =
|
|
623
|
-
if (
|
|
654
|
+
const skillsSrc = resolveAssetDir(__dirname, "claude-skills");
|
|
655
|
+
const skillsDir = join3(targetDir, ".claude", "skills");
|
|
656
|
+
if (existsSync2(skillsSrc)) {
|
|
624
657
|
const count = copyDirSync(skillsSrc, skillsDir);
|
|
625
658
|
console.log(`Installed Claude skills: ${count} files \u2192 ${skillsDir}`);
|
|
626
659
|
} else {
|
|
627
660
|
console.log("Claude skills not found in package. Skipping.");
|
|
628
661
|
}
|
|
629
|
-
const mcpJsonPath =
|
|
630
|
-
if (
|
|
631
|
-
const mcpConfig = JSON.stringify({
|
|
632
|
-
mcpServers: {
|
|
633
|
-
reaper: {
|
|
634
|
-
command: "npx",
|
|
635
|
-
args: ["@mthines/reaper-mcp", "serve"]
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}, null, 2);
|
|
639
|
-
copyFileSync("/dev/null", mcpJsonPath);
|
|
640
|
-
const { writeFileSync } = await import("node:fs");
|
|
641
|
-
writeFileSync(mcpJsonPath, mcpConfig + "\n", "utf-8");
|
|
662
|
+
const mcpJsonPath = join3(targetDir, ".mcp.json");
|
|
663
|
+
if (createMcpJson(mcpJsonPath)) {
|
|
642
664
|
console.log(`
|
|
643
665
|
Created: ${mcpJsonPath}`);
|
|
644
666
|
} else {
|
|
@@ -655,12 +677,12 @@ async function doctor() {
|
|
|
655
677
|
if (!bridgeRunning) {
|
|
656
678
|
console.log(' \u2192 Run "reaper-mcp setup" then load mcp_bridge.lua in REAPER');
|
|
657
679
|
}
|
|
658
|
-
const knowledgeExists =
|
|
680
|
+
const knowledgeExists = existsSync2(join3(process.cwd(), "knowledge"));
|
|
659
681
|
console.log(`Knowledge base: ${knowledgeExists ? "\u2713 Found in project" : "\u2717 Not installed"}`);
|
|
660
682
|
if (!knowledgeExists) {
|
|
661
683
|
console.log(' \u2192 Run "reaper-mcp install-skills" in your project directory');
|
|
662
684
|
}
|
|
663
|
-
const mcpJsonExists =
|
|
685
|
+
const mcpJsonExists = existsSync2(join3(process.cwd(), ".mcp.json"));
|
|
664
686
|
console.log(`MCP config: ${mcpJsonExists ? "\u2713 .mcp.json found" : "\u2717 .mcp.json missing"}`);
|
|
665
687
|
if (!mcpJsonExists) {
|
|
666
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"
|