Skip to main content
Glama
David7ce
by David7ce

{"type": "text"}# audio2score-mcp

Convierte un archivo de audio grabado en una partitura musical editable: audio → MIDI → MusicXML.

MusicXML es el objetivo porque es el "SVG de la notación musical": un formato abierto basado en texto que cualquier aplicación de notación (MuseScore, Sibelius, Guitar Pro, Finale, Dorico) puede abrir, editar y reexportar sin ser dueño del pipeline que lo produjo. Este proyecto solo produce los archivos .mid y .musicxml; abrir, editar y exportar a cualquier otra cosa (PDF, audio, tab) ocurre en la aplicación de notación que elijas, manualmente — ver "Formatos a los que se conecta" más abajo para saber por qué este proyecto deliberadamente no envuelve esa parte.

Dos formas de ejecutarlo: como scripts CLI simples, o como un servidor MCP que expone los mismos pasos como herramientas que Claude puede llamar.

Qué hay aquí

  • transcribe.py — archivo de audio → MIDI, mediante basic-pitch de Spotify

  • to_score.py — archivo MIDI → MusicXML, mediante music21

  • score_to_notes.py — un archivo de partitura (MIDI, MusicXML, o cualquier cosa que music21 pueda leer) → arreglo JSON de notas en el formato batch_set_notes de daw-mcp

  • mcp_server.py — servidor MCP que envuelve los tres como herramientas (transcribe_audio, midi_to_score, score_to_notes)

Cada paso es un artefacto real y separado en el disco, no un intermediario oculto. La pausa entre MIDI y notación es deliberada: la transcripción automática es con pérdida, por lo que el MIDI crudo merece un vistazo (o una corrección manual) antes de convertirse en partitura.

score_to_notes.py es intencionalmente agnóstico al formato, no específico de MIDI: music21.converter.parse() maneja MIDI y MusicXML de manera idéntica, por lo que alimentarlo con un .mid de transcribe.py o un .mxl de una herramienta OMR externa (ver "Formatos a los que se conecta") sigue el mismo camino de código. No hay una herramienta separada de MusicXML→MIDI o MusicXML→PDF en este proyecto: una vez que existe un .musicxml, cualquier aplicación de notación ya lo abre y exporta, así que construirlo aquí solo duplicaría lo que ya está instalado.

Related MCP server: whisper-mcp

Dónde van los archivos

Recomendado: coloca los archivos de entrada en workspace/ (local al repositorio, ignorado por git - ver .gitignore - nada colocado aquí se compromete jamás, incluidos los archivos de entrada). Sin embargo, no hay un requisito estricto: cualquier ruta funciona. Cada salida aterriza junto a su archivo de entrada, mismo nombre base, diferente extensión:

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)

Para ver: abre el .mid o .musicxml directamente en la aplicación de notación que tengas; nada aquí lanza una por ti. Si MuseScore llama al .musicxml "corrupto", consulta la advertencia de polifonía más abajo antes de asumir que el archivo está roto.

Configuración

Requiere Python 3.11 específicamente: basic-pitch trae TensorFlow 2.15, cuyas ruedas se detienen en cp311; 3.12 y 3.13 fallarán al resolver. El venv resultante es de ~2GB (TensorFlow completo, no un backend más ligero).

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

Las dependencias están fijadas exactamente (basic-pitch==0.4.0, music21==10.5.0, setuptools==65.5.0, mcp==2.0.0) — este proyecto no tiene suite de pruebas automatizadas, por lo que un entorno nuevo que coincida exactamente con lo verificado es el sustituto. setuptools específicamente está fijado porque las versiones más nuevas rompen una importación transitiva de resampy que basic-pitch necesita.

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

La salida siempre aterriza junto a la entrada, mismo nombre base, diferente extensión. Los tres scripts se niegan a sobrescribir un archivo de salida existente — bórralo o muévelo primero si quieres volver a ejecutar. Los errores (entrada faltante, fallo de biblioteca) imprimen un mensaje claro a stderr y salen con código no cero; nada falla en silencio.

Ejecuta solo la(s) herramienta(s) que tu objetivo real necesita: no encadenes las tres por defecto. Cada herramienta produce exactamente un archivo; ejecutar más de lo necesario solo agrega archivos que nadie pidió.

