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
| Tool | Description |
|---|---|
get_parts |
List all voice parts in a score — returns part name, ID, and measure count |
synthesize |
Render the score (or selected parts) to a WAV file, with optional tempo adjustment |
list_capabilities |
Return server metadata: backend version, soundfont status, FluidSynth availability |
health_check |
Check that the soundfont, FluidSynth, and music21 are all available and ready |
Installation
cd synth-mcp
uv sync
System library required:
# Ubuntu / Debian
sudo apt install libfluidsynth-dev
# macOS
brew install fluid-synth
A soundfont (SF2) file is also required. Free options:
| Soundfont | Size | Notes |
|---|---|---|
| TimGM6mb | ~6 MB | Ships with Ubuntu (/usr/share/sounds/sf2/TimGM6mb.sf2) |
| MuseScore General | ~200 MB | Better quality; download from musescore.org |
| GeneralUser GS | ~30 MB | Download from schristiancollins.com |
Quick install
Prefer not to do the above by hand? Run ./install.sh — it installs uv, 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
SYNTH_SOUNDFONT_PATH=/usr/share/sounds/sf2/TimGM6mb.sf2 uv run synth-mcp
Configuration
| Variable | Required | Description |
|---|---|---|
SYNTH_SOUNDFONT_PATH |
Yes | Path to an SF2 soundfont file |
Claude Desktop configuration
{
"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
// List parts in a score
{"tool": "get_parts", "arguments": {"musicxml": "<score-partwise>...</score-partwise>"}}
// 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",
"part_ids": ["Soprano"],
"tempo_factor": 0.8
}
}
Note: part_ids are the part names returned by get_parts (e.g. "Soprano", "Alto"),
not XML <part id>-style values like "P1" — music21 uses the part name as its id.
tempo_factor range: 0.25–4.0. Values below 1.0 slow down; above 1.0 speed up. Does not affect pitch.
Testing
# 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.mp3if needed - Large scores (100+ measures) may take several seconds to synthesize
System requirements
- Python 3.11+
libfluidsynthshared library (libfluidsynth.so.3on Linux)- An SF2 soundfont file
Metadata
Release files for synth-mcp 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| synth_mcp-0.2.1.tar.gz | 142.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| synth_mcp-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 153.0 kB
Release files / synth_mcp-0.2.1.tar.gz
| Download URL | synth_mcp-0.2.1.tar.gz |
|---|---|
| Size | 142.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1a489eb46914622dcb472e9f18e74129cebd997f96e150125def9bec8fa63adc
|
|
BLAKE2b-256 checksum How to use checksums |
bc5a2b8f9935087724942a44e0635f90ce268e69462361b245081def3d4ec663
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency logRelease files / synth_mcp-0.2.1-py3-none-any.whl
| Download URL | synth_mcp-0.2.1-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
541378fee5e320fb1c1430ac953b84aaa287a85c3ac646c512222eb74662f399
|
|
BLAKE2b-256 checksum How to use checksums |
8915bdadb0081384b5030e404500f2e3bf00b686d06e5499a0db9de796d271be
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 26, 2026.
Transparency log