@mthines/reaper-mcp 0.1.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 +281 -0
- package/claude-rules/architecture.md +39 -0
- package/claude-rules/development.md +54 -0
- package/claude-rules/lua-bridge.md +50 -0
- package/claude-rules/testing.md +42 -0
- package/claude-skills/learn-plugin.md +123 -0
- package/knowledge/genres/_template.md +109 -0
- package/knowledge/genres/electronic.md +112 -0
- package/knowledge/genres/hip-hop.md +111 -0
- package/knowledge/genres/metal.md +136 -0
- package/knowledge/genres/orchestral.md +132 -0
- package/knowledge/genres/pop.md +108 -0
- package/knowledge/genres/rock.md +117 -0
- package/knowledge/plugins/_template.md +82 -0
- package/knowledge/plugins/fabfilter/pro-c-2.md +117 -0
- package/knowledge/plugins/fabfilter/pro-l-2.md +95 -0
- package/knowledge/plugins/fabfilter/pro-q-3.md +112 -0
- package/knowledge/plugins/neural-dsp/helix-native.md +104 -0
- package/knowledge/plugins/stock-reaper/js-1175-compressor.md +94 -0
- package/knowledge/plugins/stock-reaper/rea-comp.md +100 -0
- package/knowledge/plugins/stock-reaper/rea-delay.md +95 -0
- package/knowledge/plugins/stock-reaper/rea-eq.md +103 -0
- package/knowledge/plugins/stock-reaper/rea-gate.md +99 -0
- package/knowledge/plugins/stock-reaper/rea-limit.md +75 -0
- package/knowledge/plugins/stock-reaper/rea-verb.md +76 -0
- package/knowledge/reference/common-mistakes.md +307 -0
- package/knowledge/reference/compression.md +176 -0
- package/knowledge/reference/frequencies.md +154 -0
- package/knowledge/reference/metering.md +166 -0
- package/knowledge/workflows/drum-bus.md +211 -0
- package/knowledge/workflows/gain-staging.md +165 -0
- package/knowledge/workflows/low-end.md +261 -0
- package/knowledge/workflows/master-bus.md +204 -0
- package/knowledge/workflows/vocal-chain.md +246 -0
- package/main.js +755 -0
- package/package.json +44 -0
- package/reaper/install.sh +50 -0
- package/reaper/mcp_analyzer.jsfx +167 -0
- package/reaper/mcp_bridge.lua +1105 -0
- package/reaper/mcp_correlation_meter.jsfx +148 -0
- package/reaper/mcp_crest_factor.jsfx +108 -0
- package/reaper/mcp_lufs_meter.jsfx +301 -0
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mthines/reaper-mcp",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "MCP server for controlling REAPER DAW — real-time mixing, FX control, and frequency analysis for AI agents",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "mthines",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/mthines/reaper-mcp.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/mthines/reaper-mcp",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/mthines/reaper-mcp/issues"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"reaper",
|
|
19
|
+
"daw",
|
|
20
|
+
"audio",
|
|
21
|
+
"mixing",
|
|
22
|
+
"ai",
|
|
23
|
+
"model-context-protocol",
|
|
24
|
+
"reascript"
|
|
25
|
+
],
|
|
26
|
+
"bin": {
|
|
27
|
+
"reaper-mcp": "./main.js"
|
|
28
|
+
},
|
|
29
|
+
"engines": {
|
|
30
|
+
"node": ">=20.0.0"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"main.js",
|
|
34
|
+
"reaper/**",
|
|
35
|
+
"knowledge/**",
|
|
36
|
+
"claude-rules/**",
|
|
37
|
+
"claude-skills/**",
|
|
38
|
+
"README.md",
|
|
39
|
+
"LICENSE"
|
|
40
|
+
],
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Quick install script for the REAPER MCP bridge components.
|
|
3
|
+
# Usage: ./install.sh [REAPER_RESOURCE_PATH]
|
|
4
|
+
|
|
5
|
+
set -e
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
8
|
+
|
|
9
|
+
# Detect REAPER resource path
|
|
10
|
+
if [ -n "$1" ]; then
|
|
11
|
+
REAPER_PATH="$1"
|
|
12
|
+
elif [ -n "$REAPER_RESOURCE_PATH" ]; then
|
|
13
|
+
REAPER_PATH="$REAPER_RESOURCE_PATH"
|
|
14
|
+
elif [ "$(uname)" = "Darwin" ]; then
|
|
15
|
+
REAPER_PATH="$HOME/Library/Application Support/REAPER"
|
|
16
|
+
elif [ "$(uname)" = "Linux" ]; then
|
|
17
|
+
REAPER_PATH="$HOME/.config/REAPER"
|
|
18
|
+
else
|
|
19
|
+
echo "Could not detect REAPER resource path. Please provide it as an argument."
|
|
20
|
+
echo "Usage: $0 /path/to/REAPER/resource/dir"
|
|
21
|
+
exit 1
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
echo "REAPER resource path: $REAPER_PATH"
|
|
25
|
+
|
|
26
|
+
# Install Lua bridge
|
|
27
|
+
SCRIPTS_DIR="$REAPER_PATH/Scripts"
|
|
28
|
+
mkdir -p "$SCRIPTS_DIR"
|
|
29
|
+
cp "$SCRIPT_DIR/mcp_bridge.lua" "$SCRIPTS_DIR/mcp_bridge.lua"
|
|
30
|
+
echo "Installed: $SCRIPTS_DIR/mcp_bridge.lua"
|
|
31
|
+
|
|
32
|
+
# Install JSFX analyzer
|
|
33
|
+
EFFECTS_DIR="$REAPER_PATH/Effects"
|
|
34
|
+
mkdir -p "$EFFECTS_DIR"
|
|
35
|
+
cp "$SCRIPT_DIR/mcp_analyzer.jsfx" "$EFFECTS_DIR/mcp_analyzer.jsfx"
|
|
36
|
+
echo "Installed: $EFFECTS_DIR/mcp_analyzer.jsfx"
|
|
37
|
+
|
|
38
|
+
# Create bridge data directory
|
|
39
|
+
BRIDGE_DIR="$SCRIPTS_DIR/mcp_bridge_data"
|
|
40
|
+
mkdir -p "$BRIDGE_DIR"
|
|
41
|
+
echo "Created: $BRIDGE_DIR"
|
|
42
|
+
|
|
43
|
+
echo ""
|
|
44
|
+
echo "Installation complete!"
|
|
45
|
+
echo ""
|
|
46
|
+
echo "Next steps:"
|
|
47
|
+
echo " 1. Open REAPER"
|
|
48
|
+
echo " 2. Actions > Show action list > Load ReaScript"
|
|
49
|
+
echo " 3. Select: $SCRIPTS_DIR/mcp_bridge.lua"
|
|
50
|
+
echo " 4. Run the script (it runs persistently via defer loop)"
|
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
desc:MCP Spectrum Analyzer
|
|
2
|
+
// Real-time FFT spectrum analyzer for MCP bridge integration.
|
|
3
|
+
// Writes frequency bin magnitudes (in dB) to shared memory (gmem)
|
|
4
|
+
// so the Lua bridge can read them and pass to the MCP server.
|
|
5
|
+
//
|
|
6
|
+
// gmem layout:
|
|
7
|
+
// gmem[0] = bin count (fft_size / 2)
|
|
8
|
+
// gmem[1] = peak dB
|
|
9
|
+
// gmem[2] = RMS dB
|
|
10
|
+
// gmem[3 .. 3+bin_count-1] = magnitude in dB per frequency bin
|
|
11
|
+
|
|
12
|
+
options:gmem=MCPAnalyzer
|
|
13
|
+
|
|
14
|
+
slider1:fft_size_slider=4096<512,8192,1>FFT Size
|
|
15
|
+
slider2:window_type=1<0,3,1{Rectangular,Hann,Hamming,Blackman-Harris}>Window Function
|
|
16
|
+
slider3:smoothing=0.8<0,0.99,0.01>Smoothing
|
|
17
|
+
|
|
18
|
+
@init
|
|
19
|
+
// Allocate memory blocks
|
|
20
|
+
fft_buf = 0; // FFT input buffer
|
|
21
|
+
window_buf = 16384; // Window function
|
|
22
|
+
mag_buf = 32768; // Magnitude accumulator (smoothed)
|
|
23
|
+
work_buf = 49152; // Working buffer for FFT
|
|
24
|
+
|
|
25
|
+
fft_size = 4096;
|
|
26
|
+
fft_pos = 0;
|
|
27
|
+
bin_count = fft_size / 2;
|
|
28
|
+
|
|
29
|
+
// Pre-compute window function
|
|
30
|
+
function compute_window(size, wtype) (
|
|
31
|
+
i = 0;
|
|
32
|
+
loop(size,
|
|
33
|
+
wtype == 0 ? ( // Rectangular
|
|
34
|
+
window_buf[i] = 1.0;
|
|
35
|
+
) :
|
|
36
|
+
wtype == 1 ? ( // Hann
|
|
37
|
+
window_buf[i] = 0.5 * (1.0 - cos(2.0 * $pi * i / (size - 1)));
|
|
38
|
+
) :
|
|
39
|
+
wtype == 2 ? ( // Hamming
|
|
40
|
+
window_buf[i] = 0.54 - 0.46 * cos(2.0 * $pi * i / (size - 1));
|
|
41
|
+
) :
|
|
42
|
+
( // Blackman-Harris
|
|
43
|
+
window_buf[i] = 0.35875
|
|
44
|
+
- 0.48829 * cos(2.0 * $pi * i / (size - 1))
|
|
45
|
+
+ 0.14128 * cos(4.0 * $pi * i / (size - 1))
|
|
46
|
+
- 0.01168 * cos(6.0 * $pi * i / (size - 1));
|
|
47
|
+
);
|
|
48
|
+
i += 1;
|
|
49
|
+
);
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
compute_window(fft_size, window_type);
|
|
53
|
+
|
|
54
|
+
// Initialize smoothed magnitude buffer to -150 dB
|
|
55
|
+
i = 0;
|
|
56
|
+
loop(bin_count,
|
|
57
|
+
mag_buf[i] = -150.0;
|
|
58
|
+
i += 1;
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
peak_val = 0;
|
|
62
|
+
rms_sum = 0;
|
|
63
|
+
rms_count = 0;
|
|
64
|
+
|
|
65
|
+
@slider
|
|
66
|
+
new_fft_size = slider1;
|
|
67
|
+
// Snap to valid FFT sizes
|
|
68
|
+
new_fft_size <= 512 ? new_fft_size = 512 :
|
|
69
|
+
new_fft_size <= 1024 ? new_fft_size = 1024 :
|
|
70
|
+
new_fft_size <= 2048 ? new_fft_size = 2048 :
|
|
71
|
+
new_fft_size <= 4096 ? new_fft_size = 4096 :
|
|
72
|
+
new_fft_size = 8192;
|
|
73
|
+
|
|
74
|
+
new_fft_size != fft_size ? (
|
|
75
|
+
fft_size = new_fft_size;
|
|
76
|
+
bin_count = fft_size / 2;
|
|
77
|
+
fft_pos = 0;
|
|
78
|
+
compute_window(fft_size, window_type);
|
|
79
|
+
// Reset smoothed magnitudes
|
|
80
|
+
i = 0;
|
|
81
|
+
loop(bin_count,
|
|
82
|
+
mag_buf[i] = -150.0;
|
|
83
|
+
i += 1;
|
|
84
|
+
);
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
compute_window(fft_size, window_type);
|
|
88
|
+
|
|
89
|
+
@sample
|
|
90
|
+
// Mix to mono and accumulate into FFT buffer
|
|
91
|
+
mono = (spl0 + spl1) * 0.5;
|
|
92
|
+
|
|
93
|
+
// Track peak and RMS
|
|
94
|
+
abs_mono = abs(mono);
|
|
95
|
+
abs_mono > peak_val ? peak_val = abs_mono;
|
|
96
|
+
rms_sum += mono * mono;
|
|
97
|
+
rms_count += 1;
|
|
98
|
+
|
|
99
|
+
// Apply window and store in FFT buffer
|
|
100
|
+
fft_buf[fft_pos] = mono * window_buf[fft_pos];
|
|
101
|
+
|
|
102
|
+
fft_pos += 1;
|
|
103
|
+
|
|
104
|
+
// When buffer is full, perform FFT and write to gmem
|
|
105
|
+
fft_pos >= fft_size ? (
|
|
106
|
+
// Copy to work buffer for FFT (real FFT needs 2x size)
|
|
107
|
+
memcpy(work_buf, fft_buf, fft_size);
|
|
108
|
+
|
|
109
|
+
// Perform real FFT
|
|
110
|
+
fft_real(work_buf, fft_size);
|
|
111
|
+
|
|
112
|
+
// Calculate magnitudes and write to gmem with smoothing
|
|
113
|
+
smooth = smoothing;
|
|
114
|
+
inv_smooth = 1.0 - smooth;
|
|
115
|
+
scale = 2.0 / fft_size;
|
|
116
|
+
|
|
117
|
+
i = 0;
|
|
118
|
+
loop(bin_count,
|
|
119
|
+
// Real FFT output: DC at [0], Nyquist at [1], then pairs [2i, 2i+1]
|
|
120
|
+
i == 0 ? (
|
|
121
|
+
re = work_buf[0];
|
|
122
|
+
im = 0;
|
|
123
|
+
) : i == bin_count ? (
|
|
124
|
+
re = work_buf[1];
|
|
125
|
+
im = 0;
|
|
126
|
+
) : (
|
|
127
|
+
re = work_buf[i * 2];
|
|
128
|
+
im = work_buf[i * 2 + 1];
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
magnitude = sqrt(re * re + im * im) * scale;
|
|
132
|
+
magnitude < 0.000001 ? magnitude = 0.000001; // floor at -120 dB
|
|
133
|
+
mag_db = 20.0 * log10(magnitude);
|
|
134
|
+
|
|
135
|
+
// Apply smoothing
|
|
136
|
+
mag_buf[i] = smooth * mag_buf[i] + inv_smooth * mag_db;
|
|
137
|
+
|
|
138
|
+
// Write to gmem
|
|
139
|
+
gmem[3 + i] = mag_buf[i];
|
|
140
|
+
|
|
141
|
+
i += 1;
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
// Write metadata to gmem
|
|
145
|
+
gmem[0] = bin_count;
|
|
146
|
+
|
|
147
|
+
// Peak dB
|
|
148
|
+
peak_val < 0.000001 ? peak_val = 0.000001;
|
|
149
|
+
gmem[1] = 20.0 * log10(peak_val);
|
|
150
|
+
|
|
151
|
+
// RMS dB
|
|
152
|
+
rms_count > 0 ? (
|
|
153
|
+
rms_val = sqrt(rms_sum / rms_count);
|
|
154
|
+
rms_val < 0.000001 ? rms_val = 0.000001;
|
|
155
|
+
gmem[2] = 20.0 * log10(rms_val);
|
|
156
|
+
) : (
|
|
157
|
+
gmem[2] = -150.0;
|
|
158
|
+
);
|
|
159
|
+
|
|
160
|
+
// Reset accumulators
|
|
161
|
+
peak_val = 0;
|
|
162
|
+
rms_sum = 0;
|
|
163
|
+
rms_count = 0;
|
|
164
|
+
fft_pos = 0;
|
|
165
|
+
);
|
|
166
|
+
|
|
167
|
+
// Pass audio through unmodified
|