@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/README.md
ADDED
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# reaper-mcp
|
|
2
|
+
|
|
3
|
+
AI-powered mixing for REAPER DAW. An MCP server that gives AI agents (Claude Code, etc.) full control over REAPER — real-time metering, FX management, transport control, frequency analysis, and an AI mix engineer knowledge base.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
"Please gain stage my tracks"
|
|
7
|
+
"The chorus needs more energy — make the vocals cut through"
|
|
8
|
+
"I hear some low-end rumble, can you fix that?"
|
|
9
|
+
"Roast my mix — what could be improved?"
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
# 1. Install REAPER components (Lua bridge + JSFX analyzers)
|
|
16
|
+
npx @mthines/reaper-mcp setup
|
|
17
|
+
|
|
18
|
+
# 2. In REAPER: Actions > Load ReaScript > select mcp_bridge.lua > Run
|
|
19
|
+
|
|
20
|
+
# 3. Install AI mix knowledge in your project
|
|
21
|
+
cd your-project
|
|
22
|
+
npx @mthines/reaper-mcp install-skills
|
|
23
|
+
|
|
24
|
+
# 4. Open Claude Code — you're ready to mix
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
That's it. Claude Code now has 26 REAPER tools and a professional mix engineer's knowledge base.
|
|
28
|
+
|
|
29
|
+
## What it does
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Claude Code
|
|
33
|
+
├── MCP Tools (26) ──→ controls REAPER in real-time
|
|
34
|
+
│ ├── Track management (list, get/set properties)
|
|
35
|
+
│ ├── FX management (add/remove, get/set parameters, presets)
|
|
36
|
+
│ ├── Transport (play, stop, record, cursor position)
|
|
37
|
+
│ ├── Metering (peak/RMS, FFT spectrum, LUFS, correlation, crest factor)
|
|
38
|
+
│ ├── Plugin discovery (list installed FX, search, presets)
|
|
39
|
+
│ ├── Snapshots (save/restore mixer state for A/B comparison)
|
|
40
|
+
│ └── Routing (sends, receives, bus structure)
|
|
41
|
+
│
|
|
42
|
+
└── Mix Engineer Knowledge ──→ knows HOW to use those tools
|
|
43
|
+
├── Plugin knowledge (ReaEQ, Pro-Q 3, Helix Native, etc.)
|
|
44
|
+
├── Genre rules (rock, pop, hip-hop, electronic, orchestral, metal)
|
|
45
|
+
├── Workflows (gain staging, vocal chain, drum bus, mastering)
|
|
46
|
+
└── Reference (frequencies, compression, LUFS targets, common mistakes)
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Architecture
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Claude Code ←stdio→ MCP Server (TypeScript) ←JSON files→ Lua Bridge (REAPER)
|
|
53
|
+
│
|
|
54
|
+
ReaScript API ←─┘
|
|
55
|
+
gmem[] shared memory ←── JSFX Analyzers
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
REAPER's scripting environment is sandboxed — no sockets, no HTTP. The Lua bridge runs inside REAPER via `reaper.defer()` at ~30ms intervals, polling a shared directory for JSON command/response files. Round-trip latency: ~50-150ms.
|
|
59
|
+
|
|
60
|
+
## Installation
|
|
61
|
+
|
|
62
|
+
### Prerequisites
|
|
63
|
+
|
|
64
|
+
- [REAPER](https://www.reaper.fm/) v6.0+ (v7.0+ recommended)
|
|
65
|
+
- [Node.js](https://nodejs.org/) 20+
|
|
66
|
+
- [SWS Extensions](https://www.sws-extension.org/) (recommended — enables plugin discovery and enhanced features)
|
|
67
|
+
|
|
68
|
+
### Step 1: Install REAPER components
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx @mthines/reaper-mcp setup
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
This copies into your REAPER resource folder:
|
|
75
|
+
- `mcp_bridge.lua` — persistent Lua bridge script
|
|
76
|
+
- `mcp_analyzer.jsfx` — FFT spectrum analyzer
|
|
77
|
+
- `mcp_lufs_meter.jsfx` — ITU-R BS.1770 LUFS meter
|
|
78
|
+
- `mcp_correlation_meter.jsfx` — stereo correlation analyzer
|
|
79
|
+
- `mcp_crest_factor.jsfx` — dynamics/crest factor meter
|
|
80
|
+
|
|
81
|
+
### Step 2: Start the Lua bridge in REAPER
|
|
82
|
+
|
|
83
|
+
1. Open REAPER
|
|
84
|
+
2. **Actions > Show action list > Load ReaScript**
|
|
85
|
+
3. Select `mcp_bridge.lua` from your REAPER Scripts folder
|
|
86
|
+
4. Click **Run** — the bridge runs persistently in the background
|
|
87
|
+
|
|
88
|
+
You should see in REAPER's console: `MCP Bridge: Started`
|
|
89
|
+
|
|
90
|
+
### Step 3: Install AI mix knowledge in your project
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
cd your-music-project
|
|
94
|
+
npx @mthines/reaper-mcp install-skills
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
This creates in your project:
|
|
98
|
+
- `knowledge/` — plugin knowledge, genre rules, workflows, reference data
|
|
99
|
+
- `.claude/rules/` — architecture and development rules
|
|
100
|
+
- `.claude/skills/` — skills like `/learn-plugin`
|
|
101
|
+
- `.mcp.json` — MCP server configuration for Claude Code
|
|
102
|
+
|
|
103
|
+
### Step 4: Verify
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
npx @mthines/reaper-mcp doctor
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
Checks that the bridge is connected, knowledge is installed, and MCP config exists.
|
|
110
|
+
|
|
111
|
+
## MCP Tools (26)
|
|
112
|
+
|
|
113
|
+
### Track Management
|
|
114
|
+
| Tool | Description |
|
|
115
|
+
|------|-------------|
|
|
116
|
+
| `get_project_info` | Project name, tempo, time sig, sample rate, transport state |
|
|
117
|
+
| `list_tracks` | All tracks with volume, pan, mute/solo, FX count, routing |
|
|
118
|
+
| `get_track_properties` | Detailed track info + full FX chain list |
|
|
119
|
+
| `set_track_property` | Set volume (dB), pan, mute, solo |
|
|
120
|
+
|
|
121
|
+
### FX Management
|
|
122
|
+
| Tool | Description |
|
|
123
|
+
|------|-------------|
|
|
124
|
+
| `add_fx` | Add FX by name (partial match: "ReaEQ", "Pro-Q 3") |
|
|
125
|
+
| `remove_fx` | Remove FX from chain by index |
|
|
126
|
+
| `get_fx_parameters` | List all FX params with values and ranges |
|
|
127
|
+
| `set_fx_parameter` | Set FX parameter (normalized 0.0-1.0) |
|
|
128
|
+
| `list_available_fx` | Discover all installed plugins (VST, VST3, JS, CLAP, AU) |
|
|
129
|
+
| `search_fx` | Fuzzy search installed plugins by name |
|
|
130
|
+
| `get_fx_preset_list` | List available presets for an FX |
|
|
131
|
+
| `set_fx_preset` | Load a preset by name |
|
|
132
|
+
|
|
133
|
+
### Transport
|
|
134
|
+
| Tool | Description |
|
|
135
|
+
|------|-------------|
|
|
136
|
+
| `play` | Start playback |
|
|
137
|
+
| `stop` | Stop playback/recording |
|
|
138
|
+
| `record` | Start recording |
|
|
139
|
+
| `get_transport_state` | Play/record/pause, cursor positions, tempo, time sig |
|
|
140
|
+
| `set_cursor_position` | Move edit cursor to position (seconds) |
|
|
141
|
+
|
|
142
|
+
### Metering & Analysis
|
|
143
|
+
| Tool | Description |
|
|
144
|
+
|------|-------------|
|
|
145
|
+
| `read_track_meters` | Peak/RMS L/R in dB |
|
|
146
|
+
| `read_track_spectrum` | FFT frequency bins (auto-inserts analyzer) |
|
|
147
|
+
| `read_track_lufs` | Integrated/short-term/momentary LUFS + true peak |
|
|
148
|
+
| `read_track_correlation` | Stereo correlation, width, mid/side levels |
|
|
149
|
+
| `read_track_crest` | Crest factor (peak-to-RMS ratio) |
|
|
150
|
+
|
|
151
|
+
### Snapshots (A/B Testing)
|
|
152
|
+
| Tool | Description |
|
|
153
|
+
|------|-------------|
|
|
154
|
+
| `snapshot_save` | Save current mixer state (volumes, pans, FX, mutes) |
|
|
155
|
+
| `snapshot_restore` | Restore a saved snapshot |
|
|
156
|
+
| `snapshot_list` | List all saved snapshots |
|
|
157
|
+
|
|
158
|
+
### Routing
|
|
159
|
+
| Tool | Description |
|
|
160
|
+
|------|-------------|
|
|
161
|
+
| `get_track_routing` | Sends, receives, parent/folder info for a track |
|
|
162
|
+
|
|
163
|
+
## AI Mix Engineer Knowledge
|
|
164
|
+
|
|
165
|
+
The knowledge base is what makes this more than just a remote control — it's a mix engineer's brain.
|
|
166
|
+
|
|
167
|
+
### Plugin Knowledge
|
|
168
|
+
|
|
169
|
+
Ships with knowledge for stock REAPER plugins and popular third-party suites:
|
|
170
|
+
|
|
171
|
+
| Plugin | Category | Preference |
|
|
172
|
+
|--------|----------|-----------|
|
|
173
|
+
| ReaEQ, ReaComp, ReaDelay, ReaVerb, ReaGate, ReaLimit | Stock | 30-50 |
|
|
174
|
+
| FabFilter Pro-Q 3, Pro-C 2, Pro-L 2 | Premium EQ/Comp/Limiter | 85-92 |
|
|
175
|
+
| Line 6 Helix Native | Amp Sim | 82 |
|
|
176
|
+
| JS: 1175 Compressor | Character Comp | 50 |
|
|
177
|
+
|
|
178
|
+
The agent automatically discovers your installed plugins and uses the best available option for each task. If you have Pro-Q 3, it uses that. If not, it falls back to ReaEQ.
|
|
179
|
+
|
|
180
|
+
### Adding Your Own Plugins
|
|
181
|
+
|
|
182
|
+
Use the `/learn-plugin` skill in Claude Code:
|
|
183
|
+
|
|
184
|
+
```
|
|
185
|
+
You: /learn-plugin
|
|
186
|
+
Claude: What plugin would you like me to learn about?
|
|
187
|
+
You: JST Gain Reduction Deluxe — it's a VCA compressor from Joey Sturgis Tones
|
|
188
|
+
Claude: [asks about parameters, presets, usage]
|
|
189
|
+
Claude: Created knowledge/plugins/jst/gain-reduction-deluxe.md
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Or manually add a markdown file to `knowledge/plugins/`. See `knowledge/plugins/_template.md` for the format.
|
|
193
|
+
|
|
194
|
+
### Genre Rules
|
|
195
|
+
|
|
196
|
+
Processing decisions adapt to the genre:
|
|
197
|
+
|
|
198
|
+
| Genre | LUFS Target | Key Characteristics |
|
|
199
|
+
|-------|------------|---------------------|
|
|
200
|
+
| Rock | -11 to -9 | Parallel drum compression, hard-panned guitars |
|
|
201
|
+
| Pop | -14 to -10 | Vocal-forward, two-stage compression, bus glue |
|
|
202
|
+
| Hip-Hop | -10 to -7 | 808 saturation, aggressive vocal comp, mono sub |
|
|
203
|
+
| Electronic | -10 to -6 | Sidechain pump, sub mono, stereo width |
|
|
204
|
+
| Orchestral | -23 to -16 | Preserve dynamics, hall reverb staging |
|
|
205
|
+
| Metal | -11 to -8 | V-scoop guitars, tight drums, 4-guitar wall |
|
|
206
|
+
|
|
207
|
+
## CLI Commands
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
reaper-mcp # Start MCP server (default)
|
|
211
|
+
reaper-mcp serve # Start MCP server (stdio mode)
|
|
212
|
+
reaper-mcp setup # Install Lua bridge + JSFX into REAPER
|
|
213
|
+
reaper-mcp install-skills # Install AI knowledge into your project
|
|
214
|
+
reaper-mcp doctor # Verify everything is configured
|
|
215
|
+
reaper-mcp status # Check bridge connection
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
## Claude Code Integration
|
|
219
|
+
|
|
220
|
+
After `install-skills`, your project has a `.mcp.json`:
|
|
221
|
+
|
|
222
|
+
```json
|
|
223
|
+
{
|
|
224
|
+
"mcpServers": {
|
|
225
|
+
"reaper": {
|
|
226
|
+
"command": "npx",
|
|
227
|
+
"args": ["@mthines/reaper-mcp", "serve"]
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
Claude Code reads this automatically. Open Claude Code in your project and the REAPER tools are available.
|
|
234
|
+
|
|
235
|
+
## Environment Variables
|
|
236
|
+
|
|
237
|
+
| Variable | Description | Default |
|
|
238
|
+
|----------|-------------|---------|
|
|
239
|
+
| `REAPER_RESOURCE_PATH` | Override REAPER resource directory | Auto-detected per OS |
|
|
240
|
+
|
|
241
|
+
Platform defaults:
|
|
242
|
+
- **macOS**: `~/Library/Application Support/REAPER`
|
|
243
|
+
- **Windows**: `%APPDATA%/REAPER`
|
|
244
|
+
- **Linux**: `~/.config/REAPER`
|
|
245
|
+
|
|
246
|
+
## Project Structure
|
|
247
|
+
|
|
248
|
+
```
|
|
249
|
+
reaper-mcp/
|
|
250
|
+
├── apps/
|
|
251
|
+
│ ├── reaper-mcp-server/ # MCP server (26 tools, esbuild bundle)
|
|
252
|
+
│ └── reaper-mix-agent/ # AI mix agent (knowledge loader, plugin resolver)
|
|
253
|
+
├── libs/protocol/ # Shared TypeScript types
|
|
254
|
+
├── knowledge/ # AI mix engineer knowledge base
|
|
255
|
+
│ ├── plugins/ # Plugin-specific knowledge (extensible)
|
|
256
|
+
│ ├── genres/ # Genre mixing conventions
|
|
257
|
+
│ ├── workflows/ # Step-by-step mixing workflows
|
|
258
|
+
│ └── reference/ # Frequency, compression, metering cheat sheets
|
|
259
|
+
├── reaper/ # Files installed into REAPER
|
|
260
|
+
│ ├── mcp_bridge.lua # Persistent Lua bridge
|
|
261
|
+
│ ├── mcp_analyzer.jsfx # FFT spectrum analyzer
|
|
262
|
+
│ ├── mcp_lufs_meter.jsfx # LUFS meter (BS.1770)
|
|
263
|
+
│ ├── mcp_correlation_meter.jsfx # Stereo correlation meter
|
|
264
|
+
│ └── mcp_crest_factor.jsfx # Crest factor meter
|
|
265
|
+
├── docs/TESTING.md # End-to-end testing guide
|
|
266
|
+
└── nx.json # Nx workspace config
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Development
|
|
270
|
+
|
|
271
|
+
```bash
|
|
272
|
+
pnpm install
|
|
273
|
+
pnpm nx run-many --target=build # Build all
|
|
274
|
+
pnpm nx run-many --target=lint # Lint all
|
|
275
|
+
pnpm nx run-many --target=test # Test all (70+ tests)
|
|
276
|
+
pnpm nx run-many --target=build,lint,test # Everything
|
|
277
|
+
```
|
|
278
|
+
|
|
279
|
+
## License
|
|
280
|
+
|
|
281
|
+
MIT
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Core architecture rules for the REAPER MCP Server project
|
|
3
|
+
paths: ["**/*.ts", "**/*.lua", "**/*.jsfx"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Architecture Rules
|
|
7
|
+
|
|
8
|
+
## Communication Pattern
|
|
9
|
+
|
|
10
|
+
This project uses **file-based JSON IPC** between the TypeScript MCP server and a Lua bridge running inside REAPER DAW. This is NOT a design choice that can be changed -- REAPER's Lua scripting environment is sandboxed with no sockets, HTTP, or stdin/stdout.
|
|
11
|
+
|
|
12
|
+
The flow is always:
|
|
13
|
+
1. MCP Server writes `command_{uuid}.json` to bridge directory
|
|
14
|
+
2. Lua bridge reads command, executes ReaScript API, writes `response_{uuid}.json`
|
|
15
|
+
3. MCP Server polls for response and returns to client
|
|
16
|
+
|
|
17
|
+
Never attempt to use WebSockets, HTTP, or any other transport between the server and REAPER.
|
|
18
|
+
|
|
19
|
+
## Monorepo Structure
|
|
20
|
+
|
|
21
|
+
- `apps/` contains runnable applications (currently just `reaper-mcp-server`)
|
|
22
|
+
- `libs/` contains shared libraries (currently just `protocol`)
|
|
23
|
+
- `reaper/` contains files that get installed INTO REAPER (Lua scripts, JSFX plugins)
|
|
24
|
+
- The protocol library is the shared contract between server and bridge -- types here must match the Lua implementation
|
|
25
|
+
|
|
26
|
+
## Dependency Direction
|
|
27
|
+
|
|
28
|
+
- `apps/reaper-mcp-server` -> `libs/protocol` (allowed)
|
|
29
|
+
- `libs/protocol` -> nothing (no app dependencies, no external deps)
|
|
30
|
+
- Never import from `apps/` into `libs/`
|
|
31
|
+
- The `reaper/` directory is not a TypeScript package -- it contains Lua/JSFX files
|
|
32
|
+
|
|
33
|
+
## Bridge Directory
|
|
34
|
+
|
|
35
|
+
All IPC files go to `{REAPER_RESOURCE_PATH}/Scripts/mcp_bridge_data/`. This path is OS-dependent and auto-detected. The `REAPER_RESOURCE_PATH` env var overrides it.
|
|
36
|
+
|
|
37
|
+
## Spectrum Analysis
|
|
38
|
+
|
|
39
|
+
FFT data flows through JSFX gmem shared memory, NOT through JSON files. The JSFX analyzer writes to `gmem[]` and the Lua bridge reads it directly. This avoids the latency of file I/O for high-frequency audio data.
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Development workflow and coding standards
|
|
3
|
+
paths: ["**/*.ts", "**/*.json"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Development Rules
|
|
7
|
+
|
|
8
|
+
## Build & Test
|
|
9
|
+
|
|
10
|
+
- Always use `pnpm` (not npm or yarn) -- this is a pnpm workspace
|
|
11
|
+
- Always use `pnpm nx <target> <project>` to run targets, not raw tool commands
|
|
12
|
+
- Build order matters: `protocol` must build before `reaper-mcp-server` (Nx handles this via `dependsOn: ["^build"]`)
|
|
13
|
+
- Run `pnpm nx run-many --target=build,lint,test` to validate everything before committing
|
|
14
|
+
|
|
15
|
+
## TypeScript
|
|
16
|
+
|
|
17
|
+
- ESM modules throughout (`"type": "module"` in package.json, `"module": "esnext"` in tsconfig)
|
|
18
|
+
- Use `.js` extensions in imports even for TypeScript files (ESM requires this)
|
|
19
|
+
- Path alias `@reaper-mcp/protocol` resolves to `libs/protocol/src/index.ts`
|
|
20
|
+
- Strict mode is enabled -- no `any` types, no implicit returns, etc.
|
|
21
|
+
- Target ES2022 / Node 20
|
|
22
|
+
|
|
23
|
+
## Adding MCP Tools
|
|
24
|
+
|
|
25
|
+
Every new tool requires changes in 4 places (always update all 4):
|
|
26
|
+
|
|
27
|
+
1. `libs/protocol/src/commands.ts` -- Add to `CommandType` union + params interface
|
|
28
|
+
2. `libs/protocol/src/responses.ts` -- Add response data interface if needed
|
|
29
|
+
3. `apps/reaper-mcp-server/src/tools/<file>.ts` -- Implement tool with `server.tool()` + zod schema
|
|
30
|
+
4. `reaper/mcp_bridge.lua` -- Add handler to the `handlers` table
|
|
31
|
+
|
|
32
|
+
If you miss any of these, the tool will either not compile, not be registered, or silently fail at runtime.
|
|
33
|
+
|
|
34
|
+
## Tool Implementation Pattern
|
|
35
|
+
|
|
36
|
+
Tools follow this exact pattern:
|
|
37
|
+
- Use `zod` for parameter validation in the `server.tool()` call
|
|
38
|
+
- Call `sendCommand()` from `bridge.ts` with the command type and params
|
|
39
|
+
- Check `response.success` and return error content if false
|
|
40
|
+
- Return `JSON.stringify(response.data, null, 2)` as text content on success
|
|
41
|
+
|
|
42
|
+
## ESLint
|
|
43
|
+
|
|
44
|
+
- Uses flat config (`eslint.config.mjs`) with typescript-eslint + Nx module boundary enforcement
|
|
45
|
+
- Empty interfaces should be `type X = Record<string, never>` not `interface X {}`
|
|
46
|
+
- No unused imports -- remove them, don't comment them out
|
|
47
|
+
- The `@nx/enforce-module-boundaries` rule prevents invalid cross-package imports
|
|
48
|
+
|
|
49
|
+
## Nx
|
|
50
|
+
|
|
51
|
+
- Lint and test targets are **inferred** by `@nx/eslint/plugin` and `@nx/vite/plugin` -- do NOT add them to `project.json`
|
|
52
|
+
- Build and serve targets are explicit in `project.json`
|
|
53
|
+
- Nx Cloud is enabled for remote caching
|
|
54
|
+
- NX AI is disabled (`"nxAI": false`)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Rules for working with the Lua bridge and JSFX files in the reaper/ directory
|
|
3
|
+
paths: ["reaper/**"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Lua Bridge & JSFX Rules
|
|
7
|
+
|
|
8
|
+
## Lua Bridge (`mcp_bridge.lua`)
|
|
9
|
+
|
|
10
|
+
- The bridge runs as a persistent `reaper.defer()` loop inside REAPER -- it polls every ~30ms
|
|
11
|
+
- It writes a `heartbeat.json` file every 1 second so the MCP server can detect if it's alive
|
|
12
|
+
- JSON parsing: uses `CF_Json_Parse` (REAPER 7+) if available, falls back to Lua pattern matching
|
|
13
|
+
- JSON encoding: custom implementation that handles strings, numbers, booleans, arrays, and nested objects
|
|
14
|
+
- All ReaScript API calls are in handler functions inside the `handlers` table
|
|
15
|
+
- The bridge must be resilient to malformed input -- always wrap file reads in pcall
|
|
16
|
+
|
|
17
|
+
### Adding a Lua Handler
|
|
18
|
+
|
|
19
|
+
```lua
|
|
20
|
+
handlers["new_command_type"] = function(params)
|
|
21
|
+
-- params is a Lua table from JSON parsing
|
|
22
|
+
-- Use ReaScript API calls here
|
|
23
|
+
local result = reaper.SomeApiFunction(params.someValue)
|
|
24
|
+
-- Return a Lua table that will be JSON-encoded as response.data
|
|
25
|
+
return { field = result }
|
|
26
|
+
end
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Important ReaScript API Notes
|
|
30
|
+
|
|
31
|
+
- Track indices are 0-based in the MCP protocol but ReaScript uses `GetTrack(proj, idx)` which is also 0-based
|
|
32
|
+
- Volume values: ReaScript uses linear scale internally, the bridge converts to/from dB
|
|
33
|
+
- FX names support partial matching via `TrackFX_AddByName()`
|
|
34
|
+
- `Track_GetPeakInfo()` returns linear values -- convert to dB with `20 * math.log(value, 10)`
|
|
35
|
+
|
|
36
|
+
## JSFX Analyzer (`mcp_analyzer.jsfx`)
|
|
37
|
+
|
|
38
|
+
- Runs in REAPER's audio processing thread (not the scripting thread)
|
|
39
|
+
- Communicates with Lua via `gmem[]` shared memory (namespace: `MCPAnalyzer`)
|
|
40
|
+
- gmem layout: `gmem[0]=bin_count, gmem[1]=peak_dB, gmem[2]=rms_dB, gmem[3..]=bins`
|
|
41
|
+
- Must pass audio through unmodified (transparent insert)
|
|
42
|
+
- FFT size is configurable via slider (512-8192, default 4096)
|
|
43
|
+
- Window functions: Rectangular, Hann (default), Hamming, Blackman-Harris
|
|
44
|
+
- Output smoothing is configurable (default 0.8)
|
|
45
|
+
|
|
46
|
+
## Testing Without REAPER
|
|
47
|
+
|
|
48
|
+
- The MCP server can be tested by mocking `sendCommand()` in bridge.ts
|
|
49
|
+
- For integration tests, create a mock bridge that reads command files and writes canned response files
|
|
50
|
+
- The Lua bridge cannot be unit tested outside of REAPER -- test it manually
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Testing patterns and conventions
|
|
3
|
+
paths: ["**/*.test.ts", "**/*.spec.ts", "**/vitest.config.ts"]
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Testing Rules
|
|
7
|
+
|
|
8
|
+
## Framework
|
|
9
|
+
|
|
10
|
+
- **Vitest** with `globals: true` (no need to import `describe`, `it`, `expect`)
|
|
11
|
+
- Environment: `node`
|
|
12
|
+
- Test files: `*.test.ts` or `*.spec.ts` colocated with source files or in `__tests__/` directories
|
|
13
|
+
- Both vitest configs have `watch: false` and `passWithNoTests: true`
|
|
14
|
+
|
|
15
|
+
## Server Test Strategy
|
|
16
|
+
|
|
17
|
+
Since the MCP server communicates with REAPER via file-based IPC, tests should:
|
|
18
|
+
|
|
19
|
+
1. **Mock `sendCommand()`** from `bridge.ts` to return canned `BridgeResponse` objects
|
|
20
|
+
2. Test that tools correctly validate parameters (zod schemas)
|
|
21
|
+
3. Test that tools correctly format responses (success and error cases)
|
|
22
|
+
4. Test bridge utility functions (`isBridgeRunning`, `cleanupStaleFiles`, `getBridgeDir`)
|
|
23
|
+
|
|
24
|
+
Do NOT try to start an actual REAPER instance in tests.
|
|
25
|
+
|
|
26
|
+
## Protocol Test Strategy
|
|
27
|
+
|
|
28
|
+
- Test type exports and ensure interfaces match expected shapes
|
|
29
|
+
- These are mainly compile-time checks -- if the build passes, types are correct
|
|
30
|
+
|
|
31
|
+
## Running Tests
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
pnpm nx test reaper-mcp-server # Test server
|
|
35
|
+
pnpm nx test protocol # Test protocol
|
|
36
|
+
pnpm nx run-many --target=test # Test all
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Vitest Config Locations
|
|
40
|
+
|
|
41
|
+
- `apps/reaper-mcp-server/vitest.config.ts` -- has `@reaper-mcp/protocol` alias for path resolution
|
|
42
|
+
- `libs/protocol/vitest.config.ts` -- minimal config
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: learn-plugin
|
|
3
|
+
description: Interview the user about a plugin and generate a knowledge file for the mix agent
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# /learn-plugin
|
|
7
|
+
|
|
8
|
+
This skill interviews the user about a plugin they want the mix agent to know about,
|
|
9
|
+
then generates a properly formatted knowledge file and writes it to `knowledge/plugins/`.
|
|
10
|
+
|
|
11
|
+
## Trigger
|
|
12
|
+
|
|
13
|
+
When the user types `/learn-plugin` or asks Claude to "learn about a plugin" or "add plugin knowledge".
|
|
14
|
+
|
|
15
|
+
## Instructions
|
|
16
|
+
|
|
17
|
+
### Step 1: Ask for the plugin name
|
|
18
|
+
|
|
19
|
+
Start the conversation:
|
|
20
|
+
|
|
21
|
+
> "What plugin would you like me to learn about? Tell me its name and what it does."
|
|
22
|
+
|
|
23
|
+
Wait for the user's response.
|
|
24
|
+
|
|
25
|
+
### Step 2: Gather required information
|
|
26
|
+
|
|
27
|
+
Ask these questions **one group at a time** (not all at once). Wait for each answer before proceeding.
|
|
28
|
+
|
|
29
|
+
**Group A — Identification:**
|
|
30
|
+
1. "What is the plugin's full name as it appears in REAPER's FX browser? Copy it exactly — for example: `VST3: Pro-Q 3 (FabFilter)` or `JS: ReaEQ (Cockos)`."
|
|
31
|
+
2. "Are there any other names or variations it shows up as? (e.g., different between VST2/VST3, or different on Windows vs Mac)"
|
|
32
|
+
|
|
33
|
+
**Group B — Categorization:**
|
|
34
|
+
3. "What category best describes this plugin?"
|
|
35
|
+
- Present options: `eq`, `compressor`, `limiter`, `saturator`, `reverb`, `delay`, `gate`, `de-esser`, `amp-sim`, `channel-strip`, `analyzer`, `stereo-imager`, `multiband`, `pitch-correction`
|
|
36
|
+
4. "What is its character or style?" (optional)
|
|
37
|
+
- Present options: `transparent`, `character`, `vintage`, `modern`, `surgical`
|
|
38
|
+
5. "Who makes it? (vendor name)"
|
|
39
|
+
|
|
40
|
+
**Group C — Usage:**
|
|
41
|
+
6. "On a scale of 1–100, how strongly do you prefer this plugin over alternatives for its category? (e.g., 85 = your go-to, 50 = use sometimes, 30 = only when nothing else available)"
|
|
42
|
+
7. "What are the most important parameters you adjust, and what do they do?"
|
|
43
|
+
8. "What are your typical settings for different use cases? For example: how do you set it up on vocals vs kick drum?"
|
|
44
|
+
9. "Are there any factory presets worth loading as starting points?"
|
|
45
|
+
10. "When do you reach for this plugin instead of its alternatives?"
|
|
46
|
+
|
|
47
|
+
### Step 3: Generate the knowledge file
|
|
48
|
+
|
|
49
|
+
Once you have all the answers, generate a knowledge file in this format:
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
---
|
|
53
|
+
name: [full display name]
|
|
54
|
+
fx_match: ["[exact REAPER FX list name 1]", "[alternate name 2 if any]"]
|
|
55
|
+
category: [category]
|
|
56
|
+
style: [style if provided]
|
|
57
|
+
vendor: [vendor name]
|
|
58
|
+
preference: [preference score]
|
|
59
|
+
replaces: []
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
# [Plugin Name]
|
|
63
|
+
|
|
64
|
+
## What it does
|
|
65
|
+
|
|
66
|
+
[One paragraph describing the plugin based on user's description. Be specific about its sonic character and primary use cases.]
|
|
67
|
+
|
|
68
|
+
## Key parameters by name
|
|
69
|
+
|
|
70
|
+
[Table of parameters the user mentioned, with the exact names as they appear in the plugin UI]
|
|
71
|
+
|
|
72
|
+
| Parameter | Range | Description |
|
|
73
|
+
|-----------|-------|-------------|
|
|
74
|
+
[rows based on user input]
|
|
75
|
+
|
|
76
|
+
## Recommended settings
|
|
77
|
+
|
|
78
|
+
[One section per use case the user described]
|
|
79
|
+
|
|
80
|
+
### [Use case 1]
|
|
81
|
+
|
|
82
|
+
| Parameter | Value | Why |
|
|
83
|
+
|-----------|-------|-----|
|
|
84
|
+
[rows based on user input]
|
|
85
|
+
|
|
86
|
+
## Presets worth knowing
|
|
87
|
+
|
|
88
|
+
[Based on user's answer, or "No notable factory presets. Build from the recommended settings."]
|
|
89
|
+
|
|
90
|
+
## When to prefer this
|
|
91
|
+
|
|
92
|
+
[Based on user's answer about when they reach for it]
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Step 4: Determine the file path
|
|
96
|
+
|
|
97
|
+
- Ask the user: "What vendor slug should I use for the directory? For example, FabFilter would be `fabfilter`, Line 6 would be `line-6`."
|
|
98
|
+
- Suggest a slug if the vendor is obvious.
|
|
99
|
+
- Plugin slug: lowercase plugin name, spaces to hyphens, remove special characters.
|
|
100
|
+
|
|
101
|
+
Example: FabFilter Pro-Q 3 → `knowledge/plugins/fabfilter/pro-q-3.md`
|
|
102
|
+
|
|
103
|
+
### Step 5: Write the file
|
|
104
|
+
|
|
105
|
+
Write the generated file to `knowledge/plugins/{vendor-slug}/{plugin-slug}.md`.
|
|
106
|
+
|
|
107
|
+
### Step 6: Confirm
|
|
108
|
+
|
|
109
|
+
Tell the user:
|
|
110
|
+
|
|
111
|
+
> "Done! I've created `knowledge/plugins/{vendor}/{plugin}.md`.
|
|
112
|
+
>
|
|
113
|
+
> The mix agent will now prefer **[Plugin Name]** for **[category]** tasks.
|
|
114
|
+
>
|
|
115
|
+
> You can edit the file directly to refine the settings. To teach me about another plugin, run `/learn-plugin` again."
|
|
116
|
+
|
|
117
|
+
## Notes
|
|
118
|
+
|
|
119
|
+
- Always use the **exact** FX name from REAPER's FX browser — this is critical for pattern matching
|
|
120
|
+
- If the user doesn't know the exact FX name, suggest they open REAPER, go to FX Browser, find the plugin, and copy the name
|
|
121
|
+
- The `preference` score determines which plugin wins when multiple options are available for the same category
|
|
122
|
+
- Do not add gray-matter or YAML library imports — the knowledge-loader parses frontmatter with a simple regex
|
|
123
|
+
- VST3 versions are preferred over VST2 when both exist (add both to fx_match)
|