Skip to main content

comparer-mcp

MCP server for music-aware comparison of MusicXML files. Provides structured, multi-level diffs that report what changed between two scores — from global similarity down to individual notes.

What it does

  • Version / arrangement comparison — Compare different editions, arrangements, or simplifications of the same piece
  • OMR quality evaluation — Compare omr-mcp output against a known-good reference
  • Round-trip fidelity — Verify MusicXML → ABC → MusicXML through musicxml-abc-mcp
  • Regression testing — Detect regressions when OMR models or conversion logic change
  • Score editing validation — Confirm LLM-driven edits only changed intended elements

Installation

bash install.sh

See SETUP.md for client config snippets (Claude Desktop, Cursor, Windsurf, Continue, Zed) and TROUBLESHOOTING.md if something doesn't work.

MCP Tools

Tool Description
compare_musicxml Full diff of two MusicXML strings → structured ComparisonResult JSON
compare_musicxml_files Full diff of two MusicXML file paths (.musicxml, .xml, or .mxl) → structured ComparisonResult JSON
quick_similarity Similarity score (0.0–1.0) + summary statistics only, no per-note detail
list_changes Note-level diffs (operation != MATCH), optionally filtered by part name and/or measure range
generate_comparison_report Human-readable version comparison report — similarity headline, missing/extra parts and measures, key/time signature changes, note-level differences grouped by measure range (e.g. "transposed by 3 semitones in measures 17-24")
export_annotated_musicxml MusicXML with per-note color annotations marking the diff; returns reference_annotated_musicxml + target_annotated_musicxml, chainable straight into render-mcp's render_to_pdf/render_to_image
health_check Server status — verifies music21 is importable and runs a self-comparison smoke test
list_capabilities Server metadata per project conventions
// 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",
    "measure_range": [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", ...}}

compare_musicxml, compare_musicxml_files, generate_comparison_report, and export_annotated_musicxml all accept an optional options object:

{
  "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
  "part_filter": ["Soprano"],     // compare only named parts (case-insensitive)
  "measure_range": [1, 32]        // compare only measures 1-32, inclusive
}

Using the engine directly

The comparison engine (src/comparer_mcp/engine.py) has no MCP dependency and is fully usable as a plain Python library, independent of the MCP server:

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]

Errors are raised as comparer_mcp.engine.ProcessingError (e.g. for a missing file or invalid MusicXML), carrying a .error_code attribute (FILE_NOT_FOUND, INVALID_INPUT, etc.) matching the format the MCP tools return.

Testing

# 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

Dependencies

  • music21 — MusicXML parsing, score object model, stream alignment
  • numpy — distance matrix for note alignment (transitive via music21)
  • mcp — MCP protocol

System requirements

  • Python 3.11+
  • No system libraries required

Phase status

Phase Status
Phase 1 — Core comparison (MVP) Complete — 45/45 tests passing (43 unit + 2 integration)
Phase 2 — Rich detail (key/time signature diffs, voice-aware alignment, articulations) Complete — 67/67 tests passing (65 unit + 2 integration)
Phase 3 — MCP server & integration (server.py, all 6 tools, install.sh, SETUP.md, client config examples) Complete — 94/94 tests passing (90 unit + 4 integration)
Phase 4 — Advanced features (options wiring, generate_comparison_report, export_annotated_musicxml) Complete — 134/134 tests passing (127 unit + 7 integration)

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

comparer_mcp-0.1.0.tar.gz (155.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

comparer_mcp-0.1.0-py3-none-any.whl (22.9 kB view details)

Uploaded Python 3

File details

Details for the file comparer_mcp-0.1.0.tar.gz.

File metadata

  • Download URL: comparer_mcp-0.1.0.tar.gz
  • Upload date:
  • Size: 155.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for comparer_mcp-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f777dc03a42e8f5f4c399fe4fc1db9f0ec1e9095b2436272db2288d42edcbc2b
MD5 60c31c9f3b2887204c0ef630988183fe
BLAKE2b-256 3fe3743b84ea75834a08058c2e33865a1d51a02dc8804ce2ab41136f54aa2296

See more details on using hashes here.

Provenance

The following attestation bundles were made for comparer_mcp-0.1.0.tar.gz:

Publisher: publish.yml on raulkivi/music-assistant

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file comparer_mcp-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: comparer_mcp-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 22.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for comparer_mcp-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6641bd23b67639b6a4edd8da7d8946dd52edefbe318fd4f3ebb21dc69fd96228
MD5 c3cf58b63f0961398cff19eb3579403f
BLAKE2b-256 b5f78948c691cd9a770f6f124451336255c9a8e2d122b103ce20ec60b864e51f

See more details on using hashes here.

Provenance

The following attestation bundles were made for comparer_mcp-0.1.0-py3-none-any.whl:

Publisher: publish.yml on raulkivi/music-assistant

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 files

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page