audio2score-mcp
audio2score-mcp
将录制的音频文件转换为可编辑的乐谱:音频 → MIDI → MusicXML。
选择 MusicXML 作为目标格式,因为它是"乐谱界的 SVG"——一种开放的、基于文本的格式,任何记谱应用(MuseScore、Sibelius、Guitar Pro、Finale、Dorico)都可以打开、编辑和重新导出,而无需拥有生成它的流水线。本项目只生成 .mid 和 .musicxml 文件;打开、编辑以及导出为任何其他格式(PDF、音频、六线谱)都在你选择的记谱应用中手动完成——关于本项目为何刻意不封装这部分,请参阅下文"此项目连接到的格式"。
两种运行方式:作为普通 CLI 脚本运行,或作为 MCP 服务器运行,将相同的步骤暴露为 Claude 可以调用的工具。
目录内容
transcribe.py— 音频文件 → MIDI,通过 Spotify 的 basic-pitchto_score.py— MIDI 文件 → MusicXML,通过 music21score_to_notes.py— 乐谱文件(MIDI、MusicXML,或任何 music21 能读取的格式)→ 以 daw-mcp 的batch_set_notes格式输出的 JSON 音符数组mcp_server.py— MCP 服务器,将以上三个脚本封装为工具(transcribe_audio、midi_to_score、score_to_notes)
每一步都是磁盘上独立、真实存在的产物——不是隐藏的中间结果。MIDI 与记谱之间的停顿是刻意设计的:自动转写是有损的,因此在它变成乐谱之前,原始 MIDI 值得检查(或手动修正)一下。
score_to_notes.py 刻意设计为格式无关的,而非 MIDI 专用——music21.converter.parse() 对 MIDI 和 MusicXML 的处理完全相同,因此将 transcribe.py 生成的 .mid 或外部 OMR 工具(参见"此项目连接到的格式")生成的 .mxl 喂给它,走的是同一条代码路径。本项目没有单独的 MusicXML→MIDI 或 MusicXML→PDF 工具——一旦生成了 .musicxml,任何记谱应用都能直接打开并导出它,所以在这里构建这些功能只是重复安装已有的东西。
Related MCP server: whisper-mcp
文件存放位置
建议:将输入文件放入 workspace/(仓库本地目录,已被 gitignore——参见 .gitignore——放在这里的任何内容都不会被提交,包括输入文件)。不过这不是硬性要求——任何路径都可以。每个输出文件都生成在其输入文件旁边,同名不同扩展名:
workspace/song.mp3 <- you put this here (any format basic-pitch/librosa reads: mp3, wav, ogg, flac...)
workspace/song.mid <- transcribe_audio writes this
workspace/song.musicxml <- midi_to_score writes this (open in MuseScore/Guitar Pro/Sibelius/Finale/Dorico)
workspace/song.notes.json <- score_to_notes writes this (feed into daw-mcp's batch_set_notes)查看方式:直接用你手头的任何记谱应用打开 .mid 或 .musicxml——本项目不会为你启动任何应用。如果 MuseScore 提示 .musicxml"已损坏",在断定文件有问题之前,请先查看下面的复调注意事项。
环境搭建
需要 Python 3.11 特定版本——basic-pitch 依赖 TensorFlow 2.15,其 wheel 只支持到 cp311;3.12 和 3.13 将无法解析。生成的虚拟环境约为 2GB(完整版 TensorFlow,而非更轻量的后端)。
uv venv --python 3.11 venv
uv pip install -r requirements.txt --python venv/Scripts/python.exe依赖项已精确锁定(basic-pitch==0.4.0、music21==10.5.0、setuptools==65.5.0、mcp==2.0.0)——本项目没有自动化测试套件,因此一个与已验证环境完全一致的全新环境就是替代方案。setuptools 特别被锁定,是因为较新版本会破坏 basic-pitch 所需的传递依赖 resampy 的导入。
用法:CLI
venv/Scripts/python.exe transcribe.py "C:\path\to\song.mp3"
# -> C:\path\to\song.mid
venv/Scripts/python.exe to_score.py "C:\path\to\song.mid"
# -> C:\path\to\song.musicxml
venv/Scripts/python.exe score_to_notes.py "C:\path\to\song.mid"
# -> C:\path\to\song.notes.json (daw-mcp's batch_set_notes format - also
# takes a .musicxml/.mxl directly, e.g. from OMR, no separate step needed)输出始终生成在输入旁边,同名不同扩展名。三个脚本都拒绝覆盖已存在的输出文件——如果想重新运行,请先删除或移动旧文件。错误(输入缺失、库故障)会向 stderr 打印清晰的消息并以非零状态退出;不会有静默失败。
只运行你的实际目标所需的工具——不要默认把三个全部串联起来。 每个工具只生成一个文件;运行超出需要的工具只会产生没人要的文件。
目标 | 运行 | 生成的文件 |
将录音作为记谱查看/编辑 |
|
|
将录音的音符导入 daw-mcp |
|
|
将扫描/排版好的乐谱导入 daw-mcp | Audiveris(外部工具,参见"此项目连接到的格式")→ 对 |
|
将扫描乐谱作为记谱查看/编辑 | 仅 Audiveris |
|
前两行中的 .mid 与其说是"输出",不如说是不可避免的检查点——basic-pitch 只能输出 MIDI,而且在信任其后续结果之前值得检查一下(原因参见下面的"已知问题")。
实际示例
这是一个真实运行,而非假设。输入:一个合成的单声道 WAV,C 大调琶音(C4-E4-G4-C5,四分音符,带有短衰减包络,因此起音清晰)——这是本项目关心的意义上的"真实音频"(磁盘上实际的波形,而非手打的 MIDI),只是合成而非录制,因此转写结果可以在没有版权文件散落在公共仓库中的情况下复现。
$ venv/Scripts/python.exe transcribe.py c_major_arpeggio.wav
WARNING:root:Coremltools is not installed. ...
WARNING:root:tflite-runtime is not installed. ...
WARNING:root:onnxruntime is not installed. ...
Wrote c_major_arpeggio.mid
$ venv/Scripts/python.exe to_score.py c_major_arpeggio.mid
Wrote c_major_arpeggio.musicxml
$ venv/Scripts/python.exe score_to_notes.py c_major_arpeggio.mid
Wrote c_major_arpeggio.notes.json三行 WARNING:root 是 basic-pitch 提示可选后端(CoreML、TFLite、ONNX)未安装——无害,实际使用的是 TensorFlow 后端,而且这正是 transcribe.py v1.1.1 现在正确隐藏的内容,不会破坏 mcp_server.py 的 stdout 流(参见 CHANGELOG.md)——它只出现在终端上,不会进入 MCP 协议通道。
c_major_arpeggio.notes.json,即 daw-mcp 就绪的输出:
[[0.0, 60, 83, 1.0], [1.25, 64, 80, 1.0], [2.3333, 67, 80, 1.0], [3.5, 72, 78, 0.5], [4.0, 72, 78, 0.5]]输入了四个音符(C4、E4、G4、C5);basic-pitch 正确检测了全部四个音符的音高和力度(60/64/67/72,与琶音完全一致),但将最后一个音符(C5)拆成了两个连续的条目而非一个——衰减包络的尾部显然被识别为第二个起音。这就是上文"目录内容"部分警告的自动转写有损性,在第一个具有自然(非平直)音量形状的音符上就实际出现了:在盲目信任 .musicxml/.notes.json 之前,请检查 .mid,尤其是在持续音或衰减音附近。
c_major_arpeggio.musicxml 可以在任何记谱应用中正常打开(已验证格式良好:正确的 MusicXML 4.0 DOCTYPE,C4/E4/G4/G4/C5/C5/C5 的 <step>/<octave> 音高——被拆分的 C5 以跨小节线的连音形式出现,这是 MusicXML 中一个音符无法放入单个小节时的标准表示,而非第二个 bug)。
用法:MCP 服务器
在 Claude Code 的配置中注册为 audio2score——全新安装后请重启 Claude Code 才能看到它(MCP 服务器在启动时加载)。
三个工具,与三个脚本完全对应:
transcribe_audio(audio_path)→ 返回.mid路径midi_to_score(midi_path)→ 返回.musicxml路径score_to_notes(score_path)→ 返回.notes.json路径(daw-mcp 的batch_set_notes音符数组格式;接受 MIDI 或 MusicXML)
底层行为与 CLI 相同(相同的覆盖保护、相同的错误)——MCP 服务器是薄封装,而非不同的实现。
如果调用似乎挂起,需要知道一件事: 如果 transcribe_audio 调用看起来超时或被取消,转写可能仍在后台运行,并且无论如何都会完成 .mid 文件的写入。重试时就会触发覆盖保护("已存在"),即使第一次调用看起来从未成功。这不是 bug——重试前先检查 .mid 是否已存在。
要在其他地方自行注册服务器,请将以下内容添加到你的 MCP 配置(mcpServers)中,两个字段都使用绝对路径——客户端启动 stdio 服务器时没有定义工作目录,因此相对路径无法解析:
"audio2score": {
"type": "stdio",
"command": "<absolute path to>\\venv\\Scripts\\python.exe",
"args": ["<absolute path to>\\mcp_server.py"],
"env": {}
}此项目不做什么
不提供乐谱/MIDI → 音频、PDF 或六线谱输出,也不提供 MusicXML → MIDI 转换——原因及替代方案参见下文"此项目连接到的格式"
不提供声部分离或多乐器拆分
刻意不设自动化测试套件——验证始终是对真实音频的真实运行
此项目连接到的格式
一旦生成了 .musicxml,本项目就刻意止步——每个记谱应用都已原生支持打开 MusicXML,并从自己的菜单中导出所需内容(PDF、音频、六线谱、MIDI)。围绕这些导出构建自动化封装的做法曾被尝试过,但大部分已回退(完整的反复过程参见 CHANGELOG.md v1.2.0 至 v2.0.0)——在确认 score_to_notes.py 可以直接接受 MusicXML 而无需单独转换步骤之后,最终发现仍然值得自动化的方向一个都没有。
方向 | 使用 | 备注 |
MusicXML → PDF、音频、六线谱、MIDI | MuseScore Studio 或 Guitar Pro,正常打开 | 刻意不在此封装——见上文。(MuseScore 的 CLI 转换模式 |
PDF(扫描/排版乐谱)→ MusicXML | Audiveris( |
|
PDF → daw-mcp 的音符格式 | Audiveris(上文)→ 本项目的 | 两步,都是真实的,并且已在真实乐谱上端到端测试——中间无需 MIDI 转换 |
对待 OMR 输出的怀疑程度至少应与对待 basic-pitch 的音频转写相同——在信任之前检查中间的 .musicxml,并且不要期望 Audiveris 能成功处理每个 PDF(参见上面六线谱书的失败案例)。
已知问题:MuseScore 可能会将转录的 .musicxml 文件视为“已损坏”并拒绝打开
高度复调的转录可能会生成一个 MuseScore Studio 拒绝打开并称之为“已损坏”的 .musicxml 文件。根本原因:当一首曲子需要多个同时进行的声部(5+)时,music21 自带的 MusicXML 写入器会在某些 <note> 元素上省略 <voice> 标签——这已通过一段真实的 45 秒录音得到验证,该录音被转录为密集且经常重叠的音符(这是 basic-pitch 在真实音频上拾取泛音/伪影所导致的副作用,而不是干净的单一旋律线)。已确认这是 music21 写入器的问题,而不是本项目的代码:to_score.py 只是一个两行的 parse() + write() 调用,本身没有任何音符/声部逻辑;即使在写入前显式调用 score.makeNotation() 也无法修复。用 music21 本身重新解析同一文件时,它只会发出警告(Cannot put in an element with a missing voice tag),并通过将这些音符默认归入声部 1 来恢复;而 MuseScore 的导入器只是更严格,直接拒绝,而不是容忍这种情况。
变通方法:点击“仍然打开”——文件可以正常加载,只是那些特定音符会进入声部 1,而不是原先检测到的声部;这只是小的排版异常,不是数据丢失。在干净、低复调的输入(手工创作的旋律 MIDI,转录并重新验证后没有任何 voice 标签问题)上不会出现——这专门针对杂乱、密集的真实音频转录输出。
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceAn MCP server that connects Claude to FL Studio, allowing the AI to compose music, control instruments, and live record melodies, chords, and drums to the piano roll.97
- AlicenseAqualityCmaintenanceMCP server that provides a transcribe_audio tool to convert voice messages from channels into text using OpenAI Whisper, enabling Claude Code to process audio attachments.1MIT
- AlicenseBqualityDmaintenanceAn MCP server that enables natural language control of Steinberg Dorico music notation software through Claude Desktop or ChatGPT, offering tools for score creation, note input, notation, harmony analysis, and orchestration.5410MIT
- -licenseNot gradedqualityNot gradedmaintenanceMCP server for vibe coding with music, enabling format conversion (LilyPond, MusicXML, MIDI, ABC, etc.), audio-to-sheet transcription, and transposition with robust fallback outputs.1
Related MCP Connectors
MCP server for Producer/Riffusion AI music generation
Generate AI music via the Lacuna Music API from MCP clients like Claude Desktop & Code.
MCP server for Suno AI music generation, lyrics, and covers
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/David7ce/audio2score-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server