livepilot 1.2.1 → 1.4.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/CHANGELOG.md +21 -0
- package/README.md +129 -13
- 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 +36 -18
- package/mcp_server/tools/memory.py +198 -0
- package/mcp_server/tools/mixing.py +18 -10
- package/mcp_server/tools/notes.py +2 -0
- 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 +5 -0
- package/plugin/commands/memory.md +22 -0
- package/plugin/plugin.json +4 -3
- package/plugin/skills/livepilot-core/SKILL.md +58 -10
- package/plugin/skills/livepilot-core/references/memory-guide.md +107 -0
- package/plugin/skills/livepilot-core/references/overview.md +19 -6
- package/remote_script/LivePilot/arrangement.py +28 -8
- package/remote_script/LivePilot/browser.py +26 -12
- package/remote_script/LivePilot/devices.py +4 -3
- package/remote_script/LivePilot/transport.py +3 -1
- package/remote_script/LivePilot/utils.py +7 -1
- package/LivePilot audit report.md +0 -87
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [1.4.0] — 2026-03-18
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
- **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
|
|
7
|
+
- Memory guide reference (`references/memory-guide.md`) with qualities template and examples
|
|
8
|
+
- `/memory` command for browsing the technique library
|
|
9
|
+
- Producer agent now consults memory by default before creative decisions (override with "fresh" / "ignore history")
|
|
10
|
+
- Three memory modes: Informed (default), Fresh (override), Explicit Recall
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
- Tool count: 96 → 104 (10 domains, was 9)
|
|
14
|
+
- Commands: 4 → 5 (added /memory)
|
|
15
|
+
|
|
16
|
+
## 1.3.0 — 2026-03-17
|
|
17
|
+
|
|
18
|
+
### Enhancements
|
|
19
|
+
- **Device tools now support return tracks and master track** — use negative `track_index` for return tracks (-1=A, -2=B) and -1000 for master track. Works with all 12 device tools: `get_device_info`, `get_device_parameters`, `set_device_parameter`, `batch_set_parameters`, `toggle_device`, `delete_device`, `load_device_by_uri`, `find_and_load_device`, `get_rack_chains`, `set_simpler_playback_mode`, `set_chain_volume`, `get_device_presets`
|
|
20
|
+
- **Mixing tools now support return tracks** — `set_track_volume`, `set_track_pan`, `get_track_routing`, `set_track_routing` accept negative indices for return tracks
|
|
21
|
+
- Fixed `quantize_clip` grid parameter documentation — was incorrectly documented as float beats, now correctly documented as integer enum (0-8)
|
|
22
|
+
- Fixed tempo range typo in SKILL.md (was 20-969, corrected to 20-999)
|
|
23
|
+
|
|
3
24
|
## 1.2.1 — 2026-03-17
|
|
4
25
|
|
|
5
26
|
### Fixes
|
package/README.md
CHANGED
|
@@ -11,18 +11,44 @@
|
|
|
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
|
+
|
|
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
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Build Your Own AI Producer
|
|
23
|
+
|
|
24
|
+
LivePilot isn't just a tool collection — it's a framework for building **your own personalized AI production partner**.
|
|
25
|
+
|
|
26
|
+
Out of the box, the agent ships with a deep reference corpus: genre-specific drum patterns, chord voicings, sound design recipes, mixing templates, song structures. It knows how music works. But that's just the starting point.
|
|
27
|
+
|
|
28
|
+
**The real power is training it to work like you.**
|
|
29
|
+
|
|
30
|
+
Every time you produce something you like — a beat, a device chain, a mixing setup — you tell the agent to remember it. It doesn't just store raw data. It writes a rich stylistic analysis: *what makes this groove feel the way it does, what the sonic texture is, what it pairs with, what artists it evokes.* Over sessions, your saved techniques become a **stylistic fingerprint** the agent understands and draws from.
|
|
31
|
+
|
|
32
|
+
Here's how you build your agent's palette:
|
|
33
|
+
|
|
34
|
+
- **Save beats you like** — "remember this groove" — the agent captures the pattern AND analyzes why it works
|
|
35
|
+
- **Pin your go-to sounds** — "save this reverb chain" — instant recall next time, with context about when to use it
|
|
36
|
+
- **Set preferences** — "I always want Utility on every track" — the agent adapts its workflow to match yours
|
|
37
|
+
- **Curate over time** — rate, favorite, and refine saved techniques — the best ones float to the top
|
|
38
|
+
|
|
39
|
+
The next time you say "make me a beat", the agent checks your library. It doesn't copy — it reads your tendencies (the swing you like, the kits you reach for, your harmonic language) and creates something **new that sounds like you**. Say "ignore my history" and it starts fresh. Say "use that boom bap groove" and it replays exactly what you saved.
|
|
40
|
+
|
|
41
|
+
**You're not configuring software. You're building a creative relationship.**
|
|
17
42
|
|
|
18
43
|
---
|
|
19
44
|
|
|
20
45
|
## What You Can Do
|
|
21
46
|
|
|
22
47
|
- **Produce** — Create tracks, load instruments, program drum patterns, bass lines, chord progressions, and melodies
|
|
23
|
-
- **Arrange** — Build full song structures in arrangement view with MIDI
|
|
24
|
-
- **Design sounds** — Browse Ableton's library, load presets, tweak device
|
|
25
|
-
- **Mix** — Set levels, panning, sends, and routing. Run diagnostics to catch silent tracks and
|
|
48
|
+
- **Arrange** — Build full song structures in arrangement view with MIDI editing, cue points, automation, and timeline navigation
|
|
49
|
+
- **Design sounds** — Browse Ableton's library, load presets, tweak every device parameter, chain effects
|
|
50
|
+
- **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
|
|
51
|
+
- **Remember and evolve** — Save techniques, build a personal style library, and let the agent learn your taste over time
|
|
26
52
|
- **Iterate fast** — Transpose, humanize, quantize, duplicate, and reshape patterns through conversation
|
|
27
53
|
|
|
28
54
|
---
|
|
@@ -70,9 +96,9 @@ claude plugin add github:dreamrec/LivePilot/plugin
|
|
|
70
96
|
</details>
|
|
71
97
|
|
|
72
98
|
<details>
|
|
73
|
-
<summary><strong>Claude Desktop</strong></summary>
|
|
99
|
+
<summary><strong>Claude Desktop (macOS)</strong></summary>
|
|
74
100
|
|
|
75
|
-
Add to
|
|
101
|
+
Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
76
102
|
|
|
77
103
|
```json
|
|
78
104
|
{
|
|
@@ -89,6 +115,32 @@ Restart Claude Desktop after saving.
|
|
|
89
115
|
|
|
90
116
|
</details>
|
|
91
117
|
|
|
118
|
+
<details>
|
|
119
|
+
<summary><strong>Claude Desktop (Windows)</strong></summary>
|
|
120
|
+
|
|
121
|
+
On Windows, `npx` can cause EBUSY file-locking errors. Install globally instead:
|
|
122
|
+
|
|
123
|
+
```cmd
|
|
124
|
+
npm install -g github:dreamrec/LivePilot
|
|
125
|
+
livepilot --install
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Add to `%APPDATA%\Claude\claude_desktop_config.json`:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"mcpServers": {
|
|
133
|
+
"LivePilot": {
|
|
134
|
+
"command": "livepilot"
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Restart Claude Desktop after saving.
|
|
141
|
+
|
|
142
|
+
</details>
|
|
143
|
+
|
|
92
144
|
<details>
|
|
93
145
|
<summary><strong>Cursor</strong></summary>
|
|
94
146
|
|
|
@@ -156,7 +208,7 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
156
208
|
|
|
157
209
|
---
|
|
158
210
|
|
|
159
|
-
##
|
|
211
|
+
## 104 Tools Across 10 Domains
|
|
160
212
|
|
|
161
213
|
| Domain | Tools | What you can do |
|
|
162
214
|
|--------|:-----:|-----------------|
|
|
@@ -164,11 +216,12 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
164
216
|
| **Tracks** | 14 | Create MIDI/audio/return tracks, name, color, mute, solo, arm, group fold, input monitoring |
|
|
165
217
|
| **Clips** | 11 | Create, delete, duplicate, fire, stop, loop settings, launch mode, warp mode |
|
|
166
218
|
| **Notes** | 8 | Add/get/remove/modify MIDI notes, transpose, quantize, duplicate |
|
|
167
|
-
| **Devices** | 12 | Load instruments & effects, tweak parameters, rack chains, presets |
|
|
219
|
+
| **Devices** | 12 | Load instruments & effects, tweak parameters, rack chains, presets — works on regular, return, and master tracks |
|
|
168
220
|
| **Scenes** | 8 | Create, delete, duplicate, fire, rename, color, per-scene tempo |
|
|
169
|
-
| **Mixing** | 8 | Volume, pan, sends, routing
|
|
221
|
+
| **Mixing** | 8 | Volume, pan, sends, routing — return tracks and master fully supported |
|
|
170
222
|
| **Browser** | 4 | Search Ableton's library, browse categories, load presets |
|
|
171
223
|
| **Arrangement** | 19 | Create clips, full MIDI note CRUD, cue points, recording, automation |
|
|
224
|
+
| **Memory** | 8 | Save, recall, replay, and manage production techniques |
|
|
172
225
|
|
|
173
226
|
<details>
|
|
174
227
|
<summary><strong>Full tool list</strong></summary>
|
|
@@ -200,13 +253,22 @@ npx -y github:dreamrec/LivePilot --status
|
|
|
200
253
|
### Arrangement (19)
|
|
201
254
|
`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`
|
|
202
255
|
|
|
256
|
+
### Memory (8)
|
|
257
|
+
`memory_learn` · `memory_recall` · `memory_get` · `memory_replay` · `memory_list` · `memory_favorite` · `memory_update` · `memory_delete`
|
|
258
|
+
|
|
203
259
|
</details>
|
|
204
260
|
|
|
205
261
|
---
|
|
206
262
|
|
|
207
263
|
## Claude Code Plugin
|
|
208
264
|
|
|
209
|
-
The plugin
|
|
265
|
+
The plugin turns LivePilot from a tool collection into a **production partner that learns your style**.
|
|
266
|
+
|
|
267
|
+
```bash
|
|
268
|
+
claude plugin add github:dreamrec/LivePilot/plugin
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
### Commands
|
|
210
272
|
|
|
211
273
|
| Command | Description |
|
|
212
274
|
|---------|-------------|
|
|
@@ -214,8 +276,60 @@ The plugin adds production-focused skills, slash commands, and an autonomous pro
|
|
|
214
276
|
| `/beat` | Guided beat creation — genre, tempo, instrumentation |
|
|
215
277
|
| `/mix` | Mixing assistant — levels, panning, sends |
|
|
216
278
|
| `/sounddesign` | Sound design workflow — instruments, effects, presets |
|
|
279
|
+
| `/memory` | Browse, search, and manage your saved technique library |
|
|
280
|
+
|
|
281
|
+
### The Producer Agent
|
|
282
|
+
|
|
283
|
+
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.
|
|
284
|
+
|
|
285
|
+
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.
|
|
217
286
|
|
|
218
|
-
|
|
287
|
+
But the shipped corpus is just the floor. The real value builds over time.
|
|
288
|
+
|
|
289
|
+
### Technique Memory — Your Evolving Stylistic Palette
|
|
290
|
+
|
|
291
|
+
Most AI music tools are stateless — every session starts blank. LivePilot remembers.
|
|
292
|
+
|
|
293
|
+
When you make something you like — a beat, a device chain, a mixing setup, a favorite preset — you tell the agent to save it. But it doesn't just store the raw MIDI data or parameter values. It writes a **stylistic analysis**: what makes this groove feel the way it does, what the sonic character is, what it pairs well with, what artists or styles it evokes. Over time, your saved techniques become a **stylistic fingerprint** — a palette the agent understands.
|
|
294
|
+
|
|
295
|
+
The next time you say "make me a beat", the agent checks your library first. It doesn't copy a stored pattern — it reads across your saved techniques, understands your tendencies (the swing amounts you like, the kits you reach for, your harmonic language), and creates something **new that sounds like you**. It's the difference between an assistant that follows instructions and one that knows your taste.
|
|
296
|
+
|
|
297
|
+
Three modes, always under your control:
|
|
298
|
+
|
|
299
|
+
- **Informed** (default) — the agent consults your memory and lets it influence creative choices
|
|
300
|
+
- **Fresh** — say "ignore my history" and the agent starts with a blank slate, pure musical knowledge
|
|
301
|
+
- **Explicit recall** — say "use that boom bap beat I saved" for direct retrieval and replay
|
|
302
|
+
|
|
303
|
+
The memory is 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 override it.
|
|
304
|
+
|
|
305
|
+
### Core Skill
|
|
306
|
+
|
|
307
|
+
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.
|
|
308
|
+
|
|
309
|
+
---
|
|
310
|
+
|
|
311
|
+
## How It Compares
|
|
312
|
+
|
|
313
|
+
| Feature | LivePilot | [AbletonMCP](https://github.com/ahujasid/ableton-mcp) | [Ableton MCP Extended](https://github.com/uisato/ableton-mcp-extended) |
|
|
314
|
+
|---------|:---------:|:---------:|:---------:|
|
|
315
|
+
| **Tools** | 104 | ~20 | ~50 |
|
|
316
|
+
| **Arrangement view** | Full (clips, notes, cue points, automation) | No | Partial (automation "not perfect yet") |
|
|
317
|
+
| **MIDI note editing** | Full CRUD with note IDs, probability, velocity deviation | Basic add/get | Add/get/modify |
|
|
318
|
+
| **Device control** | Load, params, batch edit, rack chains, presets, Simpler modes | Load, basic params | Load, params |
|
|
319
|
+
| **Browser search** | Tree navigation, path filtering, URI-based loading | Basic search | Search with categories |
|
|
320
|
+
| **Mixing** | Volume, pan, sends, routing, master, diagnostics | Volume, pan | Volume, pan, sends |
|
|
321
|
+
| **Undo support** | Full (begin/end_undo_step wrapping) | No | Partial |
|
|
322
|
+
| **Session diagnostics** | Built-in health checks (armed tracks, solos, silent tracks) | No | No |
|
|
323
|
+
| **Per-note probability** | Yes (Live 12 API) | No | No |
|
|
324
|
+
| **Plugin/skills** | Claude Code plugin with 5 commands + producer agent | No | No |
|
|
325
|
+
| **Voice generation** | No | No | Yes (ElevenLabs) |
|
|
326
|
+
| **UDP low-latency mode** | No (TCP, reliable) | No | Yes (experimental) |
|
|
327
|
+
| **Protocol** | JSON/TCP, single-client, structured errors | JSON/TCP | JSON/TCP + UDP |
|
|
328
|
+
| **Installation** | Auto-detect CLI (`--install`) | Manual copy | Manual copy |
|
|
329
|
+
| **Live version** | Live 12 (modern note API) | Live 11+ | Live 11+ |
|
|
330
|
+
| **License** | MIT | MIT | MIT |
|
|
331
|
+
|
|
332
|
+
LivePilot focuses on **comprehensive, deterministic control** with safety nets (undo wrapping, diagnostics, verification patterns). It trades real-time parameter streaming (Extended's UDP mode) and external service integration (Extended's ElevenLabs) for deeper coverage of Ableton's core operations — especially arrangement, device management, and MIDI editing with Live 12's modern note API.
|
|
219
333
|
|
|
220
334
|
---
|
|
221
335
|
|
|
@@ -238,7 +352,9 @@ Claude / AI Client
|
|
|
238
352
|
└─────────────────────┘
|
|
239
353
|
```
|
|
240
354
|
|
|
241
|
-
Single-client TCP
|
|
355
|
+
All commands execute on Ableton's main thread via `schedule_message` — the same thread that handles the UI. This guarantees consistency with what you see on screen. Single-client TCP by design, because Ableton's Live Object Model is not thread-safe.
|
|
356
|
+
|
|
357
|
+
**Structured errors** with codes (`INDEX_ERROR`, `NOT_FOUND`, `INVALID_PARAM`, `STATE_ERROR`, `TIMEOUT`, `INTERNAL`) so the AI can understand what went wrong and recover.
|
|
242
358
|
|
|
243
359
|
---
|
|
244
360
|
|
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.
|