rubin

rubin

A minimal MCP server that composes MIDI, loads Logic Pro factory patches (including Alchemy), and drives transport, turning Logic Pro into an AI-playable instrument.

Category
访问服务器

README

rubin

tests

A minimal, dependency-free MCP server that turns Logic Pro into an AI-playable instrument: compose MIDI, load any factory patch (Alchemy included), and drive the transport.

A rubin-composed 40-bar arrangement playing in Logic Pro — five tracks
composed as MIDI, Alchemy patches loaded via the Library, piano roll showing
the lead hook

Everything in this screenshot was placed by rubin: the five tracks and their regions (composed as a Standard MIDI File), the Alchemy patches on each channel strip (loaded through the Library), tempo, and key.

Why it works

UI-automation-first tools (clicking Logic's interface for every note) fail silently and read garbage state. rubin flips the approach:

  • Composition is a file, not clicks. Notes, CC automation, pitch bends, tempo, and time signature are written into a real Standard MIDI File — deterministic, testable, no UI involved. Logic maps each track's GM program to a software instrument on import.
  • Patch discovery is a disk read, not a guess. Logic's ~6,000 factory patches live on disk with the synth engine recorded inside each bundle; find_patches filters them by name, category, or engine (Alchemy, Retro Synth, ES2, Sculpture...).
  • UI scripting is a last resort, and verified. Only patch loading, import, and transport touch the UI — anchored to stable accessibility landmarks (the Library's "Search Sounds" field, track-header fields), with list_tracks reading real state back so nothing fails silently.

Tools

Tool What it does
compose_midi Write a .mid from notes / CC / bends / volume / pan per track
open_midi_as_project Open a .mid in Logic as a new project (no dialogs, most reliable)
import_midi File > Import > MIDI File into the open project at bar 1
compose_and_import Both steps in one call
transcribe_audio Audio → MIDI via basic-pitch, content-hash cached
list_transcriptions Browse the transcription cache
analyze_midi Full analysis: key/swing/chord detection, density contour, warnings, per-track stats
describe_midi The same, as one readable paragraph
suggest_accompaniment Analysis → ready compose_midi args that fit a source file (registers, key, feel)
find_patches Search the on-disk factory patch index (name / category / engine)
find_surge_presets Discover installed Surge XT presets (load via Surge's browser)
find_channel_strips Discover factory FX-chain settings (.cst) — names for the Setting menu; not Library-loadable
select_track Select track N (1-based)
load_patch Load a Library patch onto the selected track; returns the loaded name
list_tracks Read back [{name, patch}] from the open project
save_project Save the project (Cmd+S); reports the sheet if the project is unnamed
transport play / stop / record / go_to_beginning
answer_dialog Click through a Logic sheet/dialog (e.g. tempo-import prompt)
logic_status Is Logic running + front window title

Note format: {start, dur, pitch, vel} — start/dur in beats, pitch 0–127 (60 = middle C), velocity 1–127. Channel 9 is GM drums (36 kick, 38 snare, 39 clap, 42 closed hat, 46 open hat). Tracks also accept cc ({beat, controller, value}), bends ({beat, value} −8192…8191), program, volume, pan. Compositions accept time_sig ([3, 4]), key ("Am", "Eb", "F#m"), tempo_changes ([{beat, bpm}]), and swing (50 = straight, ~62 = MPC feel; swing_unit 0.5/0.25 for 8th/16th swing; per-track override supported). Tracks can declare a progression ({chords: ["Am", "F", "Cmaj7", "E7"]}) instead of raw notes — voicings are generated (styles: pad / bass / arp / melody — the latter writes a hook: chord tones on strong beats, one peak, resolves to the root), with repeat and start_bar for staged entrances; drums: {pattern: "half_time"} generates a full groove. analyze_midi reads the same chord names back.

Example: a full backing track from declarations

compose_midi {tempo: 85, key: "Am", name: "sketch", tracks: [
  {name: "Pad",   channel: 1, progression: {chords: ["Am","F","C","E"], repeat: 2}},
  {name: "Drums", channel: 9, drums: {pattern: "half_time", bars: 12, start_bar: 4}},
  {name: "Bass",  channel: 0, progression: {chords: ["Am","F","C","E"], style: "bass", start_bar: 4}},
  {name: "Arp",   channel: 2, progression: {chords: ["Am","F","C","E"], style: "arp", start_bar: 8}},
]}
describe_midi {path: "~/Desktop/sketch.mid"}
  → 4 track(s), 283 notes, ~16 bars at 85 BPM. key Am (82% confident).
    progression Am-F-C-E... dynamic arrangement (density 0.4-6.7 notes/beat). ...

Staged entrances (start_bar) give the arrangement a real build; the analyzer verifies its own output — key, chords, contour, and warnings for register clashes or robotic velocities.

Example: an Alchemy pad in three calls

find_patches {category: "Synthesizer/Pad", plugin: "Alchemy"}
  → [{"name": "Drifting Away", ...}, ...]
select_track {index: 3}
load_patch {query: "Drifting Away"}
  → Loaded patch 'Drifting Away' on the selected track

Genre starting points (stock Logic, index-verified)

Role Patches (exact load_patch names)
Future-bass chord stabs Massive Stack, Chicago Stack, Sparkle Chord (category EDM Chord)
Vocal-chop feel Breathy Vox, Starlight Vox, Rhythmic Vox
Sub bass Deep Sub Bass, Full Sub, Super Sub 808 Bass
Wobble bass (CC1 = wobble) Mega Wobble Bass, FM Wobble Bass, Sharp Wobble Bass
Dark pads Drifting Away (Alchemy)
Trap/808 kits Modern 808; dub: Dub Machine
Punk/rock SoCal+ kit, Hard Rock guitar, Punchy Bottom bass

rubin's CC automation maps onto these: cc 1 drives the wobble patches' filter, cc 11 fakes sidechain pump on stabs, bends do scoops and slides.

Ears: audio in, MIDI out

transcribe_audio turns any recording — a hummed melody, a guitar take, a sample — into MIDI with Spotify's basic-pitch, cached by content hash under ~/.cache/rubin/midi so repeat calls are free. analyze_midi then reads the result back (rubin has its own SMF parser) and reports what the instrument plays: pitch range, note density, polyphony. That loop — hear it, read it, compose against it — is how rubin learns what source material sounds like.

Install

# from a clone (development)
claude mcp add --scope user rubin -- /usr/bin/python3 ~/dev/rubin/server.py

# or installed as a package
pip install git+https://github.com/mrcolo/rubin
claude mcp add --scope user rubin -- rubin-mcp
python3 server.py --check   # environment health: Logic, indexes, AUs, transcription
python3 server.py --verify song.mid   # pre-flight: analysis + warnings, exit 1 if dirty
# optional, for transcribe_audio:
cd ~/dev/rubin && python3 -m venv .venv-bp && .venv-bp/bin/pip install basic-pitch

Requires macOS Accessibility + Automation permissions for the host app (Claude / terminal) — only for the UI-touching tools. compose_midi, find_patches, and open_midi_as_project need no permissions at all.

Test & demo

python3 -m unittest discover -s tests   # 76 tests, no Logic needed for most
python3 server.py --demo                # compose + open a demo beat in Logic
python3 server.py --demo --write-only   # just write the .mid

Files

  • server.py — MCP stdio server (hand-rolled JSON-RPC, no SDK)
  • midi.py — Standard MIDI File writer
  • midi_read.py — SMF parser + per-track analyzer
  • transcribe.py — basic-pitch wrapper + content-addressed cache
  • patches.py — factory patch index reader
  • logic_ctl.py — the minimal AppleScript/AX layer
  • demo_beat.py — 8-bar dark R&B demo (85 BPM, Am–F–C–E)
  • tests/ — unit + protocol tests

Known limits

  • import_audio is best-effort and often aborts: Logic imports audio through a Browser pane, not a file dialog. It is hardened to NEVER type a path into the arrange window (a path's letters fire as key commands — r starts a recording — which once damaged a live session). Drag audio from Finder for reliability.

  • import_midi and import_audio both confirm a file panel is frontmost before typing a path, and abort with Escape otherwise — they never leak a path into the arrange window. import_midi's happy path is live-verified; import_audio usually aborts (audio import is a Browser pane).

  • Patch loading, track selection, and import drive Logic's UI; they're anchored to stable AX landmarks (bounded subtree scans, never the whole window — real projects have thousands of AX elements) but a future Logic redesign could move them. list_tracks exists so failures are visible, not silent.

  • Logic auto-renames a track to its patch name after load_patch unless the track was named manually first.

  • Track-header patch labels can sit in an off-screen column and read stale — header text is NOT a reliable patch readback (this once produced a false "loading is broken" diagnosis). The selected track's channel-strip name in the inspector is ground truth; load_patch verifies against it and returns VERIFIED or FAILED accordingly.

  • Tested on Logic Pro X 10.x/11 ("Logic Pro X.app" and "Logic Pro.app" are both handled), macOS 14+.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选