fcp-midi
Allows composing music semantically by describing musical intent (notes, chords, dynamics, tempo changes) and rendering it into standard MIDI files.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fcp-midiCompose electronic music with sub-bass and arpeggios, save as track.mid"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fcp-midi
MCP server for semantic MIDI composition.
What It Does
fcp-midi lets LLMs compose music by describing musical intent -- notes, chords, dynamics, tempo changes -- and renders it into standard MIDI files. Instead of manipulating raw bytes or MIDI events, the LLM works with operations like note Bass E2 at:1.1 dur:quarter vel:90 and crescendo @track:Lead vel:45-75 @range:3.1-6.4. Built on the FCP framework; a mido.MidiFile is the source of truth throughout, so there's no separate serialization step.
Related MCP server: Vibe Composer MIDI MCP
Quick Example
midi_session('new "Voltage Drop" tempo:140 key:E-minor')
midi([
'note Drums kick at:1.1 dur:eighth vel:100',
'note Bass E2 at:1.1 dur:quarter vel:90',
'chord Pad Em at:1.1 dur:whole vel:70',
'crescendo @track:Lead vel:45-75 @range:3.1-6.4',
'tempo 174 at:11.1',
])
midi_session('save as:./voltage_drop.mid')Available MCP Tools
Tool | Purpose |
| Batch mutations -- notes, chords, tracks, tempo, dynamics, copy/transpose |
| Inspect the composition -- map, tracks, events, piano-roll, instruments, find |
| Lifecycle -- new, open, save, checkpoint, undo, redo |
| Full reference card |
Hero Examples
Plumber's Journey -- Classic game theme faithfully recreated: 4 tracks, 288 notes, 16 seconds, 180 BPM.
Voltage Drop -- A drum-and-bass track with tempo acceleration (140 -> 155 -> 174 BPM), 5 tracks, breakbeats, sub-bass, arpeggios, and a signature DROP section. Also used in the FCP vs raw Python agent battle -- FCP produced 1,674 notes across 12 tracks in 87 seconds, compared to 694 notes from ~689 lines of hand-written Python.
See docs/examples/ for MIDI files and the full writeup.
Installation
Requires Python >= 3.11.
pip install fcp-midiMCP Client Configuration
{
"mcpServers": {
"midi": {
"command": "uv",
"args": ["run", "python", "-m", "fcp_midi"]
}
}
}Architecture
Mido-native — no parallel semantic model between the op handlers and the file format:
MCP Server (fcp-core create_fcp_server + MidiAdapter)
Parses op strings, dispatches to verb handlers, session lifecycle
|
MidiModel (mido.MidiFile is the source of truth)
Op handlers read/write mido messages directly on the tracks;
a NoteIndex gives fast selector lookups. Undo/redo and batch
atomicity are byte snapshots of the file, not event replay.Key features:
Instrument library -- GM instruments by name (
acoustic-grand-piano,synth-bass-1,standard-kit)Soundfont support -- Load custom instrument banks
Beat addressing --
at:1.1(bar 1, beat 1),at:3.2.240(bar 3, beat 2, tick 240)Duration vocabulary --
whole,half,quarter,eighth,sixteenth,tripletDynamics --
crescendo,diminuendoacross rangesCopy/transpose -- Duplicate and shift musical phrases
Development
uv sync
uv run pytest # 620 tests
uv run pytest -m "not slow" # skip stress tests (604 tests, ~0.25s)
uv run ruff check # linting
uv run pyright # type checkingLicense
MIT
Available Tools
4 toolsmidiA
Execute midi operations. Each op string follows: VERB TARGET [key:value ...] Call midi_help for the full reference card.
MUSIC: note TRACK PITCH at:POS dur:DUR [vel:V] [ch:N] chord TRACK SYMBOL at:POS dur:DUR [vel:V] [ch:N] track add|remove NAME [instrument:INST] [program:N] [ch:N] [bank:MSB[.LSB]] cc TRACK CC_NAME VALUE at:POS [ch:N] bend TRACK VALUE at:POS [ch:N] tracker TRACK import at:POS [res:RES] ... tracker end
STATE: mute TRACK solo TRACK program TRACK INSTRUMENT|program:N [at:POS] [bank:MSB[.LSB]]
META: tempo BPM [at:POS] time-sig N/D [at:POS] key-sig KEY-MODE [at:POS] marker TEXT at:POS title TEXT
EDITING: remove SELECTORS move SELECTORS to:POS copy SELECTORS to:POS transpose SELECTORS SEMITONES velocity SELECTORS DELTA quantize SELECTORS grid:DUR modify SELECTORS [pitch:P] [vel:V] [dur:D] [at:POS] [ch:N] repeat SELECTORS [to:POS] count:N crescendo SELECTORS from:VEL to:VEL decrescendo SELECTORS from:VEL to:VEL
SELECTORS: @track:NAME @channel:N @range:M.B-M.B @pitch:PITCH @velocity:N-M @all @recent @recent:N @not:TYPE:VALUE Combine to intersect: @track:Piano @range:1.1-4.4
POSITION: M.B (1.1 = start) M.B.T (tick offset) tick:N +DUR -DUR end
DURATION: whole, half, quarter, eighth, sixteenth, 32nd 1n, 2n, 4n, 8n, 16n, 32n dotted-quarter, triplet-eighth, ticks:N
PITCH: C4, D#5, Bb3 (note+accidental+octave) midi:60 (raw MIDI number)
CHORDS: Cmaj, Am, Dm7, G7, Bdim, Faug, Csus4, Asus2 Cmaj7, Am7, Dm7b5, G9, Cm6, Cadd9, Dm/F (slash)
VELOCITY: 0-127 (numeric) ppp, pp, p, mp, mf, f, ff, fff (dynamic names)
CC NAMES: volume, pan, modulation, expression, sustain, reverb, chorus, brightness, portamento, breath
GM INSTRUMENTS (EXAMPLES): acoustic-grand-piano, electric-piano-1, vibraphone acoustic-guitar-nylon, electric-bass-finger, violin trumpet, alto-sax, flute, string-ensemble-1 program:N (raw 0-127) bank:MSB[.LSB]
RESPONSE PREFIXES:
note/chord added ~ event modified
track modified - event removed ! meta event @ bulk operation
CONVENTIONS:
Positions are 1-based: measure 1, beat 1 = 1.1
Channels are 1-indexed user-facing (ch:1 through ch:16)
Channel 10 is drums (GM standard)
Track names are unique identifiers
Batch multiple ops in one call for efficiency
Call midi_help after context truncation for full reference
| Name | Required | Description | Default |
|---|---|---|---|
| ops | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure. It does well by documenting response prefixes, 1-based positions, 1-indexed channels, and GM conventions. It stops short of explaining failure modes, transactionality of batched ops, or persistence behavior, which are relevant for an execution tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but meticulously organized into labeled sections (MUSIC, STATE, META, EDITING, SELECTORS, etc.) with a monospaced format for readability. The front-loaded instruction 'Each op string follows: VERB TARGET [key:value ...]' and the pointer to midi_help ensure efficiency. Every section provides essential syntax for a complex DSL, so no space is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity, the absence of an output schema, and zero annotations, this description is remarkably complete. It covers all major operation types, selectors, notational conventions, and response prefixes. It also references midi_help for deeper coverage, making it sufficient for correct tool invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has a single undocumented parameter 'ops' (an array of strings), and the description fully compensates by defining the exact op syntax, selectors, positions, durations, pitches, chords, velocities, and more. This is a comprehensive semantic specification that makes parameter usage unambiguous.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'Execute midi operations,' a clear verb+resource statement that identifies the tool's core purpose. It also differentiates from midi_help by instructing users to call it for the full reference card. However, it does not explicitly contrast with midi_query or midi_session, so it doesn't fully distinguish among all sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description offers some usage guidance, such as batching multiple ops for efficiency and calling midi_help when context is truncated. However, it does not explicitly state when to use this tool instead of midi_query or midi_session, and the guidance is mostly implied through the operation list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
midi_helpA
Returns the midi reference card with all syntax.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral transparency. It only states that a reference card is returned, without detailing the format, whether it is read-only, or any other operational aspects. For a help tool this is minimal but lacks depth.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single 8-word sentence with no extraneous detail, front-loading the key action and outcome.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter help tool with no output schema, the description sufficiently explains the return value (the reference card) and its scope (all syntax). It lacks some specifics about the card's content, but overall is complete for its simplicity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters and the schema covers 100% of the interface, so description-level parameter semantics are unnecessary. Baseline score of 4 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a reference card for MIDI syntax, using the specific verb 'Returns' and a concrete resource. This differentiates it from siblings like midi_query or midi_session.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies this tool is used to obtain reference information, but it does not explicitly state when to use it or provide alternatives. There is no mention of situations where other sibling tools would be more appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
midi_queryD
Query midi state.
| Name | Required | Description | Default |
|---|---|---|---|
| q | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden for behavioral disclosure. 'Query' implies a read operation, but there is no explicit mention of safety, side effects, permissions, or output behavior, making the tool behaviorally opaque.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single short sentence, which is concise, but it is under-specified rather than efficiently informative. It lacks essential details and does not earn its brevity, similar to the 'Process' example where minimalism harms usability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the lack of annotations, an opaque parameter, no output schema, and no usage context, the description is grossly incomplete. The agent has no information about query syntax, return values, or operational constraints, making the tool nearly unusable for reliable invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema only defines a required string 'q' with 0% description coverage. The description adds no meaning for the parameter—it does not explain what 'q' should contain, the query syntax, or expected format. The parameter is completely underdocumented.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Query midi state' provides a verb and a resource, but 'midi state' is vague and does not specify what aspect of MIDI state is being queried. It does not distinguish itself from sibling tools like 'midi' or 'midi_session', and the purpose remains ambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given for when to use this tool versus alternatives. The description does not mention any context, prerequisites, or comparisons to sibling tools, leaving the agent without direction for tool selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
midi_sessionC
Session: 'new "Title"', 'open ./file', 'save', 'checkpoint v1', 'undo', 'redo'
| Name | Required | Description | Default |
|---|---|---|---|
| action | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full responsibility for behavioral disclosure. It lists commands like 'undo' and 'redo' which imply state changes, but it does not explain side effects, persistence semantics, error behavior, or any side effects beyond naming the actions. The behavior is largely opaque.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short and to the point, listing commands in a compact format. It is front-loaded with 'Session:' which sets the context. The structure is somewhat unstructured as a free-form string, but it contains no fluff and every word contributes to the set of examples.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having only one parameter and no output schema, the description is still too minimal. It does not explain what the tool returns, whether commands are executed sequentially, what 'checkpoint' does, or what constitutes valid input. For a session management tool, the description lacks essential operational context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single 'action' parameter has no schema description and no enum, but the description partially compensates by providing concrete example values (e.g., 'new "Title"', 'open ./file'). This gives the agent some sense of expected syntax, though the format is ambiguous (mixing quotes, spaces, and version strings) and not all actions are equally explained.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description implies session management through a list of example commands ('new', 'open', 'save', etc.), but it never explicitly states the tool's purpose as a verb+resource (e.g., 'Manage MIDI sessions'). It is more of a usage hint than a clear functional definition, and it does not explicitly distinguish itself from sibling tools like 'midi' or 'midi_query'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The sibling tools are not mentioned, and there is no description of scenarios suitable for session operations. The examples imply actions, but no context or exclusion criteria are given.
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. Dates show when Glama detected each change.
4 tool updates
v0.2.0- First observed
midi - First observed
midi_help - First observed
midi_query - First observed
midi_session
TDQS
Each tool has a clearly distinct role: midi for editing/creating music, midi_query for reading state, midi_session for session/file management, and midi_help for documentation. There is no overlap in their primary purposes.
All tools follow a consistent 'midi[_suffix]' pattern using snake_case. The base 'midi' denotes the core operation, while suffixes like '_query', '_session', and '_help' clearly indicate auxiliary functions. This is a predictable and uniform convention.
With exactly 4 tools, the set is well-scoped and right-sized. The main tool centralizes a rich DSL for MIDI operations, while the supporting tools handle query, session, and help functions. No redundancy or excessive splitting.
The tool set provides full lifecycle coverage for MIDI work: creating/editing via midi, reading state via midi_query, session control (new/open/save/undo/redo) via midi_session, and reference via midi_help. There are no obvious missing operations within the domain.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Turn any LLM multimodal; generate images, voices, videos, 3D models, music, and more.
Deterministic music theory for agents: analyze, voice, reharmonize, conduct — computed, not guessed
Generate AI music via the Lacuna Music API from MCP clients like Claude Desktop & Code.
Image, video, music and text generation across 100+ models through one endpoint.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA MIDI composition system that enables AI assistants to create music through FluidSynth, with capabilities for playing notes, creating melodies, managing tracks, and exporting audio.1-
- AlicenseCqualityDmaintenanceEnables LLMs to compose and play multi-track MIDI music through natural language prompts. Supports outputting to software or hardware synthesizers for enhanced audio quality.22424MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI-assisted music composition through copyable pattern templates, style constraints, and arrangement tools that compile to MIDI files. Provides 30+ tools for managing musical structures, layers, patterns, and styles with deterministic compilation from YAML arrangements.1MIT
- AlicenseAqualityFmaintenanceEnables AI-driven MIDI composition with chord name support, interactive piano-roll preview, and multiple deployment modes.251MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/os-tack/fcp-midi'
If you have feedback or need assistance with the MCP directory API, please join our Discord server