Skip to main content
Glama
David7ce
by David7ce

audio2score-mcp

Verwandle eine aufgenommene Audiodatei in eine bearbeitbare Partitur: Audio → MIDI → MusicXML.

MusicXML ist das Ziel, weil es das "SVG der Notenschrift" ist — ein offenes, textbasiertes Format, das jede Notations-App (MuseScore, Sibelius, Guitar Pro, Finale, Dorico) öffnen, bearbeiten und neu exportieren kann, ohne die Pipeline zu besitzen, die es erzeugt hat. Dieses Projekt erzeugt nur die .mid- und .musicxml-Dateien; das Öffnen, Bearbeiten und Exportieren in alles andere (PDF, Audio, Tabulatur) passiert in der jeweiligen Noten-App, die du wählst, von Hand — siehe „Formate, an die dieses Projekt anbindet" weiter unten, warum dieses Projekt diesen Teil bewusst nicht umschließt.

Zwei Möglichkeiten, es auszuführen: als einfache CLI-Skripte oder als MCP-Server, der dieselben Schritte als Tools bereitstellt, die Claude aufrufen kann.

Was hier enthalten ist

  • transcribe.py — Audiodatei → MIDI, über Spotifys basic-pitch

  • to_score.py — MIDI-Datei → MusicXML, über music21

  • score_to_notes.py — eine Partiturdatei (MIDI, MusicXML oder alles, was music21 lesen kann) → JSON-Notenarray im batch_set_notes-Format von daw-mcp

  • mcp_server.py — MCP-Server, der alle drei als Tools umschließt (transcribe_audio, midi_to_score, score_to_notes)

Jeder Schritt ist ein separates, reales Artefakt auf der Festplatte — kein verstecktes Zwischenprodukt. Die Pause zwischen MIDI und Notation ist beabsichtigt: automatische Transkription ist verlustbehaftet, daher lohnt sich ein Blick auf das rohe MIDI (oder eine manuelle Korrektur), bevor es zu einer Partitur wird.

score_to_notes.py ist bewusst formatagnostisch, nicht MIDI-spezifisch — music21.converter.parse() behandelt MIDI und MusicXML identisch, sodass die Zuführung einer .mid von transcribe.py oder einer .mxl von einem externen OMR- Tool (siehe „Formate, hier" weiter unten) denselben Codepfad nimmt. Es gibt kein separates MusicXML→MIDI- oder MusicXML→PDF-Tool in diesem Projekt — sobald eine .musicxml existiert, öffnet und exportiert sie jede Noten-App bereits, sodass das hier zu bauen nur das duplizieren würde, was bereits installiert ist.

Related MCP server: whisper-mcp

Wo Dateien hingehen

Empfohlen: Eingabedateien in workspace/ ablegen (repo-lokal, gitignored — siehe .gitignore — nichts, was hier abgelegt wird, wird jemals committet, auch Eingaben nicht). Es gibt aber keine harte Anforderung — jeder Pfad funktioniert. Jede Ausgabe landet neben ihrer Eingabedatei, gleicher Basisname, andere Endung:

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)

Zum Anzeigen: die .mid- oder .musicxml-Datei direkt in der Noten-App deiner Wahl öffnen — nichts hier startet eine für dich. Wenn MuseScore die .musicxml als „beschädigt" meldet, siehe den Hinweis zur Polyphonie unten, bevor du annimmst, dass die Datei defekt ist.

Einrichtung

Erfordert Python 3.11 speziell — basic-pitch zieht TensorFlow 2.15 herein, dessen Wheels bei cp311 enden; 3.12 und 3.13 werden nicht aufgelöst. Das resultierende venv ist ~2GB (volles TensorFlow, kein leichteres Backend).

uv venv --python 3.11 venv
uv pip install -r requirements.txt --python venv/Scripts/python.exe

