关于 MusicXML Comparer
MusicXML Comparer 是用于结构化、音乐感知乐谱比较的 MCP 服务。它面向需要检查编曲、OMR 输出、格式转换或乐谱编辑的音乐工作者和开发者,可从整体相似度比较到单个音符差异。
主要功能
- 01比较 MusicXML 文本或文件
- 02计算相似度并汇总变化
- 03按声部或小节查看音符差异
- 04生成易读的比较报告
- 05导出带颜色差异标注的 MusicXML
- 06描述乐谱结构和元数据
适用场景
- 01比较同一作品的不同版本或编曲
- 02根据参考乐谱评估 OMR 输出
- 03检查 MusicXML 转换往返结果
- 04验证乐谱编辑并发现回归问题
MCP 相关
向 MCP 客户端提供乐谱比较、报告、标注、描述和健康检查工具。乐谱可直接以内联内容或允许目录中的文件路径提供。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
8收录的工具列表 · 更新于 2 周前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| options | object | 否 | 比较选项(docs/architecture.md §8)。expand_repeats 默认为 false(选择启用——参见 docs/PLAN.md 'Changed decisions');normalize_pitch、ignore_articulations、part_filter、measure_range 均默认为关闭/未设置。 |
| options.part_filter | array | 否 | |
| options.measure_range | array | 否 | |
| options.expand_repeats | boolean | 否 | |
| options.normalize_pitch | boolean | 否 | |
| options.ignore_articulations | boolean | 否 | |
| target_xml | string | 是 | 作为字符串提供的目标 MusicXML 文档,与参考文档进行比较 |
| reference_xml | string | 是 | 作为字符串提供的参考 MusicXML 文档 |
详细介绍
comparer-mcp
用于感知音乐内容并比较 MusicXML 文件的 MCP 服务。提供结构化的多层级差异, 报告两个乐谱之间的变化,从整体相似度到单个音符。
功能
- 版本/编曲比较 — 比较同一作品的不同版本、编曲或简化版本
- OMR 质量评估 — 将
omr-mcp的输出与已知的优质参考进行比较 - 往返保真度 — 通过
musicxml-abc-mcp验证 MusicXML → ABC → MusicXML 转换 - 回归测试 — 检测 OMR 模型或转换逻辑变更时是否出现回归
- 乐谱编辑验证 — 确认由 LLM 驱动的编辑只更改了预期元素
安装
bash install.sh
有关客户端配置示例(Claude Desktop、Cursor、Windsurf、Continue、Zed),请参阅 SETUP.md; 如果遇到问题,请参阅 TROUBLESHOOTING.md。
MCP 工具
| 工具 | 描述 |
|---|---|
compare_musicxml | 对两个乐谱进行完整差异比较,可内联传入或通过路径指定 → 结构化 ComparisonResult JSON |
compare_musicxml_files | 对允许文件夹中的两个 MusicXML 文件路径(.musicxml、.xml 或 .mxl)进行完整差异比较 → 结构化 ComparisonResult JSON |
quick_similarity | 仅返回相似度分数(0.0–1.0)和摘要统计信息,不含逐音符详情 |
list_changes | 音符级差异(操作不等于 MATCH),可按声部名称和/或小节范围筛选 |
generate_comparison_report | 易读的版本比较报告——相似度摘要、缺失/额外的声部和小节、调号/拍号变化,以及按小节范围分组的音符级差异(例如“小节 17-24 中移调了 3 个半音”) |
export_annotated_musicxml | 为 MusicXML 添加逐音符颜色标注以标记差异。较小的结果会内联返回(reference_annotated_musicxml + target_annotated_musicxml);较大的结果会写入文件,并作为 *_path 字段及 score_summary 返回(return:auto/path/inline)。将路径作为 musicxml_path 传给 render-mcp 的 render_to_pdf/render_to_image |
describe_score | 返回乐谱的标题、调号、拍号、速度、声部(ID、名称、谱号、音域)、小节数和时长,但不返回乐谱本身 |
health_check | 服务状态——验证 music21 可导入,并运行自比较冒烟测试 |
list_capabilities | 按项目约定返回服务元数据 |
每份乐谱都可以内联传入(reference_xml、target_xml),也可以通过文件路径指定
(reference_path、target_path;.musicxml、.xml 或 .mxl),每组参数必须且只能指定一个。使用路径
可避免在对话中复制整份乐谱。路径必须位于输出文件夹(SHEET_MUSIC_OUTPUT_ROOT,默认为工作目录)、客户端的根目录之一,或
SHEET_MUSIC_INPUT_ROOTS 中列出的文件夹内。
// Compare two MusicXML strings
{
"tool": "compare_musicxml",
"arguments": {
"reference_xml": "<score-partwise>...</score-partwise>",
"target_xml": "<score-partwise>...</score-partwise>"
}
}
// Compare two files
{
"tool": "compare_musicxml_files",
"arguments": {
"reference_path": "/path/to/reference.musicxml",
"target_path": "/path/to/omr_output.musicxml"
}
}
// Quick similarity check
{
"tool": "quick_similarity",
"arguments": {
"reference_xml": "<score-partwise>...</score-partwise>",
"target_xml": "<score-partwise>...</score-partwise>"
}
}
// → {"similarity_score": 0.87, "summary": {...}}
// Filtered changes, e.g. "what changed in the Alto, measures 17-24?"
{
"tool": "list_changes",
"arguments": {
"reference_xml": "<score-partwise>...</score-partwise>",
"target_xml": "<score-partwise>...</score-partwise>",
"part": "Alto",
"measures": [17, 24]
}
}
// → {"changes": [{"measure_number": 18, "operation": "PITCH_CHANGE", "part_name": "Alto", ...}], "count": 1}
// Human-readable report
{
"tool": "generate_comparison_report",
"arguments": {
"reference_xml": "<score-partwise>...</score-partwise>",
"target_xml": "<score-partwise>...</score-partwise>"
}
}
// → {"report": "Overall similarity: 87% (minor differences)\n...", "similarity_score": 0.87}
// Colored MusicXML diff export — chain straight into render-mcp to visualize
{
"tool": "export_annotated_musicxml",
"arguments": {
"reference_xml": "<score-partwise>...</score-partwise>",
"target_xml": "<score-partwise>...</score-partwise>"
}
}
// → {"reference_annotated_musicxml": "...", "target_annotated_musicxml": "...",
// "similarity_score": 0.87, "legend": {"PITCH_CHANGE": "#FF8800", ...}}
// For scores over 8 KB (return: "auto", the default):
// → {"reference_annotated_musicxml_path": ".../scores/annotated-reference_annotated_musicxml-....musicxml",
// "target_annotated_musicxml_path": "...", "similarity_score": 0.87, "legend": {...},
// "score_summary": {"reference_annotated_musicxml": {...}, "target_annotated_musicxml": {...}}}
// Paths instead of inline text
{
"tool": "quick_similarity",
"arguments": {
"reference_path": "scores/reference.musicxml",
"target_path": "scores/omr_output.mxl"
}
}
compare_musicxml、compare_musicxml_files、generate_comparison_report 和
export_annotated_musicxml 均接受可选的 options 对象:
{
"expand_repeats": false, // unfold repeats before comparing (default: false — opt-in)
"normalize_pitch": false, // transpose transposing instruments to concert/sounding pitch
"ignore_articulations": false, // exclude articulations from NoteInfo/diffs
"parts": ["Soprano"], // compare only these parts: IDs, names or voices ("P1", "S");
// part_filter is a deprecated alias
"measures": [1, 32] // only differences in measures 1-32, inclusive (scores are not
// cut); measure_range is a deprecated alias
}
直接使用引擎
比较引擎(src/comparer_mcp/engine.py)不依赖 MCP,可作为普通 Python 库独立使用,无需启动 MCP 服务:
cd comparer-mcp
uv sync
from comparer_mcp.engine import compare, compare_files
# Compare two MusicXML strings
result = compare(reference_xml, target_xml)
# Compare two files (.musicxml, .xml, or compressed .mxl)
result = compare_files("reference.musicxml", "omr_output.mxl")
print(result.similarity_score) # float, 0.0-1.0
print(result.summary) # ComparisonSummary: parts/measures/notes matched, missing, changed
print(result.part_diffs) # list[PartDiff] -> list[MeasureDiff] -> list[NoteDiff]
错误会以 comparer_mcp.engine.ProcessingError 的形式抛出(例如文件缺失或 MusicXML 无效时),并带有 .error_code 属性(FILE_NOT_FOUND、INVALID_INPUT 等),与 MCP 工具返回的格式一致。
测试
# Unit tests
VIRTUAL_ENV= .venv/bin/pytest tests/ -v -m "not integration"
# Integration tests (real .mxl SATB fixtures shared with omr-mcp)
VIRTUAL_ENV= .venv/bin/pytest tests/ -v -m integration
# Install dependencies
uv sync
依赖项
系统要求
- Python 3.11+
- 无需系统库
阶段状态
| 阶段 | 状态 |
|---|---|
| 阶段 1 — 核心比较(MVP) | 已完成 — 45/45 项测试通过(43 项单元测试 + 2 项集成测试) |
| 阶段 2 — 丰富细节(调号/拍号差异、感知声部的对齐、演奏法) | 已完成 — 67/67 项测试通过(65 项单元测试 + 2 项集成测试) |
阶段 3 — MCP 服务与集成(server.py、全部 6 个工具、install.sh、SETUP.md、客户端配置示例) | 已完成 — 94/94 项测试通过(90 项单元测试 + 4 项集成测试) |
阶段 4 — 高级功能(options 接线、generate_comparison_report、export_annotated_musicxml) | 已完成 — 134/134 项测试通过(127 项单元测试 + 7 项集成测试) |
UX 第 2 波 — 乐谱引用(reference_path/target_path、用于标注导出的 return、describe_score) | 已完成 — 239 项单元测试通过(+7 项集成测试) |
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。