Skip to main content
Glama
MuseScore MCP Server

MuseScore MCP Server

by lenborje

MuseScore MCP Server

An MCP (Model Context Protocol) server that connects MuseScore Studio 4 to LLM agents (Vibe, Codex, Claude, Copilot) for composing and editing music through natural language.

What the server can do

Through the MCP tools an agent can:

  • Connect to a running MuseScore and work on the open score

  • Read the score: structure, metadata, notes, rests, tuplets and lyrics, per measure, per staff and per voice

  • Read and write chord symbols (Harmony), including slash chords, with getHarmonies / setHarmony; summaries include the symbols per measure

  • Write notes, rests and tuplets, insert and append measures, select and delete, set time signature and tempo, and undo

  • Navigate by measure and element, staff by staff; the active voice is a parameter (0-3) wherever it matters

  • Work with voices: census per staff, writing in voices 1-4, swapping (exchanging) the content of two voices over whole measures, and toggling linked-part voice visibility (main-score filtering is unsupported)

  • Drive the mixer: read it, set channel volume/pan/chorus/reverb and MIDI program/bank, per-voice playback flags, staff mute, replace instrument sounds

  • Execute whole JavaScript tasks inside the plugin (run_qml) when a job would otherwise need many round trips

The architecture is a pure bridge: score data moves as JSON between the MCP client, the Python server and the QML plugin - no file exports, no MusicXML round trips, no analysis libraries in the server.

  • docs/ACTIONS.md - the complete action reference

  • docs/AGENT-COOKBOOK.md - writing run_qml code, with worked examples

Related MCP server: mcp-score

Limitations

  • Interactive navigation between the voices of a staff is not offered; actions take the voice as a parameter (index 0-3)

  • Voice swap relies on undocumented command codes (voice-xNN on MuseScore 4.7.x) and is verified per version with dev/verify-voices.qml

  • run_qml is opt-in, controlled by allowEval in musescore-mcp-plugin.qml. The published default is false; enable it at installation with musescore-mcp install-plugin --allow-eval (or edit the installed plugin file and fully restart MuseScore). It runs arbitrary code in-process on MuseScore's GUI thread: undo-aware engraving changes in one run group into a single undo step with rollback on error, and an infinite loop freezes MuseScore unrecoverably

Connection limits

The plugin's WebSocket API binds all interfaces, without authentication, TLS or an Origin check. The Python client connects to localhost, but the listener is not local-only - restrict access through your host firewall where needed. MuseScore's QML wrapper does not expose a way to change the bind.

The bridge serializes concurrent requests, accepts replies up to 16 MiB and applies a 30-second send/response timeout (overridable with MUSESCORE_MCP_HOST, MUSESCORE_MCP_PORT, MUSESCORE_MCP_TIMEOUT). A failed exchange closes the connection and returns outcomeUnknown: true

  • the edit may have happened. The next call reconnects; the failed action is never replayed automatically.

Work with one score per plugin session. Save your work and fully restart MuseScore when switching to another score or installing changed plugin QML.

Requirements

  • Python 3.12+ (CPython or GraalPy)

  • MuseScore Studio 4.4.2+

  • One MCP-capable agent host (see the table below)

Installation

Both the server and the plugin are installed by the agent that will use them.

The quickest path: point your agent at docs/INSTALL-PROMPT.md and let it install the MCP into itself - it performs every step below, including registering the server with its host, and checks the connection.