Abhängigkeiten sind exakt festgelegt (basic-pitch==0.4.0, music21==10.5.0, setuptools==65.5.0, mcp==2.0.0) — dieses Projekt hat keine automatisierte Testsuite, also ist eine frische Umgebung, die exakt dem entspricht, was verifiziert wurde, der Ersatz. setuptools ist speziell festgelegt, weil neuere Versionen einen transitiven resampy-Import brechen, den basic-pitch benötigt.

Verwendung: 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)

Die Ausgabe landet immer neben der Eingabe, gleicher Basisdateiname, andere Endung. Alle drei Skripte weigern sich, eine vorhandene Ausgabedatei zu überschreiben — lösche oder verschiebe sie zuerst, wenn du erneut ausführen willst. Fehler (fehlende Eingabe, ein Bibliotheksfehler) geben eine klare Meldung auf stderr aus und beenden mit einem Nicht-Null-Status; nichts schlägt still fehl.

Führe nur das/die Tool(s) aus, die dein tatsächliches Ziel braucht — verketten nicht alle drei standardmäßig. Jedes Tool erzeugt genau eine Datei; mehr auszuführen als nötig fügt nur Dateien hinzu, die niemand angefordert hat.

Ziel

Ausführen

Erzeugte Dateien

Aufnahme als Notation anzeigen/bearbeiten

transcribe_audiomidi_to_score

.mid, .musicxml

Noten einer Aufnahme in daw-mcp bringen

transcribe_audioscore_to_notes

.mid, .notes.json (überspringe midi_to_score — für dieses Ziel nicht nötig)

Gescannte/gesetzte Noten in daw-mcp bringen

Audiveris (extern, siehe „Formate, hier") → score_to_notes auf der .mxl

.mxl, .notes.json (kein MIDI-Schritt überhaupt)

Gescannte Noten als Notation anzeigen/bearbeiten

Nur Audiveris

.mxl — bereits MusicXML, direkt öffnen, kein Tool hier nötig

.mid in den ersten beiden Zeilen ist nicht wirklich „Ausgabe", sondern eher ein unvermeidlicher Checkpoint — basic-pitch kann nur MIDI ausgeben, und es lohnt sich, einen Blick darauf zu werfen, bevor man dem vertraut, was danach kommt (siehe unten „Bekanntes Problem", warum).

Durchgearbeitetes Beispiel

Ein echter Lauf, kein hypothetischer. Eingabe: ein synthetisches Mono-WAV, ein C-Dur- Arpeggio (C4-E4-G4-C5, Viertelnoten mit einer kurzen abklingenden Hüllkurve, sodass die Einsätze sauber sind) — „echtes Audio" im Sinne dieses Projekts (eine tatsächliche Wellenform auf der Platte, nicht handgetipptes MIDI), nur synthetisiert statt aufgenommen, damit die Transkription ohne eine urheberrechtlich geschützte Datei reproduzierbar ist, die in einem öffentlichen Repo liegt.

$ 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

Die drei WARNING:root-Zeilen sind basic-pitch, das darauf hinweist, dass optionale Backends (CoreML, TFLite, ONNX) nicht installiert sind — harmlos, TensorFlow ist das tatsächlich verwendete Backend, und genau das versteckt transcribe.py v1.1.1 jetzt korrekt, ohne den stdout-Stream von mcp_server.py zu beschädigen (siehe CHANGELOG.md) — es landet nur auf dem Terminal, nicht auf dem MCP-Protokollkanal.

c_major_arpeggio.notes.json, die daw-mcp-bereite Ausgabe:

[[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]]

Vier Noten gingen hinein (C4, E4, G4, C5); basic-pitch erkannte Tonhöhe und Lautstärke für alle vier korrekt (60/64/67/72, exakt passend zum Arpeggio), aber teilte die letzte Note (C5) in zwei aufeinanderfolgende Einträge statt in einen — der Schwanz der abklingenden Hülle wurde offenbar als zweiter Einsatz gelesen. Dies ist die Verlustbehaftung der automatischen Transkription, vor der der Abschnitt „Was hier ist" oben warnt, im echten Leben erwischt an der allerersten Note mit einer naturalistischen (nicht flachen) Lautstärkeform: Prüfe die .mid, bevor du der .musicxml/.notes.json blind vertraust, besonders bei gehaltenen oder abklingenden Noten.

