A DAW-first AI producer copilot. Claude Code plans and edits songs through a local MCP server; Ardour remains the authoritative session host.
Claude never generates opaque audio. It controls symbolic MIDI, track templates, plugin presets, automation envelopes, and vocal stems via typed MCP tool calls — all visible and editable inside Ardour.
Claude Code ──stdio──► MCP Server (Bun)
├── Ardour Lua scripts (session structure)
├── Ardour OSC adapter (mix surface)
├── MIDI generator (music21 + pretty_midi)
└── SoulX / RVC adapter (vocal synthesis)
| Tool | Version | Purpose |
|---|---|---|
| Bun | ≥ 1.1 | TypeScript MCP server runtime |
| Python | ≥ 3.11 | MIDI generation + vocal adapters |
| uv | latest | Python package manager |
| just | latest | Task runner |
| Ardour | 8.x | DAW (headless via xvfb + JACK on Linux) |
| Claude Code | latest | MCP client (the AI) |
Linux / WSL2 only for the Ardour integration. The MIDI pipeline and MCP server run on macOS/Windows without Ardour.
git clone https://github.com/YOUR_USERNAME/serenade.git
cd serenadecurl -fsSL https://bun.sh/install | bash
source ~/.bashrc # or restart terminalcurl -LsSf https://astral.sh/uv/install.sh | sh
source ~/.bashrccurl --proto '=https' --tlsv1.2 -sSf https://just.systems/install.sh \
| bash -s -- --to ~/.local/binEnsure ~/.local/bin is on your PATH:
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc && source ~/.bashrcjust install
# equivalent to: bun install && uv sync --extra devcp .env.example .envEdit .env and set at minimum:
SERENADE_PROJECT_ROOT=/home/yourname/ardour-sessionsAll other vars have working defaults or are only needed for specific features (SoulX vocals, RVC).
Add to ~/.claude.json under "mcpServers":
{
"mcpServers": {
"serenade": {
"command": "/home/yourname/.bun/bin/bun",
"args": ["run", "/path/to/serenade/apps/mcp-server/src/server.ts"],
"env": {
"SERENADE_PROJECT_ROOT": "/home/yourname/ardour-sessions"
}
}
}
}Or use the Claude Code /mcp command to add it interactively.
Restart Claude Code. Type /mcp to verify you see the 10 serenade tools.
For full session control (Lua scripts + OSC), you need Ardour 8 running headlessly.
bash scripts/setup-ardour-wsl2.shThis installs Ardour 8 via Flatpak, sets up JACK dummy backend, and creates shims.
# 1. System packages
sudo apt-get install -y xvfb jackd2 lua5.3 flatpak
# 2. Ardour 8 via Flatpak
flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo
flatpak install -y flathub org.ardour.Ardour
# 3. Create ardour8 shim
echo '#!/usr/bin/env bash
exec flatpak run org.ardour.Ardour "$@"' > ~/.local/bin/ardour8
chmod +x ~/.local/bin/ardour8
# 4. Start JACK (dummy audio — no real soundcard needed)
jackd -d dummy -r 48000 -p 1024 &
# 5. Start Ardour headless
DISPLAY=:99 xvfb-run -a ardour8 --no-splash &First launch only: Open Ardour GUI, go to Edit → Preferences → Control Surfaces → Open Sound Control, enable it, set port 3819.
just ardour-start# Run all tests (115 — no Ardour required)
just test
# Generate demo MIDI from fixture
just demo
# Output: /tmp/serenade-demo/midi/{drums_01,bass_01,lead_01,vocal_01}.mid
# Harmony generation demo
just harmony-demo
# Validate all JSON schemas
just validate-schema
# TypeScript typecheck
just typecheck
# Python lint
just lintOnce the server is wired into Claude Code, you can ask Claude things like:
"Bootstrap a new Ardour session called 'morning-groove' at 95 BPM, 4/4, 16 bars with drums, bass, and lead synth tracks."
"Add a C major I–IV–V–I chord progression to the bass track and generate MIDI."
"Write a volume automation fade-out on the lead synth over the last 4 bars."
| Tool | What it does |
|---|---|
system.health |
Check Ardour OSC + SoulX status |
session.bootstrap |
Create/reconcile Ardour session from SongSpec JSON |
tracks.create |
Add tracks (skips existing by name) |
markers.create |
Add named timeline markers |
midi.upsert_region |
Create or replace a MIDI region |
audio.import_file |
Import WAV/FLAC onto a track |
plugins.apply_mapping |
Apply plugin chain from category registry |
automation.write |
Write gain/pan/plugin automation |
vocals.render_soulx |
Render vocal stem via SoulX-Singer or RVC |
mix.export |
Export session to WAV/FLAC (+ stems) |
All tools validate input against packages/schemas/copilot-bundle.json and return structured E_* error codes.
Requires a voice reference — a prompt WAV + its preprocessing metadata:
SOULX_PYTHON=/path/to/soulx-venv/bin/python
SOULX_REPO=/path/to/SoulX-SingerCompile MIDI + lyrics to SoulX target metadata:
python adapters/soulx/compile_metadata.py \
--midi-json notes.json --tempo 120 --out target.jsonGenerate a harmony part before rendering:
python adapters/soulx/harmony_vocals.py \
--notes notes.json --key "C major" --part third_above --out harmony.jsonRVC_PYTHON=/path/to/rvc-venv/bin/python
RVC_REPO=/path/to/RVC-ProjectPass engine: "rvc" and modelPath in the VoiceProfile when calling vocals.render_soulx.
Claude selects plugins by category only — never by raw path. Categories are defined in packages/plugin-registry/mappings.json:
| Category | Plugin |
|---|---|
synth.lead / synth.pad / synth.bass |
Surge XT (VST3) |
drums.acoustic |
DrumGizmo (LV2) |
drums.electronic |
sfizz (LV2) |
fx.bus |
Calf Studio Gear + Dragonfly Reverb |
vocal.lead / vocal.harmony |
template-only |
- MCP transport: stdio only by default. Loopback HTTP (
127.0.0.1) only whenSERENADE_HTTP_DEBUG=1. - All file paths validated against
SERENADE_PROJECT_ROOT+SERENADE_ALLOWED_ROOTS. ..traversal and symlink escapes rejected.- Subprocess executable allowlist:
ardour8,ardour7,luasession,jackdonly. - Per-tool rate limiting + max 2 concurrent render jobs.
- All mutation tools require + return a
stateHashetag to reject stale edits.
See docs/architecture.md for the full system design including sequence diagrams, data model, and component breakdown.
See docs/prd.md for product requirements and roadmap.
See CLAUDE.md for AI copilot instructions and Lua script conventions.
just test # all 115 tests
just test-ts # TypeScript only (78 — bun:test)
just test-py # Python only (37 — pytest)No Ardour required to run the test suite. Tests cover:
- Schema validation (ajv, all fixture JSON)
- OSC protocol encode/decode + real UDP round-trips
- pathGuard traversal/allowlist/extension blocking
- stateHash etag stale rejection
- MIDI generation determinism
- SoulX metadata compilation + harmony generation
- RVC + SoulX voice profile validation
- Rate limiter slot enforcement
serenade/
├── apps/mcp-server/src/ # Bun MCP server — 10 tools + security + state
├── adapters/
│ ├── ardour-lua/scripts/ # 7 Lua EditorAction scripts
│ ├── ardour-osc/src/ # UDP OSC adapter + SSID strip cache
│ ├── midi/ # music21 + pretty_midi MIDI generators
│ └── soulx/ # SoulX, RVC, harmony vocal adapters
├── packages/schemas/ # JSON Schema + TypeScript types
├── packages/plugin-registry/# Category → plugin mappings
├── fixtures/songs/ # Demo SongSpec fixture
├── voices/ # VoiceProfile registry
├── tests/ # Unit + integration tests
├── docs/ # PRD + architecture
├── scripts/ # setup-ardour-wsl2.sh
├── CLAUDE.md # AI copilot guide
├── justfile # Dev commands
├── pyproject.toml # Python deps (uv)
└── package.json # Bun workspace