Manual, step by step:

  1. Install the package (it bundles the MuseScore plugin and the docs, version-locked with the server). PyPI publication is pending; until then install directly from this repository:

    pipx install git+https://github.com/lenborje/musescore-mcp.git
    # or, into a venv: pip install git+https://github.com/lenborje/musescore-mcp.git

    Zero-install alternative (fetch and run, nothing installed):

    uvx --from git+https://github.com/lenborje/musescore-mcp.git musescore-mcp

    Once published on PyPI, all of the above becomes pip install musescore-mcp / uvx musescore-mcp.

  2. Install the MuseScore plugin:

    musescore-mcp install-plugin

    Enable it once in MuseScore (Plugins > Manage plugins, "MuseScore API Server"), and launch it from the Plugins menu each session. To also enable run_qml - which executes arbitrary code inside MuseScore and is off by default - install with musescore-mcp install-plugin --allow-eval.

  3. Register the server with your host; the command is simply musescore-mcp (it runs the server):

    Host

    Registration

    Takes effect

    Vibe

    vibe mcp add musescore --transport stdio --command musescore-mcp

    next session

    Codex CLI

    codex mcp add musescore -- musescore-mcp

    next session

    Claude Code

    claude mcp add musescore -- musescore-mcp

    next session

    Claude Desktop

    mcpServers entry in claude_desktop_config.json

    after full app restart

    Copilot in VS Code

    .vscode/mcp.json (or "MCP: Open User Configuration")

    on save, VS Code offers to start it

    For the zero-install uvx variant the command is uvx with args --from git+https://github.com/lenborje/musescore-mcp.git musescore-mcp (plain musescore-mcp once published on PyPI).

    docs/INSTALL-PROMPT.md contains the exact config snippets.

  4. Check the setup with musescore-mcp doctor (Python, dependencies, tool count, installed plugin version, live plugin probe).

From a source checkout instead: pip install -e ., then continue at step 2. Publishing to PyPI runs through GitHub Actions on version tags (.github/workflows/publish.yml).

Usage

Prepare MuseScore

Launch MuseScore and open the score you want to work on. Start the API Server plugin from the Plugins menu; the bridge connects to it on localhost:8765.

Example queries

  • Suggest chords that fit the melody in my score

  • Compose a simple melody and show me four ways to harmonize it

  • Extend measures 1-12 with four measures that match the style of the piece

Development verification

dev/verify-voices.qml is a small native regression plugin for the single-staff dev/test-voices.mscz fixture: it checks voice pitches, the voice-x12 swap and version-aware undo, logging through api.log with no score export (the historical export experiment is closed).

Automated regressions, no MuseScore required:

python -m unittest discover -s tests
node dev/plugin-regression-test.js
node dev/harmony-test.js
node dev/test-client-test.js

The MCP tests drive real stdio through the production bridge into an isolated WebSocket server that executes the actual plugin JS against a model of the native API. The guarded dev/mcp-live-test.py targets a real MuseScore session with dev/test-multistaff.musicxml; dev/mcp-part-live-test.py --write verifies actual voice filtering and undo in a linked-part tab. Native integration passed against MuseScore 4.7.6 on 2026-11-04 - full-suite rollback/undo and linked-part voice filtering included. Those native results are separate from the model tests; they certify neither every MuseScore version nor subjective audio/layout judgments.

Harmony regression: node dev/harmony-test.js. Live checks: venv/bin/python dev/harmony-live-test.py (read-only), or add --write to verify edits and their undo. After a plugin change, fully quit and restart MuseScore, then relaunch the API Server plugin: MuseScore reads plugin QML once per process.

testClient.html is a manual development tool - a plain browser page that talks to the plugin's WebSocket endpoint directly; extend it when you add actions.

License

MIT - see LICENSE. This is an independent code base: the project began in 2026 by replacing every component of an earlier fork of Jordan Sucher's musescore-mcp with new implementations under this license, and no original code remains. Voices, run_qml, harmony symbols, mixer actions, GraalPy support, packaging and CI were developed here.

Available Tools

7 tools
connect_to_musescoreB

Open the WebSocket to the MuseScore plugin; returns {"success": bool}.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

B3.3/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden, and it discloses little: it does not say whether calling it when already connected errors or is a no-op, what happens if the MuseScore plugin is not running, whether it blocks or times out, or whether the connection persists across calls. The only behavioral detail given, the return shape, is already covered by the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One front-loaded sentence with an explicit action and return shape, no filler. It is efficient, though the return-value clause is redundant with the output schema and could have been spent on connection semantics instead.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter connection tool with an output schema, the essentials of what it does and what it returns are covered. What is missing is the operational context an agent actually needs: invocation ordering relative to the other MuseScore tools and failure behavior when the plugin is unreachable.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a parameterless tool applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a concrete verb and resource: opens the WebSocket connection to the MuseScore plugin. It is distinguishable from siblings like ping_musescore or get_score, but does not explicitly contrast itself with ping_musescore, which is the nearest alternative for checking connectivity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies this is a connection-establishment step that logically precedes score/cursor operations, but it never says so, nor does it state when to prefer ping_musescore or what to do if a connection already exists. Usage is inferable rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_cursor_infoA

