@williamzujkowski/live-coding-music-mcp 2.0.0 → 4.0.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 +175 -249
- package/dist/AudioAnalyzer.js +0 -1
- package/dist/PatternStore.js +0 -1
- package/dist/index.js +0 -0
- package/dist/server/resources.js +175 -0
- package/dist/server/server.js +227 -349
- package/dist/server/tools/ai.js +59 -59
- package/dist/server/tools/analysis.js +245 -82
- package/dist/server/tools/capture.js +51 -42
- package/dist/server/tools/compose.js +145 -0
- package/dist/server/tools/diagnostics.js +77 -72
- package/dist/server/tools/editor.js +100 -99
- package/dist/server/tools/generate.js +146 -175
- package/dist/server/tools/history.js +132 -124
- package/dist/server/tools/playback.js +41 -26
- package/dist/server/tools/session.js +93 -93
- package/dist/server/tools/storage.js +61 -53
- package/dist/server/tools/transform.js +193 -206
- package/dist/server/tools/types.js +66 -1
- package/dist/services/AudioCaptureService.js +4 -3
- package/dist/services/GeminiService.js +1 -1
- package/dist/services/MIDIExportService.js +2 -4
- package/dist/services/SessionManager.js +4 -2
- package/dist/services/StrudelEngine.js +24 -126
- package/dist/services/StrudelEngineHelpers.js +151 -0
- package/package.json +1 -1
- package/dist/__tests__/MusicTheory.test.js +0 -245
- package/dist/__tests__/PatternGenerator.test.js +0 -337
- package/dist/__tests__/PatternStore.test.js +0 -153
- package/dist/__tests__/utils/MockPlaywright.js +0 -130
- package/dist/server/EnhancedMCPServer.js +0 -654
- package/dist/server/EnhancedMCPServerFixed.js +0 -2506
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
>
|
|
5
5
|
> **Unofficial fan project.** Not affiliated with, or endorsed by, the [Strudel project](https://codeberg.org/uzu/strudel). This adapter exists to make live-coding music accessible to beginners who want to try pattern-based music without learning the whole ecosystem first.
|
|
6
6
|
>
|
|
7
|
-
> **Status:** Beta |
|
|
7
|
+
> **Status:** Beta | 86% statement coverage | Published to npm | Actively developed
|
|
8
8
|
|
|
9
9
|
<a href="https://glama.ai/mcp/servers/@williamzujkowski/live-coding-music-mcp">
|
|
10
10
|
<img width="380" height="200" src="https://glama.ai/mcp/servers/@williamzujkowski/live-coding-music-mcp/badge" alt="live-coding-music-mcp server" />
|
|
@@ -13,16 +13,16 @@
|
|
|
13
13
|
[](https://github.com/williamzujkowski/live-coding-music-mcp/actions)
|
|
14
14
|
[](https://www.npmjs.com/package/@williamzujkowski/live-coding-music-mcp)
|
|
15
15
|
[](https://nerq.ai/kya/live-coding-music-mcp)
|
|
16
|
-
[]()
|
|
17
17
|
[](LICENSE)
|
|
18
18
|
|
|
19
19
|
A Model Context Protocol (MCP) server that drives [Strudel.cc](https://strudel.cc/) from Claude for AI-assisted live-coding music, pattern generation, and algorithmic composition.
|
|
20
20
|
|
|
21
|
-
**Current State: Beta.** The core workflow (init → generate → write → play → analyze) works reliably with real audio output
|
|
21
|
+
**Current State: Beta.** The core workflow (init → generate → write → play → analyze) works reliably with real audio output. 1771 tests pass, 86.76% statement coverage / 77.32% branch coverage. CI is hardened with OpenSSF Scorecard, SHA-pinned actions, CODEOWNERS, Dependabot, and lint as a blocking gate.
|
|
22
22
|
|
|
23
23
|
**What "Beta" means here:**
|
|
24
24
|
- Tool schemas are stable within minor versions; breaking changes require a major bump
|
|
25
|
-
-
|
|
25
|
+
- Multi-session is supported as of v3.0.0 ([#108](https://github.com/williamzujkowski/live-coding-music-mcp/issues/108)) — named sessions get isolated browser, history, and audio-capture state
|
|
26
26
|
- Upstream `@strudel/*` dependencies pinned to known-good versions; Dependabot bumps gated on CI
|
|
27
27
|
- Expect hands-on iteration for non-standard patterns — report rough edges, they get fixed
|
|
28
28
|
|
|
@@ -44,40 +44,39 @@ A Model Context Protocol (MCP) server that drives [Strudel.cc](https://strudel.c
|
|
|
44
44
|
|
|
45
45
|
## Features
|
|
46
46
|
|
|
47
|
-
### 🎹
|
|
48
|
-
- **
|
|
49
|
-
- **
|
|
50
|
-
- **
|
|
51
|
-
- **
|
|
52
|
-
- **
|
|
53
|
-
- **
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
-
|
|
60
|
-
-
|
|
61
|
-
-
|
|
47
|
+
### 🎹 Music control
|
|
48
|
+
- **84 MCP tools** covering pattern editing, playback, audio analysis, generation, history, sessions, and Gemini-backed assists. 26 are the canonical consolidated tools (`pattern_store`, `edit_pattern`, `transform`, `analyze`, `history`, `playback`, `effect`, `shape`, `audio_capture`, `browser_window`, `generate_part`, `generate_rhythm`, `music_theory`, `session`, `ai_assist`, ...); the rest are deprecated aliases kept for one release ([#178](https://github.com/williamzujkowski/live-coding-music-mcp/issues/178)).
|
|
49
|
+
- **4 MCP resources** for catalog browsing without burning tool calls: `strudel://examples`, `strudel://patterns`, `strudel://styles`, `strudel://docs/tools`.
|
|
50
|
+
- **Real browser automation** of Strudel.cc through Playwright.
|
|
51
|
+
- **Multi-session support** — every browser-touching tool accepts an optional `session_id`; sessions have isolated browser pages, undo/redo/history stacks, and audio-capture services.
|
|
52
|
+
- **Audio analysis** via Web Audio API (FFT spectrum, tempo detection, key detection, rhythm complexity).
|
|
53
|
+
- **Template-based pattern generation** across 8 genres (techno, house, dnb, ambient, trap, jungle, jazz, experimental); optional Gemini-backed `ai_assist` for feedback, suggestions, and jamming.
|
|
54
|
+
- **Music theory helpers**: 15+ scales, 8+ chord progression styles, euclidean and polyrhythm generation.
|
|
55
|
+
- **Pattern persistence**: JSON-backed save/load with tags + the in-memory edit history (undo/redo/restore/compare).
|
|
56
|
+
- **Result envelope** on every `tools/call`: clients branch on `{ ok, errorCategory, isRetryable }` instead of parsing free-text.
|
|
57
|
+
|
|
58
|
+
### 🔧 Testing & CI status
|
|
59
|
+
- **1771 passing tests** across unit, integration, and example-validation suites.
|
|
60
|
+
- **86.76% statement coverage / 77.32% branch coverage**.
|
|
61
|
+
- **Lint blocking in CI**: 0 errors, ~163 warnings (mostly `any` in test mocks).
|
|
62
|
+
- **OIDC trusted publishing** to npm with SLSA build provenance attestation on every release.
|
|
62
63
|
|
|
63
64
|
**Not Production-Ready:** This is experimental software under active development. Use for exploration and experimentation. Expect breaking changes, bugs, and incomplete features. See [CONTRIBUTING.md](CONTRIBUTING.md) to help improve it.
|
|
64
65
|
|
|
65
|
-
### 🎼 Example
|
|
66
|
+
### 🎼 Example patterns
|
|
66
67
|
|
|
67
|
-
|
|
68
|
+
18 example patterns ship in [`patterns/examples/`](patterns/examples/), grouped by genre:
|
|
68
69
|
|
|
69
|
-
- **Techno**:
|
|
70
|
-
- **House**:
|
|
71
|
-
- **Drum & Bass**:
|
|
72
|
-
- **Ambient**:
|
|
73
|
-
- **Trap**:
|
|
74
|
-
- **Jungle**:
|
|
75
|
-
- **Jazz**:
|
|
76
|
-
- **
|
|
77
|
-
- **Trip Hop**: Portishead, Massive Attack, Flying Lotus style
|
|
78
|
-
- **Boom Bap**: DJ Premier, Alchemist, golden era hip hop
|
|
70
|
+
- **Techno**: hard-techno, minimal-techno
|
|
71
|
+
- **House**: deep-house, tech-house
|
|
72
|
+
- **Drum & Bass**: liquid-dnb, neurofunk
|
|
73
|
+
- **Ambient**: dark-ambient, drone
|
|
74
|
+
- **Trap**: modern-trap, cloud-trap
|
|
75
|
+
- **Jungle**: classic-jungle, ragga-jungle
|
|
76
|
+
- **Jazz**: bebop, modal-jazz
|
|
77
|
+
- **Longform** (multi-minute pieces): dark-ambient-journey, driving-techno, liquid-dnb-roller, nu-jazz-session
|
|
79
78
|
|
|
80
|
-
Each example
|
|
79
|
+
Each example is a JSON file with pattern code, BPM, key, and a description. See [`patterns/examples/README.md`](patterns/examples/README.md) for details. Agents can also list these via the `strudel://examples` MCP resource without making any tool calls.
|
|
81
80
|
|
|
82
81
|
## Migrating from `@williamzujkowski/strudel-mcp-server`
|
|
83
82
|
|
|
@@ -156,16 +155,21 @@ npm run build
|
|
|
156
155
|
|
|
157
156
|
Common commands for immediate use:
|
|
158
157
|
|
|
159
|
-
| Action |
|
|
160
|
-
|
|
158
|
+
| Action | Tool call |
|
|
159
|
+
|---|---|
|
|
161
160
|
| Initialize browser | `init` |
|
|
162
|
-
| Create techno beat | `
|
|
163
|
-
| Play pattern | `play` |
|
|
164
|
-
| Stop playback | `stop` |
|
|
161
|
+
| Create a techno beat in one shot | `compose({ style: "techno" })` |
|
|
162
|
+
| Play pattern | `playback({ action: "play" })` |
|
|
163
|
+
| Stop playback | `playback({ action: "stop" })` |
|
|
165
164
|
| Get current pattern | `get_pattern` |
|
|
166
|
-
| Analyze audio | `analyze` |
|
|
167
|
-
|
|
|
168
|
-
|
|
|
165
|
+
| Analyze audio (all features) | `analyze({ include: ["all"] })` |
|
|
166
|
+
| Detect tempo only | `analyze({ include: ["tempo"] })` |
|
|
167
|
+
| Save pattern | `pattern_store({ action: "save", name: "my-pattern" })` |
|
|
168
|
+
| Undo last edit | `history({ action: "undo" })` |
|
|
169
|
+
| Edit current pattern | `edit_pattern({ mode: "write", pattern: "..." })` |
|
|
170
|
+
| Create an isolated session | `session({ action: "create", session_id: "live-1" })` |
|
|
171
|
+
|
|
172
|
+
The legacy single-verb tools (`play`, `stop`, `save`, `undo`, `write`, `generate_pattern`, ...) were deprecated aliases during the `3.0.x` line and were removed in v4.0.0 ([#178](https://github.com/williamzujkowski/live-coding-music-mcp/issues/178)). Use the consolidated tools above.
|
|
169
173
|
|
|
170
174
|
**One-shot workflow:**
|
|
171
175
|
```
|
|
@@ -197,7 +201,7 @@ Then ask Claude:
|
|
|
197
201
|
|
|
198
202
|
<!-- TOOLS:START -->
|
|
199
203
|
|
|
200
|
-
**
|
|
204
|
+
**26 tools** across 14 categories:
|
|
201
205
|
|
|
202
206
|
<details><summary><strong>Setup</strong> (1)</summary>
|
|
203
207
|
|
|
@@ -207,127 +211,94 @@ Then ask Claude:
|
|
|
207
211
|
|
|
208
212
|
</details>
|
|
209
213
|
|
|
210
|
-
<details><summary><strong>Pattern Editing</strong> (
|
|
214
|
+
<details><summary><strong>Pattern Editing</strong> (2)</summary>
|
|
211
215
|
|
|
212
216
|
| Tool | Description |
|
|
213
217
|
|------|-------------|
|
|
214
|
-
| `
|
|
215
|
-
| `append` | Append code to current pattern |
|
|
216
|
-
| `insert` | Insert code at specific line |
|
|
217
|
-
| `replace` | Replace pattern section |
|
|
218
|
+
| `edit_pattern` | Mutate the current session pattern. |
|
|
218
219
|
| `get_pattern` | Get current pattern code |
|
|
219
220
|
|
|
220
221
|
</details>
|
|
221
222
|
|
|
222
|
-
<details><summary><strong>Playback</strong> (
|
|
223
|
+
<details><summary><strong>Playback</strong> (2)</summary>
|
|
223
224
|
|
|
224
225
|
| Tool | Description |
|
|
225
226
|
|------|-------------|
|
|
226
|
-
| `
|
|
227
|
-
| `clear` | Clear the editor |
|
|
228
|
-
| `play` | Start playing pattern |
|
|
229
|
-
| `pause` | Pause playback |
|
|
230
|
-
| `stop` | Stop playback |
|
|
227
|
+
| `playback` | Control transport on the current session. |
|
|
231
228
|
| `set_tempo` | Set BPM |
|
|
232
229
|
|
|
233
230
|
</details>
|
|
234
231
|
|
|
235
|
-
<details><summary><strong>Storage</strong> (
|
|
232
|
+
<details><summary><strong>Storage</strong> (1)</summary>
|
|
236
233
|
|
|
237
234
|
| Tool | Description |
|
|
238
235
|
|------|-------------|
|
|
239
|
-
| `
|
|
240
|
-
| `load` | Load saved pattern |
|
|
241
|
-
| `list` | List saved patterns |
|
|
236
|
+
| `pattern_store` | Persist patterns to disk and read them back. |
|
|
242
237
|
|
|
243
238
|
</details>
|
|
244
239
|
|
|
245
|
-
<details><summary><strong>History</strong> (
|
|
240
|
+
<details><summary><strong>History</strong> (1)</summary>
|
|
246
241
|
|
|
247
242
|
| Tool | Description |
|
|
248
243
|
|------|-------------|
|
|
249
|
-
| `
|
|
250
|
-
| `redo` | Redo action |
|
|
251
|
-
| `list_history` | List recent pattern history with timestamps and previews |
|
|
252
|
-
| `restore_history` | Restore a previous pattern from history by ID |
|
|
244
|
+
| `history` | Navigate or inspect the pattern edit history. |
|
|
253
245
|
|
|
254
246
|
</details>
|
|
255
247
|
|
|
256
|
-
<details><summary><strong>Generation</strong> (
|
|
248
|
+
<details><summary><strong>Generation</strong> (3)</summary>
|
|
257
249
|
|
|
258
250
|
| Tool | Description |
|
|
259
251
|
|------|-------------|
|
|
260
|
-
| `compose` | Generate, write, and play a complete pattern in one step. Auto-initializes browser if needed. |
|
|
261
|
-
| `
|
|
262
|
-
| `
|
|
263
|
-
| `generate_bassline` | Generate bassline |
|
|
264
|
-
| `generate_melody` | Generate melody from scale |
|
|
265
|
-
| `generate_polyrhythm` | Generate polyrhythm |
|
|
266
|
-
| `generate_fill` | Generate drum fill |
|
|
267
|
-
| `generate_variation` | Create pattern variations |
|
|
252
|
+
| `compose` | Generate, write, and play a complete pattern in one step. Auto-initializes default browser if needed. |
|
|
253
|
+
| `generate_part` | Generate a single instrumental layer and append it to the current session pattern. |
|
|
254
|
+
| `generate_rhythm` | Generate a rhythmic pattern and append it to the current session. |
|
|
268
255
|
|
|
269
256
|
</details>
|
|
270
257
|
|
|
271
|
-
<details><summary><strong>Music Theory</strong> (
|
|
258
|
+
<details><summary><strong>Music Theory</strong> (1)</summary>
|
|
272
259
|
|
|
273
260
|
| Tool | Description |
|
|
274
261
|
|------|-------------|
|
|
275
|
-
| `
|
|
276
|
-
| `generate_chord_progression` | Generate chord progression |
|
|
277
|
-
| `generate_euclidean` | Generate Euclidean rhythm |
|
|
278
|
-
| `apply_scale` | Apply scale to notes |
|
|
262
|
+
| `music_theory` | Music-theory queries. |
|
|
279
263
|
|
|
280
264
|
</details>
|
|
281
265
|
|
|
282
|
-
<details><summary><strong>Transform</strong> (
|
|
266
|
+
<details><summary><strong>Transform</strong> (3)</summary>
|
|
283
267
|
|
|
284
268
|
| Tool | Description |
|
|
285
269
|
|------|-------------|
|
|
286
|
-
| `
|
|
287
|
-
| `
|
|
288
|
-
| `
|
|
289
|
-
| `quantize` | Quantize to grid |
|
|
290
|
-
| `humanize` | Add human timing variation |
|
|
291
|
-
| `add_effect` | Add effect to pattern |
|
|
292
|
-
| `remove_effect` | Remove effect |
|
|
293
|
-
| `add_swing` | Add swing to pattern |
|
|
294
|
-
| `set_energy` | Adjust the overall energy level of the current pattern on a 0-10 scale. 0: minimal/ambient, 1-2: sparse, 3-4: light/relaxed, 5-6: normal/moderate, 7-8: driving/intense, 9-10: maximum. Auto-plays after applying energy level. |
|
|
270
|
+
| `transform` | Apply a single transform op to the current session pattern. |
|
|
271
|
+
| `effect` | Add or remove a Strudel effect on the current session pattern. |
|
|
272
|
+
| `shape` | Shape the current pattern along one of three high-level dimensions. |
|
|
295
273
|
|
|
296
274
|
</details>
|
|
297
275
|
|
|
298
|
-
<details><summary><strong>AI</strong> (
|
|
276
|
+
<details><summary><strong>AI</strong> (1)</summary>
|
|
299
277
|
|
|
300
278
|
| Tool | Description |
|
|
301
279
|
|------|-------------|
|
|
302
|
-
| `
|
|
303
|
-
| `jam_with` | AI generates a complementary layer to jam with your pattern. Analyzes current pattern to detect tempo, key, and existing layers, then generates a matching layer that fits musically. |
|
|
304
|
-
| `shift_mood` | Transform current pattern to match a different emotional mood by adjusting tempo, effects, and note choices. Moods: dark, euphoric, melancholic, aggressive, dreamy, peaceful, energetic. |
|
|
305
|
-
| `refine` | Incrementally refine the current pattern with simple directional commands. Supports: faster/slower (tempo), louder/quieter (gain), brighter/darker (filter cutoff), "more reverb"/drier (reverb). Auto-plays after applying refinement. |
|
|
280
|
+
| `ai_assist` | Gemini-backed pattern assistance. |
|
|
306
281
|
|
|
307
282
|
</details>
|
|
308
283
|
|
|
309
|
-
<details><summary><strong>Analysis</strong> (
|
|
284
|
+
<details><summary><strong>Analysis</strong> (6)</summary>
|
|
310
285
|
|
|
311
286
|
| Tool | Description |
|
|
312
287
|
|------|-------------|
|
|
313
|
-
| `analyze` |
|
|
314
|
-
| `analyze_spectrum` | FFT spectrum analysis |
|
|
315
|
-
| `analyze_rhythm` | Rhythm analysis |
|
|
316
|
-
| `detect_tempo` | BPM detection |
|
|
317
|
-
| `detect_key` | Key detection |
|
|
288
|
+
| `analyze` | Audio analysis on the currently-playing pattern. |
|
|
318
289
|
| `validate_pattern_runtime` | Validate pattern with runtime error checking (monitors Strudel console for errors) |
|
|
319
|
-
| `
|
|
290
|
+
| `validate_pattern_local` | Validate pattern syntax against the in-process StrudelEngine (no browser required) |
|
|
291
|
+
| `analyze_pattern_local` | Static analysis (events/cycle, complexity, optional BPM) without browser playback |
|
|
292
|
+
| `query_pattern_events` | Enumerate events the pattern would emit between two cycle indices (max 16 cycles) |
|
|
293
|
+
| `transpile_pattern` | Transpile pattern source via StrudelEngine; returns transpiled code or syntax error |
|
|
320
294
|
|
|
321
295
|
</details>
|
|
322
296
|
|
|
323
|
-
<details><summary><strong>Session</strong> (
|
|
297
|
+
<details><summary><strong>Session</strong> (1)</summary>
|
|
324
298
|
|
|
325
299
|
| Tool | Description |
|
|
326
300
|
|------|-------------|
|
|
327
|
-
| `
|
|
328
|
-
| `destroy_session` | Close and destroy a Strudel session, releasing its resources. |
|
|
329
|
-
| `list_sessions` | List all active Strudel sessions with their metadata. |
|
|
330
|
-
| `switch_session` | Change the default session used by other tools. |
|
|
301
|
+
| `session` | Manage isolated Strudel browser sessions (multi-session, #108). |
|
|
331
302
|
|
|
332
303
|
</details>
|
|
333
304
|
|
|
@@ -336,41 +307,27 @@ Then ask Claude:
|
|
|
336
307
|
| Tool | Description |
|
|
337
308
|
|------|-------------|
|
|
338
309
|
| `export_midi` | Export current pattern to MIDI file. Parses note(), n(), and chord() functions. |
|
|
339
|
-
| `
|
|
340
|
-
|
|
341
|
-
</details>
|
|
342
|
-
|
|
343
|
-
<details><summary><strong>Audio</strong> (3)</summary>
|
|
344
|
-
|
|
345
|
-
| Tool | Description |
|
|
346
|
-
|------|-------------|
|
|
347
|
-
| `start_audio_capture` | Start capturing audio from Strudel output. Audio must be playing for capture to work. |
|
|
348
|
-
| `stop_audio_capture` | Stop audio capture and return the recorded audio as base64-encoded data. |
|
|
349
|
-
| `capture_audio_sample` | Capture a fixed-duration audio sample from Strudel output. Audio must be playing. |
|
|
310
|
+
| `browser_window` | Interact with the visible Strudel browser window. |
|
|
350
311
|
|
|
351
312
|
</details>
|
|
352
313
|
|
|
353
|
-
<details><summary><strong>
|
|
314
|
+
<details><summary><strong>Audio</strong> (1)</summary>
|
|
354
315
|
|
|
355
316
|
| Tool | Description |
|
|
356
317
|
|------|-------------|
|
|
357
|
-
| `
|
|
358
|
-
| `performance_report` | Get performance metrics and bottlenecks |
|
|
359
|
-
| `memory_usage` | Get current memory usage statistics |
|
|
360
|
-
| `diagnostics` | Get detailed browser diagnostics including cache, errors, and performance |
|
|
361
|
-
| `show_errors` | Display captured console errors and warnings from Strudel |
|
|
318
|
+
| `audio_capture` | Record audio output from the live Strudel session. |
|
|
362
319
|
|
|
363
320
|
</details>
|
|
364
321
|
|
|
365
|
-
<details><summary><strong>
|
|
322
|
+
<details><summary><strong>Debug</strong> (1)</summary>
|
|
366
323
|
|
|
367
324
|
| Tool | Description |
|
|
368
325
|
|------|-------------|
|
|
369
|
-
| `
|
|
326
|
+
| `diagnostics` | Inspect server and browser state. |
|
|
370
327
|
|
|
371
328
|
</details>
|
|
372
329
|
|
|
373
|
-
_Auto-generated from source.
|
|
330
|
+
_Auto-generated from source. 26 tools registered._
|
|
374
331
|
|
|
375
332
|
<!-- TOOLS:END -->
|
|
376
333
|
|
|
@@ -657,14 +614,15 @@ The Strudel MCP Server is built with a modular architecture that separates conce
|
|
|
657
614
|
|
|
658
615
|
### Core Components
|
|
659
616
|
|
|
660
|
-
#### 1. **StrudelMCPServer** (`src/server/server.ts
|
|
617
|
+
#### 1. **StrudelMCPServer** (`src/server/server.ts`, ~510 lines)
|
|
661
618
|
|
|
662
|
-
|
|
663
|
-
-
|
|
664
|
-
-
|
|
665
|
-
-
|
|
666
|
-
-
|
|
667
|
-
-
|
|
619
|
+
Thin MCP dispatcher that:
|
|
620
|
+
- Aggregates 26 tool definitions from the per-domain modules in `src/server/tools/`
|
|
621
|
+
- Routes `tools/call` requests to the right module's `execute()`
|
|
622
|
+
- Wraps every response in the discriminated result envelope (`{ ok, errorCategory, isRetryable, ... }`)
|
|
623
|
+
- Tracks initialization, per-session history bundles, per-session audio capture services
|
|
624
|
+
- Advertises and serves MCP resources (`strudel://examples`, etc.)
|
|
625
|
+
- Lazy-initializes the default browser controller on first browser-touching call
|
|
668
626
|
|
|
669
627
|
Key Features:
|
|
670
628
|
```typescript
|
|
@@ -769,28 +727,42 @@ Persistent pattern storage:
|
|
|
769
727
|
live-coding-music-mcp/
|
|
770
728
|
├── src/
|
|
771
729
|
│ ├── server/
|
|
772
|
-
│ │
|
|
730
|
+
│ │ ├── server.ts # MCP dispatcher (~510 lines)
|
|
731
|
+
│ │ ├── resources.ts # MCP resources (#131)
|
|
732
|
+
│ │ └── tools/
|
|
733
|
+
│ │ ├── ai.ts, analysis.ts, capture.ts, compose.ts,
|
|
734
|
+
│ │ ├── diagnostics.ts, editor.ts, generate.ts, history.ts,
|
|
735
|
+
│ │ ├── playback.ts, session.ts, storage.ts, transform.ts,
|
|
736
|
+
│ │ └── types.ts # ToolContext, Envelope, helpers
|
|
773
737
|
│ ├── services/
|
|
774
|
-
│ │ ├── MusicTheory.ts #
|
|
775
|
-
│ │
|
|
738
|
+
│ │ ├── MusicTheory.ts # Scale/chord/euclidean helpers
|
|
739
|
+
│ │ ├── PatternGenerator.ts # Template-based generation
|
|
740
|
+
│ │ ├── SessionManager.ts # Multi-session lifecycle (#108)
|
|
741
|
+
│ │ ├── AudioCaptureService.ts # Audio recording
|
|
742
|
+
│ │ ├── MIDIExportService.ts # MIDI export
|
|
743
|
+
│ │ ├── GeminiService.ts # Gemini API client (ai_assist)
|
|
744
|
+
│ │ ├── StrudelEngine.ts # @strudel/* wrapper
|
|
745
|
+
│ │ └── StrudelEngineHelpers.ts # Pure helpers (#107)
|
|
776
746
|
│ ├── utils/
|
|
777
|
-
│ │
|
|
778
|
-
│ ├──
|
|
779
|
-
│ │
|
|
780
|
-
│ ├──
|
|
781
|
-
│
|
|
782
|
-
│ ├──
|
|
747
|
+
│ │ ├── Logger.ts
|
|
748
|
+
│ │ ├── PatternValidator.ts # Syntax + safety checks
|
|
749
|
+
│ │ ├── ErrorRecovery.ts # Retry / backoff
|
|
750
|
+
│ │ ├── PerformanceMonitor.ts
|
|
751
|
+
│ │ └── InputValidator.ts # Input bound checks
|
|
752
|
+
│ ├── StrudelController.ts # Browser automation (~800 lines)
|
|
753
|
+
│ ├── AudioAnalyzer.ts # Audio analysis (~800 lines)
|
|
754
|
+
│ ├── PatternStore.ts # On-disk pattern persistence
|
|
783
755
|
│ └── index.ts # Entry point
|
|
784
|
-
├──
|
|
785
|
-
|
|
786
|
-
│ ├──
|
|
787
|
-
│
|
|
788
|
-
|
|
789
|
-
│
|
|
790
|
-
|
|
791
|
-
├── config.json #
|
|
792
|
-
├── package.json
|
|
793
|
-
└── tsconfig.json
|
|
756
|
+
├── src/__tests__/ # Jest suites (unit + integration + browser)
|
|
757
|
+
├── patterns/
|
|
758
|
+
│ ├── examples/ # 18 bundled example patterns
|
|
759
|
+
│ └── *.json # Saved patterns at runtime
|
|
760
|
+
├── scripts/
|
|
761
|
+
│ ├── generate-tool-docs.ts # README tool-table generator
|
|
762
|
+
│ └── generate-changelog.ts
|
|
763
|
+
├── config.json # Local config (gitignored)
|
|
764
|
+
├── package.json
|
|
765
|
+
└── tsconfig.json
|
|
794
766
|
```
|
|
795
767
|
|
|
796
768
|
### Data Flow
|
|
@@ -956,102 +928,49 @@ gh release create v$(node -p "require('./package.json').version") --generate-not
|
|
|
956
928
|
|
|
957
929
|
The package uses OIDC trusted publishing with provenance attestation for supply chain security.
|
|
958
930
|
|
|
959
|
-
###
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
│ ├── PerformanceMonitor.ts # Performance tracking
|
|
983
|
-
│ ├── PatternValidator.ts # Pattern syntax validation
|
|
984
|
-
│ └── ErrorRecovery.ts # Error handling & recovery
|
|
985
|
-
│
|
|
986
|
-
├── types/
|
|
987
|
-
│ └── index.ts # TypeScript type definitions
|
|
988
|
-
│
|
|
989
|
-
├── StrudelController.ts # Browser automation
|
|
990
|
-
│ - Chromium management via Playwright
|
|
991
|
-
│ - CodeMirror editor manipulation
|
|
992
|
-
│ - Playback control
|
|
993
|
-
│ - Pattern validation
|
|
994
|
-
│ - Error recovery
|
|
995
|
-
│
|
|
996
|
-
├── AudioAnalyzer.ts # Real-time audio analysis
|
|
997
|
-
│ - Web Audio API injection
|
|
998
|
-
│ - FFT spectral analysis
|
|
999
|
-
│ - Frequency band detection
|
|
1000
|
-
│ - Playing state monitoring
|
|
1001
|
-
│
|
|
1002
|
-
├── PatternStore.ts # Pattern persistence
|
|
1003
|
-
│ - JSON-based storage
|
|
1004
|
-
│ - Tag-based organization
|
|
1005
|
-
│ - Metadata tracking
|
|
1006
|
-
│ - List caching
|
|
1007
|
-
│
|
|
1008
|
-
└── index.ts # Application entry point
|
|
1009
|
-
```
|
|
1010
|
-
|
|
1011
|
-
### Adding New Tools
|
|
1012
|
-
|
|
1013
|
-
To add a new MCP tool:
|
|
1014
|
-
|
|
1015
|
-
1. **Define the tool** in `getTools()` method:
|
|
1016
|
-
```typescript
|
|
1017
|
-
{
|
|
1018
|
-
name: 'my_new_tool',
|
|
1019
|
-
description: 'Description of what it does',
|
|
1020
|
-
inputSchema: {
|
|
1021
|
-
type: 'object',
|
|
1022
|
-
properties: {
|
|
1023
|
-
param1: { type: 'string', description: 'Parameter description' },
|
|
1024
|
-
param2: { type: 'number', description: 'Numeric parameter' }
|
|
1025
|
-
},
|
|
1026
|
-
required: ['param1']
|
|
1027
|
-
}
|
|
1028
|
-
}
|
|
1029
|
-
```
|
|
931
|
+
### Adding new tools
|
|
932
|
+
|
|
933
|
+
Tools live in per-domain modules under `src/server/tools/<domain>.ts`. `server.ts` just dispatches. To add a tool:
|
|
934
|
+
|
|
935
|
+
1. **Pick the right domain module** (or add a new one). Add the tool definition to that module's `tools` array:
|
|
936
|
+
|
|
937
|
+
```typescript
|
|
938
|
+
export const tools: Tool[] = [
|
|
939
|
+
// ...
|
|
940
|
+
{
|
|
941
|
+
name: 'my_new_tool',
|
|
942
|
+
description: 'One-line description; agents read this to pick between adjacent tools',
|
|
943
|
+
inputSchema: {
|
|
944
|
+
type: 'object',
|
|
945
|
+
properties: {
|
|
946
|
+
param1: { type: 'string', description: 'What it is' },
|
|
947
|
+
session_id: { type: 'string', description: 'Optional session ID (#108)' },
|
|
948
|
+
},
|
|
949
|
+
required: ['param1'],
|
|
950
|
+
},
|
|
951
|
+
},
|
|
952
|
+
];
|
|
953
|
+
```
|
|
1030
954
|
|
|
1031
|
-
2. **
|
|
1032
|
-
```typescript
|
|
1033
|
-
case 'my_new_tool':
|
|
1034
|
-
// Your implementation here
|
|
1035
|
-
return await this.someService.doSomething(args.param1, args.param2);
|
|
1036
|
-
```
|
|
955
|
+
2. **Add the case** to the module's `execute()` switch:
|
|
1037
956
|
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
// Implementation
|
|
1043
|
-
return `Result: ${param1}`;
|
|
1044
|
-
}
|
|
1045
|
-
```
|
|
957
|
+
```typescript
|
|
958
|
+
case 'my_new_tool':
|
|
959
|
+
return await ctx.getController(args.session_id).doSomething(args.param1);
|
|
960
|
+
```
|
|
1046
961
|
|
|
1047
|
-
|
|
1048
|
-
```bash
|
|
1049
|
-
# Build
|
|
1050
|
-
npm run build
|
|
962
|
+
3. **Add a service method** if needed (`MusicTheory`, `PatternGenerator`, etc.) and surface it through `ToolContext` (`src/server/tools/types.ts`) if other modules need it.
|
|
1051
963
|
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
964
|
+
4. **Don't hand-edit the README tool table.** It auto-generates via `npm run build` → `scripts/generate-tool-docs.ts`. A Jest test plus a CI step guard against drift.
|
|
965
|
+
|
|
966
|
+
5. **Use the envelope helpers** for returns: `ok(data)`, `empty(data)`, `err('validation', 'message')` from `src/server/tools/types.ts`. Raw returns still work — the dispatcher normalises them — but native envelope construction is clearer.
|
|
967
|
+
|
|
968
|
+
6. **Build and test**:
|
|
969
|
+
|
|
970
|
+
```bash
|
|
971
|
+
npm run build
|
|
972
|
+
echo '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"my_new_tool","arguments":{"param1":"test"}},"id":2}' | node dist/index.js
|
|
973
|
+
```
|
|
1055
974
|
|
|
1056
975
|
### Testing Strategy
|
|
1057
976
|
|
|
@@ -1074,7 +993,7 @@ npm run test:integration
|
|
|
1074
993
|
# - Pattern generation
|
|
1075
994
|
# - Audio analysis
|
|
1076
995
|
# - Pattern storage
|
|
1077
|
-
# - All
|
|
996
|
+
# - All 84 registered tools
|
|
1078
997
|
```
|
|
1079
998
|
|
|
1080
999
|
#### 3. Manual Testing
|
|
@@ -1289,12 +1208,19 @@ SMOOTHING=0.8
|
|
|
1289
1208
|
|
|
1290
1209
|
## Performance
|
|
1291
1210
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1211
|
+
Measured against the current `StrudelController` cache + Strudel.cc on a developer machine:
|
|
1212
|
+
|
|
1213
|
+
| Operation | Latency |
|
|
1214
|
+
|---|---|
|
|
1215
|
+
| Browser initialization | 1.5–2 s (with resource blocking) |
|
|
1216
|
+
| Pattern write | 50–80 ms (cached CodeMirror editor access) |
|
|
1217
|
+
| Pattern read (cached) | 10–15 ms |
|
|
1218
|
+
| Play / pause / stop | 100–150 ms |
|
|
1219
|
+
| Audio analysis (single FFT) | 10–15 ms |
|
|
1220
|
+
| Tempo detection | <100 ms (onset-based; degraded under headless audio) |
|
|
1221
|
+
| Key detection | <100 ms (Krumhansl-Schmuckler) |
|
|
1222
|
+
| Pattern generation | <100 ms (template-based) |
|
|
1223
|
+
| Process resident memory | ~120–150 MB |
|
|
1298
1224
|
|
|
1299
1225
|
## Advanced Usage
|
|
1300
1226
|
|
|
@@ -1555,7 +1481,7 @@ npm run build
|
|
|
1555
1481
|
# Check if server responds
|
|
1556
1482
|
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node dist/index.js
|
|
1557
1483
|
|
|
1558
|
-
# Should return JSON with
|
|
1484
|
+
# Should return JSON with 26 tools
|
|
1559
1485
|
|
|
1560
1486
|
# Reinstall MCP server in Claude
|
|
1561
1487
|
claude mcp remove strudel
|
|
@@ -1734,6 +1660,6 @@ Earlier versions of this package (including `@williamzujkowski/strudel-mcp-serve
|
|
|
1734
1660
|
|
|
1735
1661
|
---
|
|
1736
1662
|
|
|
1737
|
-
**
|
|
1663
|
+
**v4.0.0** — Open source, AGPL-3.0-or-later, experimental | [Report issues](https://github.com/williamzujkowski/live-coding-music-mcp/issues) | [Contribute](https://github.com/williamzujkowski/live-coding-music-mcp/pulls)
|
|
1738
1664
|
|
|
1739
1665
|
*This project is under active development. Core features work, but expect bugs and breaking changes. Not recommended for production use.*
|
package/dist/AudioAnalyzer.js
CHANGED
|
@@ -625,7 +625,6 @@ export class AudioAnalyzer {
|
|
|
625
625
|
return 0;
|
|
626
626
|
let syncopationScore = 0;
|
|
627
627
|
for (let i = 1; i < onsets.length; i++) {
|
|
628
|
-
const interval = onsets[i] - onsets[i - 1];
|
|
629
628
|
const phase = (onsets[i] % (meanInterval * 4)) / meanInterval;
|
|
630
629
|
// Check if onset is on an off-beat (not on 0, 1, 2, 3)
|
|
631
630
|
const nearestBeat = Math.round(phase);
|
package/dist/PatternStore.js
CHANGED
package/dist/index.js
CHANGED
|
File without changes
|