audio2score-mcp
{"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 Spotifyto_score.py— archivo MIDI → MusicXML, mediante music21score_to_notes.py— un archivo de partitura (MIDI, MusicXML, o cualquier cosa que music21 pueda leer) → arreglo JSON de notas en el formatobatch_set_notesde daw-mcpmcp_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.exeLas 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 |
|
|
Obtener las notas de una grabación en daw-mcp |
|
|
Obtener partitura escaneada/compuesta en daw-mcp | Audiveris (externo, ver "Formatos a los que se conecta") → |
|
Ver/editar partitura escaneada como notación | Solo Audiveris |
|
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.jsonLas 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.midmidi_to_score(midi_path)→ devuelve la ruta del.musicxmlscore_to_notes(score_path)→ devuelve la ruta del.notes.json(formato de arreglo de notasbatch_set_notesde 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, |
PDF (partitura escaneada/compuesta) → MusicXML | Audiveris ( |
|
PDF → formato de notas de daw-mcp | Audiveris (arriba) → | 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.
This server cannot be installed
Maintenance
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
- FlicenseNot gradedqualityDmaintenanceAn MCP server that connects Claude to FL Studio, allowing the AI to compose music, control instruments, and live record melodies, chords, and drums to the piano roll.97
- AlicenseAqualityCmaintenanceMCP 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.1MIT
- AlicenseBqualityDmaintenanceAn MCP server that enables natural language control of Steinberg Dorico music notation software through Claude Desktop or ChatGPT, offering tools for score creation, note input, notation, harmony analysis, and orchestration.5410MIT
- -licenseNot gradedqualityNot gradedmaintenanceMCP 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
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
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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