Get the current cursor position, the selection and a score summary.

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden; 'Get' reliably implies a read-only operation and the description does enumerate what is retrieved. However, it never mentions that a connected MuseScore instance is presumably required, given the connect_to_musescore sibling, nor any failure behavior without a connection.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with three concrete returned items and no filler. Every word contributes to identifying the resource.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so detailed return-value explanation is unnecessary, and a zero-parameter tool needs little schema narration. The only real gap relative to its complexity is the unstated dependency on an active MuseScore session.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a no-parameter tool applies. Nothing is misstated or missing on this dimension.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Get') and three concrete resources (cursor position, selection, score summary), which makes the output recognizable and distinct from get_score or get_score_metadata. It stops short of explicitly contrasting itself with those siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the word 'current' signals this reports live editor state rather than stored score data. There is no explicit statement of when to prefer it over get_score or what preconditions (e.g., an active MuseScore connection) must hold.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_scoreA

Get the full score analysis (metadata, all measures, staves, notes, harmonies).

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the burden of behavioral disclosure. It does convey the return payload scope well, but it omits traits that matter for a full-score dump: potential response size across all measures/staves/notes, whether a score must already be open or connected, and whether the call is read-only (only implied by the verb "Get").

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single sentence with the action front-loaded and the payload scoped in a compact parenthetical. Nothing is redundant and nothing could be trimmed without losing information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, and with zero parameters the schema burden is nil, so the definition is close to complete. The remaining gap is routing: the reader is not told how this differs from get_score_metadata or what preconditions (e.g. an active connection) apply.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to explain; the baseline of 4 applies. The description does not confuse matters by implying hidden inputs, and the empty schema is consistent with the stated behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Get the full score analysis" pairs a specific verb with a specific resource and enumerates the returned contents (metadata, measures, staves, notes, harmonies). It is clear what the tool does, but it does not explicitly distinguish itself from the sibling get_score_metadata, whose name overlaps with the first item in the list.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word "full" implies this is the heavyweight, return-everything option, which implicitly contrasts with get_score_metadata, but no when-to-use or when-not-to-use condition is stated. An agent must infer that this is the right choice when it needs more than metadata, and must infer the cost of a full dump.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_score_metadataA

Get score metadata only (title, composer, measures, staves, time/key signatures).

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the full disclosure burden; it does state the exact scope of data returned, which usefully bounds the operation. It does not state that the call is read-only, whether a connection/session is required, or what happens if no score is loaded — gaps that matter for an unannotated tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single front-loaded sentence with the resource named first and the returned fields parenthesized for scannability. No redundant or filler wording.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, and with zero parameters there is no input complexity to cover. It is nearly complete for a simple read tool; only the connection prerequisite and read-only nature are unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the baseline for a no-parameter tool applies. The field list in the description corresponds to output content rather than inputs, which is appropriate here.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('Get') and resource ('score metadata') and enumerates the fields returned (title, composer, measures, staves, time/key signatures), which makes the scope concrete. The word 'only' implicitly contrasts it with the broader get_score sibling, though it never names that sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The word 'only' hints that this is the lightweight alternative when full score content is unnecessary, implying get_score is the heavier option. However, there is no explicit statement of when to prefer this tool, and no mention of prerequisites such as connecting to MuseScore first, which the sibling connect_to_musescore suggests is required.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

ping_musescoreA

Ping the MuseScore WebSocket API to check the connection.

Also performs a version handshake: the response carries the server version and the plugin's version. If versionsMatch is false, the installed plugin is out of sync with the server - fix with musescore-mcp install-plugin (then restart MuseScore and relaunch the plugin).

NameRequiredDescriptionDefault

No parameters

Output Schema

