MusicXML Synthesizer

io.github.raulkiviPublished by GitHub account raulkiviv0.2.3Updated Oct 24, 2026

Synthesizes audio from MusicXML, with voice-part selection and tempo control

VerifiedSTDIODesktop onlyFiles & StorageMedia & Design

Overview

AI-generated overview

Renders MusicXML scores into WAV audio with FluidSynth, letting an assistant pick voice parts, adjust tempo and build practice tracks.

What you can do
  • Inspect a score: list voice parts with IDs and measure counts, and summarize title, key, tempo, parts and duration
  • Render audio: synthesize the full score or selected parts to a WAV file with tempo adjustment
  • Build practice tracks: limit to bars, repeat, add count-in and metronome clicks, choose timbre and per-part volumes
  • Get starting notes: return each part's first pitch as text plus a short piano clip
  • Check readiness: report backend version, soundfont status and FluidSynth availability
When to use it
Useful for choir singers, conductors or music students who want to hear a specific voice part or a slowed-down practice track from a MusicXML or compressed MXL score, and for assistants that need to inspect a score's structure before rendering.
Requirements
Runs locally as a Python package (Python 3.11+) launched with uvx or uv; needs the libfluidsynth system library and an SF2 soundfont file whose path is set in SYNTH_SOUNDFONT_PATH. Optional SHEET_MUSIC_OUTPUT_ROOT and SHEET_MUSIC_INPUT_ROOTS restrict where audio is written and scores are read. Desktop only.
Before you install
Synthesize writes WAV files to disk, by default under the output root; set SHEET_MUSIC_OUTPUT_ROOT and SHEET_MUSIC_INPUT_ROOTS to limit which folders can be written to or read. Scores can be passed inline in the conversation or by path, so choose paths deliberately. Output is always WAV, and music21's MIDI export may drop some articulations and dynamics.

Installation

In SourceWeft

  1. Open MusicXML Synthesizer in the dashboard and add it to a workspace.
  2. Enable the server for the chats that should use its tools.

Desktop only via STDIO. STDIO servers start a local process, so they need the SourceWeft desktop host.

Other MCP clients

Follow the launch instructions in the repository.

README

synth-mcp

MCP server that synthesizes audio from MusicXML. Supports voice part selection (Soprano, Alto, Tenor, Bass) and tempo control.

What it does

Takes a MusicXML score, optionally filters to one or more voice parts, and renders a WAV audio file using FluidSynth. Useful for choir singers who want to practice a specific voice part.

Tools

ToolDescription
get_partsList all voice parts in a score — returns part name, ID, and measure count
synthesizeRender the score (or selected parts) to a WAV file, with optional tempo adjustment and practice options (bars, repeats, count-in, metronome, timbre, part volumes)
starting_pitchesEach part's first note as text ("S: D5, A: A4, T: F#4, B: D3") and a short piano clip
describe_scoreSummarize a score cheaply: title, key, time, tempo, parts (ID, clef, range), measures, duration
list_capabilitiesReturn server metadata: backend version, soundfont status, FluidSynth availability
health_checkCheck that the soundfont, FluidSynth, and music21 are all available and ready

Installation

bash
cd synth-mcpuv sync

System library required:

bash
# Ubuntu / Debiansudo apt install libfluidsynth-dev
# macOSbrew install fluid-synth

A soundfont (SF2) file is also required. Free options:

SoundfontSizeNotes
TimGM6mb~6 MBShips with Ubuntu (/usr/share/sounds/sf2/TimGM6mb.sf2)
MuseScore General~200 MBBetter quality; download from musescore.org
GeneralUser GS~30 MBDownload from schristiancollins.com

Quick install

Prefer not to do the above by hand? Run ./install.sh — with uv already installed, it installs the system libfluidsynth package and a soundfont automatically. See SETUP.md for a non-technical walkthrough, and TROUBLESHOOTING.md if something goes wrong. Ready-made client configs (Claude Desktop, Cursor, Windsurf, Continue, Zed) are in examples/.

Running

bash
SYNTH_SOUNDFONT_PATH=/usr/share/sounds/sf2/TimGM6mb.sf2 uv run synth-mcp

Configuration

VariableRequiredDescription
SYNTH_SOUNDFONT_PATHYesPath to an SF2 soundfont file
SHEET_MUSIC_OUTPUT_ROOTNoFolder output_path must be inside; also readable by musicxml_path (default: working directory). Without output_path, synthesize writes audio/output-<timestamp>.wav here (earlier releases used /tmp/synth-mcp-<uid>/; use the returned audio_path)
SHEET_MUSIC_INPUT_ROOTSNoExtra folders musicxml_path may read (:-separated; ; on Windows)

Claude Desktop configuration

