mcpField
M
MusicXML Comparer

MusicXML Comparer

ローカル
github.com/raulkiviメディア・デザイン12 日前に更新

MusicXML Comparer について

MusicXML Comparerは、2つの楽譜を音楽的な構造に沿って比較するMCPサーバーです。編曲、OMR出力、変換結果、楽譜編集を確認する音楽関係者や開発者向けに、全体の類似度から個々の音符まで差分を示します。

主な機能

  1. 01MusicXMLテキストまたはファイルの比較
  2. 02類似度の算出と変更点の要約
  3. 03パートや小節ごとの音符差分表示
  4. 04読みやすい比較レポートの生成
  5. 05差分を色分けしたMusicXMLの出力
  6. 06楽譜構造とメタデータの説明

活用シーン

  1. 01作品の版や編曲の比較
  2. 02参照楽譜を使ったOMR出力の評価
  3. 03MusicXML変換の往復結果の確認
  4. 04楽譜編集の検証と回帰の検出

MCP 対応

楽譜比較、レポート、注釈、説明、ヘルスチェックのツールをMCPクライアントに提供します。楽譜はインライン入力、または許可されたフォルダー内のファイルパスで渡せます。

設定

ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。

mcp.json · 共通設定
{
"mcpServers": {
"raulkivi-comparer": {
"command": "uvx",
"args": [
"comparer-mcp"
]
}
}
}
起動コマンドuvx comparer-mcp

ローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。

パッケージ
pypicomparer-mcp0.2.1

ツール

8

掲載時のツール一覧 · 2 週間前に更新

パラメーター型必須説明
optionsobjectいいえ比較オプション(docs/architecture.md §8)。expand_repeats のデフォルトは false(オプトイン。docs/PLAN.md 'Changed decisions' を参照)。normalize_pitch、ignore_articulations、part_filter、measure_range はすべてデフォルトでオフ/未設定です。
options.part_filterarrayいいえ
options.measure_rangearrayいいえ
options.expand_repeatsbooleanいいえ
options.normalize_pitchbooleanいいえ
options.ignore_articulationsbooleanいいえ
target_xmlstringはい参照ドキュメントとの比較対象となる、文字列形式のターゲット MusicXML ドキュメント
reference_xmlstringはい文字列形式の参照 MusicXML ドキュメント

詳細

comparer-mcp

MusicXML ファイルを音楽的に比較するための MCP サーバーです。2つの楽譜の間で何が変わったかを、全体的な類似度から個々の音符まで、複数の階層で構造化された差分として報告します。

できること

  • バージョン/編曲の比較 — 同じ曲の異なる版、編曲、または簡易版を比較します
  • OMR 品質評価 — omr-mcp の出力を、既知の正解データと比較します
  • 往復変換の忠実度確認 — musicxml-abc-mcp を介した MusicXML → ABC → MusicXML の変換結果を検証します
  • リグレッションテスト — OMR モデルや変換ロジックが変わった際のリグレッションを検出します
  • 楽譜編集の検証 — LLM による編集で意図した要素だけが変更されたことを確認します

インストール

bash install.sh

クライアント設定の例については SETUP.md(Claude Desktop、Cursor、Windsurf、Continue、Zed)を、正常に動作しない場合は TROUBLESHOOTING.md を参照してください。

MCP ツール

ツール説明
compare_musicxml2つの楽譜の完全な差分。インラインまたはパスで指定 → 構造化された ComparisonResult JSON
compare_musicxml_files許可されたフォルダー内にある2つの 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)、大きな結果はファイルに書き込まれ、score_summary とともに *_path フィールドで返されます(return: auto/path/inline)。パスを render-mcp の render_to_pdf/render_to_image に musicxml_path として渡します
describe_score楽譜のタイトル、調、拍子、テンポ、パート(ID、名前、音部記号、音域)、小節数、演奏時間を返します。楽譜自体は返しません
health_checkサーバーの状態 — music21 がインポート可能であることを確認し、自己比較のスモークテストを実行します
list_capabilitiesプロジェクトの規約に基づくサーバーメタデータ

各楽譜はインライン(reference_xml、target_xml)またはファイルパス(reference_path、target_path。.musicxml、.xml、.mxl)で渡せます。各ペアから指定するのは1つだけです。パスを使うと、会話を通じて楽譜全体をコピーせずに済みます。パスは出力フォルダー(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 の依存関係がなく、MCP サーバーとは独立した通常の Python ライブラリとして完全に利用できます。

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

依存関係

  • music21 — MusicXML の解析、楽譜オブジェクトモデル、ストリームのアラインメント
  • numpy — 音符のアラインメント用距離行列(music21 経由の推移的依存関係)
  • mcp — MCP プロトコル

システム要件

  • 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 Wave 2 — スコア参照(reference_path/target_path、注釈付きエクスポート用の return、describe_score)完了 — ユニットテスト 239 件が成功(統合テスト +7 件)

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。