NameRequiredDescription
resultYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full load and does disclose non-obvious behavior: the call performs a version handshake, the response includes server and plugin versions, and a false versionsMatch means the plugin is out of sync. It also names the fix command and the required restart steps. It stops short of saying whether the call has side effects or what happens on a failed ping (error vs. a boolean field).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose, then the handshake detail, then the failure remediation in priority order. Every sentence carries information, though the parenthetical restart sequence is slightly verbose for a description field.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a no-parameter diagnostic with an output schema, this is nearly complete: purpose, side benefit (version handshake), how to read the key result field, and the recovery procedure. Missing only a note on expected failure modes (e.g., connection refused) and whether it is safe to call repeatedly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate — the baseline applies. The description correctly adds no parameter discussion, which is appropriate rather than a gap.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Ping the MuseScore WebSocket API to check the connection" gives a specific verb (ping) and target (the WebSocket connection) plus the intent (health check). It is clearly distinct from get_score/run_qml, though it never explicitly contrasts itself with the sibling connect_to_musescore, which is the nearest ambiguity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the diagnostic use case and even prescribes remediation when versionsMatch is false, which is real guidance. However it never says when NOT to use it — notably whether connect_to_musescore should be called first when no connection exists — so the agent must infer the ordering.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

processSequenceC

Process a sequence of documented plugin actions.

Each entry is {action, params}; the available actions, their parameters and return shapes are specified in docs/ACTIONS.md. Sequences may nest one level (a processSequence action inside a sequence); edit actions are wrapped and rolled back per action.

NameRequiredDescriptionDefault
sequenceYes

Output Schema

NameRequiredDescription
resultYes

TDQS

C2.7/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With zero annotations, the description carries the full behavioral burden and only partially meets it. It usefully discloses two traits: nesting is permitted exactly one level, and edit actions are wrapped and rolled back per action — but it does not say whether a failing action aborts the whole sequence, whether successful earlier actions persist, whether the call is idempotent, or what authorization/session state is required.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences with the envelope shape and the two key behavioral rules front-loaded, no filler. It loses a point because the second sentence outsources essential information to an external document rather than earning its place with self-contained content.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

This is a high-complexity tool — 35 action variants, one required parameter, no annotations — and the description is far too thin for it. An output schema exists so return shapes needn't be explained, but the reliance on an out-of-band markdown file leaves an agent unable to determine action semantics, error/rollback boundaries, or cursor-state effects from the definition alone.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters2/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%: 35 action variants are enumerated structurally with const discriminators and required fields, but none of the fields are described anywhere. The description only restates the {action, params} envelope and delegates all meaning (pitch, advanceCursorAfterAction, ratio, harmonyType) to docs/ACTIONS.md, so it adds almost nothing beyond the schema's structure.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: processing a sequence of plugin actions, with each entry shaped as {action, params}. This clearly distinguishes it from the single-purpose siblings (ping_musescore, get_score, run_qml) by signaling batched execution, though 'process' is generic enough that the domain (score editing) must be inferred from the action names.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to choose a sequence over calling individual tools, no preconditions (must a score be connected first?), and no exclusions. The only routing information is a pointer to docs/ACTIONS.md, which is an external artifact the agent may not have access to, so it cannot be relied upon as actionable guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_qmlA

Execute QML/JavaScript code inside the MuseScore plugin and return its result.

For complex score tasks that would otherwise need many round trips. The code is a function body, run as function(ctx, params, state):

  • ctx: plugin API facade - ctx.score (current Score), ctx.newCursor(), ctx.processCommand({action, params}), ctx.processElement(element), ctx.getScoreSummary(), ctx.getVoices(params), ctx.log(msg)

  • params: the params object of this call (yours to shape)

  • state: object persisting across run_qml calls (for multi-step work; mutate it, do not reassign it) The return value must be JSON-serializable (checked before commit). Undo-aware engraving changes in a run form one undo step; errors roll them back, including nested ctx actions. Playback/mixer actions, undo and recursive eval are rejected inside a run. Raw native writes bypassing MuseScore's undo stack (such as setMetaTag) are outside this guarantee. Call get_score before and after a run when you want your own before/after comparison - the server itself keeps no state. The code runs on MuseScore's GUI thread - an infinite loop freezes MuseScore unrecoverably. See docs/AGENT-COOKBOOK.md for patterns and known pitfalls. Requires the plugin property allowEval: true; otherwise returns an error explaining how to enable it.