json
{  "mcpServers": {    "synth": {      "command": "uv",      "args": ["--directory", "/absolute/path/to/synth-mcp", "run", "synth-mcp"],      "env": {        "SYNTH_SOUNDFONT_PATH": "/absolute/path/to/soundfont.sf2"      }    }  }}

Usage examples

json
// List parts in a score{"tool": "get_parts", "arguments": {"musicxml": "<score-partwise>...</score-partwise>"}}
// The same, reading a file instead of copying the score into the conversation{"tool": "get_parts", "arguments": {"musicxml_path": "scores/chorale.mxl"}}
// Synthesize the full score{  "tool": "synthesize",  "arguments": {    "musicxml": "<score-partwise>...</score-partwise>",    "output_path": "/tmp/full.wav"  }}
// Synthesize Soprano part only at 80% tempo{  "tool": "synthesize",  "arguments": {    "musicxml": "<score-partwise>...</score-partwise>",    "output_path": "/tmp/soprano.wav",    "parts": ["Soprano"],    "tempo_factor": 0.8  }}
// Practice track: Alto loud, others soft, bars 17-24 three times, one bar of count-in{  "tool": "synthesize",  "arguments": {    "musicxml_path": "scores/chorale.mxl",    "preset": "learning",    "focus_part": "Alto",    "measures": [17, 24],    "repeat": 3,    "count_in_bars": 1  }}
// Starting notes before singing{"tool": "starting_pitches", "arguments": {"musicxml_path": "scores/chorale.mxl"}}

parts accepts part IDs from get_parts ("P1"), part names ("Soprano", any case) or voices ("S", "Alto", "Alt", "A1" for divisi); an unknown part returns the valid choices. part_ids still works as a deprecated alias for one minor release.

Every tool that takes musicxml also takes musicxml_path instead (exactly one of the two): a .musicxml, .xml or compressed .mxl file inside the output root, a folder the client shares as an MCP root, or a folder in SHEET_MUSIC_INPUT_ROOTS. Prefer it, and pass on paths other servers return. describe_score reports part IDs, ranges and duration without returning the score.

tempo_factor range: 0.25–4.0. Values below 1.0 slow down; above 1.0 speed up. Does not affect pitch.

Practice options on synthesize (all optional; leaving them out gives the plain track):

OptionValuesEffect
measures[start, end]Only these printed bars (a pickup is 0)
repeat1–20Play the selection this many times
count_in_bars0–4Wood-block clicks before the music
metronometrue / falseClicks on every beat of the music too
timbrescore, piano, choir, organSound for every part (score keeps the score's instruments)
preset + focus_partlearning (focus 1.5, others 0.5), karaoke (focus muted), equalPart volumes
part_gainspart → 0.0–2.0Per-part volume, overrides the preset

starting_pitches returns the text always; the clip (mono 16 kHz WAV, inline when ≤ 200 KB) needs the soundfont and FluidSynth. Without them the result says why in audio_unavailable.

Testing

bash
# Unit tests (no soundfont required)VIRTUAL_ENV= .venv/bin/pytest tests/ -v
# Integration tests (synthesizes real audio)VIRTUAL_ENV= SYNTH_SOUNDFONT_PATH=/usr/share/sounds/sf2/TimGM6mb.sf2 \  .venv/bin/pytest tests/ -v -m integration

Dependencies

  • music21 — score parsing and MIDI export
  • pyfluidsynth — Python bindings for FluidSynth
  • mcp — MCP protocol

Known limitations

  • music21's MIDI export may drop some articulations and dynamics
  • Audio output is always WAV; convert with ffmpeg -i out.wav out.mp3 if needed
  • Large scores (100+ measures) may take several seconds to synthesize

System requirements

  • Python 3.11+
  • libfluidsynth shared library (libfluidsynth.so.3 on Linux)
  • An SF2 soundfont file

Source: synth-mcp/README.md at commit 417deaf

Tools

0
SourceWeft has not started this package in its sandbox yet, so its tools are not known.

Version history

3
  1. v0.2.3LatestOct 17, 2026
  2. v0.2.2Oct 12, 2026
  3. v0.2.1Sep 26, 2026

Score

50% of the applicable checks met

How complete this listing is, computed from the registry entry, the endpoint and public sources. Not a rating of the server and not a statement that it is safe or working today: reachability is a dated check, and no installs or reviews go into the score.

  • Reached in the last 30 days25 pts

    Keep the endpoint answering the MCP handshake; SourceWeft probes it every 30 days.

  • Auth declared10 pts

    Declare the credential headers in the registry entry, or keep the endpoint answering the probe so its auth can be classified.

  • Tools listed15 pts

    Answer tools/list without a credential, or ship a package that starts in a sandbox without one.

  • DescriptionRequired15 pts
  • Logo10 pts
  • Documentation15 pts
  • License10 pts