Objetivo

Ejecución

Archivos producidos

Ver/editar una grabación como notación

transcribe_audiomidi_to_score

.mid, .musicxml

Obtener las notas de una grabación en daw-mcp

transcribe_audioscore_to_notes

.mid, .notes.json (omite midi_to_score - no necesario para este objetivo)

Obtener partitura escaneada/compuesta en daw-mcp

Audiveris (externo, ver "Formatos a los que se conecta") → score_to_notes en el .mxl

.mxl, .notes.json (sin paso MIDI en absoluto)

Ver/editar partitura escaneada como notación

Solo Audiveris

.mxl - ya es MusicXML, ábrelo directamente, no se necesita herramienta aquí

El .mid en las dos primeras filas no es realmente "salida" sino un punto de control inevitable: basic-pitch solo puede emitir MIDI, y vale la pena echarle un vistazo antes de confiar en lo que viene después (ver "Problema conocido" más abajo sobre por qué).

Ejemplo práctico

Una ejecución real, no hipotética. Entrada: un WAV mono sintético, un arpegio de Do mayor (C4-E4-G4-C5, negras con un sobre corto de decaimiento para que los ataques sean limpios) - "audio real" en el sentido que le importa a este proyecto (una forma de onda real en el disco, no MIDI escrito a mano), solo que sintetizado en lugar de grabado, para que la transcripción sea reproducible sin un archivo con derechos de autor en un repositorio público.

$ 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

Las tres líneas WARNING:root son basic-pitch notando que los backends opcionales (CoreML, TFLite, ONNX) no están instalados - inofensivo, TensorFlow es el backend realmente usado, y esto es exactamente lo que transcribe.py v1.1.1 ahora oculta correctamente sin corromper el flujo stdout de mcp_server.py (ver CHANGELOG.md) - solo aterriza en la terminal, no en el canal de protocolo MCP.

c_major_arpeggio.notes.json, la salida lista para 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]]

Cuatro notas entraron (C4, E4, G4, C5); basic-pitch detectó correctamente el tono y la velocidad de las cuatro (60/64/67/72, coincidiendo exactamente con el arpegio) pero dividió la última nota (C5) en dos entradas consecutivas en lugar de una: la cola del sobre de decaimiento aparentemente se leyó como un segundo ataque. Esta es la pérdida de la transcripción automática de la que advierte la sección "Qué hay aquí" más arriba, capturada en la naturaleza en la primera nota que tenía una forma de volumen naturalista (no plana): revisa el .mid antes de confiar ciegamente en el .musicxml/.notes.json, especialmente alrededor de notas sostenidas o en decaimiento.

c_major_arpeggio.musicxml se abre limpiamente en cualquier aplicación de notación (verificado bien formado: DOCTYPE correcto de MusicXML 4.0, tonos <step>/<octave> para C4/E4/G4/G4/C5/C5/C5 - el C5 dividido aparece como notas ligadas a través de un límite de compás, lo cual es MusicXML estándar para una nota que no cabe en un compás, no un segundo error).

Uso: servidor MCP

Registrado en la configuración de Claude Code como audio2score — reinicia Claude Code después de una instalación nueva para que aparezca (los servidores MCP se cargan al inicio).

Tres herramientas, que reflejan exactamente los tres scripts:

  • transcribe_audio(audio_path) → devuelve la ruta del .mid

  • midi_to_score(midi_path) → devuelve la ruta del .musicxml

  • score_to_notes(score_path) → devuelve la ruta del .notes.json (formato de arreglo de notas batch_set_notes de daw-mcp; acepta MIDI o MusicXML)

Mismo comportamiento que el CLI subyacente (misma protección contra sobrescritura, mismos errores) — el servidor MCP es un envoltorio delgado, no una implementación diferente.

Una cosa a saber si una llamada parece colgarse: si una llamada a transcribe_audio parece agotar el tiempo o se cancela, la transcripción puede seguir ejecutándose en segundo plano y terminará escribiendo el archivo .mid de todos modos. Un reintento entonces chocará con la protección contra sobrescritura ("ya existe") aunque la primera llamada pareciera que nunca tuvo éxito. Esto no es un error: verifica si el .mid ya existe antes de reintentar.

