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.

概览

AI 生成的概览

面向 Ableton Live 的本地 MCP 服务器,可读取你自己的 .als 工程,并向正在运行的 Live 工程写入 MIDI、设备链、自动化与标记。

可以做什么
  • 检查与分析 .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。
安装前请注意
写入类工具会改动正在运行的 Live 工程或磁盘上的 .als:MIDI、片段、定位标记、设备链、自动化,以及仅在无头环境测试过的 delete_track 与 delete_locator。写入默认是试运行,需经批准。安装脚本会修改 MCP 客户端配置并做备份。结果不确定时不会自动重试,日志并非精确一次,需自行核对状态。音频采集需要 macOS 的屏幕与系统音频录制权限。

安装

在 SourceWeft 中

  1. 打开 控制台中的 Loom by SubverseLab,将其添加到工作区。
  2. 为需要使用其工具的对话启用该服务。

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.

[checks] [release]

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

LayerJob
SenseiMIDI variation (drum / bass / chord) from a locked, hash-verified dataset
ArrangementGPSA project plan from a prompt: tempo, key, genre, channels, sections (Node)
AIMixMaster.als inspection, gain staging, clip alignment, drum buss, automation writing (on the file)
Presetor / AISoundDesignerDevice chains and a sound palette measured from the user's own projects
MusicalIntelligenceGenre evidence measured from real records; part suggestions keyed to the project
Mix Check / SampleAgentAudio measurement against profiles of released masters; YouTube → sliced sample pack; a crate-digging agent
Loom extensionThe Ableton Extension inside Live: the MCP's only connection to a running set
mcp_server45 tools, resources, prompts, progress and cancellation over stdio JSON-RPC

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)

bash
python3 install.py            # installspython3 install.py --check    # changes nothing, reports state

install.py:

  1. Registers Loom with every MCP client it finds (Claude Desktop, Claude Code, Antigravity), backing up each config; it is safe to re-run.
  2. 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, id subverselab.loom. An installed legacy package (loom.sensei-midi-writer) is reported: the MCP never sends it a mutation (LEGACY_EXTENSION).
  3. 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

KindToolsProven by
Through Live (extension)live_state, live_bridge_status, live_command (set_tempo, set_mixer, set_device_parameter, list_device_parameters, create_locator, create_midi_track, import_audio_clip, render_pre_fx, drum_pads, build_drum_kit, journal_import, delete_track, delete_locator), midi_write_arrangement, midi_write_to_live (session clip), crate_to_live, mix_from_live, project_build, midi_generate (auto_write)mcp_server/tests/test_bridge_consumer_real.py (the real bridge.ts), test_extension_path.py, extension/tests/bridge.test.ts
Engines without Liveproject_*, automation_*, drumbuss_*, chain_*, render_*, palette_read, library_search, genre_evidence, part_suggest, plan_create, plan_verify, projects_arrangement_shapes, mix_measure/analyze/profiles, crate_fetch/read/spots/chop/agent, setup_scan, gap_recordmcp_server/tests/test_mcp_tools.py (45 tools over stdio) and each engine's own pytest suite
OS level, on requestlive_project (open / close / status of Live, verified from Live's own log; changing the set restarts the extension host)test_live_project.py
Machine-boundmix_capture (method="tap": a Core Audio process tap launched as LiveTap.app through LaunchServices; macOS grants the "Screen & System Audio Recording" permission to the LiveTap entry, not to the app running the MCP; measured from a playing Live on 2026-09-06)only on a real machine

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 .adg reader), 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 under needs_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=[...] and device_map the answer's simplification block 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; the project_build step is reported as UNSUPPORTED_BY_SDK
  • loading presets / the browser → create_midi_track only adds a native device with its default preset (not_loadable_in_extension); kits are rebuilt (above), instruments go through device_map or a user step
  • time signature → bar-to-beat conversion asks for an explicit beats_per_bar, reads it from the .als when given one, and otherwise says it assumed 4/4 in beats_per_bar_source
  • metering, recording (record mode / resampling) → mix_capture method="resample", the capture_* 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

bash
./scripts/check_ci.sh    # needs neither Ableton nor personal data; CI runs this./scripts/check_all.sh   # everything; needs a real Ableton install

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.

bash
python3 scripts/extract_device_chains.py --out Presetor/data/measured_device_chains.jsonpython3 scripts/extract_sound_sources.py --out AISoundDesigner/data/measured_sound_sources.jsonpython3 scripts/setup_scan.py --check      # catalogs: what is there, what is missing

Status and known limits

  • Real-Live acceptance passed on 2026-09-07. Starting from an empty set it opened real .adg / .adv presets, 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 with extension/manifest.json.
  • Rendering needs Live's audio engine; render_plan says what should come out, render_verify says 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_owned only 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_verify and audio measurement need soundfile / 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
SourceWeft 尚未在沙箱中启动过该软件包,因此其工具未知。

版本历史

1
  1. v0.4.4最新Sep 16, 2026

评分

已满足适用检查项的 50%

该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。

  • 近 30 天内可连通25 分

    请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。

  • 已声明认证方式10 分

    请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。

  • 已列出工具15 分

    请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。

  • 描述必需15 分
  • 图标10 分
  • 文档15 分
  • 许可证10 分