NameRequiredDescriptionDefault
codeYes
paramsNo

Output Schema

NameRequiredDescription
resultYes

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations supplied, the description carries the full burden and does so thoroughly: undo-step grouping and rollback on error (including nested ctx actions), the setMetaTag/native-write exception, GUI-thread freeze risk from infinite loops, JSON-serializability check before commit, and the allowEval: true prerequisite with its error behavior. It also discloses that the server keeps no state, which is critical for multi-call reasoning.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads purpose and the rest is organized with bullets that map to the mental model an agent needs (ctx/params/state, persistence, constraints). It is dense but nearly every line carries operational consequence; the known-pitfalls doc pointer is the one piece that delegates rather than informs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a high-risk eval tool with two parameters, an output schema covering the return value, and no annotations, the description supplies the missing safety envelope, state semantics, and failure modes. Nothing an agent needs in order to call it correctly, or to avoid freezing MuseScore, is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 0%, so the description must compensate, and it does: it explains that code is a function body invoked as function(ctx, params, state), enumerates the ctx facade members, clarifies that params is caller-shaped, and warns that state must be mutated rather than reassigned to persist across calls. This adds substantially more meaning than the two bare schema properties provide.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

"Execute QML/JavaScript code inside the MuseScore plugin and return its result" names a specific verb (execute), a specific resource (QML/JavaScript code in the plugin), and the outcome (returns result). It is unmistakable against siblings like get_score, ping_musescore, and get_cursor_info, which read state rather than running arbitrary code.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"For complex score tasks that would otherwise need many round trips" gives explicit when-to-use guidance that routes the agent away from piecemeal sibling calls. It also states what is rejected inside a run (playback/mixer actions, undo, recursive eval) and points to get_score before/after for comparisons. It does not explicitly name the sibling tools to use instead for simple tasks, so it stops short of full when-not routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

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

  1. 7 tool updatesv1.0.1
    • First observedconnect_to_musescore
    • First observedget_cursor_info
    • First observedget_score
    • First observedget_score_metadata
    • First observedping_musescore
    • First observedprocessSequence
    • First observedrun_qml

TDQS

B3.4/5.0

Scored across 7 tools

Disambiguation3/5

The read tools have a clear subset relationship (get_score_metadata is a lighter get_score) and connect/ping are distinguishable, but two generic escape hatches exist: processSequence runs documented actions while run_qml runs arbitrary code that can itself call ctx.processCommand, so their boundary is fuzzy. Descriptions help, but an agent must reason about which execution path to pick.

Naming Consistency4/5

Six of seven tools follow a consistent snake_case verb_noun pattern (connect_to_musescore, get_score, get_cursor_info, run_qml, etc.). processSequence is the sole camelCase outlier, a minor but noticeable deviation from an otherwise predictable convention.

Tool Count4/5

Seven tools is well within the sweet spot and the set is logically grouped (connection, reads, execution). The one arguable redundancy is get_score_metadata, whose output is already contained in get_score, so not every tool strictly earns its place.

Completeness4/5

Connection, health/version check, full and partial score reads, cursor/selection state, batched action sequencing, and arbitrary scripting give broad lifecycle coverage, including edits and rollback. Gaps are minor: no explicit disconnect/close tool and no tool to enumerate available actions (agents must consult docs/ACTIONS.md externally).

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol server that provides programmatic control over MuseScore through a WebSocket-based plugin system, allowing AI assistants to compose music, add lyrics, navigate scores, and control MuseScore directly.
    137
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    An AI composition partner that remote-controls Steinberg Dorico through the Model Context Protocol, enabling composers to create, edit, play back, and refine musical scores using natural language.
    30
    3
    AGPL 3.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to connect to Ableton Live, inspect the arrangement, compose and edit MIDI, manage tracks/scenes/clips, insert and tweak devices, and control the mixer.
    MIT