livepilot 1.6.2 → 1.6.4
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/CHANGELOG.md +37 -0
- package/README.md +65 -6
- package/m4l_device/livepilot_bridge.js +11 -7
- package/mcp_server/__init__.py +1 -1
- package/mcp_server/curves.py +6 -5
- package/mcp_server/m4l_bridge.py +1 -1
- package/mcp_server/memory/technique_store.py +2 -1
- package/mcp_server/server.py +2 -1
- package/mcp_server/tools/analyzer.py +1 -1
- package/mcp_server/tools/theory.py +872 -0
- package/package.json +2 -2
- package/plugin/plugin.json +4 -3
- package/plugin/skills/livepilot-core/SKILL.md +70 -5
- package/plugin/skills/livepilot-core/references/overview.md +17 -3
- package/plugin/skills/livepilot-release/SKILL.md +3 -3
- package/remote_script/LivePilot/__init__.py +3 -1
- package/remote_script/LivePilot/browser.py +0 -1
- package/remote_script/LivePilot/clip_automation.py +30 -28
- package/remote_script/LivePilot/clips.py +2 -1
- package/requirements.txt +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,42 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.6.4 — Music Theory (March 2026)
|
|
4
|
+
|
|
5
|
+
**7 new tools (135 -> 142), music21-powered theory analysis on live MIDI clips.**
|
|
6
|
+
|
|
7
|
+
### Theory Domain (7 tools)
|
|
8
|
+
- `analyze_harmony` — chord-by-chord Roman numeral analysis of session clips
|
|
9
|
+
- `suggest_next_chord` — theory-valid chord continuations with style presets (common_practice, jazz, modal, pop)
|
|
10
|
+
- `detect_theory_issues` — parallel fifths/octaves, out-of-key notes, voice crossing, unresolved dominants
|
|
11
|
+
- `identify_scale` — Krumhansl-Schmuckler key/mode detection with confidence-ranked alternatives
|
|
12
|
+
- `harmonize_melody` — 2 or 4-voice SATB harmonization with smooth voice leading
|
|
13
|
+
- `generate_countermelody` — species counterpoint (1st or 2nd species) against a melody
|
|
14
|
+
- `transpose_smart` — diatonic or chromatic transposition preserving scale relationships
|
|
15
|
+
|
|
16
|
+
### Architecture
|
|
17
|
+
- Notes-to-Stream bridge: converts LivePilot note dicts → music21 Part objects with quantization (1/32 note grid)
|
|
18
|
+
- Lazy imports: music21 is optional — all 135 core tools work without it installed
|
|
19
|
+
- Key hint parsing: handles "A minor" → lowercase tonic for music21 compatibility
|
|
20
|
+
|
|
21
|
+
### Dependencies
|
|
22
|
+
- Optional: `pip install 'music21>=9.3'` (not auto-installed — ~50MB with numpy/matplotlib)
|
|
23
|
+
|
|
24
|
+
## 1.6.3 — Audit Hardening (March 2026)
|
|
25
|
+
|
|
26
|
+
- Fix: cursor aliasing in M4L bridge `walk_device` — nested rack traversal now reads chain/pad counts before recursion clobbers shared cursors
|
|
27
|
+
- Fix: `clip_automation.py` — use `get_clip()` for bounds-checked access, add negative index guards, proper validation in `clear_clip_automation`
|
|
28
|
+
- Fix: `set_clip_loop` crash when `enabled` param omitted
|
|
29
|
+
- Fix: Brownian curve reflection escaping [0,1] for large volatility
|
|
30
|
+
- Fix: division by zero in M4L bridge when `sample_rate=0`
|
|
31
|
+
- Fix: `technique_store.get()` shallow copy allows shared mutation — now uses deepcopy
|
|
32
|
+
- Fix: `asyncio.get_event_loop()` deprecation — use `get_running_loop()` (Python 3.12+)
|
|
33
|
+
- Fix: dead code in `browser.py`, stale tool counts in docs (107 → 115 core)
|
|
34
|
+
- Fix: wrong param name in tool-reference docs (`soloed` → `solo`)
|
|
35
|
+
- Fix: social banner missing "automation" domain (11 → 12)
|
|
36
|
+
- Fix: tautological spring test, dead automation contract test, misleading clips test
|
|
37
|
+
- Add: `livepilot-release` skill registered in plugin.json
|
|
38
|
+
- Add: `__version__` to Remote Script `__init__.py`
|
|
39
|
+
|
|
3
40
|
## 1.6.2 — Automation Params Fix (March 2026)
|
|
4
41
|
|
|
5
42
|
- Fix: expose all curve-specific params in `generate_automation_curve` and `apply_automation_shape` MCP tools — `values` (steps), `hits`/`steps` (euclidean), `seed`/`drift`/`volatility` (organic), `damping`/`stiffness` (spring), `control1`/`control2` (bezier), `easing_type`, `narrowing` (stochastic)
|
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
[](https://github.com/dreamrec/LivePilot/stargazers)
|
|
13
13
|
[](https://www.npmjs.com/package/livepilot)
|
|
14
14
|
|
|
15
|
-
**AI copilot for Ableton Live 12** —
|
|
15
|
+
**AI copilot for Ableton Live 12** — 142 MCP tools, a deep device knowledge corpus, real-time audio analysis, and persistent technique memory.
|
|
16
16
|
|
|
17
17
|
Most Ableton MCP servers give the AI tools to push buttons. LivePilot gives it three things on top of that:
|
|
18
18
|
|
|
@@ -20,7 +20,7 @@ Most Ableton MCP servers give the AI tools to push buttons. LivePilot gives it t
|
|
|
20
20
|
- **Perception** — An M4L analyzer that reads the master bus in real-time: 8-band spectrum, RMS/peak metering, pitch tracking, key detection. The AI makes decisions based on what it hears, not just what's configured.
|
|
21
21
|
- **Memory** — A technique library that persists across sessions. The AI remembers how you built that bass sound, what swing you like on hi-hats, which reverb chain worked on vocals. It learns your taste over time.
|
|
22
22
|
|
|
23
|
-
These three layers sit on top of
|
|
23
|
+
These three layers sit on top of 142 deterministic MCP tools that cover transport, tracks, clips, MIDI, devices, scenes, mixing, browser, arrangement, and sample manipulation. Every command goes through Ableton's official Live Object Model API — the same interface Ableton's own control surfaces use. Everything is reversible with undo.
|
|
24
24
|
|
|
25
25
|
---
|
|
26
26
|
|
|
@@ -77,12 +77,64 @@ No other Ableton MCP server does this. Others have tools. LivePilot has tools +
|
|
|
77
77
|
|
|
78
78
|
---
|
|
79
79
|
|
|
80
|
+
## Automation Intelligence
|
|
81
|
+
|
|
82
|
+
Most DAW integrations let the AI set a parameter to a value. LivePilot lets the AI write **automation curves** — envelopes that evolve parameters over time inside clips. This is the difference between a static mix and a living one.
|
|
83
|
+
|
|
84
|
+
### The Curve Engine
|
|
85
|
+
|
|
86
|
+
16 mathematically precise curve types, organized in 4 categories:
|
|
87
|
+
|
|
88
|
+
| Category | Curves | What they do |
|
|
89
|
+
|----------|--------|-------------|
|
|
90
|
+
| **Basic Waveforms** | `linear` · `exponential` · `logarithmic` · `s_curve` · `sine` · `sawtooth` · `spike` · `square` · `steps` | The building blocks. Exponential for filter sweeps (perceptually even). Logarithmic for volume fades (matches the ear). Spike for dub throws. Sawtooth for sidechain pumps. |
|
|
91
|
+
| **Organic / Natural** | `perlin` · `brownian` · `spring` | What makes automation feel alive. Perlin noise for drifting textures. Brownian for analog-style parameter wander. Spring for realistic knob movements with overshoot and settle. |
|
|
92
|
+
| **Shape Control** | `bezier` · `easing` | Precision curves for intentional design. Bezier with arbitrary control points. 8 easing types from the animation world: bounce, elastic, back overshoot, ease in/out. |
|
|
93
|
+
| **Algorithmic** | `euclidean` · `stochastic` | Generative intelligence. Euclidean distributes automation events using the Bjorklund algorithm (the same math behind Euclidean rhythms). Stochastic applies Xenakis-inspired controlled randomness within narrowing bounds. |
|
|
94
|
+
|
|
95
|
+
Every curve generates normalized points (0.0–1.0) that map to any parameter in Ableton — volume, pan, sends, device parameters, anything with an envelope.
|
|
96
|
+
|
|
97
|
+
### 15 Production Recipes
|
|
98
|
+
|
|
99
|
+
Named presets for common techniques. One tool call instead of manual point calculation:
|
|
100
|
+
|
|
101
|
+
| Recipe | Curve | What it does |
|
|
102
|
+
|--------|-------|-------------|
|
|
103
|
+
| `filter_sweep_up` | exponential | LP filter opening over 8-32 bars |
|
|
104
|
+
| `filter_sweep_down` | logarithmic | LP filter closing, mirrors the sweep up |
|
|
105
|
+
| `dub_throw` | spike | Instant send spike for reverb/delay throws |
|
|
106
|
+
| `tape_stop` | exponential | Pitch dropping to zero — steep deceleration |
|
|
107
|
+
| `build_rise` | exponential | Tension build on HP filter + volume + reverb |
|
|
108
|
+
| `sidechain_pump` | sawtooth | Volume ducking per beat — fast duck, slow recovery |
|
|
109
|
+
| `fade_in` / `fade_out` | log / exp | Perceptually smooth volume fades |
|
|
110
|
+
| `tremolo` | sine | Periodic volume oscillation |
|
|
111
|
+
| `auto_pan` | sine | Stereo movement via pan |
|
|
112
|
+
| `stutter` | square | Rapid on/off gating |
|
|
113
|
+
| `breathing` | sine | Subtle filter movement — acoustic instrument feel |
|
|
114
|
+
| `washout` | exponential | Reverb/delay feedback increasing to wash |
|
|
115
|
+
| `vinyl_crackle` | sine | Slow bit reduction for lo-fi character |
|
|
116
|
+
| `stereo_narrow` | exponential | Collapse stereo to mono before drop |
|
|
117
|
+
|
|
118
|
+
### The Feedback Loop
|
|
119
|
+
|
|
120
|
+
`analyze_for_automation` reads the spectrum and device chain, then suggests what to automate:
|
|
121
|
+
|
|
122
|
+
1. **Reads the spectrum** — identifies frequency balance, sub content, dynamic range
|
|
123
|
+
2. **Scans the device chain** — detects filters, reverbs, synths, distortion
|
|
124
|
+
3. **Suggests automation targets** — "Filter detected → automate cutoff for movement", "Heavy sub content → HP filter sweep for builds"
|
|
125
|
+
4. **Recommends recipes** — maps each suggestion to the right named recipe
|
|
126
|
+
|
|
127
|
+
The AI doesn't just write automation — it knows what to automate based on what it hears.
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
80
131
|
## What You Can Do
|
|
81
132
|
|
|
82
133
|
- **Produce** — Create tracks, load instruments from the atlas, program drum patterns, bass lines, chord progressions, and melodies — informed by your saved techniques
|
|
83
134
|
- **Arrange** — Build full song structures in arrangement view with MIDI editing, cue points, automation, and timeline navigation
|
|
84
135
|
- **Design sounds** — Browse Ableton's library, load presets, tweak every device parameter, chain effects, walk nested racks 6 levels deep
|
|
85
136
|
- **Mix with ears** — Set levels, panning, sends, and routing. Read the spectrum, check RMS, detect the key. The analyzer tells the AI what changed, not just what was set
|
|
137
|
+
- **Automate intelligently** — Write clip automation with 16 mathematically precise curve types, apply named recipes (dub throws, filter sweeps, sidechain pumps), get spectral-aware suggestions for what to automate next
|
|
86
138
|
- **Remember and evolve** — Save techniques, build a personal style library, replay past decisions exactly or as variations
|
|
87
139
|
- **Chop samples** — Load audio into Simpler, slice, reverse, crop, warp, and reprogram — all from conversation
|
|
88
140
|
- **Iterate fast** — Transpose, humanize, quantize, duplicate, and reshape patterns through conversation
|
|
@@ -244,7 +296,7 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
244
296
|
|
|
245
297
|
---
|
|
246
298
|
|
|
247
|
-
##
|
|
299
|
+
## 142 Tools Across 13 Domains
|
|
248
300
|
|
|
249
301
|
| Domain | Tools | What you can do |
|
|
250
302
|
|--------|:-----:|-----------------|
|
|
@@ -257,8 +309,10 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
257
309
|
| **Mixing** | 11 | Volume, pan, sends, routing, meters, mix snapshot — return tracks and master fully supported |
|
|
258
310
|
| **Browser** | 4 | Search Ableton's library, browse categories, load presets |
|
|
259
311
|
| **Arrangement** | 19 | Create clips, full MIDI note CRUD, cue points, recording, automation |
|
|
312
|
+
| **Automation** | 8 | Clip envelope CRUD, 16-type curve engine, 15 named recipes, spectral-aware suggestions |
|
|
260
313
|
| **Memory** | 8 | Save, recall, replay, and manage production techniques |
|
|
261
314
|
| **Analyzer** | 20 | Real-time spectral analysis, key detection, sample manipulation, warp markers, device introspection (requires M4L device) |
|
|
315
|
+
| **Theory** | 7 | Harmony analysis, Roman numerals, scale identification, chord suggestions, countermelody, SATB harmonization, smart transposition (requires music21) |
|
|
262
316
|
|
|
263
317
|
<details>
|
|
264
318
|
<summary><strong>Full tool list</strong></summary>
|
|
@@ -290,6 +344,9 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
290
344
|
### Arrangement (19)
|
|
291
345
|
`get_arrangement_clips` · `create_arrangement_clip` · `add_arrangement_notes` · `get_arrangement_notes` · `remove_arrangement_notes` · `remove_arrangement_notes_by_id` · `modify_arrangement_notes` · `duplicate_arrangement_notes` · `transpose_arrangement_notes` · `set_arrangement_clip_name` · `set_arrangement_automation` · `back_to_arranger` · `jump_to_time` · `capture_midi` · `start_recording` · `stop_recording` · `get_cue_points` · `jump_to_cue` · `toggle_cue_point`
|
|
292
346
|
|
|
347
|
+
### Automation (8)
|
|
348
|
+
`get_clip_automation` · `set_clip_automation` · `clear_clip_automation` · `apply_automation_shape` · `apply_automation_recipe` · `get_automation_recipes` · `generate_automation_curve` · `analyze_for_automation`
|
|
349
|
+
|
|
293
350
|
### Memory (8)
|
|
294
351
|
`memory_learn` · `memory_recall` · `memory_get` · `memory_replay` · `memory_list` · `memory_favorite` · `memory_update` · `memory_delete`
|
|
295
352
|
|
|
@@ -334,7 +391,7 @@ The agent ships with a 2,700-line reference corpus (drum patterns, chord voicing
|
|
|
334
391
|
|
|
335
392
|
The LivePilot Analyzer (`LivePilot_Analyzer.amxd`) gives the AI ears. Drop it on the master track and 20 additional tools unlock: 8-band spectral analysis, RMS/peak metering, Krumhansl-Schmuckler key detection, plus deep LOM access for sample manipulation, warp markers, device introspection, and human-readable parameter display values.
|
|
336
393
|
|
|
337
|
-
All
|
|
394
|
+
All 115 core tools work without it. The analyzer is what turns LivePilot from a remote control into a feedback loop — the AI can set an EQ curve and then read the spectrum to verify the result.
|
|
338
395
|
|
|
339
396
|
---
|
|
340
397
|
|
|
@@ -346,7 +403,7 @@ There are **15+ MCP servers for Ableton Live** as of March 2026. Here's how the
|
|
|
346
403
|
|
|
347
404
|
| | [LivePilot](https://github.com/dreamrec/LivePilot) | [AbletonMCP](https://github.com/ahujasid/ableton-mcp) | [MCP Extended](https://github.com/uisato/ableton-mcp-extended) | [Ableton Copilot](https://github.com/xiaolaa2/ableton-copilot-mcp) | [AbletonBridge](https://github.com/hidingwill/AbletonBridge) | [Producer Pal](https://github.com/adamjmurray/producer-pal) |
|
|
348
405
|
|---|:-:|:-:|:-:|:-:|:-:|:-:|
|
|
349
|
-
| **Tools** |
|
|
406
|
+
| **Tools** | 142 | ~20 | ~35 | ~45 | 322 | ~25 |
|
|
350
407
|
| **Device knowledge** | 280+ devices | -- | -- | -- | -- | -- |
|
|
351
408
|
| **Audio analysis** | Spectrum/RMS/key | -- | -- | -- | Metering | -- |
|
|
352
409
|
| **Technique memory** | Persistent | -- | -- | -- | -- | -- |
|
|
@@ -363,6 +420,8 @@ There are **15+ MCP servers for Ableton Live** as of March 2026. Here's how the
|
|
|
363
420
|
| Session clips | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
364
421
|
| **Arrangement view** | ✅ | — | — | ✅ | ? | ? |
|
|
365
422
|
| **Arrangement automation** | ✅ | — | — | — | ? | — |
|
|
423
|
+
| **Clip automation (envelopes)** | ✅ | — | — | — | — | — |
|
|
424
|
+
| **Automation curve engine** | ✅ | — | — | — | — | — |
|
|
366
425
|
| MIDI notes (add/get) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
|
367
426
|
| **MIDI notes (modify/delete by ID)** | ✅ | — | — | ✅ | ? | — |
|
|
368
427
|
| **Per-note probability** | ✅ | — | — | — | — | — |
|
|
@@ -401,7 +460,7 @@ Every server on this list gives the AI tools to control Ableton. LivePilot is th
|
|
|
401
460
|
|
|
402
461
|
The practical difference: other servers let the AI set a parameter. LivePilot lets the AI choose the right parameter based on what device is loaded (atlas), verify the result by reading the audio output (analyzer), and remember the technique for next time (memory).
|
|
403
462
|
|
|
404
|
-
AbletonBridge has more raw tools (322 vs
|
|
463
|
+
AbletonBridge has more raw tools (322 vs 142). Producer Pal has the easiest install (drag a .amxd). The original AbletonMCP has the community (2.3k stars). LivePilot has the deepest integration — tools that execute, knowledge that informs, perception that verifies, and memory that accumulates.
|
|
405
464
|
|
|
406
465
|
---
|
|
407
466
|
|
|
@@ -68,7 +68,7 @@ function anything() {
|
|
|
68
68
|
function dispatch(cmd, args) {
|
|
69
69
|
switch(cmd) {
|
|
70
70
|
case "ping":
|
|
71
|
-
send_response({"ok": true, "version": "1.6.
|
|
71
|
+
send_response({"ok": true, "version": "1.6.4"});
|
|
72
72
|
break;
|
|
73
73
|
case "get_params":
|
|
74
74
|
cmd_get_params(args);
|
|
@@ -300,6 +300,8 @@ function cmd_walk_rack(args) {
|
|
|
300
300
|
function walk_device(path, depth) {
|
|
301
301
|
if (depth > 6) return {"error": "max depth reached"};
|
|
302
302
|
|
|
303
|
+
// Read all properties from cursor BEFORE recursing — recursion
|
|
304
|
+
// overwrites both cursors, so we must capture everything first.
|
|
303
305
|
cursor_a.goto(path);
|
|
304
306
|
var result = {
|
|
305
307
|
name: cursor_a.get("name").toString(),
|
|
@@ -310,11 +312,15 @@ function walk_device(path, depth) {
|
|
|
310
312
|
param_count: cursor_a.getcount("parameters")
|
|
311
313
|
};
|
|
312
314
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
+
// Capture chain/pad counts BEFORE recursion clobbers cursors
|
|
316
|
+
var chain_count = result.can_have_chains ? cursor_a.getcount("chains") : 0;
|
|
317
|
+
var pad_count = result.can_have_drum_pads ? cursor_a.getcount("drum_pads") : 0;
|
|
318
|
+
|
|
319
|
+
if (chain_count > 0) {
|
|
315
320
|
result.chains = [];
|
|
316
321
|
for (var c = 0; c < chain_count; c++) {
|
|
317
322
|
var chain_path = path + " chains " + c;
|
|
323
|
+
// Re-goto cursor_b each iteration (recursion may have moved it)
|
|
318
324
|
cursor_b.goto(chain_path);
|
|
319
325
|
var chain = {
|
|
320
326
|
index: c,
|
|
@@ -329,10 +335,8 @@ function walk_device(path, depth) {
|
|
|
329
335
|
}
|
|
330
336
|
}
|
|
331
337
|
|
|
332
|
-
if (
|
|
333
|
-
var pad_count = cursor_a.getcount("drum_pads");
|
|
338
|
+
if (pad_count > 0) {
|
|
334
339
|
result.drum_pads = [];
|
|
335
|
-
// Only report populated pads (up to 128, but most are empty)
|
|
336
340
|
for (var p = 0; p < Math.min(pad_count, 128); p++) {
|
|
337
341
|
var pad_path = path + " drum_pads " + p;
|
|
338
342
|
cursor_b.goto(pad_path);
|
|
@@ -686,7 +690,7 @@ function cmd_get_simpler_slices(args) {
|
|
|
686
690
|
"playback_mode_name": ["Classic", "One-Shot", "Slicing"][playback_mode] || "Unknown",
|
|
687
691
|
"sample_rate": sample_rate,
|
|
688
692
|
"sample_length_frames": length,
|
|
689
|
-
"sample_length_seconds": length / sample_rate,
|
|
693
|
+
"sample_length_seconds": sample_rate > 0 ? length / sample_rate : 0,
|
|
690
694
|
"slice_count": slices.length,
|
|
691
695
|
"slices": slices
|
|
692
696
|
});
|
package/mcp_server/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
"""LivePilot MCP Server — bridges MCP protocol to Ableton Live."""
|
|
2
|
-
__version__ = "1.6.
|
|
2
|
+
__version__ = "1.6.4"
|
package/mcp_server/curves.py
CHANGED
|
@@ -365,11 +365,12 @@ def _brownian(duration: float, density: int, start: float = 0.5,
|
|
|
365
365
|
points.append({"time": t * duration, "value": value})
|
|
366
366
|
step = drift / density + volatility * _det_random(i, seed)
|
|
367
367
|
value += step
|
|
368
|
-
# Soft boundary reflection (bounce off 0/1
|
|
369
|
-
|
|
370
|
-
value
|
|
371
|
-
|
|
372
|
-
value
|
|
368
|
+
# Soft boundary reflection (bounce off 0/1 until within range)
|
|
369
|
+
while value > 1.0 or value < 0.0:
|
|
370
|
+
if value > 1.0:
|
|
371
|
+
value = 2.0 - value
|
|
372
|
+
if value < 0.0:
|
|
373
|
+
value = -value
|
|
373
374
|
return points
|
|
374
375
|
|
|
375
376
|
|
package/mcp_server/m4l_bridge.py
CHANGED
|
@@ -234,7 +234,7 @@ class M4LBridge:
|
|
|
234
234
|
return {"error": "LivePilot Analyzer not connected. Drop it on the master track."}
|
|
235
235
|
|
|
236
236
|
# Create a future for the response
|
|
237
|
-
loop = asyncio.
|
|
237
|
+
loop = asyncio.get_running_loop()
|
|
238
238
|
future = loop.create_future()
|
|
239
239
|
if self.receiver:
|
|
240
240
|
self.receiver.set_response_future(future)
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
"""Persistent JSON store for LivePilot techniques (beat patterns, device chains, etc.)."""
|
|
2
2
|
|
|
3
|
+
import copy
|
|
3
4
|
import json
|
|
4
5
|
import os
|
|
5
6
|
import threading
|
|
@@ -101,7 +102,7 @@ class TechniqueStore:
|
|
|
101
102
|
with self._lock:
|
|
102
103
|
for t in self._data["techniques"]:
|
|
103
104
|
if t["id"] == technique_id:
|
|
104
|
-
return
|
|
105
|
+
return copy.deepcopy(t)
|
|
105
106
|
raise ValueError(f"NOT_FOUND: technique '{technique_id}' does not exist")
|
|
106
107
|
|
|
107
108
|
def search(
|
package/mcp_server/server.py
CHANGED
|
@@ -18,7 +18,7 @@ async def lifespan(server):
|
|
|
18
18
|
m4l = M4LBridge(spectral, receiver)
|
|
19
19
|
|
|
20
20
|
# Start UDP listener for incoming M4L spectral data (port 9880)
|
|
21
|
-
loop = asyncio.
|
|
21
|
+
loop = asyncio.get_running_loop()
|
|
22
22
|
try:
|
|
23
23
|
transport, _ = await loop.create_datagram_endpoint(
|
|
24
24
|
lambda: receiver,
|
|
@@ -56,6 +56,7 @@ from .tools import arrangement # noqa: F401, E402
|
|
|
56
56
|
from .tools import memory # noqa: F401, E402
|
|
57
57
|
from .tools import analyzer # noqa: F401, E402
|
|
58
58
|
from .tools import automation # noqa: F401, E402
|
|
59
|
+
from .tools import theory # noqa: F401, E402
|
|
59
60
|
|
|
60
61
|
|
|
61
62
|
# ---------------------------------------------------------------------------
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Analyzer MCP tools — real-time spectral analysis and deep LOM access.
|
|
2
2
|
|
|
3
3
|
20 tools requiring the LivePilot Analyzer M4L device on the master track.
|
|
4
|
-
These tools are optional — all
|
|
4
|
+
These tools are optional — all 115 core tools work without the device.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from __future__ import annotations
|