c_major_arpeggio.musicxml öffnet sauber in jeder Noten-App (verifiziert wohlgeformt: korrekte MusicXML-4.0-DOCTYPE, <step>/<octave>-Tonhöhen für C4/E4/G4/G4/C5/C5/C5 — das geteilte C5 erscheint als gebundene Noten über eine Taktgrenze hinweg, was Standard-MusicXML für eine Note ist, die nicht in einen Takt passt, nicht ein zweiter Bug).

Verwendung: MCP-Server

Registriert in der Konfiguration von Claude Code als audio2score — starte Claude Code nach einer frischen Installation neu, damit es erscheint (MCP-Server werden beim Start geladen).

Drei Tools, die die drei Skripte exakt spiegeln:

  • transcribe_audio(audio_path) → gibt den .mid-Pfad zurück

  • midi_to_score(midi_path) → gibt den .musicxml-Pfad zurück

  • score_to_notes(score_path) → gibt den .notes.json-Pfad zurück (daw-mcp's batch_set_notes-Notenarray-Format; akzeptiert MIDI oder MusicXML)

Gleiches Verhalten wie die CLI darunter (gleicher Überschreibschutz, gleiche Fehler) — der MCP-Server ist ein dünner Wrapper, keine andere Implementierung.

Eine Sache, die du wissen solltest, wenn ein Aufruf zu hängen scheint: Wenn ein transcribe_audio-Aufruf scheinbar eine Zeitüberschreitung hat oder abgebrochen wird, kann die Transkription im Hintergrund weiterlaufen und die .mid-Datei trotzdem fertig schreiben. Ein erneuter Versuch trifft dann auf den Überschreibschutz („existiert bereits"), obwohl der erste Aufruf aussah, als wäre er nie erfolgreich gewesen. Das ist kein Bug — prüfe, ob die .mid bereits existiert, bevor du es erneut versuchst.

Um den Server selbst woanders zu registrieren, füge dies zu deiner MCP-Konfiguration (mcpServers) hinzu, mit absoluten Pfaden für beide Felder — der Client startet stdio-Server ohne definiertes Arbeitsverzeichnis, also werden relative Pfade nicht aufgelöst:

"audio2score": {
  "type": "stdio",
  "command": "<absolute path to>\\venv\\Scripts\\python.exe",
  "args": ["<absolute path to>\\mcp_server.py"],
  "env": {}
}

Was dieses Projekt nicht tut

  • Keine Partitur/MIDI → Audio-, PDF- oder Tabulatur-Ausgabe, auch keine MusicXML → MIDI- Konvertierung — siehe „Formate, hier" unten, warum und was stattdessen zu verwenden ist

  • Keine Stimmseparation oder Multi-Instrument-Splitting

  • Keine automatisierte Testsuite per Design — Verifikation ist immer ein echter Lauf gegen echtes Audio

Formate, hier

Sobald eine .musicxml existiert, hört dieses Projekt bewusst auf — jede Noten-App öffnet MusicXML nativ und exportiert, was nötig ist (PDF, Audio, Tab, MIDI) aus ihrem eigenen Menü. Automatisierte Wrapper um diese Exporte zu bauen, wurde versucht und größtenteils zurückgerollt (siehe CHANGELOG.md v1.2.0 bis v2.0.0 für das vollständige Hin und Her) — die eine Richtung, die sich noch lohnte, zu automatisieren, stellte sich als keine von ihnen heraus, sobald score_to_notes.py bestätigt wurde, MusicXML direkt zu akzeptieren, ohne separaten Konvertierungsschritt.

Richtung

Verwendung

Hinweise

MusicXML → PDF, Audio, Tabulatur, MIDI

MuseScore Studio oder Guitar Pro, normal geöffnet

Bewusst nicht hier umschlossen — siehe oben. (MuseScores CLI-Konvertermodus, -j job.json, kann PDF-Export zuverlässig automatisieren, wenn du es für dein eigenes Skripting willst — nur nicht in dieses Projekt eingebaut)

PDF (gescannte/gesetzte Noten) → MusicXML

Audiveris (C:\Program Files\Audiveris\Audiveris.exe): Audiveris.exe -batch -export -output "<Ordner>" "<Eingabe>.pdf"

-batch überspringt tatsächlich seine GUI. Getestet auf 3 echten PDFs: 2 saubere einseitige Partituren exportierten korrekt (eine mit einer kleinen Taktart-Warnung); ein 24-seitiges Gitarren-Tab-Buch traf auf echte interne Audiveris-Abstürze (NullPointerException/IndexOutOfBoundsException in seiner Rhythmusanalyse) auf mehreren Seiten — OMR-Zuverlässigkeit fällt schnell bei komplexen, mehrseitigen oder tab-lastigen Eingaben

PDF → daw-mcp's Notenformat

Audiveris (oben) → dieses Projekts score_to_notes.py, direkt auf der .mxl

Zwei Schritte, beide real und Ende-zu-Ende auf echter Noten getestet — keine MIDI-Konvertierung dazwischen nötig

Behandle OMR-Ausgabe mit mindestens so viel Misstrauen wie basic-pitchs Audio- Transkription — prüfe die Zwischen-.musicxml, bevor du ihr vertraust, und erwarte nicht, dass Audiveris auf jedem PDF erfolgreich ist (siehe das Tab-Buch-Fehler oben).

Bekanntes Problem: MuseScore kann ein transkribiertes .musicxml als „beschädigt" ablehnen

Stark polyphone Transkriptionen können ein .musicxml erzeugen, das MuseScore Studio sich weigert zu öffnen und als „beschädigt" bezeichnet. Ursache: Der eigene MusicXML-Writer von music21 lässt das <voice>-Tag bei einigen <note>-Elementen weg, wenn ein Stück viele gleichzeitige Stimmen (5+) benötigt – verifiziert an einer echten 45-Sekunden-Aufnahme, die in dichte, oft überlappende Noten transkribiert wurde (ein Nebeneffekt davon, dass basic-pitch Obertöne/Artefakte in echtem Audio aufnimmt, nicht eine saubere einzelne Melodielinie). Bestätigt, dass dies der Writer von music21 ist, nicht der Code dieses Projekts: to_score.py ist ein zweizeiliger parse()- + write()-Aufruf ohne eigene Noten-/Stimmenlogik, und ein expliziter Aufruf von score.makeNotation() vor dem Schreiben behebt es ebenfalls nicht. Ein erneutes Parsen derselben Datei mit music21 selbst erzeugt nur eine Warnung (Cannot put in an element with a missing voice tag) und behebt das Problem, indem es diese Noten standardmäßig auf Stimme 1 setzt – der Importeur von MuseScore ist einfach strenger und lehnt die Datei rundweg ab, anstatt sie zu tolerieren.

Workaround: „Trotzdem öffnen" klicken – die Datei lädt einwandfrei, nur mit diesen bestimmten Noten in Stimme 1 statt ihrer ursprünglich erkannten Stimme, eine kleine Layout-Eigenheit, kein Datenverlust.

Nicht beobachtet bei sauberer Eingabe mit geringer Polyphonie (eine handgeschriebene Melodie-MIDI, transkribiert und erneut verifiziert ohne Probleme mit Voice-Tags) – dies ist spezifisch für unordentliche, dichte Transkriptionsausgabe von echtem Audio.

F
license - not found
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    A
    quality
    C
    maintenance
    MCP 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.
    1
    MIT
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    MCP 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

View all related MCP servers

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

View all MCP Connectors

Latest Blog Posts

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