Skip to main content
Glama
romanstark

Dorico Maestro

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault

No arguments

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
connect_to_doricoA

Connect to Dorico Remote Control and return application status.

Call this before anything else here: every other tool that talks to Dorico
needs the session this opens. It is safe to call again on an open connection.

Returns:
    Result dictionary with the connection outcome and the first status snapshot.

Note:
    On the first connection Dorico shows an authorization prompt inside the
    application, and nothing proceeds until a person accepts it. The token is
    then kept in AppData and later runs connect without asking.

    Use get_status afterwards to re-read the state without reconnecting.
get_statusA

Return Dorico's current pushed application status snapshot.

The state of the application rather than of the music: which mode is active,
whether note input is running, whether anything is selected, whether an undo is
available.

Returns:
    Result dictionary carrying the merged status snapshot.

Note:
    Dorico pushes status as deltas and this is the accumulated snapshot of them,
    so it costs nothing to read and needs no command to be sent.

    This is also how to check whether a command that answered kOK actually took
    effect, since kOK only says the UI queue accepted it (docs/protocol.md,
    'Command Acceptance vs Effect'). For the properties of the selected notes
    rather than the state of the application, use read_selection.
read_selectionA

Read rhythmic and notation properties of the active selection.

Reports duration, dots, articulations, accidental and event type for whatever a
person has selected in Dorico. Nothing here can change the selection, so make it
in Dorico or move the caret with goto_bar first.

Returns:
    Result dictionary with has_selection, and the properties when it is true.
    An empty selection answers has_selection=False rather than an error.

Note:
    Pitch and bar or beat position are not exposed by Dorico's Remote API, so
    they are absent here and no amount of selecting will produce them. To read
    pitches, export the flow with export_musicxml and read it with read_score,
    or read a saved project with read_project_info.
add_notesA

Input notes at the caret, then leave note-input mode cleanly.

ONE insertion at the current caret. For a SEQUENCE of notes or chords over
time, use ``write_score`` / ``render_to_dorico`` with a ScoreSpec (a chord is
one event with >=2 pitches). Repeated ``add_notes`` calls do NOT chain: each
re-enters note input at the same spot, so successive chords stack on one beat.

Returns:
    Result dictionary with the notes and duration entered, the note input mode
    they landed in, whether an undo is available, and displaces_existing.

Note:
    Read displaces_existing before treating this as an addition. Dorico has an
    overwrite note input mode, and in it these notes replace the music already
    at the caret instead of pushing it along. The mode belongs to the
    application rather than to this call, so it is reported back and not chosen
    here. get_status reads it beforehand.

    Uses :class:`NoteInputSession`, so note input is always exited even on
    error. Success indicates command acceptance (kOK). Verify note placement
    via get_status, playback, or score inspection. Do not read can_undo as
    that verification: entering note input alone already sets it.
add_restA

Input one rest at the caret, then leave note-input mode cleanly.

One rest at the current caret position, which then advances by that duration.
Note input is always exited afterwards, including when the call fails.

Returns:
    Result dictionary with success, the duration entered, the undo flag and the
    resulting mode.

Note:
    Success means Dorico accepted the command (kOK), not that the rest is where
    it was wanted (docs/protocol.md, 'Command Acceptance vs Effect'). Check with
    get_status or by inspecting the score.

    For a passage rather than one rest, put rest events in a ScoreSpec and use
    write_score: repeated calls here do not chain, because each one re-enters
    note input at the caret. Use goto_bar first to choose where it lands.
    Do not read can_undo as evidence: entering note input alone already sets it.
transposeA

Transpose currently selected notes up or down in the score.

Directly modifies the score by altering the pitches of the current selection
in place. Relative and repeatable: calling it twice moves the selection twice
as far, with no absolute target pitch.

Returns:
    Result dictionary with the command outcome and the catalog row
    registry_status.

Note:
    When to use: Shift existing selected notes by semitone, diatonic step,
    or octave intervals.
    When NOT to use: Do not use to enter new music (use write_score or
    add_notes). Do not use to change key signatures (use set_key_signature).

    Operates strictly on the active selection (reads are selection-only). If
    nothing is selected, Dorico ignores the command and no notes are modified;
    make a selection first or place the caret via goto_bar.

    Parameters: direction sets shift orientation ('up'/'down'). chromatic
    shifts by exact semitone when True or diatonically when False. octave=True
    overrides chromatic and shifts by a full octave.

    Maps to NoteEdit.Pitch{Up,Down}[Chromatic|Octave]. Read registry_status in
    the returned result and verify the change in the score or via playback.
