Skip to main content
Glama

🎵 Orpheus

Keeps Claude in sync with your REAPER session.

Orpheus is an MCP server that connects Claude (Claude Code, Claude Desktop, or any MCP client) to a live REAPER session.

REAPER is home base. Orpheus reads the live project (tracks, tempo map, markers, regions, what's playing), notices what you change by hand, and everything it does lands back in the project as editable tracks, MIDI, markers and effects, on REAPER's own bars and beats. Your Google Sheet stays in step: sections and chords from the sheet become markers and regions, and changes in REAPER can flow back to the sheet.

On top of that, it listens to your project and to audio you own (tempo, key, chords, sections, stems, lyrics and sound character, each with an honest confidence), explains what it hears in plain language, and works in your session: building tracks, writing MIDI, arranging songs, setting effects, and (optionally) rendering a rough sung sketch with YuE2. It asks before it changes anything, and every change can be undone.

It's built for one songwriter-producer working in REAPER, with lyrics in Google Sheets.

Status (2026-10-27): early, pre-alpha, not on PyPI yet. It has 70 tools in the default profile (fewer on a base install without the [analysis] extra; 72 with YuE2 switched on), 1364 passing Python tests and 555 Lua checks in 8 suites (ruff and mypy clean). Much of it was used for real in July on REAPER 7.78 with a song the owner owns; the rest is tested against a behavioural fake of REAPER. What works today says which is which. Change reports, meter-aware bars and the bridge's automatic start were checked live on REAPER 7.83 on 10-25; tempo-map writing, sketches in parts, the instrument library and effect recipes (10-27) are built and tested but not yet checked live; sheet sync comes later.

What you can ask

  • "What key and tempo is this song, and where does the chorus start?"

  • "Split the vocals out of this mp4 I made and put the stems on tracks."

  • "Where in the song does the hook come back?"

  • "Here are my lyrics and chords from the sheet. Lay out the song: verse, pre-chorus, chorus, bridge."

  • "Add a bass line and a half-time drum part under the verse."

  • "Make the outro vocal sound like it's coming through a telephone."

Related MCP server: ReaperMCP

What works today

Listen

All local, on audio you own:

  • tempo, beat grid, downbeats, key, loudness and sections (recon_reference);

  • an instrument-activity timeline (instrument_timeline);

  • chords (get_chords): an always-on baseline plus an optional model lane;

  • stem separation with quality gates and a retry ladder (separate_region, verify_stem);

  • sound character: spectrum, dynamics, stereo, reverb, pitch (characterize);

  • lyrics with word timings, and "find where this line is sung" (transcribe_lyrics, locate_lyric);

  • comparing two sections of a song that should match (compare_sections);

  • one entry point that routes a question to the right analysis and reports what it could and couldn't measure (analyze_reference).

It also reads your own project's MIDI for key, harmony and groove (build_project_spec, analyze_harmony, analyze_groove).

Stay in sync with the session

  • get_project_timeline: the open project's name, every tempo and time-signature change, all markers and regions with bar and beat as REAPER's ruler shows them, and the transport.

  • project_changes: what changed since the last check, in plain words ("Track 'Gtr' renamed to 'Gtr DI'", "New MIDI item on 'Bass' at bar 9"), kept per project across restarts.

  • Anything placed "at bar N" follows REAPER's own tempo and meter map.

  • set_tempo_map: tempo and time-signature changes at any bar, including tempo that glides from one change to the next (a slow-down), in one undo step.

  • get_connection_status reports which project is open (heartbeat v2).

These are tested against the fake and the Lua suite; the live check in REAPER is still owed.

Explain

Analyses return measured numbers with confidence values, which lets Claude explain why something sounds the way it does (for example "the low band is 6 dB hotter than the reference"). compare_character turns the difference between two sounds into concrete effect moves, using 14 rules.

Work in the session

  • Projects: new_project opens an empty tab for a new song and save_project saves it (in place, or as a path that then becomes its file).

  • Tracks, tempo, meter, transport, and MIDI written in beats, never ticks (a note written at beat B reads back at beat B).

  • Composing: chord progressions, bass lines, drum patterns, melodies, humanizing, whole sections, and arrange_song for a full sectioned song with markers and lyric lines.

  • Effects: add by name, set and read parameters, using calibrated maps for REAPER's stock plugins and Surge XT. remove_fx takes one off. get_fx_params shows each value as the plug-in does ("-9.0 dB"), and effect recipes dial every value in against that display, so a wrong map can't put a delay at 317 ms when the recipe says 95.

  • Effect recipes: list_effect_recipes and apply_effect_recipe put a named chain on a track (PA announcement, telephone, station hall, tape wobble, lo-fi radio, distant, intimate vocal), built from REAPER's own plugins. Every effect and setting comes back, and anything it couldn't do is listed. Tape wow and flutter come from Orpheus's own JSFX (MIT), which install_orpheus_jsfx copies into REAPER's Effects/Orpheus folder without overwriting a copy you changed.

  • Mixing: render_mix_region bounces the whole mix (the master chain on, listening solos ignored) so loudness and tone can be measured, and master is a track name for mastering effects.

  • Audio: import your stems as time-locked tracks, render a track region to WAV, and clone a take onto new tracks (for doubles). align_vocal_take puts a sung take of a lead sheet on the bars phrase by phrase, without stretching it, and align_stem_take puts the take's band stems on the bars with REAPER's stretch markers (see "Lining a take up with the bars" below).

  • Instruments: Orpheus prefers instruments you have installed, and suggest_free_vst recommends free ones. An optional sound pack (install_sound_pack, about 24.5 MB) adds three public-domain FreePats instruments (guitar, bass, upright piano) that play through REAPER's own sampler.

  • Niche instruments: find_instrument("celesta") looks through your installed plugins, the sound pack, a library of 16 public-domain (CC0) sample instruments, and the free-plugin list, and says what's nearest when something isn't available. The library has glockenspiel, vibraphone, tubular bells, wind chimes, kalimba, harp, marimba, xylophone, solo cello and violin, string sections, a soft upright, an old honky-tonk piano and water glasses, each pinned to a GitHub commit and checked file by file. fetch_instrument shows the size and licence and downloads only after you say yes; load_library_instrument plays it through REAPER's sampler.

These are tested against the fake; a live listen in REAPER is still owed for the recipes, the tape-wobble JSFX and the library instruments.

More bridge commands were built and used live in July but don't have MCP tools yet: moving and deleting tracks; regions; automation envelopes; trimming, windowing and nudging items; factory presets; refreshing media and peaks; and instruments built from your own samples. (Renaming, colouring, muting and folders have tools now: set_track_params, group_tracks.)

Verified on real REAPER

In July 2026, on REAPER 7.78: the bridge, the effect maps, region rendering, stem import, item cloning, those fifteen bridge commands, hot reload, and analysis of an owned 200-second song (separation, lyrics, sections). The full-song composer and the chord and lyric quality still need a live check by ear. The dev-log has the details.

How a song gets made

  1. You write lyrics, sections and chord charts in your Google Sheet.

  2. Claude reads the sheet through the Google Drive connector. Orpheus never signs into Google; it only gets text.

  3. Orpheus lays the song out in REAPER: section markers, chords, bass, drums, a melody, and your lyric lines on the markers.

  4. You record. Orpheus analyses the take, and Claude suggests changes. You approve each one.

Orpheus reads your sheet's own notation: chord charts (Am / Fmaj7 | C / E (x4), slash chords, holds, (stop)) and bass tab (A0 - E1 -). A section, given as written plus a melody Claude writes with you, becomes a lead sheet: arrange_lead_sheet lays it into REAPER (markers, chords, bass riff, melody, drums, lyric markers), and export_yue2_score turns it into a score for YuE2. With the optional YuE2 backend switched on (below), render_sketch sings chosen sections at the section's bar, so you can hear the idea over the arrangement before you record it. A YuE2 take is one stereo WAV with its band, melody and voice effects baked in, so each take is then unpacked into a folder of tracks you can see and edit (below): the vocal lined up on REAPER's bars, the melody it actually sang as MIDI, the raw mix, and each stem that plays. align_vocal_take, the lining-up step, also works alone on any sung take of a lead sheet and needs no YuE2.

A section can change the song's meter, tempo or key (a 6/8 bridge, a final chorus up a step, an outro that slows down with ramp_to_bpm). arrange_lead_sheet writes those changes into REAPER's tempo map. YuE2 sings meter and key changes inside one score; a score has one tempo, so where the tempo changes the sketch is sung in parts, all on the take's one track.

What it won't do

  • Fetch, rip or capture music you don't own. Analysis runs only on files you give it.

  • Need an account, a subscription or a paid API. Everything runs on your machine.

  • Master a track for release, or replace your ears.

  • Change your project without asking first.

Not built yet

  • Sheet and REAPER in step: sheet sections and chords as markers and regions, and REAPER changes written back to the sheet (Claude does the sheet side, with your yes).

  • "Sing it to me": notating a melody from a scratch vocal take.

  • Beat-map export for cutting music videos in Premiere (OpenTimelineIO).

  • Edit plans applied in one undo step (apply_changes) and style-based suggestions (recommend_changes). Both are stubs, registered only in the full profile.

  • Master rendering and audit (render_project, render_and_audit) and mix balancing.

Optional: non-commercial backends

Some useful models allow only non-commercial use: YuE2 (sung song sketches), LarsNet (drum splitting). Orpheus is MIT, so these are off by default. Switch each one on by name:

"env": { "ORPHEUS_NC_BACKENDS": "yue2" }

Their weights are never bundled. You download them yourself, under their own licence (CC BY-NC 4.0 for YuE2), and Orpheus talks to them as a separate program.

YuE2 setup. Build yue2.cpp (MIT) with CUDA and put the backbone (YuE2-3B-Q8_0.gguf, 3.8 GB) and the VAE (YuE2-Vae-F32.gguf, 0.5 GB) in its models folder, laid out as ~/.orpheus/yue2/yue2.cpp/build/Release/yue-synth.exe and ~/.orpheus/yue2/models/. docs/pins/2026-10-yue2-backend.md has the build commands and file hashes. On an RTX 3080 a sketch takes about half its length to render and peaks near 6–7 GB of VRAM; Orpheus's own GPU work waits while it runs. YuE2 often keeps playing past your last bar, so a sketch stops 4 s after it with a 2 s fade you can drag. Sketches are saved under ~/.orpheus/sketches/, one folder per render with the request, the WAV, YuE2's replay file and its log.

render_sketch exposes YuE2's whole request; the defaults sing exactly as before:

Option

What it does

takes (1-8)

different performances, one track each

variations (1-4)

the same performance re-sung under new noise from its replay file (quick)

steps

quality of the sound stage (default 32; more is slower)

guidance

how closely YuE2 follows the lyrics and style

melody_sampling, sound_sampling

temperature, top-p, top-k, repetition penalty: how adventurous each stage is

adapters

LoRA add-ons from yue2.cpp/adapters, each with a strength (list_yue2_adapters)

compose_melody

YuE2 writes its own tune to your lyrics; planned_score comes back for import_yue2_score (pass the same style)

replay_of

re-sing an earlier sketch folder with a new seed or more steps, at the same bar

measure_drift

separate each take's vocal and report the tempo it was really sung at and how far it got ahead and behind (about a minute per 4-minute take)

unpack (on by default)

each take into its own folder of tracks (below); False leaves the raw take alone

Each render takes about half its length on the 3080, and there is one per part, take and variation.

Unpacking a take. After the renders, each take goes in a folder Take #<seed> (YuE2):

Track

What it is

· vocal on the bars

the vocal, separated and lined up phrase by phrase; the one track left playing

· sung melody (MIDI)

what the take actually sang, as notes on the bars (ReaSynth), to compare with your melody or copy from

· raw mix (YuE2)

the take as YuE2 rendered it

· drums, bass, guitar, piano, other (YuE2 timing)

each stem that plays, in YuE2's own timing; an empty one (no drums in the take) gets no track and a warning

Coloured regions mark where YuE2's voice changes on its own: much wider than usual (doubled or spread) or filtered (a phone or radio sound). Everything but the lined-up vocal is muted, nothing is deleted, and each take's result has sung_vs_written: per section, how many written notes it sang as written, how many it changed, dropped or added (the same count as align_vocal_take's, below). Unpacking adds about two minutes per 4-minute take (one separation, one pitch track); a take whose tune YuE2 wrote (compose_melody) is left as rendered.

Tracks have names that say what they are, so set_track_params can rename, colour (color, "#RRGGBB") and mute (mute) a track, and group_tracks puts tracks in a folder.

Changing a section's lyrics. Two steps, so a rewrite costs a section, not a song:

  1. fit_lyrics(lead_sheet, section, lyrics) checks the new lines against the section's melody before anything renders: each line's syllables against the notes its old line had (words the sheet already splits are counted its way, others by spelling rules and listed as guessed), and whether lines that rhymed still do (rhyme, near or no, a hint for your ear). A line a syllable long or short gets a proposal: its longest note split in two, or two short neighbours merged, never its last note (the rhyme). It changes nothing; the proposal goes into the sheet only with your yes.

  2. resing_section(lead_sheet, section, take, vocal_track, midi_track) re-sings just that section. YuE2 continues the take from just before the section, from the take's own codes, so it stays in that take's voice and sound, and sings the section's new words. The new vocal is separated, lined up on the bars and spliced into the vocal track's item at the quietest moment near each edge, with 30 ms crossfades. The splice is one undo step and keeps the track's effects and fader; the sung-melody MIDI is updated for the section. A section whose syllables don't spell its lyrics is refused before the GPU runs. If it's the first section the take sang, there's nothing to continue from, so it's sung fresh with the take's seeds and the voice may differ (it says so). Live, re-singing Chorus 1 after the pre-chorus took 44 s.

Lining a take up with the bars. YuE2 doesn't keep its score's tempo. Take 8602 of "Attention, Please" sang at about 88.8 BPM against the score's 86, got 4.2 s ahead by the bridge, fell behind, then caught up. One offset can't place a take like that. align_vocal_take takes a sketch WAV (its vocal is separated first) or any vocal stem, plus the lead sheet (or lead_sheet_path, its JSON file). It maps the written melody onto the sung pitch, cuts the vocal at its breaths into pieces of 2.5 s at most, and moves each piece whole to where REAPER's own bars put it, so a 6/8 bridge and a slowing outro come out right. Nothing is stretched. It writes <sketch> aligned.wav next to the sketch and changes the project only with import_to_reaper=True (a new track at the first sung bar). Pieces sung where the score has no melody, or that the score has no room for (a line sung twice), are left out, and the result says where. On take 8602, 55 of 56 eight-second windows land within 0.1 s of the melody. The exception is one held note in the first Tag, which the earlier hand alignment also missed. Inside a piece the take keeps its own pace, so in a steep ramp (90 to 70 BPM) its notes can sit up to about 0.2 s off at a piece's edges.

What the take actually sang. A singer, or YuE2, sometimes changes the tune. With midi=True, align_vocal_take reads the notes off the lined-up vocal and compares them with your melody note by note:

In the result

What it is

sung_vs_written

per section: written notes sung as written (same_note), sung on another pitch (changed, with semitone_off and octave_off among them), not sung (dropped: a rest, a breath or a slide where a note was written), notes sung that aren't written (added: a note in a rest, a run, a held note the sheet doesn't have), and ornaments (scoops into a note, glides, fall-offs, turns)

sung_melody.changes

each changed, dropped or added note with REAPER's bar and beat, the written and sung note (E4 -> F4) and the section; the first 50, all of them in the JSON written next to the take

sung_melody.notes, range

how many notes were sung, lowest and highest

A written note counts as sung when a note of its pitch covers a good part of it or starts within 0.15 s of it (a little early or late), so one note sung in two breaths, or two repeated notes sung as one, is still the same note. A short note (under 0.25 s) joined to the melody without a breath is an ornament, not an added note; blips under 120 ms aren't counted. On take 8602 of "Attention, Please" that reads 497 of 559 written notes as sung, 45 changed, 17 dropped, 29 added and 45 ornaments (YuE2 often scoops into a note from a step below), with the Bridge changed most (76% as written) and the Final Chorus and Outro not at all. With import_to_reaper=True the notes also go on a new muted MIDI track <aligned file> · sung melody (MIDI) under the vocal, with ReaSynth so it plays when you unmute it. The notes sit on REAPER's own bars and beats, so they sound where the vocal sings them even where REAPER's meter differs from the sheet's; a note sung before the first bar starts the MIDI a bar early. The JSON written next to the take keeps every note, so nothing is lost without the import.

A band never pauses, so its stems can't be cut at breaths. align_stem_take takes the same sketch WAV and lead sheet and puts the take's drums, bass, piano, guitar and other stems on REAPER's bars with REAPER's own stretch markers, pitch kept: a marker on every bar line at the moment of the take where that bar line was played, and one on every beat of a bar where REAPER ramps. All the stems share one fit, so they stay together, and the markers stay on the items where you can see and drag them. Where the bar lines were played comes from the vocal's notes against the written melody, fine-tuned to the drums' hits nearest each beat (an eighth in 6/8). A take with no melody is followed by its beats alone, counted from its first bar; listen to the first bars. Each stem gets a new track, 'Take #8602 · drums on the bars', and they share a folder; the unpacked '(YuE2 timing)' tracks stay as they are. It uses the stems unpack separated (or separates the take once) and writes <sketch> stretch.json with every bar line and marker. On take 8602's Chorus 1 in REAPER, the rendered drums sit a median 5 ms from REAPER's beats, 97% within 30 ms (left in YuE2's timing they started half a second late). timing="beats" only counts beats, and on the full 3-minute take it lost count by whole beats through the breaks, so keep it for short takes with no melody.

Write the sheet's melody at the pitch you want to hear. YuE2 writes a male voice an octave above how it sounds, the way a tenor part sits in treble clef, so when the style names a male voice the score goes to YuE2 an octave up and the singer lands on your notes. Set yue2_vocal_shift on the sheet to override it (0 sings a male voice an octave under the sheet). A section with lyrics but no melody, such as a PA announcement over a held chord, keeps its words in the sheet for the markers, but YuE2 isn't given them: it sings the score note by note.

Settings

Set these in the env block of your MCP client config.

Variable

Values

What it does

ORPHEUS_TOOLSET

default, explain, full

Which tools Claude sees. full adds the not-built stubs.

ORPHEUS_ASR_DEVICE

auto (default), cpu, cuda

Where lyric transcription runs. auto uses CUDA only after a test run in a separate process succeeds, so a broken cuDNN setup falls back to CPU instead of crashing the server.

REAPER_MCP_BRIDGE_DIR

a folder

Where the bridge's request and response files live (default ~/.orpheus_bridge).

ORPHEUS_AUTOSTART_BRIDGE

1 (default), 0

Whether a call starts the bridge in an open REAPER by itself.

ORPHEUS_REAPER_EXE

a path

The REAPER program, if it isn't in the usual install folder.

ORPHEUS_NC_BACKENDS

e.g. yue2

Switches on named non-commercial backends; yue2 adds render_sketch.

ORPHEUS_YUE2_DIR

a folder

Where yue2.cpp and the YuE2 weights live (default ~/.orpheus/yue2).

ORPHEUS_SKETCH_DIR

a folder

Where rendered sketches are saved (default ~/.orpheus/sketches).

ORPHEUS_LIBRARY_DIR

a folder

Where fetched library instruments live (default ~/.orpheus/library).

ORPHEUS_REAPER_RESOURCE_DIR

a folder

REAPER's resource folder, if install_orpheus_jsfx can't find it.

Install

Not published yet. These are the planned install paths once v0.1 is on PyPI.

# 1. Run the server
uvx orpheus-mcp

# 2. Install the bridge into REAPER (one-time); from then on it starts with REAPER
orpheus-mcp install-bridge

Then add it to your MCP client, for example Claude Desktop's claude_desktop_config.json:

{
  "mcpServers": {
    "orpheus": { "command": "uvx", "args": ["orpheus-mcp"] }
  }
}

Open REAPER and ask Claude to "check the Orpheus connection." If REAPER was already open, Orpheus starts the bridge in it the first time Claude needs it (or run orpheus-mcp start-bridge). Per-OS steps: docs/installation.md. Working from source: CONTRIBUTING.md.

How it works

Orpheus is a Python FastMCP server. It never calls REAPER's API directly. It writes JSON request files that a Lua script running inside REAPER picks up, executes and answers. The bridge is hardened: atomic writes, a heartbeat, a fixed table of commands (nothing evaluated from the wire), per-call caps, and hot reload of new commands without restarting REAPER. Claude talks in beats; all tick and tempo math happens in the bridge. Tools that change the project are marked destructiveHint, so your client can ask you before each one. Engines with clashing dependencies (audio-separator, basic-pitch) run in their own environments as separate processes. More: docs/architecture.md.

Why not python-reapy or OSC? REAPER's OSC can't pass arguments to custom actions, so it can't create tracks or write MIDI notes. python-reapy is effectively unmaintained and throttles to about 30 to 60 calls a second. A Lua loop inside REAPER avoids both.

Credits

Orpheus reimplements patterns from these projects under MIT; it does not copy GPL-licensed code. Per-project notes: docs/frontier-analysis.md.

Model credits and licences for the analysis engines are in data/model_registry.json and docs/pins/.

The sound pack and the instrument library fetch public-domain (CC0) samples on request; none are bundled. Thanks to FreePats, Versilian Studios (VCSL and VSCO 2 Community Edition), and Karoryfer Samples with bigcat instruments (cello). Each instrument's source and licence are in data/instrument_library.json.

License

MIT © 2026 Mal0ss.

Available Tools

32 tools
add_fx_by_nameA
Destructive

Add an FX by fuzzy name, VALIDATED against the installed-plugin inventory.

On a no-match returns a graceful "not found — here's how to install it" message rather than silently loading the wrong plugin (the bug all three live servers have). Orpheus never auto-installs plugins.

Inputs: track (required), fx_name (required). Returns: object

analyze_audio_characterA
Read-only

Render stems/master to WAV and compute the post-FX sonic fingerprint: 3-band energy, spectral centroid, LUFS, true peak, crest factor, stereo width. (Sharper with the optional [analysis] extra / librosa.)

Inputs: no named parameters. Returns: Objective post-FX DSP features — the 'sonic signature' vector.

analyze_grooveA
Read-only

Compute swing%% and tightness from raw MIDI PPQ onset deviation off the grid. No existing DAW-MCP server provides this — a genuine Orpheus differentiator.

Inputs: no named parameters. Returns: swing_pct, tightness

analyze_harmonyA
Read-only

Detect key/scale/chords/Roman numerals/cadences.

Exports the project's MIDI, filters drum tracks (Krumhansl detection is garbage on beats), and runs music21. Always returns a confidence + alternatives; on drum-only or non-chordal material it hedges rather than inventing harmony.

Inputs: no named parameters. Returns: key_root, mode, key_confidence, alternative_keys, +3 more

apply_changesA
Destructive

Execute an approved EditPlan: symbolic edits (transpose, rewrite progression MIDI, swap/add FX, retarget tempo, write grooved patterns), all wrapped in one Undo_BeginBlock/EndBlock so a single Ctrl+Z reverts everything.

Pass back the exact plan the user approved — do not re-derive it here.

Inputs: plan (required). Returns: object

apply_master_matchC
Destructive

The spectral half: render the master → Matchering against the fingerprint's reference WAV → bake the matched curve onto a master-bus ReaEQ + limiter.

Inputs: fingerprint (required). Returns: object

build_project_specA
Read-only

Fuse symbolic + audio analysis into one CompositionSpec(current) + a plain-English report. The contract handed to recommend_changes.

Inputs: no named parameters. Returns: The 'LLM-Readable Music Report' — structured musical *facts*, not raw numbers.

constrain_to_keyC
Read-only

Snap a proposed note set to the nearest in-key pitches before writing.

Inputs: notes (required), key (required), mode. Returns: object

create_midi_itemA
Destructive

Create a MIDI item/take over a bar range; returns a stable take identity.

Inputs: track (required), start_bar (required), length_bars (required). Returns: object

create_trackA
Destructive

Insert a named track and return its stable GUID (one composite bridge call).

Inputs: name (required), index. Returns: object

explain_styleA
Read-only

"Why does this sound like X?" — run feature thresholds over the current project and return human-readable reasons (each matched threshold = one reason).

This is the v0.1 headline capability: understanding without transformation.

Inputs: no named parameters. Returns: object

get_connection_statusA
Read-only

Check whether REAPER is running and the Orpheus bridge loop is alive.

Call this first. Round-trips a real ping through the bridge and returns REAPER's version + latency, or a clear "not listening" message (rather than a mystery hang) if the in-REAPER script isn't running.

Inputs: no named parameters. Returns: object

get_fx_paramsA
Read-only

Decode an FX chain's parameters BY NAME (e.g. compressor ratio), not as opaque 0–1.

Inputs: track (required). Returns: object

get_genre_profileA
Read-only

A style's typical progressions / scales / BPM range / instruments / drum rhythms. The RECOMMEND-side lookup.

Inputs: genre (required). Returns: object

get_project_infoA
Read-only

Tempo, time signature, length, track count, and transport state.

Inputs: no named parameters. Returns: object

get_scale_notesC
Read-only

MIDI notes for a key/mode so generated notes stay diatonic.

Inputs: key (required), mode. Returns: object

get_track_midiA
Read-only

Read a take's MIDI notes (pitch, start/duration in BEATS, velocity) + CC.

Inputs: track (required). Returns: object

insert_midi_notesA
Destructive

Batch-write notes into a take, PPQ/tempo-correct, in ONE bridge round-trip.

Notes are in beats (pitch, start_beat, duration_beats, velocity). Batched because per-note round-trips would hit the ~10 ops/sec file-IPC ceiling. Capped per call (see BridgeClient.MAX_NOTES_PER_CALL) so REAPER's audio thread never stalls.

Inputs: track (required), notes (required), at_bar. Returns: object

list_style_fingerprintsA
Read-only

List cached target fingerprints (e.g. 'classical', 'hiphop', 'dominic-fike-sunburn'). Each is the analysis pipeline run over 3–5 per-era reference tracks.

Inputs: no named parameters. Returns: result

list_tracksA
Read-only

The typed track tree: name, vol/pan, mute/solo, role, FX-chain names, item count.

Inputs: no named parameters. Returns: result

play_stop_recordA
Destructive

Transport control: 'play' | 'stop' | 'record', via Main_OnCommand action IDs.

Inputs: command (required). Returns: object

quantize_notesA
Destructive

Quantize a take's notes to a grid (cleanup before/after analysis).

Inputs: track (required), grid. Returns: object

recommend_changesA
Read-only

Diff the current project against a target fingerprint and return an EditPlan — a list of ProposedEdit{target, action, reason, params} across the v1 dimensions (tempo, key, harmony, instrumentation, mastering-match), each annotated with a human-readable reason. Read-only: surface these reasons to the user for approval, THEN call apply_changes. Includes honest caveats (detection confidence, taste calls).

Inputs: target_style (required). Returns: The output of `recommend_changes` (read-only) and the input to `apply_changes`…

render_and_auditA
Read-only

Render, then measure LUFS/spectrum in one call so the agent self-checks ('loud enough? too bright?') and iterates without a human ear.

Inputs: no named parameters. Returns: object

render_projectC
Destructive

Headless render to WAV/MP3 (RENDER_FILE + format/bounds + Main_OnCommand(41824)).

Inputs: out_path (required), fmt. Returns: object

render_stemsC
Destructive

Render per-track stems by sequential solo — feeds analyze_audio_character.

Inputs: out_dir (required). Returns: object

set_fx_paramB
Destructive

Set an FX parameter with name→index resolution (so 'ratio' works, not just index 7).

Inputs: track (required), fx (required), param (required), value (required). Returns: object

set_tempoA
Destructive

Set the project tempo in BPM (downstream: seconds_per_beat = 60 / bpm).

Inputs: bpm (required). Returns: object

set_time_signatureC
Destructive

Set the project time signature.

Inputs: numerator (required), denominator. Returns: object

set_track_volume_panA
Destructive

Set fader/pan. Accepts fuzzy values ('-6dB', '+3', '50%', 'L50', 'center').

Inputs: track (required), volume, pan. Returns: object

suggest_chord_progressionC
Read-only

A genre-typical diatonic progression as Roman numerals + concrete MIDI.

Inputs: key (required), mode, genre. Returns: object

transpose_notesB
Destructive

Transpose a take's notes — the APPLY verb for key/mode retargeting.

Inputs: track (required), semitones (required). Returns: object

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    B3.4/5.0

    Scored across 32 tools

    Disambiguation5/5

    Each tool has a clearly distinct purpose, from analysis (analyze_audio_character, analyze_groove) to editing (transpose_notes, quantize_notes) and application (apply_changes, apply_master_match). No overlapping functionality; even similar actions like rendering are differentiated by scope (project, stems, audit).

    Naming Consistency5/5

    All 32 tools follow a consistent verb_noun naming pattern with underscores, e.g., create_track, get_project_info, set_tempo. Verbs are reused predictably (analyze_, get_, set_, render_) making the API easy to navigate.

    Tool Count2/5

    At 32 tools, the server is over-scoped for typical use. While each tool is justified by its description, the sheer number increases cognitive load and selection complexity. A leaner set (around 20) would be more manageable.

    Completeness4/5

    Covers a broad domain: project info, MIDI operations, FX management, transport, analysis, and recommendations. Minor gaps exist (e.g., explicit parameter automation, audio item editing), but core workflows for the Orpheus intelligent assistant are well-supported.

    Related MCP Connectors

    Related MCP Servers