waveform-MCP
Waveform MCP
Un servidor MCP que otorga a un agente LLM control sobre Tracktion Waveform. Pídele a Claude que escriba una canción, equilibre una mezcla o renderice a MP3, y observa cómo Waveform lo hace.
Un instrumental synthwave de 64 compases compuesto mediante llamadas a herramientas MCP: batería, bajo, dos pads, contracanto, arpegio, melodía principal. Marcadores de sección, automatización de tempo, sidechain pump, reverb de placa, fundidos a nivel de clip, cadena maestra completa.
Qué te ofrece esto
107 herramientas MCP que abarcan el ciclo de vida de la edición, pistas, MIDI, clips de audio, plugins, automatización, teoría musical, equilibrio de mezcla, renderizado, biblioteca de bucles, descubrimiento de VST, captura de esquemas y control de la interfaz de usuario de Waveform
Dos compositores integrales —
compose_lofi_trackycompose_synthwave_track— que escriben canciones completamente arregladas, mezcladas y renderizadasUn compositor ambiental —
compose_rainstorm— para paisajes sonoros de lluvia + viento + truenosUna capa de conocimiento de teoría musical — escalas, progresiones de acordes, cadencias, formas de canción, reglas de conducción de voces, niveles de referencia de equilibrio de mezcla por género
Verificación de ida y vuelta entre el modelo en memoria y el XML
.tracktioneditde WaveformFundidos a nivel de clip, ganancia, desplazamiento, curvas de automatización — primitivas probadas que el LLM puede usar para iterar musicalmente
Bucle de flujo de trabajo fiable —
compose → write → reload via File → Revert to saved → listen → tweak
Estado
Funciona de principio a fin en Windows + Waveform 13. Existen rutas para macOS / Linux para el descubrimiento de contenido (presets, biblioteca de bucles, lista de VST), pero el control de la interfaz de usuario es solo para Windows mediante UIA / pywinauto por ahora.
Construido y probado a través de unas 30 horas de iteración humano-en-el-bucle con Claude. Ambos compositores han sido renderizados a MP3 varias veces y el usuario ha dado el visto bueno a las pistas resultantes.
Inicio rápido
Instalación
cd "C:\path\to\waveform MCP"
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -e .Conectar a Claude (Code, Desktop o cualquier cliente MCP)
~/.claude.json o la configuración MCP de tu cliente:
{
"mcpServers": {
"waveform": {
"command": "waveform-mcp"
}
}
}Pruébalo
Open Waveform, then ask Claude:
"Use compose_synthwave_track to make a synthwave song,
save it to my Documents/Waveform folder, and reload it
in Waveform so I can hear it."El LLM llama a compose_synthwave_track → waveform_revert_to_saved y tú presionas play. Luego itera: "baja el volumen del bajo" → el LLM actualiza MIX_BALANCE["synthwave"]["bass"] y recarga.
Arquitectura
Cuatro capas, cada una con un contrato claro:
┌──────────────────────────────────────────────────────────────┐
│ LLM (Claude / any MCP client) │
└────────────────────────────┬─────────────────────────────────┘
│ MCP stdio
┌────────────────────────────▼─────────────────────────────────┐
│ MCP server (server.py) — 107 tools │
└────────────────────────────┬─────────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────┐ ┌──────────────┐
│ Edit model │ │ Knowledge│ │ Waveform │
│ (in-memory) │ │ (data) │ │ UI control │
├──────────────┤ ├──────────┤ ├──────────────┤
│ Tracks │ │ Scales │ │ pywinauto + │
│ Clips │ │ Chords │ │ UIA + ffmpeg │
│ Notes │ │ Forms │ │ │
│ Plugins │ │ Mix │ │ Menu invoke │
│ Automation │ │ Velocity │ │ Revert │
│ Markers │ │ Rhythm │ │ Render→MP3 │
└──────┬───────┘ └──────────┘ └──────┬───────┘
│ │
▼ ▼
┌──────────────────┐ ┌────────────────────┐
│ xml_writer.py │ │ Waveform 13 │
│ xml_reader.py │ ◀──────▶ │ (the running app) │
│ ↓ .tracktionedit │ └────────────────────┘
└──────────────────┘Decisión de diseño clave: El modelo no es un 1:1 del ValueTree de Tracktion; es la forma con la que el LLM quiere trabajar, proyectada sobre el XML al guardar y proyectada de vuelta al cargar. Esto hace que las herramientas sean simples (audio_clip_import(track_id, file_path, start_beats, length_beats, fade_in_beats, ...)) en lugar de obligar al LLM a pensar en los internos de JUCE.
Catálogo de herramientas
Ciclo de vida de la edición (edit.py)
edit_create · edit_open · edit_save · flush · edit_summary · edit_inspect · undo · narrate
Pistas + mezcla (tracks.py)
track_add · track_remove · mix_set · mix_apply_reference · send_add · marker_add · tempo_set · key_set
mix_apply_reference(track_id, genre, role) busca el objetivo en dB de una tabla de equilibrio de mezcla curada (MIX_BALANCE[genre][role]) — la referencia de "el bombo es el ancla, el bajo 5-6 dB por debajo" destilada en una función invocable.
MIDI (midi.py)
midi_clip_add · midi_notes_add · midi_notes_clear · midi_clip_quantize
Clips de audio (audio.py, clips.py)
audio_clip_import (con gain_db, fade_in_beats, fade_out_beats, offset_in_source_beats)
clip_list · clip_set · clip_move · clip_resize · clip_duplicate · clip_remove
Plugins (plugins.py, preset_library.py)
plugin_list · plugin_add · plugin_set_param · plugin_remove
plugin_add_reverb (placa / natural / no lineal con valores predeterminados sensatos)
plugin_add_drum_kit (respaldado por Sampler, un SONIDO por pad)
plugin_add_modifier (LFO / envolvente / sidechain — esquema por definir en soporte completo de Waveform)
plugin_discover (analiza knownPluginList64.settings para listar los VST instalados)
waveform_preset_list · waveform_preset_read · waveform_plugin_types
Automatización (automation.py)
automation_add · automation_envelope · automation_clear · automation_list
Objetivos: pan y plugin/<plugin_id>/<param>. El objetivo de volumen está deshabilitado a nivel de API — el plugin de volumen de Waveform no respeta nuestro esquema <AUTOMATIONCURVE> y silencia la pista. Usa mix_set/mix_apply_reference para niveles estáticos y clip_set(fade_in_beats|fade_out_beats) para fundidos. (El MCP rechaza target="volume" con un error claro que apunta a alternativas.)
Conocimiento de teoría musical (music_theory.py, music_theory_data.py)
17 herramientas de consulta: theory_scale · theory_modes · theory_diatonic_chords · theory_chord_progression · theory_cadences · theory_song_form · theory_section · theory_genre · theory_arrangement_layers · theory_velocity · theory_rhythm · theory_voice_leading_rules · theory_heuristics · theory_surprise_devices · theory_borrowed_chords · theory_mix_balance · theory_search
Los datos detrás de esto:
13 escalas (modos mayores, menor armónica, pentatónica, blues, etc.)
Más de 25 progresiones de acordes (axis_pop, ii_V_I, andaluza, lament_bass, …)
Cadencias, formas de canción, secciones con perfiles de rol/densidad/dinámica
14 géneros con BPM típico, tendencias de tonalidad, instrumentos, progresiones distintivas
Mapas de velocidad / ritmo (ratios de swing, golpes de acento, rangos de notas fantasma)
13 heurísticas de composición (regla de 3, contraste requerido, cuota de sorpresa, …)
7 dispositivos de sorpresa (modulación truck-driver, cadencia engañosa, …)
Tabla de referencia de equilibrio de mezcla — 7 géneros × 14 roles, totalmente anotada
Compositores (composer.py)
compose_lofi_track— lofi de 32 compases con batería, bajo, teclas, pad, melodía, contracanto; envolventes de velocidad conscientes de la sección; automatización de tempo; cadena maestra loficompose_synthwave_track— synthwave de 64 compases con 7 pistas; forma de 9 secciones (intro/verso/estribillo/verso/estribillo/puente/buildup/estribilloFinal/outro); sensaciones de bajo por sección (medio tiempo / 8th-pump / walking); temas de arpegio por sección; filtro tipo sidechain; marcadores de sección; fundidos de clipcompose_rainstorm— paisaje sonoro ambiental con lluvia + viento + truenos distantes pasados por filtro paso bajo; aleatorización de ganancia por clip; ajuste de desplazamiento; FX de pista
Renderizado (render.py, waveform_workflows.py)
waveform_render_export · waveform_render_to_mp3 (usa ffmpeg + libmp3lame incluidos)
Control de la interfaz de usuario de Waveform (waveform_workflows.py)
waveform_new_project · waveform_save · waveform_revert_to_saved (el desbloqueador del bucle de iteración) · waveform_close_active_tab · waveform_active_tab · waveform_project_loaded · waveform_menu_invoke · waveform_add_track · waveform_select_track · waveform_insert_clip_on_track · waveform_build_skeleton
Ciclo de vida de la aplicación (waveform_app.py)
waveform_locate · waveform_status · waveform_launch · waveform_focus · waveform_quit · waveform_settings_dir
Biblioteca de bucles (loops.py)
loop_search (por tempo / compases / nombre) · loop_drop (longitud automática, ajuste al tempo)
Captura de esquemas (schema_capture.py)
schema_snapshot_current_edit · schema_diff_snapshots · schema_list_snapshots
Interfaz de usuario / escritorio de bajo nivel (win_input.py, desktop.py)
18 primitivas para gestión de ventanas, inspección UIA, envío de teclas/clics, capturas de pantalla.
Diseño
waveform-mcp/
├── src/waveform_mcp/
│ ├── server.py MCP server entry (stdio)
│ ├── model.py Edit / Track / Clip / Note / AutomationLane dataclasses
│ ├── xml_writer.py Edit → .tracktionedit
│ ├── xml_reader.py .tracktionedit → Edit
│ ├── audio_convert.py ffmpeg-backed MP3→WAV cache for Sampler sources
│ ├── music_theory_data.py SCALES, PROGRESSIONS, GENRES, MIX_BALANCE, ...
│ ├── events.py event bus + JSONL log
│ ├── diff.py Edit-diff for change events
│ ├── tools/
│ │ ├── edit.py Edit lifecycle
│ │ ├── tracks.py Tracks + mix balance
│ │ ├── midi.py MIDI clips/notes
│ │ ├── audio.py Audio clip import
│ │ ├── clips.py Clip mutators (move, resize, duplicate, set)
│ │ ├── plugins.py Plugin add + reverb / drum kit / modifier helpers
│ │ ├── automation.py Automation lanes (pan + plugin params)
│ │ ├── preset_library.py Factory preset browser
│ │ ├── loops.py Loop library search + drop
│ │ ├── render.py Render stubs
│ │ ├── waveform_app.py App lifecycle
│ │ ├── waveform_workflows.py UI workflows (revert, render-to-mp3, etc.)
│ │ ├── desktop.py Generic desktop primitives
│ │ ├── win_input.py Windows UIA + keystroke primitives
│ │ ├── schema_capture.py Hand-fixture capture for schema reverse-engineering
│ │ ├── music_theory.py Theory query tools
│ │ ├── composer.py compose_lofi_track, compose_synthwave_track, compose_rainstorm
│ │ └── common.py @op decorator (apply + diff + event)
│ └── preview/
│ ├── app.py FastAPI + websocket
│ └── static/ HTML / JS piano-roll
├── tests/
├── docs/
│ ├── img/synthwave_arrangement.png
│ ├── ARCHITECTURE.md
│ ├── EVENT_SCHEMA.md
│ └── EDIT_MODEL.md
├── pyproject.toml
└── README.mdEl bucle de iteración que realmente funciona
Después de muchos comienzos en falso, aquí está el bucle que permite al LLM y al usuario colaborar en una pista sin reiniciar Waveform en cada ciclo:
1. Compose / mutate → composer.compose_* or clip_set / mix_apply_reference
2. Save to disk → edit_save / flush (writes .tracktionedit)
3. Reload in Waveform → waveform_revert_to_saved
(File → Revert to saved state, auto-confirms popup)
4. User listens → "turn the arp up"
5. Update MIX_BALANCE or run a clip mutator
6. → goto 2El movimiento clave fue descubrir el elemento de menú File → Revert to saved state de Waveform: obliga a la edición abierta a recargarse desde el disco, lo cual es lo que hace visible la mutación externa sin cerrar/reabrir el proyecto. waveform_revert_to_saved automatiza esa ruta con reintento.
Referencia de equilibrio de mezcla
mix_apply_reference lee de una tabla curada de "el bombo es el ancla; el bajo 5-6 dB por debajo; la melodía similar al bajo; pad/arp 6-9 dB por debajo de la melodía; ambiente lo más profundo" — destilada a través de tutoriales de género, blogs de masterización e iteraciones ajustadas de oído:
MIX_BALANCE["synthwave"] = {
"drums": -7, "kick": -6, "snare": -10, "hat": -16,
"bass": -25, "sub_bass": -28, # background-level texture
"lead": -15, "pad": -19, "arp": -8, # arp-driven mix
"counter": -14, ...
}Los compositores llaman a tracks.mix_apply_reference({track_id, genre, role}) una vez por pista. Ajusta la tabla una vez, y cada compositor se reequilibra.
Fuentes que informan la tabla:
Limitaciones conocidas
AUTOMATIONCURVEde volumen de pista está deshabilitado. El plugin devolumede Waveform no respeta nuestro esquema de curva y silencia la pista afectada. El MCP rechaza el objetivo con un error claro y apunta a alternativas funcionales (fundidos de clip, múltiples clips con ganancia por clip,mix_setestático).La matriz de modificadores de plugin es exploratoria.
plugin_add_modifierescribe una forma de matriz de modulación genérica; necesita un fixture editado a mano para confirmar el esquema por plugin antes de que la modulación LFO funcione de manera fiable para 4OSC y similares.Renderizado sin interfaz (headless) aún no construido.
waveform_render_to_mp3controla la exportación de la interfaz de usuario de Waveform — funciona, pero requiere que Waveform esté ejecutándose. Un ayudante en C++ que enlacetracktion_enginees la solución definitiva.Control de interfaz de usuario en Linux/macOS ausente. El descubrimiento de contenido (presets, biblioteca de bucles, lista de VST) es consciente del SO; la automatización de la interfaz de usuario es solo para Windows.
Bloques de construcción para próximas iteraciones
Capturar un fixture real de Waveform para
<AUTOMATIONCURVE paramID="volume">para que la automatización de volumen pueda ser reactivadaAyudante de renderizado sin interfaz en C++ sobre
tracktion_engineFixture real para Drum Sampler / Micro Drum Sampler (actualmente vuelve al Sampler simple)
Captura de modificador de sidechain
Soporte para Clip Launcher (v13)
Control de interfaz de usuario en Linux mediante
xdotool/wmctrluna vez que UIA ya no sea la única ruta
Licencia
GPL-3.0-or-later (coincide con tracktion_engine si/cuando el ayudante de renderizado en C++ enlace con él).
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
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/jarmstrong158/waveform-MCP'
If you have feedback or need assistance with the MCP directory API, please join our Discord server