set_time_signatureA

Report that a time signature cannot be set here, and what to use instead.

This writes nothing and always reports failure, which is the honest answer
rather than a silent no-op: Dorico takes a time signature only through an
interactive popover, and the Remote API cannot type into one.

Returns:
    Result dictionary explaining the limitation and naming the alternatives.

Note:
    Two ways round it. For a person at the keyboard, open_popover(kind='time')
    opens the popover for them to type into. For an unattended write, put the
    time signature in a ScoreSpec and use write_score(method='musicxml') or
    export_musicxml, both of which set it through the file rather than the UI.
set_key_signatureA

Report that a key signature cannot be set here, and what to use instead.

This writes nothing and always reports failure, for the same reason as
set_time_signature: Dorico takes a key signature only through an interactive
popover, and the Remote API cannot type into one.

Returns:
    Result dictionary explaining the limitation and naming the alternatives.

Note:
    For a person at the keyboard, open_popover(kind='key') opens the popover for
    them to type into. For an unattended write, put the key in a ScoreSpec and
    use write_score(method='musicxml') or export_musicxml, which set it through
    the file rather than the UI.
navigateA

Scroll the score viewport to the start or end of the flow.

Moves what is on screen through View.MoveViewportTo*, and nothing else: the
caret stays where it was and no music changes.

Returns:
    Result dictionary reporting the scroll, or the redirect for target='bar'.

Note:
    Use goto_bar instead to put the caret somewhere, which is what note entry
    needs. This tool would scroll past the bar and leave the caret behind. A
    target of 'bar' says so rather than doing half the job.
switch_modeA

Switch which of Dorico's five workspace modes is on screen.

Changes the window and nothing in the music: no notes, no playback position and
no selection move as a result.

Returns:
    Result dictionary reporting whether the switch was accepted.

Note:
    Note entry needs write mode, so switch there before add_notes, add_rest,
    goto_bar or write_score if the project might be in another one. get_status
    reports which mode is active without changing it.

    This is not navigation. To scroll the score use navigate, and to move the
    caret use goto_bar.
playbackA

Start, stop or rewind Dorico playback.

Transport only: no note, dynamic or layout changes as a result.

Returns:
    Result dictionary reporting whether the transport command was accepted.