Para registrar el servidor tú mismo en otro lugar, agrega esto a tu configuración MCP (mcpServers), usando rutas absolutas para ambos campos: el cliente lanza servidores stdio sin un directorio de trabajo definido, por lo que las rutas relativas no se resolverán:

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

Lo que esto no hace

  • Sin salida de partitura/MIDI → audio, PDF o tab, tampoco conversión de MusicXML → MIDI — ver "Formatos a los que se conecta" más abajo para saber por qué y qué usar en su lugar

  • Sin separación de pistas ni división multi-instrumento

  • Sin suite de pruebas automatizadas por diseño — la verificación es siempre una ejecución real contra audio real

Formatos a los que se conecta

Una vez que existe un .musicxml, este proyecto se detiene deliberadamente: toda aplicación de notación ya abre MusicXML de forma nativa y exporta lo que sea necesario (PDF, audio, tab, MIDI) desde su propio menú. Construir envoltorios automatizados alrededor de esas exportaciones se intentó y en su mayoría se revirtió (ver CHANGELOG.md v1.2.0 hasta v2.0.0 para el ida y vuelta completo) - la única dirección que aún valía la pena automatizar resultó ser ninguna, una vez que se confirmó que score_to_notes.py acepta MusicXML directamente sin un paso de conversión separado.

Dirección

Uso

Notas

MusicXML → PDF, audio, tab, MIDI

MuseScore Studio o Guitar Pro, abiertos normalmente

No envuelto aquí a propósito - ver arriba. (El modo CLI de MuseScore, -j job.json, realmente puede automatizar la exportación a PDF de manera confiable si lo quieres para tu propio scripting - simplemente no está integrado en este proyecto)

PDF (partitura escaneada/compuesta) → MusicXML

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

-batch realmente omite su GUI. Probado en 3 PDFs reales: 2 partituras de una página limpias se exportaron correctamente (una con una advertencia menor de compás); un libro de tablatura de guitarra de 24 páginas encontró fallos internos reales de Audiveris (NullPointerException/IndexOutOfBoundsException en su análisis rítmico) en varias páginas - la fiabilidad de OMR cae rápido en entradas complejas, multipágina o con mucha tablatura

PDF → formato de notas de daw-mcp

Audiveris (arriba) → score_to_notes.py de este proyecto, directamente en el .mxl

Dos pasos, ambos reales y probados de extremo a extremo en partitura real - no se necesita conversión MIDI en el medio

Trata la salida de OMR con al menos tanta sospecha como la transcripción de audio de basic-pitch: revisa el .musicxml intermedio antes de confiar en él, y no esperes que Audiveris tenga éxito en cada PDF (ver el fallo del libro de tablatura arriba).

Problema conocido: MuseScore puede rechazar un .musicxml transcrito como "corrupto"

Las transcripciones muy polifónicas pueden producir un .musicxml que MuseScore Studio se niega a abrir, calificándolo de "corrupto". Causa raíz: el propio escritor MusicXML de music21 omite la etiqueta <voice> en algunos elementos <note> cuando una pieza necesita muchas voces simultáneas (5+) - verificado en una grabación real de 45 segundos que se transcribió en notas densas y a menudo superpuestas (un efecto secundario de basic-pitch al captar armónicos/artefactos en audio real, no una línea melódica única y limpia). Confirmado que es el escritor de music21, no el código de este proyecto: to_score.py es una llamada de dos líneas parse() + write() sin lógica propia de notas/voces, y llamar explícitamente a score.makeNotation() antes de escribir tampoco lo soluciona. Re-analizar el mismo archivo con el propio music21 solo muestra una advertencia (Cannot put in an element with a missing voice tag) y se recupera asignando por defecto esas notas a la voz 1 - el importador de MuseScore es simplemente más estricto y lo rechaza directamente en lugar de tolerarlo. Solución alternativa: haga clic en "Open anyway" - se carga correctamente, solo con esas notas específicas en la voz 1 en lugar de su voz detectada originalmente, una pequeña peculiaridad de diseño, no una pérdida de datos. No se observa en entradas limpias y de baja polifonía (un MIDI de melodía creado a mano transcrito y re-verificado sin problemas de etiquetas de voz) - esto es específico de salidas de transcripción de audio real desordenadas y densas.

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