livepilot 1.3.0 → 1.4.1
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 +21 -0
- package/README.md +89 -35
- package/bin/livepilot.js +28 -17
- package/mcp_server/connection.py +6 -3
- package/mcp_server/memory/__init__.py +5 -0
- package/mcp_server/memory/technique_store.py +301 -0
- package/mcp_server/server.py +47 -0
- package/mcp_server/tools/arrangement.py +11 -8
- package/mcp_server/tools/browser.py +5 -1
- package/mcp_server/tools/clips.py +8 -4
- package/mcp_server/tools/devices.py +11 -9
- package/mcp_server/tools/memory.py +198 -0
- package/mcp_server/tools/mixing.py +8 -4
- package/mcp_server/tools/notes.py +3 -1
- package/mcp_server/tools/tracks.py +8 -4
- package/mcp_server/tools/transport.py +6 -2
- package/package.json +2 -2
- package/plugin/agents/livepilot-producer/AGENT.md +9 -8
- package/plugin/commands/memory.md +22 -0
- package/plugin/plugin.json +4 -3
- package/plugin/skills/livepilot-core/SKILL.md +56 -8
- package/plugin/skills/livepilot-core/references/memory-guide.md +107 -0
- package/plugin/skills/livepilot-core/references/overview.md +16 -3
- package/remote_script/LivePilot/arrangement.py +28 -8
- package/remote_script/LivePilot/browser.py +36 -20
- package/remote_script/LivePilot/devices.py +13 -13
- package/remote_script/LivePilot/mixing.py +4 -4
- package/remote_script/LivePilot/server.py +11 -11
- package/remote_script/LivePilot/transport.py +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.1] — 2026-03-18
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- Browser search now enforces global 10,000 iteration budget across all categories (was resetting per-category)
|
|
7
|
+
- `_search_recursive` returns early when `max_results` is reached instead of scanning remaining siblings
|
|
8
|
+
- Narrowed 29 broad `except Exception` catches to specific types (`AttributeError`, `OSError`, `ValueError`) across browser, devices, mixing, and server modules
|
|
9
|
+
- Kept `except Exception` only at the 3 outermost dispatch boundaries (router, command processor, logger)
|
|
10
|
+
|
|
11
|
+
## [1.4.0] — 2026-03-18
|
|
12
|
+
|
|
13
|
+
### Added
|
|
14
|
+
- **Technique Memory System** — 8 new MCP tools (`memory_learn`, `memory_recall`, `memory_get`, `memory_replay`, `memory_list`, `memory_favorite`, `memory_update`, `memory_delete`) for persistent technique storage with agent-written stylistic qualities
|
|
15
|
+
- Memory guide reference (`references/memory-guide.md`) with qualities template and examples
|
|
16
|
+
- `/memory` command for browsing the technique library
|
|
17
|
+
- Producer agent now consults memory by default before creative decisions (override with "fresh" / "ignore history")
|
|
18
|
+
- Three memory modes: Informed (default), Fresh (override), Explicit Recall
|
|
19
|
+
|
|
20
|
+
### Changed
|
|
21
|
+
- Tool count: 96 → 104 (10 domains, was 9)
|
|
22
|
+
- Commands: 4 → 5 (added /memory)
|
|
23
|
+
|
|
3
24
|
## 1.3.0 — 2026-03-17
|
|
4
25
|
|
|
5
26
|
### Enhancements
|
package/README.md
CHANGED
|
@@ -11,37 +11,41 @@
|
|
|
11
11
|
[](https://github.com/dreamrec/LivePilot/actions/workflows/ci.yml)
|
|
12
12
|
[](https://github.com/dreamrec/LivePilot/stargazers)
|
|
13
13
|
|
|
14
|
-
**AI copilot for Ableton Live 12** —
|
|
14
|
+
**AI copilot for Ableton Live 12** — 104 MCP tools for music production, sound design, and mixing.
|
|
15
15
|
|
|
16
16
|
Talk to your DAW. Create tracks, program MIDI, load instruments, tweak parameters, arrange songs, and mix — all through natural language. LivePilot connects any MCP-compatible AI client (Claude, Cursor, VS Code Copilot) to Ableton Live and gives it full control over your session.
|
|
17
17
|
|
|
18
|
+
Every command goes through Ableton's official Live Object Model API. No hacks, no injection — the same interface Ableton's own control surfaces use. Everything is deterministic and reversible with undo.
|
|
19
|
+
|
|
18
20
|
---
|
|
19
21
|
|
|
20
|
-
##
|
|
22
|
+
## Train Your Own AI Producer
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
You: "Set up a 126 BPM session with a drum track and a bass track"
|
|
24
|
-
Claude: Sets tempo to 126. Creates MIDI track "DRUMS" and "BASS".
|
|
25
|
-
Searches browser for a drum kit, loads "606 Core Kit".
|
|
26
|
-
Verifies kit loaded — Drum Rack with 16 chains. ✓
|
|
27
|
-
|
|
28
|
-
You: "Program a four-on-the-floor kick with offbeat hi-hats, 2 bars"
|
|
29
|
-
Claude: Creates 8-beat clip, adds kicks on every beat (pitch 36, velocity 110),
|
|
30
|
-
closed hats on offbeats (pitch 42, velocity 80/60 alternating).
|
|
31
|
-
Fires the clip.
|
|
32
|
-
|
|
33
|
-
You: "The hats are too loud, bring them down and add some swing"
|
|
34
|
-
Claude: Reads note IDs, modifies hat velocities to 65/45.
|
|
35
|
-
Adds ghost snare hits at 30% probability on the "e" and "ah".
|
|
36
|
-
The pattern evolves slightly every loop.
|
|
37
|
-
|
|
38
|
-
You: "Find an analog bass preset and write a simple sub line in D minor"
|
|
39
|
-
Claude: Searches instruments for "Analog Bass", loads a preset onto BASS track.
|
|
40
|
-
Adds root notes (D1 = pitch 38) with octave bounces.
|
|
41
|
-
Sets bass volume to 0.65, pans center. Fires to listen.
|
|
42
|
-
```
|
|
24
|
+
LivePilot ships with 104 tools and a deep reference corpus — genre-specific drum patterns, chord voicings, sound design recipes, mixing templates, song structures. Day one, it already knows how music works. But the tools are just the starting point.
|
|
43
25
|
|
|
44
|
-
|
|
26
|
+
**The real product is the agent you build on top of them.**
|
|
27
|
+
|
|
28
|
+
Every producer has a sonic identity — the swing amounts they reach for, the drum kits that feel right, the FX chains they keep coming back to, the way they EQ a vocal bus. Most AI tools ignore all of this. Every session starts blank. LivePilot is different: it has a technique memory system that turns your production decisions into a persistent, searchable stylistic palette the agent learns from over time.
|
|
29
|
+
|
|
30
|
+
Here's how you train it:
|
|
31
|
+
|
|
32
|
+
1. **Produce something you like** — a beat, a device chain, a mixing setup, a synth patch
|
|
33
|
+
2. **Tell the agent to save it** — "remember this groove" / "save this reverb chain"
|
|
34
|
+
3. **The agent writes a stylistic analysis** — not just raw MIDI data, but *what makes it work*: the rhythmic feel, the sonic texture, the mood, what it pairs with, what artists it evokes
|
|
35
|
+
4. **Your library grows** — rate and favorite the best techniques, tag them by genre or mood, build categories
|
|
36
|
+
5. **The agent develops taste** — next time you say "make me a beat", it checks your library, reads your tendencies, and creates something new that sounds like you
|
|
37
|
+
|
|
38
|
+
This isn't a preset recall system. The agent doesn't copy stored patterns — it understands the *qualities* across your saved techniques (the swing you prefer, the harmonic language you gravitate toward, the density of your arrangements) and uses that understanding to inform new creative decisions.
|
|
39
|
+
|
|
40
|
+
**Three modes, always under your control:**
|
|
41
|
+
|
|
42
|
+
- **Informed** (default) — the agent consults your memory and lets it influence creative choices naturally
|
|
43
|
+
- **Fresh** — "ignore my history" / "something completely new" — blank slate, pure musical knowledge, zero influence from saved techniques
|
|
44
|
+
- **Explicit recall** — "use that boom bap beat I saved" — direct retrieval and replay
|
|
45
|
+
|
|
46
|
+
The memory is both a drawer and a personality. You put things in, you take things out, and the agent develops taste from what you've collected — but you can always tell it to forget everything and start fresh.
|
|
47
|
+
|
|
48
|
+
**You're not configuring software. You're building a creative partner that gets better the more you use it.**
|
|
45
49
|
|
|
46
50
|
---
|
|
47
51
|
|
|
@@ -50,7 +54,8 @@ Every command goes through Ableton's official Live Object Model API. No hacks, n
|
|
|
50
54
|
- **Produce** — Create tracks, load instruments, program drum patterns, bass lines, chord progressions, and melodies
|
|
51
55
|
- **Arrange** — Build full song structures in arrangement view with MIDI editing, cue points, automation, and timeline navigation
|
|
52
56
|
- **Design sounds** — Browse Ableton's library, load presets, tweak every device parameter, chain effects
|
|
53
|
-
- **Mix** — Set levels, panning, sends, and routing. Run diagnostics to catch silent tracks and stale solos
|
|
57
|
+
- **Mix** — Set levels, panning, sends, and routing across all track types including return tracks and master. Run diagnostics to catch silent tracks and stale solos
|
|
58
|
+
- **Remember and evolve** — Save techniques, build a personal style library, and let the agent learn your taste over time
|
|
54
59
|
- **Iterate fast** — Transpose, humanize, quantize, duplicate, and reshape patterns through conversation
|
|
55
60
|
|
|
56
61
|
---
|
|
@@ -98,9 +103,9 @@ claude plugin add github:dreamrec/LivePilot/plugin
|
|
|
98
103
|
</details>
|
|
99
104
|
|
|
100
105
|
<details>
|
|
101
|
-
<summary><strong>Claude Desktop</strong></summary>
|
|
106
|
+
<summary><strong>Claude Desktop (macOS)</strong></summary>
|
|
102
107
|
|
|
103
|
-
Add to
|
|
108
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
104
109
|
|
|
105
110
|
```json
|
|
106
111
|
{
|
|
@@ -117,6 +122,32 @@ Restart Claude Desktop after saving.
|
|
|
117
122
|
|
|
118
123
|
</details>
|
|
119
124
|
|
|
125
|
+
<details>
|
|
126
|
+
<summary><strong>Claude Desktop (Windows)</strong></summary>
|
|
127
|
+
|
|
128
|
+
On Windows, `npx` can cause EBUSY file-locking errors. Install globally instead:
|
|
129
|
+
|
|
130
|
+
```cmd
|
|
131
|
+
npm install -g github:dreamrec/LivePilot
|
|
132
|
+
livepilot --install
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Add to `%APPDATA%\Claude\claude_desktop_config.json`:
|
|
136
|
+
|
|
137
|
+
```json
|
|
138
|
+
{
|
|
139
|
+
"mcpServers": {
|
|
140
|
+
"LivePilot": {
|
|
141
|
+
"command": "livepilot"
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Restart Claude Desktop after saving.
|
|
148
|
+
|
|
149
|
+
</details>
|
|
150
|
+
|
|
120
151
|
<details>
|
|
121
152
|
<summary><strong>Cursor</strong></summary>
|
|
122
153
|
|
|
@@ -184,7 +215,7 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
184
215
|
|
|
185
216
|
---
|
|
186
217
|
|
|
187
|
-
##
|
|
218
|
+
## 104 Tools Across 10 Domains
|
|
188
219
|
|
|
189
220
|
| Domain | Tools | What you can do |
|
|
190
221
|
|--------|:-----:|-----------------|
|
|
@@ -192,11 +223,12 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
192
223
|
| **Tracks** | 14 | Create MIDI/audio/return tracks, name, color, mute, solo, arm, group fold, input monitoring |
|
|
193
224
|
| **Clips** | 11 | Create, delete, duplicate, fire, stop, loop settings, launch mode, warp mode |
|
|
194
225
|
| **Notes** | 8 | Add/get/remove/modify MIDI notes, transpose, quantize, duplicate |
|
|
195
|
-
| **Devices** | 12 | Load instruments & effects, tweak parameters, rack chains, presets |
|
|
226
|
+
| **Devices** | 12 | Load instruments & effects, tweak parameters, rack chains, presets — works on regular, return, and master tracks |
|
|
196
227
|
| **Scenes** | 8 | Create, delete, duplicate, fire, rename, color, per-scene tempo |
|
|
197
|
-
| **Mixing** | 8 | Volume, pan, sends, routing
|
|
228
|
+
| **Mixing** | 8 | Volume, pan, sends, routing — return tracks and master fully supported |
|
|
198
229
|
| **Browser** | 4 | Search Ableton's library, browse categories, load presets |
|
|
199
230
|
| **Arrangement** | 19 | Create clips, full MIDI note CRUD, cue points, recording, automation |
|
|
231
|
+
| **Memory** | 8 | Save, recall, replay, and manage production techniques |
|
|
200
232
|
|
|
201
233
|
<details>
|
|
202
234
|
<summary><strong>Full tool list</strong></summary>
|
|
@@ -228,13 +260,22 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
228
260
|
### Arrangement (19)
|
|
229
261
|
`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`
|
|
230
262
|
|
|
263
|
+
### Memory (8)
|
|
264
|
+
`memory_learn` · `memory_recall` · `memory_get` · `memory_replay` · `memory_list` · `memory_favorite` · `memory_update` · `memory_delete`
|
|
265
|
+
|
|
231
266
|
</details>
|
|
232
267
|
|
|
233
268
|
---
|
|
234
269
|
|
|
235
270
|
## Claude Code Plugin
|
|
236
271
|
|
|
237
|
-
The plugin
|
|
272
|
+
The plugin turns LivePilot from a tool collection into a **production partner that learns your style**.
|
|
273
|
+
|
|
274
|
+
```bash
|
|
275
|
+
claude plugin add github:dreamrec/LivePilot/plugin
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### Commands
|
|
238
279
|
|
|
239
280
|
| Command | Description |
|
|
240
281
|
|---------|-------------|
|
|
@@ -242,10 +283,23 @@ The plugin adds production-focused skills, slash commands, and an autonomous pro
|
|
|
242
283
|
| `/beat` | Guided beat creation — genre, tempo, instrumentation |
|
|
243
284
|
| `/mix` | Mixing assistant — levels, panning, sends |
|
|
244
285
|
| `/sounddesign` | Sound design workflow — instruments, effects, presets |
|
|
286
|
+
| `/memory` | Browse, search, and manage your saved technique library |
|
|
287
|
+
|
|
288
|
+
### The Producer Agent
|
|
289
|
+
|
|
290
|
+
The heart of the plugin. An autonomous agent that builds tracks from high-level descriptions like *"Make me a 126 BPM rominimal track in D minor with hypnotic percussion"*. It handles the full pipeline: planning the arrangement, creating tracks, loading instruments, programming patterns, adding effects, and mixing — with mandatory health checks to make sure every track actually produces sound.
|
|
291
|
+
|
|
292
|
+
What makes it different from a generic AI with tools is **what it knows**. The agent ships with a deep reference corpus — genre-specific drum patterns, chord voicings, sound design recipes, mixing templates, song structures — so it doesn't start from zero every time. It knows that a boom bap kick lands on beat 1 and the "and" of 2, that a Drum Rack needs a kit preset (not an empty shell), that a Saturator with Drive at 0 is a pass-through doing nothing.
|
|
293
|
+
|
|
294
|
+
But the shipped corpus is just the floor. The real value builds over time.
|
|
295
|
+
|
|
296
|
+
### Technique Memory
|
|
297
|
+
|
|
298
|
+
8 tools for saving, searching, and replaying production techniques. Every saved technique includes a rich stylistic analysis written by the agent — not just raw data, but *what makes it work* and when to use it. See "Train Your Own AI Producer" above for how this shapes the agent over time.
|
|
245
299
|
|
|
246
|
-
|
|
300
|
+
### Core Skill
|
|
247
301
|
|
|
248
|
-
|
|
302
|
+
The `livepilot-core` skill teaches the AI how to work with Ableton properly: read session state before changing anything, verify after every write, check that instruments actually loaded, never invent device names. It's the difference between an AI that fumbles through the API and one that works like an experienced assistant.
|
|
249
303
|
|
|
250
304
|
---
|
|
251
305
|
|
|
@@ -253,7 +307,7 @@ The plugin adds production-focused skills, slash commands, and an autonomous pro
|
|
|
253
307
|
|
|
254
308
|
| Feature | LivePilot | [AbletonMCP](https://github.com/ahujasid/ableton-mcp) | [Ableton MCP Extended](https://github.com/uisato/ableton-mcp-extended) |
|
|
255
309
|
|---------|:---------:|:---------:|:---------:|
|
|
256
|
-
| **Tools** |
|
|
310
|
+
| **Tools** | 104 | ~20 | ~50 |
|
|
257
311
|
| **Arrangement view** | Full (clips, notes, cue points, automation) | No | Partial (automation "not perfect yet") |
|
|
258
312
|
| **MIDI note editing** | Full CRUD with note IDs, probability, velocity deviation | Basic add/get | Add/get/modify |
|
|
259
313
|
| **Device control** | Load, params, batch edit, rack chains, presets, Simpler modes | Load, basic params | Load, params |
|
|
@@ -262,7 +316,7 @@ The plugin adds production-focused skills, slash commands, and an autonomous pro
|
|
|
262
316
|
| **Undo support** | Full (begin/end_undo_step wrapping) | No | Partial |
|
|
263
317
|
| **Session diagnostics** | Built-in health checks (armed tracks, solos, silent tracks) | No | No |
|
|
264
318
|
| **Per-note probability** | Yes (Live 12 API) | No | No |
|
|
265
|
-
| **Plugin/skills** | Claude Code plugin with
|
|
319
|
+
| **Plugin/skills** | Claude Code plugin with 5 commands + producer agent | No | No |
|
|
266
320
|
| **Voice generation** | No | No | Yes (ElevenLabs) |
|
|
267
321
|
| **UDP low-latency mode** | No (TCP, reliable) | No | Yes (experimental) |
|
|
268
322
|
| **Protocol** | JSON/TCP, single-client, structured errors | JSON/TCP | JSON/TCP + UDP |
|
package/bin/livepilot.js
CHANGED
|
@@ -16,9 +16,16 @@ const REQUIREMENTS = path.join(ROOT, "requirements.txt");
|
|
|
16
16
|
// ---------------------------------------------------------------------------
|
|
17
17
|
|
|
18
18
|
function findPython() {
|
|
19
|
-
|
|
19
|
+
// On Windows, also try the "py -3" launcher which avoids the
|
|
20
|
+
// Microsoft Store stub that "python3" resolves to.
|
|
21
|
+
const candidates = process.platform === "win32"
|
|
22
|
+
? ["python", "python3", "py"]
|
|
23
|
+
: ["python3", "python"];
|
|
24
|
+
|
|
25
|
+
for (const cmd of candidates) {
|
|
20
26
|
try {
|
|
21
|
-
const
|
|
27
|
+
const args = cmd === "py" ? ["-3", "--version"] : ["--version"];
|
|
28
|
+
const out = execFileSync(cmd, args, {
|
|
22
29
|
encoding: "utf-8",
|
|
23
30
|
timeout: 5000,
|
|
24
31
|
}).trim();
|
|
@@ -26,8 +33,11 @@ function findPython() {
|
|
|
26
33
|
if (match) {
|
|
27
34
|
const major = parseInt(match[1], 10);
|
|
28
35
|
const minor = parseInt(match[2], 10);
|
|
29
|
-
if (major === 3 && minor >=
|
|
30
|
-
|
|
36
|
+
if (major === 3 && minor >= 9) {
|
|
37
|
+
// For "py" launcher, the actual command to use is "py -3"
|
|
38
|
+
const actualCmd = cmd === "py" ? "py" : cmd;
|
|
39
|
+
const actualArgs = cmd === "py" ? ["-3"] : [];
|
|
40
|
+
return { cmd: actualCmd, version: out, prefixArgs: actualArgs };
|
|
31
41
|
}
|
|
32
42
|
}
|
|
33
43
|
} catch {
|
|
@@ -53,7 +63,8 @@ function venvPython() {
|
|
|
53
63
|
* Ensure a local .venv exists with dependencies installed.
|
|
54
64
|
* Returns the path to the venv Python binary.
|
|
55
65
|
*/
|
|
56
|
-
function ensureVenv(systemPython) {
|
|
66
|
+
function ensureVenv(systemPython, prefixArgs) {
|
|
67
|
+
const prefix = prefixArgs || [];
|
|
57
68
|
const venvPy = venvPython();
|
|
58
69
|
|
|
59
70
|
// Check if venv already exists and has our deps
|
|
@@ -67,10 +78,10 @@ function ensureVenv(systemPython) {
|
|
|
67
78
|
return venvPy; // venv exists and fastmcp is importable
|
|
68
79
|
} catch {
|
|
69
80
|
// venv exists but deps missing — reinstall
|
|
70
|
-
console.
|
|
81
|
+
console.error("LivePilot: reinstalling Python dependencies...");
|
|
71
82
|
execFileSync(venvPy, ["-m", "pip", "install", "-q", "-r", REQUIREMENTS], {
|
|
72
83
|
cwd: ROOT,
|
|
73
|
-
stdio: "inherit",
|
|
84
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
74
85
|
timeout: 120000,
|
|
75
86
|
});
|
|
76
87
|
return venvPy;
|
|
@@ -78,17 +89,17 @@ function ensureVenv(systemPython) {
|
|
|
78
89
|
}
|
|
79
90
|
|
|
80
91
|
// Create venv from scratch
|
|
81
|
-
console.
|
|
82
|
-
execFileSync(systemPython, ["-m", "venv", VENV_DIR], {
|
|
92
|
+
console.error("LivePilot: setting up Python environment (first run)...");
|
|
93
|
+
execFileSync(systemPython, [...prefix, "-m", "venv", VENV_DIR], {
|
|
83
94
|
cwd: ROOT,
|
|
84
|
-
stdio: "inherit",
|
|
95
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
85
96
|
timeout: 30000,
|
|
86
97
|
});
|
|
87
98
|
|
|
88
|
-
console.
|
|
99
|
+
console.error("LivePilot: installing dependencies...");
|
|
89
100
|
execFileSync(venvPython(), ["-m", "pip", "install", "-q", "-r", REQUIREMENTS], {
|
|
90
101
|
cwd: ROOT,
|
|
91
|
-
stdio: "inherit",
|
|
102
|
+
stdio: ["pipe", "pipe", "inherit"],
|
|
92
103
|
timeout: 120000,
|
|
93
104
|
});
|
|
94
105
|
|
|
@@ -165,8 +176,8 @@ async function doctor() {
|
|
|
165
176
|
if (pyInfo) {
|
|
166
177
|
console.log(" Python: %s (%s)", pyInfo.version, pyInfo.cmd);
|
|
167
178
|
} else {
|
|
168
|
-
console.log(" Python: NOT FOUND (need >= 3.
|
|
169
|
-
console.log(" Fix: install Python 3.
|
|
179
|
+
console.log(" Python: NOT FOUND (need >= 3.9)");
|
|
180
|
+
console.log(" Fix: install Python 3.9+ and add to PATH");
|
|
170
181
|
ok = false;
|
|
171
182
|
}
|
|
172
183
|
|
|
@@ -326,9 +337,9 @@ async function main() {
|
|
|
326
337
|
// Default: start MCP server
|
|
327
338
|
const pyInfo = findPython();
|
|
328
339
|
if (!pyInfo) {
|
|
329
|
-
console.error("Error: Python >= 3.
|
|
340
|
+
console.error("Error: Python >= 3.9 is required but was not found.");
|
|
330
341
|
console.error("");
|
|
331
|
-
console.error("Install Python 3.
|
|
342
|
+
console.error("Install Python 3.9+ and ensure 'python3' or 'python' is on your PATH.");
|
|
332
343
|
console.error(" macOS: brew install python@3.12");
|
|
333
344
|
console.error(" Ubuntu: sudo apt install python3");
|
|
334
345
|
console.error(" Windows: https://www.python.org/downloads/");
|
|
@@ -338,7 +349,7 @@ async function main() {
|
|
|
338
349
|
// Bootstrap venv and install deps automatically
|
|
339
350
|
let pythonBin;
|
|
340
351
|
try {
|
|
341
|
-
pythonBin = ensureVenv(pyInfo.cmd);
|
|
352
|
+
pythonBin = ensureVenv(pyInfo.cmd, pyInfo.prefixArgs);
|
|
342
353
|
} catch (err) {
|
|
343
354
|
console.error("Error: failed to set up Python environment.");
|
|
344
355
|
console.error(" %s", err.message);
|
package/mcp_server/connection.py
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"""TCP client for communicating with Ableton Live's Remote Script."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import json
|
|
4
6
|
import os
|
|
5
7
|
import socket
|
|
6
8
|
import time
|
|
7
9
|
import uuid
|
|
8
10
|
from collections import deque
|
|
11
|
+
from typing import Optional
|
|
9
12
|
|
|
10
13
|
CONNECT_TIMEOUT = 5
|
|
11
14
|
RECV_TIMEOUT = 20
|
|
@@ -45,10 +48,10 @@ class AbletonConnection:
|
|
|
45
48
|
|
|
46
49
|
MAX_LOG_ENTRIES = 50
|
|
47
50
|
|
|
48
|
-
def __init__(self, host: str
|
|
51
|
+
def __init__(self, host: Optional[str] = None, port: Optional[int] = None):
|
|
49
52
|
self.host = host or os.environ.get("LIVE_MCP_HOST", "127.0.0.1")
|
|
50
53
|
self.port = port or int(os.environ.get("LIVE_MCP_PORT", "9878"))
|
|
51
|
-
self._socket: socket.socket
|
|
54
|
+
self._socket: Optional[socket.socket] = None
|
|
52
55
|
self._recv_buf: bytes = b""
|
|
53
56
|
self._command_log: deque[dict] = deque(maxlen=self.MAX_LOG_ENTRIES)
|
|
54
57
|
|
|
@@ -103,7 +106,7 @@ class AbletonConnection:
|
|
|
103
106
|
except Exception:
|
|
104
107
|
return False
|
|
105
108
|
|
|
106
|
-
def send_command(self, command_type: str, params: dict
|
|
109
|
+
def send_command(self, command_type: str, params: Optional[dict] = None) -> dict:
|
|
107
110
|
"""Send a command to Ableton and return the result dict.
|
|
108
111
|
|
|
109
112
|
Retries once on socket errors with a fresh connection.
|