
Loom by SubverseLab
io.github.senolsahan037-oss由 GitHub 帳號 senolsahan037-oss 發布v0.4.4更新於 Oct 27, 2026
Reads your own Ableton projects and writes MIDI, chains and markers into a running Live set.
概覽
面向 Ableton Live 的本機 MCP 伺服器,可讀取你自己的 .als 專案,並把 MIDI、裝置鏈、自動化與標記寫入執行中的 Live 設定。
- 可以做什麼
- 檢查與分析 .als 專案:專案檢查、增益分級、片段對齊、鼓匯流排、在檔案上寫入自動化
- 產生並寫入音樂內容:鼓、貝斯、和弦的 MIDI 變化、Session 片段、編排標記、速度、混音器與裝置參數
- 依你自己的專案與預設集 XML 建立裝置鏈、鼓組與音色庫
- 對照已發行母帶的設定檔量測與驗證混音,並抓取與切分取樣
- 規劃與驗證編排、搜尋素材庫、提供曲風證據與聲部建議
- 診斷 Live 橋接狀態,並開啟、關閉或查詢 Live 本身
- 適用情境
- 適合使用 Ableton Live 12.4 beta 的製作人,希望助理依自己的專案檔案與執行中的 Live 設定工作,而不是給出泛泛建議,並希望每次寫入都先試跑、由自己核准。
- 執行需求
- 以 stdio 在本機執行,透過 Python 安裝腳本或 MCP 套件安裝。需要 Ableton Live 12.4 beta,並在 Live 的擴充功能設定中加入 Loom 擴充功能(.ablx)後重新啟動 Live。音訊擷取與系統 Python 的說明指向 macOS;部分工具需要 soundfile 與 numpy。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 Loom by SubverseLab,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
Loom
Loom is a measurement-based production system for Ableton Live by
Şenol Şahan / SubverseLab: a local MCP server
that reads your own .als projects and library, answers with counts instead of
guesses, and writes MIDI, device chains, automation and arrangement markers into
a running Live session, verifying every write by reading it back.
Canonical home: https://subverselab.com/loom · Cite: CITATION.cff ·
Licence: AGPL-3.0-or-later · Attribution: NOTICE.
Why it exists
Ask a general-purpose model what belongs on a kick drum and it answers with confidence, having never heard a record you made. Loom replaces that guess with evidence from three places: your own project archive (which devices you actually chain, which samples you actually reach for), real released records (genre evidence measured from audio, not described from memory), and the Live set that is open right now. Where the evidence runs out, a tool returns nothing and says so. Nothing is emulated, nothing is retried on an uncertain outcome, and every write is a dry run until you approve it.
There is one connection to Live: the Loom extension, an Ableton Extension running inside Live 12.4 beta. No Control Surface, no automatic fallback, no second writer path.
What is inside
No layer produces a guess: with no evidence there is no suggestion, what the SDK cannot do is not emulated, and every writing tool is a dry run by default.
Architecture, the canonical call flow and the bridge protocol:
Docs/ARCHITECTURE.md.
Install (one path)
install.py:
- Registers Loom with every MCP client it finds (Claude Desktop, Claude Code, Antigravity), backing up each config; it is safe to re-run.
- Prepares the extension package (
extension/dist/loom.ablx, built if the toolchain is present) and compares the version and bridge protocol of the extension installed in Live with this checkout. Live shows it as Loom, idsubverselab.loom. An installed legacy package (loom.sensei-midi-writer) is reported: the MCP never sends it a mutation (LEGACY_EXTENSION). - Builds the catalogs from your own stock Ableton library.
Live's own step is a single one: add the .ablx in Live 12.4 beta's Extensions
settings and restart Live. The extension opens a file bridge in its own storage
directory; the MCP locates that bridge on every call.
The same server is packaged as an MCP bundle on the
release page
(loom-<version>.mcpb, described by server.json).
Versions are three different things: the package version is written once, in
extension/manifest.json (package.json must match; the build verifies it);
the bridge protocol is loom.bridge/3; the SDK API is 1.0.0.
Connection diagnosis (one path)
The MCP tool live_bridge_status reports which bridge it is talking to and
why, the age of the state, the session id, the capabilities the extension
publishes, mutations_allowed, the protocol verdict (OK / UPGRADE_REQUIRED
/ PROTOCOL_MISMATCH / STALE_STATE / NO_STATE), the journal's condition and
what is queued or in flight. python3 install.py --check prints the same in a
terminal.
An old extension (0.1.0 / 0.2.0, publishing no protocol) is read but never
written: every mutation is refused with UPGRADE_REQUIRED before a request
file is written. A package installed under the legacy id is treated the same
(LEGACY_EXTENSION); once the new one is installed and the old one removed from
Live, the old journal is carried over with live_command op=journal_import
(nothing forgotten, nothing deleted). More than one Loom bridge in sight is
AMBIGUOUS_BRIDGE. LOOM_BRIDGE_ROOT exists for tests only.
Supported MCP tools
The extension's single in-Live user command, "Loom: Generate" (right-click,
Session slot), goes through the same write_clip implementation and the same
ownership ledger: a clip Loom did not write is never overwritten.
Kits and presets
The SDK does not load presets (.adg / .adv). Loom does not call this
"impossible"; it separates the paths:
- A named kit:
project_build(kit="Boom Bap Kit")or a path to an.adg. The kit is read from the preset's own XML (pads, notes, names, sample files; Sensei's.adgreader), the files are resolved on this machine, and the pads are rebuilt in the extension as chain + Simpler + sample. The answer states what was carried over and what was not: per-pad effects, macros, choke groups, Simpler parameters, return chains. This is not loading the preset as is, and it is never presented as such. - A kit from samples:
live_command op=build_drum_kit pads=[{note, sample}]. - An instrument preset (bass / chord): the SDK cannot load it. Either a
native device through
device_map(Operator,Electric,Wavetable, …), or you load the preset in Live yourself and re-run the same plan; the channel is adopted and its device read from state. The answer lists both routes underneeds_preset. - Drum notes onto the kit's pads: Sensei's drum evidence is in GM pad
layout; on a kit such as 77–92 the notes are mapped by pad role (kick / snare
/ hat,
pad_mapping: by_role), unmappable roles are dropped and reported, and with no notes left no clip is written (no_notes_for_pads). - Simplification is explicit: with
tracks=[...]anddevice_mapthe answer'ssimplificationblock says which channels were dropped and why, and which device stands in for which preset. Empty channels from the template are left alone. - The file path (B): writers that work on the
.als(automation_write,drumbuss_build,chain_apply) change the set on disk; the open set is not touched and must be reopened. Preset XML is never hand-converted into a set; that is Live's job.
Not supported, because of the SDK
Extensions SDK 1.0.0-beta.1 does not provide the following. Loom does not
emulate them; it answers UNSUPPORTED_BY_SDK with the name of the missing
capability, before any request file is written:
- transport (play / stop / position) →
live_command op=transport,mix_capture follow_transport - writing the song key →
live_command op=set_key; theproject_buildstep is reported asUNSUPPORTED_BY_SDK - loading presets / the browser →
create_midi_trackonly adds a native device with its default preset (not_loadable_in_extension); kits are rebuilt (above), instruments go throughdevice_mapor a user step - time signature → bar-to-beat conversion asks for an explicit
beats_per_bar, reads it from the.alswhen given one, and otherwise says it assumed 4/4 inbeats_per_bar_source - metering, recording (record mode / resampling) →
mix_capture method="resample", thecapture_*ops
Reported to Ableton through Centercode on 2026-09-03.
The bridge contract (short)
Every answer from Live carries a structured outcome:
{kind: applied|refused|failed|indeterminate, code, applied, verified, side_effects, next_step}.
The MCP status derives from it: OK, REFUSED_IN_LIVE (Live untouched),
FAILED_IN_LIVE (attempted, previous content restored), INDETERMINATE (may
have applied; side effects and the safe next step are in the answer),
NOT_CONSUMED, INVALID_RESULT. An uncertain outcome is never retried
automatically, anywhere.
Keyed requests (build steps, idempotency_key) are journaled before the
mutation: same key + same content → the stored result; different content → a
conflict; another session → refused; half-finished → INDETERMINATE. With the
journal missing or corrupt, keyed mutations are refused and the answer says
what to do; deleting the journal is never the advice. Details in
Docs/ARCHITECTURE.md.
Tests
check_ci.sh counts every suite as passed, failed or skipped; a suite with a
missing dependency is never counted as passed. The extension's own queue code
(bridge.ts) runs both on its own (npm run test:bridge) and as the real
consumer opposite the MCP (test_bridge_consumer_real.py); the Python fake
exists for speed and is not protocol proof on its own.
Tests use temporary directories and isolated fixtures; they never touch a real Live, the installed extension or user data. The Ableton Extensions SDK is not redistributable, so the hosted runner cannot typecheck the extension; that job is marked skipped, never passed.
The real-Live acceptance script is extension/tools/measure_bridge.py (it
writes into the running Live's open set; run it on an empty set).
Data policy
This repository ships code and fixtures, never measurements. Presetor's
device-chain evidence, AISoundDesigner's palette and Sensei's catalogs are
generated from the user's own projects and Ableton installation; none of it is
in the repository. On a clean clone the tests run on synthetic fixtures, and
every answer names its origin in data_source: measured or
synthetic_fixture.
Status and known limits
- Real-Live acceptance passed on 2026-09-07. Starting from an empty set it
opened real
.adg/.advpresets, resolved the pads (16/16), wrote MIDI and locators; after save and reopen everything was in place. Open edge:delete_track/delete_locator, added in extension 0.4.4 (2026-09-11), are tested headless only; their real-Live acceptance is still to come. Version and acceptance claims are updated together withextension/manifest.json. - Rendering needs Live's audio engine;
render_plansays what should come out,render_verifysays whether what came out matches. - Automation writing (on the file) covers mixer and device parameters; no clip envelopes.
- Tool timeouts are not hard (a Python thread cannot be killed); a call that timed out never writes another request to Live.
- Because the SDK cannot read a clip's automation, colour or launch settings,
replace_ownedonly replaces the same object in place; a replacement that would need a delete is refused. No full-preservation guarantee is claimed; this narrow policy is the guarantee. - The journal is not exactly-once: work whose application is unknown is counted neither as applied nor as not applied; reading the state is the caller's job.
render_verifyand audio measurement needsoundfile/numpy; every other tool runs on macOS's own Python.
Gap log: Docs/MISSING_CONTROLS_LOG.md (its
opening note separates historical entries).
Copyright and attribution
© Şenol Şahan / SubverseLab. Free software under the
GNU AGPL v3 or later: use, modify and redistribute it, keep the
copyright and the NOTICE file, publish the source of any modified
version you distribute or run as a service, and do not strip the _source
field the server puts in every answer. Canonical home:
https://subverselab.com/loom . For written or academic citation,
CITATION.cff.
來源:README.md,提交 2c6f376
工具
0版本歷史
1- v0.4.4最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分