@mthines/reaper-mcp 0.19.0 → 0.70.2
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 +19 -570
- package/bridge-ui/mcp_bridge.html +129 -0
- package/bridge-ui/mcp_bridge.webmanifest +16 -0
- package/bridge-ui/mcp_bridge_icon_192.png +0 -0
- package/bridge-ui/mcp_bridge_icon_512.png +0 -0
- package/bridge-ui/mcp_bridge_sw.js +35 -0
- package/claude/agents/plugin-researcher.md +188 -0
- package/claude/knowledge/reference/aesthetics-scoring.md +48 -0
- package/{knowledge → claude/knowledge}/reference/common-mistakes.md +1 -1
- package/claude/knowledge/reference/lorekit-setup.md +36 -0
- package/claude/knowledge/reference/memory-protocol.md +377 -0
- package/{knowledge → claude/knowledge}/reference/metering.md +5 -5
- package/claude/knowledge/reference/perceived-loudness.md +182 -0
- package/{knowledge → claude/knowledge}/workflows/editing.md +4 -0
- package/{knowledge → claude/knowledge}/workflows/gain-staging.md +21 -23
- package/{knowledge → claude/knowledge}/workflows/learn-plugin.md +15 -48
- package/{knowledge → claude/knowledge}/workflows/master-bus.md +13 -1
- package/claude/knowledge/workflows/section-levels.md +138 -0
- package/{knowledge → claude/knowledge}/workflows/session-prep.md +4 -0
- package/claude/knowledge/workflows/transient-lighting.md +52 -0
- package/claude/skills/critique/SKILL.md +131 -0
- package/claude/skills/editing/SKILL.md +281 -0
- package/claude/skills/learn-plugin/SKILL.md +210 -0
- package/claude/skills/mastering/SKILL.md +151 -0
- package/claude/skills/mix-memory/SKILL.md +140 -0
- package/claude/skills/mixer/SKILL.md +253 -0
- package/claude/skills/new-extension/SKILL.md +324 -0
- package/main.js +7843 -1940
- package/package.json +17 -15
- package/reaper/CLAUDE.md +22 -4
- package/reaper/mcp_actions_lib.lua +375 -0
- package/reaper/mcp_analyzer.jsfx +27 -12
- package/reaper/mcp_arrange_lib.lua +949 -0
- package/reaper/mcp_bridge.lua +2321 -758
- package/reaper/mcp_edit_views_lib.lua +1378 -0
- package/reaper/mcp_envelopes_lib.lua +748 -0
- package/reaper/mcp_extensions_lib.lua +55 -0
- package/reaper/mcp_fxstate_lib.lua +144 -0
- package/reaper/mcp_gain_trace.jsfx +126 -0
- package/reaper/mcp_items_lib.lua +877 -0
- package/reaper/mcp_lufs_meter.jsfx +16 -13
- package/reaper/mcp_midi_lib.lua +555 -0
- package/reaper/mcp_mixing_lib.lua +1021 -0
- package/reaper/mcp_plan_lib.lua +801 -0
- package/reaper/mcp_prefs_lib.lua +127 -0
- package/reaper/mcp_project_lib.lua +1088 -0
- package/reaper/mcp_recording_lib.lua +595 -0
- package/reaper/mcp_render_lib.lua +492 -0
- package/reaper/mcp_snapshot_lib.lua +547 -120
- package/reaper/mcp_snapshot_next.lua +10 -4
- package/reaper/mcp_snapshot_prev.lua +11 -4
- package/reaper/mcp_snapshot_quick_save.lua +7 -32
- package/reaper/mcp_snapshots_ui_lib.lua +258 -0
- package/reaper/mcp_tracks_lib.lua +409 -0
- package/sidecar/analysis.py +661 -0
- package/sidecar/chords.py +96 -0
- package/sidecar/mixcheck.py +295 -0
- package/sidecar/requirements-chords.txt +6 -0
- package/sidecar/requirements-separation.txt +3 -0
- package/sidecar/requirements.txt +17 -0
- package/sidecar/separation.py +142 -0
- package/sidecar/server.py +622 -0
- package/sidecar/tests/test_analysis.py +249 -0
- package/sidecar/tests/test_chords.py +117 -0
- package/sidecar/tests/test_mixcheck.py +163 -0
- package/sidecar/tests/test_separation.py +73 -0
- package/sidecar/tests/test_server.py +464 -0
- package/sidecar/tests/test_verify.py +243 -0
- package/sidecar/tests/test_voice_render.py +268 -0
- package/sidecar/tests/test_voice_sketch.py +140 -0
- package/sidecar/verify.py +224 -0
- package/sidecar/voice_render.py +295 -0
- package/sidecar/voice_sketch.py +280 -0
- package/claude-agents/critique.md +0 -147
- package/claude-agents/editor.md +0 -184
- package/claude-agents/levels.md +0 -107
- package/claude-agents/mastering.md +0 -129
- package/claude-agents/mixer.md +0 -248
- package/claude-agents/preflight.md +0 -149
- package/claude-agents/producer.md +0 -159
- package/claude-agents/setup.md +0 -150
- package/claude-agents/stems.md +0 -135
- package/claude-rules/architecture.md +0 -39
- package/claude-rules/development.md +0 -54
- package/claude-rules/lua-bridge.md +0 -50
- package/claude-rules/testing.md +0 -42
- package/claude-skills/learn-plugin.md +0 -123
- package/knowledge/CLAUDE.md +0 -71
- package/knowledge/plugins/_template.md +0 -82
- package/knowledge/plugins/fabfilter/pro-c-2.md +0 -117
- package/knowledge/plugins/fabfilter/pro-l-2.md +0 -95
- package/knowledge/plugins/fabfilter/pro-q-3.md +0 -112
- package/knowledge/plugins/neural-dsp/helix-native.md +0 -104
- package/knowledge/plugins/stock-reaper/js-1175-compressor.md +0 -94
- package/knowledge/plugins/stock-reaper/rea-comp.md +0 -100
- package/knowledge/plugins/stock-reaper/rea-delay.md +0 -95
- package/knowledge/plugins/stock-reaper/rea-eq.md +0 -103
- package/knowledge/plugins/stock-reaper/rea-gate.md +0 -99
- package/knowledge/plugins/stock-reaper/rea-limit.md +0 -75
- package/knowledge/plugins/stock-reaper/rea-verb.md +0 -76
- package/knowledge/reference/perceived-loudness.md +0 -122
- package/reaper/mcp_snapshot_manager.lua +0 -1001
- /package/{knowledge → claude/knowledge}/genres/_template.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/electronic.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/hip-hop.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/metal.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/orchestral.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/pop.md +0 -0
- /package/{knowledge → claude/knowledge}/genres/rock.md +0 -0
- /package/{knowledge → claude/knowledge}/reference/compression.md +0 -0
- /package/{knowledge → claude/knowledge}/reference/frequencies.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/delivery.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/drum-bus.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/low-end.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/stem-prep.md +0 -0
- /package/{knowledge → claude/knowledge}/workflows/vocal-chain.md +0 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mix-memory
|
|
3
|
+
description: Recall and maintain the mixing skills' memory in LoreKit (scope project::reaper-mcp) — plugin knowledge records and self-healing process lessons, as a read-only built-in layer plus the user's own layer on top. Modes — recall (load what's relevant before work), consolidate (merge duplicate user lessons, fold proven plugin notes into recommended settings), promote (turn a recurring lesson into a hard rule), publish (maintainer only — move a user record into the built-in layer), status (what's stored, per layer). Triggers on "what have you learned", "recall mixing memory", "consolidate memory", "promote that lesson", "publish to built-in", "/mix-memory".
|
|
4
|
+
disable-model-invocation: false
|
|
5
|
+
argument-hint: '[recall|consolidate|promote|publish|status] [plugin-slug|lesson-slug]'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# /mix-memory
|
|
9
|
+
|
|
10
|
+
Maintain and recall the two kinds of memory the mixing skills keep in
|
|
11
|
+
**LoreKit** (scope `project::reaper-mcp`, via the `memory.*` MCP tools):
|
|
12
|
+
|
|
13
|
+
- **Process lessons** — tag `loop::mixing-lessons`
|
|
14
|
+
- **Plugin knowledge** — tag `plugin-knowledge`
|
|
15
|
+
|
|
16
|
+
Each comes in two layers: the built-in one, read through the `reaper` tools
|
|
17
|
+
`list_builtin_knowledge` / `get_builtin_knowledge` (public read-only token, no
|
|
18
|
+
LoreKit account needed), and the user's own, through `memory.*`:
|
|
19
|
+
|
|
20
|
+
| Layer | Keys | Tag | Writable here |
|
|
21
|
+
|-------|------|-----|---------------|
|
|
22
|
+
| Built-in (`reaper-mcp` org, curated) | `plugins::<vendor>/<plugin>`, `mixing-lessons::<slug>` | `layer::built-in` | only via `publish` |
|
|
23
|
+
| User (personal) | `user::plugins::<vendor>/<plugin>`, `user::mixing-lessons::<slug>` | `layer::user` | yes |
|
|
24
|
+
|
|
25
|
+
**Never write or `memory.delete` a built-in key outside `publish`** — a delete
|
|
26
|
+
without `org` archives the org row too.
|
|
27
|
+
|
|
28
|
+
The full contract — buckets, body shapes,
|
|
29
|
+
entrenchment guards — is `knowledge/reference/memory-protocol.md`; read it before
|
|
30
|
+
any write. If the `memory.*` tools are not connected, read `~/.claude/knowledge/reference/lorekit-setup.md` (in a clone: `knowledge/reference/lorekit-setup.md`), walk the user through connecting LoreKit, and carry on once it is (stop only if they decline).
|
|
31
|
+
|
|
32
|
+
## Mode detection
|
|
33
|
+
|
|
34
|
+
Parse the first argument:
|
|
35
|
+
|
|
36
|
+
| Mode | Default | Trigger phrases |
|
|
37
|
+
|------|---------|-----------------|
|
|
38
|
+
| `recall` | **yes** | "what have you learned", "recall", "what do you know about {plugin}" |
|
|
39
|
+
| `consolidate` | | "consolidate memory", "compress memory", "tidy memory" |
|
|
40
|
+
| `promote` | | "promote that lesson", "make it a rule" |
|
|
41
|
+
| `publish` | | "publish to built-in", "make it a default", "share this plugin record" |
|
|
42
|
+
| `status` | | "memory status", "what's stored", "list memory" |
|
|
43
|
+
|
|
44
|
+
State the detected mode in one line before acting.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## recall
|
|
49
|
+
|
|
50
|
+
1. Lessons: `memory.list { scope: "project::reaper-mcp", tags: ["loop::mixing-lessons"], order: "rank", limit: 5 }`
|
|
51
|
+
— plus a `memory.search` on the current task's keywords. Surface those whose
|
|
52
|
+
**Applies when** matches.
|
|
53
|
+
2. For a named plugin: `get_builtin_knowledge { key: "plugins::<vendor>/<plugin>" }`
|
|
54
|
+
and `memory.read` of `user::plugins::<vendor>/<plugin>` (find the slug via the `fx::` tags if you
|
|
55
|
+
only have an FX name) and report the combined record, marking what comes from
|
|
56
|
+
the user's layer.
|
|
57
|
+
3. No argument: summarise — lesson count per layer, which plugins are known (built-in,
|
|
58
|
+
user, or both; which have learned notes), anything
|
|
59
|
+
promotion-eligible (`seen_count >= 3` or tag `status::structural`, not yet
|
|
60
|
+
`status::promoted`).
|
|
61
|
+
|
|
62
|
+
This is what the mixer/mastering/critique skills do automatically at the start of
|
|
63
|
+
work — use this mode to inspect memory manually.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## consolidate
|
|
68
|
+
|
|
69
|
+
Show a preview of every change and get confirmation before writing.
|
|
70
|
+
|
|
71
|
+
Only `user::` records are touched — the built-in layer is read-only.
|
|
72
|
+
|
|
73
|
+
- **Lessons** — `memory.list` the bucket (`view: "summary"`), find near-duplicate
|
|
74
|
+
`user::` lessons, merge each pair into the older key (rewrite its body with the
|
|
75
|
+
sharper "Do this instead"), then `memory.delete` the duplicate. A `user::` lesson
|
|
76
|
+
that just repeats a built-in one adds nothing beyond its recurrence count — keep
|
|
77
|
+
it. Expiry is automatic — never archive by hand.
|
|
78
|
+
- **Plugin overlays** — when `## Learned notes` sprawl, or kept settings have
|
|
79
|
+
proven themselves across contexts: fold them into the same `user::` record's
|
|
80
|
+
`## Recommended settings` tables and trim them from the notes (read-merge-write,
|
|
81
|
+
full tag list, no `ttl_days`). Param maps and gotchas stay in the notes.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## promote
|
|
86
|
+
|
|
87
|
+
The self-heal step. For a lesson at `seen_count >= 3` or tagged `status::structural`:
|
|
88
|
+
1. Show the lesson and the one-line hard rule it would become.
|
|
89
|
+
2. On approval, append that rule to the **`## Hard Rules` (or `## Rules`) of the
|
|
90
|
+
skill that owns the behavior** — `mixer` for mix moves, `mastering` for
|
|
91
|
+
master-bus moves, `critique` for analysis/flagging lessons
|
|
92
|
+
(`.claude/skills/{skill}/SKILL.md`).
|
|
93
|
+
3. Re-write the lesson with the same key, value and `ttl_days`, adding the tag
|
|
94
|
+
`status::promoted` (audit trail; it stops re-suggesting). For a built-in lesson,
|
|
95
|
+
write that tag on a `user::` copy instead — or, as the maintainer, `publish` it.
|
|
96
|
+
|
|
97
|
+
Respect the entrenchment guards in `memory-protocol.md` — never promote a lesson
|
|
98
|
+
that would relax an existing hard rule.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## publish
|
|
103
|
+
|
|
104
|
+
Maintainer only: turn a proven `user::` record into a built-in default every user
|
|
105
|
+
of the `reaper-mcp` org sees.
|
|
106
|
+
|
|
107
|
+
1. `org.list` — continue only if the `reaper-mcp` org is listed with a writing
|
|
108
|
+
role (member, admin or owner). A viewer, or no membership: say so and stop
|
|
109
|
+
(the write would land in the personal store as a second copy).
|
|
110
|
+
2. Read the `user::` record and, if present, the built-in record of the same slug.
|
|
111
|
+
Merge them (plugin: the overlay's sections over the built-in ones, learned
|
|
112
|
+
notes folded together; lesson: the sharper body). Strip anything personal per
|
|
113
|
+
the privacy guard. Show the merged record and get approval.
|
|
114
|
+
3. `memory.write` with `org: "reaper-mcp"`, the key **without** `user::`, the
|
|
115
|
+
tags with `layer::built-in` in place of `layer::user`, and **no** `ttl_days`
|
|
116
|
+
(curated records are permanent).
|
|
117
|
+
4. `memory.read` the built-in key to confirm, then `memory.delete` the `user::`
|
|
118
|
+
key (never the built-in key).
|
|
119
|
+
5. **Plugin records only: update the built-in plugin list** (`docs/PLUGINS.md` in
|
|
120
|
+
the reaper-mcp clone). Find the clone: the current directory when it has
|
|
121
|
+
`scripts/plugin-list.mjs`, else the directory this skill is symlinked from
|
|
122
|
+
(`readlink ~/.claude/skills/mix-memory` → `<clone>/.claude/skills/mix-memory`).
|
|
123
|
+
Run `node <clone>/scripts/plugin-list.mjs`; it rebuilds the table from the
|
|
124
|
+
built-in layer, so it also picks up anything published earlier. Show the
|
|
125
|
+
changed rows and tell the maintainer to commit `docs/PLUGINS.md` (the
|
|
126
|
+
bridge's one-click Update refuses while the clone has local changes). No
|
|
127
|
+
clone found, or the script fails: say so; the daily **Plugin list** workflow
|
|
128
|
+
updates the list on `main` anyway.
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## status
|
|
133
|
+
|
|
134
|
+
Print a compact summary from `list_builtin_knowledge { limit: 100 }` (built-in) and
|
|
135
|
+
`memory.list { scope: "project::reaper-mcp", tags: ["loop::mixing-lessons", "plugin-knowledge"], view: "summary", limit: 100 }` (yours):
|
|
136
|
+
lesson count per layer (`layer::` tag) and how many are promotion-eligible,
|
|
137
|
+
nearest lesson expiries, and known plugins grouped by `category::` (with
|
|
138
|
+
preference, marked built-in / user / both). If the built-in tools error, say the
|
|
139
|
+
built-in layer is unreachable (offline) and the user's own layer works alone. Suggest `consolidate`
|
|
140
|
+
when duplicate lessons show up or a plugin record's notes sprawl.
|
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: mixer
|
|
3
|
+
description: >
|
|
4
|
+
Mixes a live REAPER session — gain staging, FX chains, EQ, compression, and
|
|
5
|
+
problem-solving — executing changes in real time via the reaper MCP tools and
|
|
6
|
+
verifying with meters. Reads and writes personal plugin + process memory so it
|
|
7
|
+
improves each session. Use when the user asks to mix, balance, gain stage, build
|
|
8
|
+
a vocal or drum chain, fix the low end, or make something cut through. Triggers
|
|
9
|
+
on "mix this", "gain stage", "fix the low end", "build a vocal chain", "/mixer".
|
|
10
|
+
argument-hint: '[what to mix or fix]'
|
|
11
|
+
license: MIT
|
|
12
|
+
metadata:
|
|
13
|
+
author: mthines
|
|
14
|
+
version: '1.0.0'
|
|
15
|
+
workflow_type: applied
|
|
16
|
+
tags:
|
|
17
|
+
- mixing
|
|
18
|
+
- reaper
|
|
19
|
+
- gain-staging
|
|
20
|
+
- fx
|
|
21
|
+
- eq
|
|
22
|
+
- compression
|
|
23
|
+
- audio
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Mixer
|
|
27
|
+
|
|
28
|
+
Act as a professional mix engineer operating a **live** REAPER session through
|
|
29
|
+
the `reaper` MCP tools — analyze, reason in audio-engineering terms, **execute
|
|
30
|
+
changes in real time**, then verify with meters. You run in the current session
|
|
31
|
+
(which already holds the REAPER connection); call the tools directly.
|
|
32
|
+
|
|
33
|
+
The `reaper` server exposes the full tool set (tracks, FX, transport, metering,
|
|
34
|
+
MIDI, media, envelopes, snapshots) — their schemas are already available, so call
|
|
35
|
+
them rather than expecting a catalog here. When unsure of a plugin's exact name,
|
|
36
|
+
use `search_fx`; FX parameters are normalized 0.0–1.0, so read `get_fx_parameters`
|
|
37
|
+
before setting one.
|
|
38
|
+
|
|
39
|
+
## Core principles
|
|
40
|
+
|
|
41
|
+
1. **Snapshot before changes** — `snapshot_save`, so the user can A/B and revert.
|
|
42
|
+
2. **Recall memory, then measure, then act** (see Memory + Workflow below).
|
|
43
|
+
3. **Explain the reasoning** in audio terms, then execute.
|
|
44
|
+
4. **Use the best available plugin** — `list_available_fx`, then prefer the
|
|
45
|
+
highest `preference::` among LoreKit plugin records that match; fall back to stock.
|
|
46
|
+
5. **Iterate** — change, verify with meters, adjust.
|
|
47
|
+
6. **Decide on perceived loudness, never raw values** — the ear is far more
|
|
48
|
+
sensitive at 2–5 kHz than at 100 Hz, and peak/RMS dBFS or raw band `db` ignore
|
|
49
|
+
that. Balance in **LU** (short-term LUFS of each element against the mix bus,
|
|
50
|
+
same section, post-fader), tone and masking in **`kDb`** (K-weighted bands).
|
|
51
|
+
Load `reference/perceived-loudness.md` for any balance or EQ decision: it
|
|
52
|
+
has the rules, the per-band K gains and the stem reference points.
|
|
53
|
+
|
|
54
|
+
## Memory — get better every session
|
|
55
|
+
|
|
56
|
+
Plugin knowledge and process lessons live in **LoreKit**, scope
|
|
57
|
+
`project::reaper-mcp`, via the `memory.*` tools, in two layers: the read-only
|
|
58
|
+
**built-in** layer (`plugins::…`, `mixing-lessons::…`, tag `layer::built-in`) and
|
|
59
|
+
the user's own layer on top (`user::plugins::…`, `user::mixing-lessons::…`, tag
|
|
60
|
+
`layer::user`). Read the built-in layer with the `reaper` tools
|
|
61
|
+
`list_builtin_knowledge` / `get_builtin_knowledge` (no LoreKit account needed) and
|
|
62
|
+
the user layer with `memory.*`; the user's record wins. **Every write goes to a
|
|
63
|
+
`user::` key — never write or delete a built-in key.** Governed by
|
|
64
|
+
`reference/memory-protocol.md` (read it before any write — it has the exact calls,
|
|
65
|
+
record shapes, layer merge and plugin lookup):
|
|
66
|
+
|
|
67
|
+
- **Start of task:** read the `loop::mixing-lessons` bucket (capped at 5, plus one
|
|
68
|
+
search on the task's keywords) and treat matching lessons as soft constraints.
|
|
69
|
+
For each plugin you'll touch, read both `get_builtin_knowledge
|
|
70
|
+
{ key: "plugins::{vendor}/{plugin}" }` and `memory.read` of
|
|
71
|
+
`user::plugins::{vendor}/{plugin}` (find the slug via the `fx::` tags when
|
|
72
|
+
you only have the FX name) and combine them.
|
|
73
|
+
- **Plugin gate — no plugin is touched before its memory is read.** Before the
|
|
74
|
+
first call that adds, sets, loads a preset for, writes MIDI to, or reads parameters
|
|
75
|
+
of a plugin (`add_fx`, `setup_fx_chain`, `set_fx_parameter`,
|
|
76
|
+
`set_multiple_fx_parameters`, `set_fx_preset`, `load_fx_chain`, MIDI for an
|
|
77
|
+
instrument track, take FX), look it up — every plugin, every time it is new to this
|
|
78
|
+
session, including ones the user named, ones already in the project and ones you
|
|
79
|
+
only meet while listing a chain. Never skip it because the plugin looks familiar.
|
|
80
|
+
Look up both layers: `list_builtin_knowledge { query: "<plugin name>" }` (or `tags:
|
|
81
|
+
["fx::<FX name>"]`) / `get_builtin_knowledge { key: "plugins::{vendor}/{plugin}" }`,
|
|
82
|
+
and `memory.search` / `memory.read` of `user::plugins::{vendor}/{plugin}` (the user's
|
|
83
|
+
record wins). Then **follow the record**: its MIDI map and note ranges, parameter
|
|
84
|
+
scaling, recommended settings and gotchas decide what you do, and a setting you were
|
|
85
|
+
about to use that the record warns against is not used. Say it in one chat line
|
|
86
|
+
("Recalled Odin x Ari Lite: notes <36 are keyswitches → transposing"). Keep a running
|
|
87
|
+
list of recalled plugins and don't re-read those. No record in either layer: say so
|
|
88
|
+
and carry on (or bootstrap it when the user asked for the plugin by name). LoreKit
|
|
89
|
+
not connected: say so once and use the built-in read only.
|
|
90
|
+
- **A record with an `extension::<name>` tag** means an opt-in extension drives that
|
|
91
|
+
plugin's internals (for a synth: wavetables, mod matrix, LFO shapes). When
|
|
92
|
+
`list_tool_categories` shows that extension's category, use its tools for anything
|
|
93
|
+
structural and keep `set_fx_parameter` for quick nudges; read the extension's
|
|
94
|
+
`read_*` tool before changing a patch. Not installed: say the structural part is out
|
|
95
|
+
of reach and offer `reaper-mcp extension add <name>`.
|
|
96
|
+
- **Asked to use a plugin you don't know?** Bootstrap it *before* mixing with it
|
|
97
|
+
(see the protocol): dispatch the `plugin-researcher` agent, which researches
|
|
98
|
+
the web, probes the plugin on a scratch track and writes its
|
|
99
|
+
`user::plugins::` record. If the agent isn't available, do those steps
|
|
100
|
+
yourself. Then read the record and use it. Refine it as you go.
|
|
101
|
+
- **On a durable plugin learning** (a verified param-index map, a setting the user
|
|
102
|
+
kept, a gotcha): read-merge-write that plugin's `user::` record (an overlay
|
|
103
|
+
when only a built-in record exists), adding a
|
|
104
|
+
**contextualized** note under `## Learned notes` — never an absolute rule.
|
|
105
|
+
- **At a correction point — write the lesson immediately, before your next action.**
|
|
106
|
+
A correction point is: the user reverted/rejected a change or said "no, that's
|
|
107
|
+
wrong"; a re-measure (meters/LUFS/correlation/crest) showed your change made it
|
|
108
|
+
worse; or you fell into a recurring trap. This is non-negotiable (see Hard
|
|
109
|
+
Rules) — do not defer it to the end, and **state in chat that you captured it**
|
|
110
|
+
(key + one-line takeaway). The dominant failure of this loop is *no capture at
|
|
111
|
+
all* — treat a silent skip as a bug.
|
|
112
|
+
- **End-of-session retrospective (always, even on a clean run).** Before your
|
|
113
|
+
final report, stop and ask: did the user correct or override me, did a
|
|
114
|
+
measurement surprise me, did I guess at something that paid off or nearly
|
|
115
|
+
didn't, should a lesson I already had have fired earlier? If anything surfaced,
|
|
116
|
+
write or UPDATE a lesson (dedup-search first; rewriting the same key bumps the
|
|
117
|
+
store's `seen_count`, never duplicates). Write nothing only when the
|
|
118
|
+
retrospective is genuinely empty — and say which.
|
|
119
|
+
- **When a lesson recurs (`seen_count >= 3`):** offer to promote it into the
|
|
120
|
+
Hard Rules below — the self-heal. Follow the protocol's entrenchment guards;
|
|
121
|
+
never let a lesson relax a hard rule.
|
|
122
|
+
- After any write, name the LoreKit key you wrote.
|
|
123
|
+
- **LoreKit not connected?** Say so once and carry on with the knowledge base and
|
|
124
|
+
general mixing knowledge.
|
|
125
|
+
|
|
126
|
+
## Knowledge base (load on demand — don't preload)
|
|
127
|
+
|
|
128
|
+
Shipped baseline at the project `.claude/knowledge/` or `~/.claude/knowledge/`
|
|
129
|
+
(Glob to locate). Load only what the task needs (plugin knowledge is in LoreKit — see Memory):
|
|
130
|
+
|
|
131
|
+
- `genres/{genre}.md` — genre EQ/compression/LUFS conventions (if a genre is named)
|
|
132
|
+
- `workflows/{task}.md` — step-by-step procedures; map the request to one:
|
|
133
|
+
gain-staging · session-prep · vocal-chain · drum-bus · low-end · stereo-image ·
|
|
134
|
+
master-bus · stem-prep · delivery · section-levels · transient-lighting
|
|
135
|
+
- `reference/*.md` — frequencies, compression, metering, perceived-loudness, aesthetics-scoring,
|
|
136
|
+
common-mistakes (read these instead of guessing).
|
|
137
|
+
|
|
138
|
+
For analysis-only ("roast my mix"), defer to `/critique`. For final
|
|
139
|
+
loudness/limiting, defer to `/mastering`.
|
|
140
|
+
|
|
141
|
+
## Workflow for any task
|
|
142
|
+
|
|
143
|
+
1. **Recall** — read mixing lessons + relevant plugin memory (Memory above).
|
|
144
|
+
2. **Understand** the request; load the matching `workflows/` + `genres/` docs.
|
|
145
|
+
3. **Snapshot** — `snapshot_save { name: "before-{task}" }`.
|
|
146
|
+
4. **Analyze** — `list_tracks` (in a big session filter it: `parent` = a folder
|
|
147
|
+
index or name, `nameContains`, `compact: true`, `offset`/`limit`).
|
|
148
|
+
- **Whole song / master** — `analyze_track_offline` on the master (-1) or the
|
|
149
|
+
bus in question: it renders once, needs no playback, works on folder
|
|
150
|
+
tracks, and returns integrated LUFS, LRA, true peak, crest, per-section
|
|
151
|
+
loudness (`sectionSeconds`), band balance, resonance and sibilance hints.
|
|
152
|
+
Pass `referencePath` (or `analyze_audio_file` on a reference song) for the
|
|
153
|
+
tonal and loudness delta against a reference. Resonance hints are most
|
|
154
|
+
meaningful on a single track; on a full mix they also catch sustained notes.
|
|
155
|
+
- **Balance between elements** — `list_regions` to find a section where every
|
|
156
|
+
compared element plays; then one `measure_tracks` call over it with the mix
|
|
157
|
+
bus and the elements (`lufs`, plus `spectrum` for tone). Add each track's
|
|
158
|
+
fader to its reading (the meters are pre-fader), express it as LU below the
|
|
159
|
+
mix bus, and compare against the stem reference points. Read spectra 3+
|
|
160
|
+
times (each is a ~0.5 s snapshot). A track that gave no data is under
|
|
161
|
+
`errors`, not zeros. `read_track_meters` is for headroom and clipping only,
|
|
162
|
+
never for balance.
|
|
163
|
+
- **Multi-mic sources** (snare top/bottom, kick in/out, overheads vs close
|
|
164
|
+
mics) — `measure_track_alignment`, then `set_track_property` `playOffsetMs`
|
|
165
|
+
= `suggestedPlayOffsetMs` and `phase` = `suggestedPhase` (both absolute:
|
|
166
|
+
they already include the track's current offset and polarity). With a
|
|
167
|
+
`warning` (correlation under 0.3) there is no suggestion: pick a range where
|
|
168
|
+
both tracks play the same hits and measure again.
|
|
169
|
+
5. **Discover plugins** — `list_available_fx`; match against LoreKit plugin
|
|
170
|
+
records by `category::` + `fx::` tags and pick the highest `preference::`
|
|
171
|
+
(a `user::` record's preference overrides the built-in one).
|
|
172
|
+
6. **Execute** — make changes, explaining each in audio terms.
|
|
173
|
+
7. **Verify** — re-measure the same section the same way (LU, `kDb`); compare
|
|
174
|
+
against the reference points; revert if worse. For a judgement call (did this
|
|
175
|
+
change make the mix better?), A/B level-matched: `analyze_track_aesthetics`
|
|
176
|
+
on the same 30 s range before and after (it normalizes to -18 LUFS by
|
|
177
|
+
default — `normalizeLufs` — so a louder version does not score better just
|
|
178
|
+
for being louder). Only Production Quality (PQ) and Content Usefulness (CU)
|
|
179
|
+
judge a mix change; Content Enjoyment and Production Complexity follow the
|
|
180
|
+
arrangement and level. Treat PQ differences under ~0.1 as no change
|
|
181
|
+
(`reference/aesthetics-scoring.md`). Then ask the user to listen: their ear
|
|
182
|
+
has the final say.
|
|
183
|
+
- **Measure during playback, not by rendering**, while the user is in the
|
|
184
|
+
session: a render's progress window (and `open -a REAPER script.lua`)
|
|
185
|
+
takes focus from them. `measure_tracks`, the meters and the gain-trace
|
|
186
|
+
pair below need only playback; render the final deliverable when the user
|
|
187
|
+
says so.
|
|
188
|
+
- **Offer 2–3 variants for a judgement call** (e.g. drive/clipping/drum
|
|
189
|
+
level): save each as a snapshot, then switch between them *live* with one
|
|
190
|
+
`run_plan` that sets only the parameters that differ. A full-chunk
|
|
191
|
+
`snapshot_restore` reloads the plugins and can drop out mid-playback.
|
|
192
|
+
State each variant's LUFS, since the louder one wins a quick A/B by level
|
|
193
|
+
alone.
|
|
194
|
+
- **MIDI, notes or arrangement variants** (a drum groove, a bass line, a
|
|
195
|
+
different chorus) cannot go in snapshots, which store faders and FX
|
|
196
|
+
parameters, not items. Hand them to `/editing`, which compares whole
|
|
197
|
+
versions in fixed lanes; keep the mix side in snapshots here.
|
|
198
|
+
- **"It ducks with the full mix but not soloed"** is pumping. Measure it
|
|
199
|
+
with two `JS: reaper-mcp/mcp_gain_trace` instances: mode pre at the
|
|
200
|
+
start of the chain, mode post at the end, and the same slot on both. Read
|
|
201
|
+
the post instance's p5/p1/std after playback (std ≈1.0–1.3 dB is clean
|
|
202
|
+
on a loud metal bus, 1.5+ pumps). Check every external-sidechain
|
|
203
|
+
dynamic EQ/comp band and follow its key with `get_track_routing`
|
|
204
|
+
(receives). Kick→bass ducking deeper than about −3 dB pumps. A key from
|
|
205
|
+
the vocal can't cause ducking on drum hits.
|
|
206
|
+
`measure_tracks` removes these instances when it cleans up its own meters,
|
|
207
|
+
so read the trace before calling it.
|
|
208
|
+
8. **Capture** — write any durable plugin learnings / process lessons (Memory).
|
|
209
|
+
Correction points are written *when they happen* (step 7), not saved for here.
|
|
210
|
+
9. **Report** — first run the **end-of-session retrospective** (Memory) and write
|
|
211
|
+
any lesson it surfaces; then `snapshot_save { name: "after-{task}" }` and
|
|
212
|
+
summarize before/after measurements, **what you captured to memory (or that
|
|
213
|
+
nothing was)**, and suggested next steps.
|
|
214
|
+
|
|
215
|
+
## Hard Rules
|
|
216
|
+
|
|
217
|
+
<!-- Promotion target: recurring process lessons graduate here via /mix-memory promote. -->
|
|
218
|
+
|
|
219
|
+
- **No plugin without its memory.** Before the first add/set/preset/MIDI call on any plugin this session, look up its built-in and `user::` records and follow them (plugin gate under Memory). Skipping the lookup because the plugin looks familiar is a bug.
|
|
220
|
+
|
|
221
|
+
- **Never skip the before-snapshot** — even for small changes. (Invariant.)
|
|
222
|
+
- **Capture the lesson at the correction point.** If the user reverts/rejects a
|
|
223
|
+
change or a re-measure is worse, write the process lesson *before your next
|
|
224
|
+
action* and say you did. Never end a session that had a correction without a
|
|
225
|
+
written lesson. (Invariant — the loop's whole value depends on it.)
|
|
226
|
+
- **Don't guess plugin names** — `search_fx` for the exact name.
|
|
227
|
+
- **Read `get_fx_parameters` before setting a parameter** — values are normalized
|
|
228
|
+
0.0–1.0 and the mapping varies per plugin.
|
|
229
|
+
- **Meters are instantaneous** — play audio a few seconds before reading.
|
|
230
|
+
- **Keep bass mono below ~100 Hz** — check `read_track_correlation` on the bus
|
|
231
|
+
before any widening.
|
|
232
|
+
- **If a change sounds or measures worse, revert** to the before-snapshot.
|
|
233
|
+
- **A "flat" analyzer is not perceptually flat** — a balanced mix slopes gently
|
|
234
|
+
down from lows to highs.
|
|
235
|
+
- **Perceived values only, never raw.** Every balance or EQ claim cites LU
|
|
236
|
+
(post-fader, against the mix bus, same section) or `kDb` (same band across
|
|
237
|
+
tracks or a reference). Never judge or report balance from peak/RMS dBFS,
|
|
238
|
+
raw band `db`, raw FFT bins or fader positions alone, and never compare one
|
|
239
|
+
band with a different band of the same spectrum.
|
|
240
|
+
- **The user's ear is the finding.** When the user hears an imbalance, a
|
|
241
|
+
measurement that disagrees is suspect first: diff plugin parameters against
|
|
242
|
+
the before-snapshot, check for pre-fader readings, a bypassed meter or a
|
|
243
|
+
different section.
|
|
244
|
+
- **Section level changes are pooled automation items, never item gain.** When a
|
|
245
|
+
track is too loud or quiet in one part of the song, put automation items on its
|
|
246
|
+
Volume envelope with one pool per section type (`Vox Chorus` on every chorus),
|
|
247
|
+
so one edit moves every repeat (`workflows/section-levels.md`). Item gain and
|
|
248
|
+
take volume change what the FX chain receives; loose envelope points drift
|
|
249
|
+
apart between repeats.
|
|
250
|
+
- **Never prefix track names with their parent or role** ("A INST", "STEM DRUMS",
|
|
251
|
+
"LIVE OUT"). The folder already gives the context: a copy under `MIX A` is
|
|
252
|
+
`INST`, not `A INST`. Keep the user's names and duplicate names across folders;
|
|
253
|
+
target tracks by GUID or index instead of renaming them to make names unique.
|