Note:
    Playback is the one way to hear whether a write landed, since kOK proves
    only that the command was accepted (docs/protocol.md, 'Command Acceptance
    vs Effect'). It makes sound, which matters if a person is in the room.

    Use navigate to scroll the score without playing, and goto_bar to move the
    caret. Neither of those moves the playhead.
saveA

Save the open project over its existing file on disk.

Sends File.Save, which writes the project in place. A project that has never
been saved has no path to write to, so this cannot be relied on to save one:
check that the project has a file before treating it as a save.

Returns:
    Result dictionary reporting whether the command was accepted.

Note:
    When to use: Save changes in an already-saved project file on disk.
    When NOT to use: Do not use if the project has never been saved (has no
    path). To produce a file for external use without altering the open
    project file, use export_pdf or export_musicxml instead.

    Acceptance is not completion here either (docs/protocol.md, "Command
    Acceptance vs Effect"), so a kOK does not prove the file on disk has changed.

    This overwrites the .dorico project file in place.
export_pdfA

Export the score to PDF unattended without opening a dialog.

Writes the file next to the .dorico project, named after the layout. This is the
unattended path. File.Export opens a modal dialog and is not usable from here.

Returns:
    Result dictionary reporting whether the command was accepted.

Note:
    Receiving kOK does not prove a file exists yet. Dorico runs commands on its
    UI thread, so a request sent while a modal dialog is open waits in the queue
    until the dialog closes. Tested against Dorico Elements 6.2.30. Check the
    expected path on disk rather than trusting the return.

    The all_layouts path is catalogued as untested, unlike the current-layout
    path which is verified, so treat a multi-layout export as unproven and check
    what actually landed. For an interchange format rather than a printable one,
    use export_musicxml.
goto_barA

Move the caret to a bar and return the assumed position.

The position is assumed, not read. Dorico exposes no caret coordinates over the
Remote API, so this dead-reckons: it enters note input, rewinds to bar 1 of the
top staff, then steps forward to the bar, staff and beat asked for.

Returns:
    Result dictionary with the assumed caret position and the caveat attached.

Note:
    Because it counts rather than measures, the answer drifts from the truth if
    anything moved the caret in between, and it cannot detect that. Treat it as
    the position it aimed for, and confirm what was written with read_selection
    or by inspecting the score.

    This enters note input, so it is the call to make before add_notes or
    add_rest. To scroll the view without touching the caret, use navigate.

    Ask whether the flow opens with a pickup bar before relying on a bar
    number, because Dorico leaves a pickup out of the count and this lands one
    bar short without the pickup flag. The API cannot tell, so the person with
    the score on screen has to say, or read an exported MusicXML with
    read_score.

    The move costs the same handful of commands at any flow length, so a long
    flow is no less exact than a short one.
open_popoverA

Open an input popover at the caret for manual text entry.

Opens the popover and stops there. Dorico's Remote API cannot populate popovers
directly, so this positions the caret if requested, triggers the
NoteInput.Create* command, and returns the required input format.

Returns:
    Result dictionary with the popover kind, caret location, and typing
    instructions.

Note:
    Requires user interaction in Dorico. Opening a popover leaves it waiting
    for keyboard input. Treat anything sent while it waits as unsafe: a modal
    dialog leaves later commands accepted but unexecuted (docs/protocol.md,
    'Modal Dialog Detection'), and a waiting popover has not been measured to
    behave any better.

    For an unattended write, put the marking in a ScoreSpec and use write_score:
    dynamics and clefs are ScoreSpec fields, and a key or time signature goes in
    through write_score(method='musicxml').
run_commandA

Dispatch any catalogued Dorico command by ID, with optional parameters.

The escape hatch, reaching the whole catalogued command set rather than the
handful of tools here. What it can send is bounded by the catalog.

Returns:
    Result dictionary with the command outcome and the catalog row status, which
    says how well that command is actually established.

Note:
    Read the registry_status in the answer before trusting the result: a row may
    be verified, reachable, unavailable, broken or untested, and only verified
    has been seen to work. Combined with kOK meaning acceptance rather than
    effect (docs/protocol.md), a clean return from an untested row is weak
    evidence. Check with get_status or by inspecting the score.

    Prefer a dedicated tool where one exists: write_score, transpose,
    switch_mode, playback and save all add validation or verification this does
    not. Use search_commands to find a command ID and what it takes.
score_schemaA

Return the ScoreSpec input format write_score/render_to_dorico expect.

Call this instead of guessing or reading source. Unknown keys are rejected by
the parser rather than ignored, so the shape has to match exactly.

Returns:
    Result dictionary with a copyable minimal example in both the flat and the
    nested form, the allowed enum values (durations, articulations, dynamics,
    clefs) and the indexing rules.
write_scoreA

Render a ScoreSpec into Dorico by caret entry or MusicXML import.

The main way to write music here, and the one to reach for whenever there is
more than a single beat to enter: add_notes and add_rest do not chain, because
each re-enters note input at the caret and stacks on the same beat.

Returns:
    Result dictionary with the execution report, the preflight warnings, and the
    caveats attached to what was dispatched.

Note:
    Choose the method by what the score needs. 'caret' adds to the current flow
    and leaves the rest of the project alone, but it cannot set a key or time
    signature, because those go in through a popover no API can type into.
    'musicxml' carries them, at the price of arriving as a new flow rather than
    joining the current one.

    Call score_schema first for the exact shape: unknown keys are refused rather
    than ignored. Dorico must be in write mode, so use switch_mode if unsure.
    Nothing is verified by the return, since kOK means accepted rather than
    effective (docs/protocol.md), so check the result in the score.

    The caret path repositions between staves by jumping to the start of the
    flow, so it needs to know nothing about the flow's meter or length.
render_to_doricoA

Render a ScoreSpec through the caret path, or plan it without sending.

The lower half of write_score, exposed on its own for the two cases where that
matters: seeing the command plan before it runs, and skipping the preflight
checks and the MusicXML option that write_score adds on top.

Returns:
    Result dictionary with the command plan when dry_run is true, or the
    execution outcome when it is false.

Note:
    Prefer write_score for ordinary composition: it runs the range and voice
    leading checks first and can take the MusicXML path when a key or time
    signature is needed. Come here to inspect what would be sent, or when the
    caret path is specifically what is wanted.

    With dry_run true this is a read: nothing is dispatched and Dorico need not
    even be running.
export_musicxmlA

Write a ScoreSpec to a MusicXML file on disk, without Dorico.

Entirely offline: no connection is opened and Dorico need not be running. Key,
time signature, clefs, dynamics and tempo all survive the round trip, which is
what makes this the way to set the two signatures no popover will accept.

Returns:
    Result dictionary with the outcome and the path that was written.

Note:
    A specified path is overwritten without confirmation. Omit the path to
    write to a temporary file.

    To get the file into Dorico afterwards, import_musicxml opens it as a new
    flow, and write_score(method='musicxml') does both steps in one call. For a
    printable file rather than an interchange one, use export_pdf.
read_project_infoA

Read metadata, flows, and player rosters from a saved .dorico file.

Opens the project as the ZIP archive it is and reads the document and per-flow
metadata out of it. Entirely offline: Dorico need not be running, and this works
on a project nobody has open.

Returns:
    Result dictionary with the document metadata, the flows, and the players.

Note:
    This reads the project wrapper, not the music: for notes and rhythms, export
    with export_musicxml and read that with read_score. For the project open in
    Dorico right now, get_status reports its state and read_selection its
    selection.
read_scoreA

Read an existing MusicXML file measure by measure using music21.

Entirely offline and read-only. This is the way to see pitches, which Dorico
itself will not report over the Remote API.

Returns:
    Structured dictionary with the metadata, parts, measures and note events.

Note:
    Use the bars filter rather than reading everything when the question is
    local: a full read of a long score returns every note of every part.

    To see the music currently in Dorico, export it with export_musicxml first
    and read that. read_project_info reads a .dorico project wrapper instead,
    and read_selection reports the live selection without pitches.
read_open_scoreA

Read the whole open score back by way of a MusicXML export.

The only route to the full contents of the score that is open. Reads over the
Remote API see the selection alone, so everything else here works blind. This
is what makes bar count, key, time signature and above all a pickup bar
knowable instead of guessed.

Returns:
    Result dictionary with the parsed summary, the pickup finding, the last
    bar number, and the file that was read.

Note:
    Dorico's MusicXML export filter opens a modal dialog that requires user
    confirmation. This tool triggers the export dialog and awaits the resulting
    file in export_dir. Point the export dialog to export_dir once in Dorico to
    enable one-key export confirmations on subsequent reads.

    The result is a snapshot of the score at export time. Re-export after
    edits to refresh score state.
import_musicxmlA

Import a MusicXML file into Dorico via the Remote Control API.

Dispatches File.Open with MusicXMLImportFilter.

Returns:
    Result dictionary with success, supported, attempted,
    requires_confirmation, code, path and note.

Note:
    An import arrives as a new flow rather than joining the one on screen, and
    Dorico may raise a player assignment prompt that waits for a person. While
    that prompt is open, later commands are accepted but sit unexecuted in the
    queue (docs/protocol.md, "Modal Dialogs").

    To add music into the flow already open, use write_score(method="caret").
    Use export_musicxml to produce the file in the first place, or
    write_score(method="musicxml") to do both steps in one call.
analyze_harmonyA

Estimate the key of a ScoreSpec and name its chords in Roman numerals.

Entirely offline: the score is analysed as data and Dorico is not involved, so
this works on music that has never been in a project.

Returns:
    Result dictionary with the key estimate, its confidence, and a Roman numeral
    reading of each sonority.

Note:
    Key estimation relies on pitch distribution. For short or highly chromatic
    excerpts, verify the estimated tonal center before relying on Roman numerals.

    This answers what the harmony is. For whether the voices move well between
    those chords use check_voice_leading, for strict two-part exercises
    check_counterpoint, and for what could come next suggest_next_chord.
check_voice_leadingA

Audit a ScoreSpec for parallel fifths and octaves, overlaps and spacing.

Entirely offline and read-only: nothing in the score is changed and Dorico is
not involved. Written for part-writing of any number of voices, so a chorale or
a string quartet is the natural input.

Returns:
    Result dictionary with one entry per issue found, each naming the rule, the
    voices involved and where it happens. An empty list means nothing was found.

Note:
    These are the common-practice rules, so a passage that breaks them on purpose
    is reported too. The findings are advice and nothing here rewrites the music.

    For a strict two-part species exercise, check_counterpoint applies the
    stricter set of rules that belongs to it. For what the chords are rather than
    how the voices move between them, use analyze_harmony.
suggest_next_chordA

Suggest functional continuations for a Roman numeral progression.

Entirely offline and read-only: this reasons about numerals as symbols and never
touches a score or Dorico.

Returns:
    Result dictionary with the candidate next chords, each carrying its harmonic
    function and why it follows.

Note:
    Suggestions come from common-practice function, so they describe what usually
    follows rather than what must. Nothing is written anywhere. To hear a
    candidate, put it in a ScoreSpec and use write_score.

    This takes numerals, not notes. To get numerals out of actual music, run
    analyze_harmony first and feed its reading in here.
instrument_rangeA

Look up a standard instrument compass, or test one pitch against it.

Two questions through one door: without a pitch it reports the range, with one it
reports whether that note is inside it. Entirely offline and read-only.

Returns:
    Result dictionary with in_range when a pitch was given, or the lowest and
    highest playable pitches when it was not.

Note:
    These are the standard written ranges for a competent player, not the limits
    of the instrument or of a particular one: professionals exceed them and
    beginners do not reach them.

    Worth calling before write_score when writing for an instrument, since
    write_score with preflight left on runs the same check over a whole score and
    reports what falls outside.
check_counterpointA

Check a two-part first-species counterpoint against the classic rules.

Entirely offline and read-only. Enforces the strict set: begin and end on a
perfect consonance, consonant verticals only, no consecutive perfect fifths,
octaves or unisons, no voice crossing, and one melodic climax in the
counterpoint.

Returns:
    Result dictionary with one entry per issue, each naming the rule and the beat
    it happens on. An empty list means the exercise passes.

Note:
    Only first species is implemented, so passing any other species is refused
    rather than checked loosely. The two lines must be the same length, since
    note against note pairs them one to one.

    These rules are stricter than ordinary part-writing on purpose. For a
    chorale or a quartet use check_voice_leading, which applies the
    common-practice rules to any number of voices.
search_commandsA

Search the Dorico command catalog by query, category, or status.

Entirely offline: the catalog ships with this server, so nothing is asked of
Dorico and it need not be running.

Returns:
    Result dictionary with the total number of matches, a count per status, and
    the matching commands with their IDs, parameters and documentation.

Note:
    This is how to find a command ID and what it takes before sending it with
    run_command, and how to see the status that tells you how far to trust it.
    Only 'verified' rows have been observed to work.

    Prefer a dedicated tool where one exists: much of what the catalog can reach
    is already covered by write_score, transpose, playback, save and the rest,
    with validation run_command does not perform.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription
commands_catalogReturn the complete Dorico command catalog formatted as JSON. Exposes all 348 commands with metadata, parameter signatures, and verification status without requiring individual tool declarations.

TDQS

A4.3/5.0

Scored across 30 tools

Disambiguation4/5

Most tools have clearly distinct purposes, but a few could be confused: write_score and render_to_dorico overlap significantly, and read_score, read_open_score, and read_project_info all deal with reading scores but from different sources. The descriptions do a good job of clarifying the differences, so misselection is unlikely for an agent that reads them carefully.

Naming Consistency4/5

Tool names mostly follow a verb_noun pattern (e.g., search_commands, read_selection, write_score), but a few deviate: transpose, playback, and save are single verbs, and score_schema is a noun. These deviations are minor and the overall naming is still predictable and readable.

Tool Count2/5

With 30 tools, this server exceeds the 25-tool threshold that the rubric considers too many. While the domain is complex and the tools cover a broad range of operations (editing, playback, export, analysis), the large surface area may overwhelm agents and increase the chance of misselection. The count is not extreme (not 50+), but it is still high.

Completeness4/5

The tool set covers the core workflows: writing notes (add_notes, add_rest, write_score), editing (transpose), reading (read_selection, read_score, read_open_score), export/import (export_pdf, export_musicxml, import_musicxml), and analysis (analyze_harmony, check_voice_leading, etc.). Gaps exist, such as inability to set key/time signatures directly and no explicit undo/redo, but these are addressed through documented workarounds (e.g., using write_score with MusicXML, or run_command). The surface is largely complete for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues