logic-pro-mcp
by rubenknol
README.md
# logic-pro-mcp
An MCP server that lets an AI assistant operate **Apple Logic Pro** — transport,
mixing, a full Mackie Control surface, playhead positioning, and MIDI region
read/write.
## Why it exists
Logic is the least scriptable major DAW: no AppleScript API and no plugin SDK
that reaches project data. This server stitches together the macOS channels that
*do* work — and deliberately favours the ones that **don't force Logic to the
foreground**:
- **Mackie Control (MCU) over MIDI** for transport, the mixer, and the control
surface — channels addressed by number, like real hardware.
- **Accessibility (AX) value reads/sets** for playhead position (focus-independent).
- **SMF round-trip + IAC streaming** for reading and writing region note data.
## Architecture
```
Claude ⇄ MCP server (TypeScript) ⇄ JSON-RPC over stdio ⇄ Python worker
src/index.ts src/bridge.ts python/worker.py
├── logic/mcu.py Mackie Control surface (persistent)
├── logic/mcu_protocol.py MCU byte map + codecs
├── logic/midiport.py MMC + IAC streaming (rtmidi)
├── logic/write_region.py playhead + record-to-track
├── logic/export_region.py region export (AX)
├── logic/smf.py SMF read/write (mido)
├── logic/axui.py Accessibility helpers
└── logic/keys.py CGEvent keys (fallback)
```
TypeScript owns only the MCP protocol. **Python owns all MIDI and macOS-native
work**, and is testable standalone via `python/cli.py` and `python/mcudev.py`.
## Supported operations
- **Transport** — play / stop / record over the MCU surface (background, no
foreground; falls back to MMC then key commands).
- **Tracks** — list all channels (numbered, scanned across banks) with live
state: arm, mute, solo, select, fader, pan, meter.
- **Track control** — arm / mute / solo / select any channel by number.
- **Mixing** — set volume (precise), pan, or center-pan, per channel or master.
- **Surface** — read full control-surface state (faders, V-pots, meters,
timecode, lit buttons) and press any Mackie button with modifiers.
- **Playhead** — read position and go-to-bar via AX (focus-independent).
- **Cycle** — read or set the loop region (start/end bar) and toggle cycle
on/off via AX (focus-independent).
- **MIDI content** — read the selected region or whole timeline as note data;
record notes onto a track at a bar (IAC streaming); write notes to a `.mid`.
## Installation
```bash
npm install
python3 -m venv .venv && .venv/bin/pip install -r python/requirements.txt
npm run build
```
**macOS setup:**
1. Grant **Accessibility** permission to the worker's host process
(System Settings ▸ Privacy & Security ▸ Accessibility).
2. Create two **IAC Driver** buses in Audio MIDI Setup: `IAC Driver MCU Cmd`
and `IAC Driver MCU Fb`, plus `IAC Driver Bus 1` for note streaming.
3. In Logic ▸ Settings ▸ MIDI: enable **MMC input** ("Listen to MMC Input"),
add a **Mackie Control** surface using `MCU Cmd` as Input and `MCU Fb` as
Output, and filter both MCU buses out of track inputs.
4. For cycle locator control: show the locators in the Control Bar LCD
(right-click the Control Bar ▸ Customize Control Bar and Display ▸ LCD ▸
**Custom** ▸ check **Locators (Bar/Beat)**).
## Configure your AI harness
The server is a stdio MCP server: run `dist/index.js` with `node`, and set
`LOGIC_MCP_PYTHON` to the venv's Python so the worker uses the right interpreter.
Use **absolute paths** everywhere — most harnesses don't run from this directory.
(`dist/` is gitignored, so run `npm run build` first.)
The base config block, reused by every harness below:
```json
{
"command": "/ABSOLUTE/PATH/TO/node",
"args": ["/ABSOLUTE/PATH/logic-pro-mcp/dist/index.js"],
"env": { "LOGIC_MCP_PYTHON": "/ABSOLUTE/PATH/logic-pro-mcp/.venv/bin/python" }
}
```
Find your absolute paths with `which node` and `pwd`.
**Claude Code** — register from the repo root (writes to `~/.claude.json`):
```bash
npm run build
claude mcp add logic-pro "$(which node)" "$(pwd)/dist/index.js" \
--env LOGIC_MCP_PYTHON="$(pwd)/.venv/bin/python"
```
Or drop a `.mcp.json` in a project root to share it with that project
(`claude mcp add` with `--scope project` does the same):
```json
{ "mcpServers": { "logic-pro": { <base config block> } } }
```
**Claude Desktop** — edit
`~/Library/Application Support/Claude/claude_desktop_config.json`, add the server
under `mcpServers`, then restart the app:
```json
{ "mcpServers": { "logic-pro": { <base config block> } } }
```
**Other harnesses** (Cursor, Cline, custom SDK clients) take the same shape:
a stdio server with `command`, `args`, and `env`. Consult the host's MCP docs
for where its config file lives.
After registering, confirm the tools load (in Claude Code: `/mcp` should list
`logic-pro`). If they don't, check the worker can start standalone:
`.venv/bin/python python/worker.py` and send `{"id":1,"method":"ping"}`.
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues