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
npm install
python3 -m venv .venv && .venv/bin/pip install -r python/requirements.txt
npm run build
macOS setup:
- Grant Accessibility permission to the worker's host process
(System Settings ▸ Privacy & Security ▸ Accessibility).
- 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.
- 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.
- 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:
{
"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):
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):
{ "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:
{ "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"}.











