MCP 服务器

Keyboardia

io.github.adewale/keyboardia
媒体与内容 生产力 公开且可连接 MCP 2025-11-25

此 MCP 可以做什么

Creates and edits collaborative step-sequencer music sessions, analyzes musical content, publishes or remixes sessions, and exports MIDI.

analyze_session
Analyze Keyboardia session
Describe what is happening musically in a session — rhythm, pitch content, inferred key, and chords — without changing anything. Use this to explain music rather than to edit it. Results come from the same music-theory module the browser's Key Assistant and Chromatic Grid use, and report where the analysis is uncertain instead of guessing.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['session_id'], 'properties': {'session_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The UUID after /s/ in a Keyboardia share URL. Pass only the UUID, not the full URL.'}}, 'additionalProperties': False}
create_session
Create Keyboardia session
Create a new editable Keyboardia session with the normal defaults and return its shareable URL. The session starts with no tracks; use edit_session to add them. Pass the same idempotency_key when retrying so an uncertain attempt cannot leave duplicate sessions behind.
幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['idempotency_key'], 'properties': {'name': {'type': 'string', 'maxLength': 100, 'minLength': 1, 'description': 'Optional display name for the new session.'}, 'tempo': {'type': 'number', 'maximum': 180, 'minimum': 60, 'description': "Starting tempo in BPM. Defaults to Keyboardia's own default."}, 'idempotency_key': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'A UUID you generate for this creation attempt. Reusing it returns the session the first attempt created instead of making another one.'}}, 'additionalProperties': False}
edit_session
Edit Keyboardia session
Make one narrow, retry-safe edit to an existing collaborative session. After every attempt, the next Keyboardia call must be get_session for the same session. A successful call includes a backwards-compatible compact snapshot plus an acknowledgement. That snapshot is not authoritative verification; do not make another edit or finish from it. Read with get_session next. Supported operations: add_track, set_track_instrument, set_track_pan, set_steps, and set_tempo. set_steps changes only the named steps; it never replaces a track or session. set_track_instrument replaces only a track's sound source, keeping its pattern, mix, timing, and custom name.
可能执行破坏性操作 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['session_id', 'edit'], 'properties': {'edit': {'oneOf': [{'type': 'object', 'required': ['operation', 'track_id', 'sample_id'], 'properties': {'name': {'type': 'string', 'maxLength': 32, 'minLength': 1, 'description': 'Optional display name. The instrument name is used when omitted.'}, 'track_id': {'type': 'string', 'pattern': '^(?=.{10,64}$)[A-Za-z0-9][A-Za-z0-9._-]*-[0-9a-fA-F]{8,32}$', 'description': 'Generate a fresh collision-resistant ID that ends with at least eight hexadecimal characters, such as agent-kick-a7f3c29d. Generate it once and reuse it on retries.'}, 'operation': {'type': 'string', 'const': 'add_track'}, 'sample_id': {'enum': ['advanced:acid-bass', 'advanced:sub-bass', 'advanced:supersaw', 'advanced:thick-lead', 'advanced:tremolo-strings', 'advanced:vibrato-lead', 'advanced:warm-pad', 'advanced:wobble-bass', 'bass', 'cabasa', 'chord', 'clap', 'clave', 'conga', 'cowbell', 'hihat', 'kick', 'lead', 'noise', 'openhat', 'pad', 'pluck', 'rim', 'sampled:808-clap', 'sampled:808-hihat-closed', 'sampled:808-hihat-open', 'sampled:808-kick', 'sampled:808-snare', 'sampled:acoustic-crash', 'sampled:acoustic-guitar', 'sampled:acoustic-hihat-closed', 'sampled:acoustic-hihat-open', 'sampled:acoustic-kick', 'sampled:acoustic-ride', 'sampled:acoustic-snare', 'sampled:alto-sax', 'sampled:brushes-snare', 'sampled:clean-guitar', 'sampled:finger-bass', 'sampled:french-horn', 'sampled:hammond-organ', 'sampled:kalimba', 'sampled:marimba', 'sampled:piano', 'sampled:slap-bass', 'sampled:steel-drums', 'sampled:string-section', 'sampled:vibraphone', 'sampled:vinyl-crackle', 'shaker', 'snare', 'subbass', 'synth:acid', 'synth:bass', 'synth:bell', 'synth:brass', 'synth:clavinet', 'synth:discobass', 'synth:dreampop', 'synth:epiano', 'synth:evolving', 'synth:funkbass', 'synth:glass', 'synth:growl', 'synth:hoover', 'synth:hypersaw', 'synth:jangle', 'synth:lead', 'synth:organ', 'synth:organphase', 'synth:pad', 'synth:pluck', 'synth:reese', 'synth:rhodes', 'synth:shimmer', 'synth:stab', 'synth:strings', 'synth:sub', 'synth:supersaw', 'synth:sweep', 'synth:vibes', 'synth:warmpad', 'synth:wobble', 'synth:wurlitzer', 'tambourine', 'tom', 'tone:am-bell', 'tone:am-tremolo', 'tone:duo-lead', 'tone:fm-bass', 'tone:fm-bell', 'tone:fm-epiano', 'tone:membrane-kick', 'tone:membrane-tom', 'tone:metal-cymbal', 'tone:metal-hihat', 'tone:pluck-string', 'woodblock', 'zap'], 'type': 'string', 'description': 'The canonical Keyboardia instrument ID. Use one of the enumerated values exactly.'}}, 'description': 'Add one track. Retrying the same track_id and definition is a no-op; a conflicting reuse is rejected.', 'additionalProperties': False}, {'type': 'object', 'required': ['operation', 'track_id', 'sample_id'], 'properties': {'track_id': {'type': 'string', 'pattern': '^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$', 'description': 'For add_track, choose a stable unique ID and reuse it on retries. For set_steps, set_track_instrument, or set_track_pan, copy an existing track_id from get_session.'}, 'operation': {'type': 'string', 'const': 'set_track_instrument'}, 'sample_id': {'enum': ['advanced:acid-bass', 'advanced:sub-bass', 'advanced:supersaw', 'advanced:thick-lead', 'advanced:tremolo-strings', 'advanced:vibrato-lead', 'advanced:warm-pad', 'advanced:wobble-bass', 'bass', 'cabasa', 'chord', 'clap', 'clave', 'conga', 'cowbell', 'hihat', 'kick', 'lead', 'noise', 'openhat', 'pad', 'pluck', 'rim', 'sampled:808-clap', 'sampled:808-hihat-closed', 'sampled:808-hihat-open', 'sampled:808-kick', 'sampled:808-snare', 'sampled:acoustic-crash', 'sampled:acoustic-guitar', 'sampled:acoustic-hihat-closed', 'sampled:acoustic-hihat-open', 'sampled:acoustic-kick', 'sampled:acoustic-ride', 'sampled:acoustic-snare', 'sampled:alto-sax', 'sampled:brushes-snare', 'sampled:clean-guitar', 'sampled:finger-bass', 'sampled:french-horn', 'sampled:hammond-organ', 'sampled:kalimba', 'sampled:marimba', 'sampled:piano', 'sampled:slap-bass', 'sampled:steel-drums', 'sampled:string-section', 'sampled:vibraphone', 'sampled:vinyl-crackle', 'shaker', 'snare', 'subbass', 'synth:acid', 'synth:bass', 'synth:bell', 'synth:brass', 'synth:clavinet', 'synth:discobass', 'synth:dreampop', 'synth:epiano', 'synth:evolving', 'synth:funkbass', 'synth:glass', 'synth:growl', 'synth:hoover', 'synth:hypersaw', 'synth:jangle', 'synth:lead', 'synth:organ', 'synth:organphase', 'synth:pad', 'synth:pluck', 'synth:reese', 'synth:rhodes', 'synth:shimmer', 'synth:stab', 'synth:strings', 'synth:sub', 'synth:supersaw', 'synth:sweep', 'synth:vibes', 'synth:warmpad', 'synth:wobble', 'synth:wurlitzer', 'tambourine', 'tom', 'tone:am-bell', 'tone:am-tremolo', 'tone:duo-lead', 'tone:fm-bass', 'tone:fm-bell', 'tone:fm-epiano', 'tone:membrane-kick', 'tone:membrane-tom', 'tone:metal-cymbal', 'tone:metal-hihat', 'tone:pluck-string', 'woodblock', 'zap'], 'type': 'string', 'description': 'The canonical Keyboardia instrument ID. Use one of the enumerated values exactly.'}}, 'description': "Replace only an existing track's sound source while preserving its name, pattern, mix, and timing.", 'additionalProperties': False}, {'type': 'object', 'required': ['operation', 'track_id', 'pan'], 'properties': {'pan': {'type': 'number', 'maximum': 1, 'minimum': -1, 'description': 'Normalized equal-power stereo position: -1 left, 0 center, 1 right.'}, 'track_id': {'type': 'string', 'pattern': '^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$', 'description': 'For add_track, choose a stable unique ID and reuse it on retries. For set_steps, set_track_instrument, or set_track_pan, copy an existing track_id from get_session.'}, 'operation': {'type': 'string', 'const': 'set_track_pan'}}, 'description': "Set one existing track's normalized stereo position without changing its notes or level.", 'additionalProperties': False}, {'type': 'object', 'required': ['operation', 'track_id', 'changes'], 'properties': {'changes': {'type': 'array', 'items': {'type': 'object', 'required': ['step', 'value'], 'properties': {'step': {'type': 'integer', 'maximum': 127, 'minimum': 0, 'description': "Zero-based step index. It must be within this track's current step_count."}, 'value': {'type': 'boolean', 'description': 'true activates the step; false clears it.'}}, 'additionalProperties': False}, 'maxItems': 128, 'minItems': 1, 'description': 'Assignments for named steps only. Every unmentioned step is preserved.'}, 'track_id': {'type': 'string', 'pattern': '^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$', 'description': 'For add_track, choose a stable unique ID and reuse it on retries. For set_steps, set_track_instrument, or set_track_pan, copy an existing track_id from get_session.'}, 'operation': {'type': 'string', 'const': 'set_steps'}}, 'description': 'Change only the listed steps on an existing track. Read get_session first to obtain its track_id and step_count.', 'additionalProperties': False}, {'type': 'object', 'required': ['operation', 'tempo'], 'properties': {'tempo': {'type': 'number', 'maximum': 180, 'minimum': 60, 'description': 'Session tempo in beats per minute (60-180).'}, 'operation': {'type': 'string', 'const': 'set_tempo'}}, 'description': 'Set the session-wide tempo without changing any track.', 'additionalProperties': False}], 'description': 'Exactly one narrow session edit.'}, 'session_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The UUID after /s/ in a Keyboardia share URL. Pass only the UUID, not the full URL.'}}, 'description': 'The target session and one retry-safe edit to apply.', 'additionalProperties': False}
export_midi
Export Keyboardia session as MIDI
Export the session as a base64-encoded Standard MIDI File, matching what Keyboardia's own Export MIDI produces for the same music. The session is not modified. The result lists any session features a MIDI file cannot carry rather than approximating them silently.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['session_id'], 'properties': {'session_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The UUID after /s/ in a Keyboardia share URL. Pass only the UUID, not the full URL.'}}, 'additionalProperties': False}
get_session
Get Keyboardia session
Read the current tempo and compact track patterns from an existing Keyboardia session.
只读 幂等
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['session_id'], 'properties': {'session_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The UUID after /s/ in a Keyboardia share URL. Pass only the UUID, not the full URL.'}}, 'additionalProperties': False}
publish_session
Publish Keyboardia session
Freeze the current music into a new immutable session and return its URL. The source session stays editable at its own URL. Only call this when someone explicitly asks to publish; it is never a side effect of editing or exporting.
可访问外部资源
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['session_id'], 'properties': {'session_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The UUID after /s/ in a Keyboardia share URL. Pass only the UUID, not the full URL.'}}, 'additionalProperties': False}
remix_session
Remix Keyboardia session
Copy an existing session — published or editable — into a new editable session that records the original as its source. The source is never modified, so this is how to continue from published work.
输入模式
{'type': 'object', '$schema': 'https://json-schema.org/draft/2020-12/schema', 'required': ['session_id'], 'properties': {'session_id': {'type': 'string', 'format': 'uuid', 'pattern': '^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$', 'description': 'The UUID after /s/ in a Keyboardia share URL. Pass only the UUID, not the full URL.'}}, 'additionalProperties': False}
已添加
analyze_session
2026年9月17日 12:40
已添加
export_midi
2026年9月17日 12:40
已添加
publish_session
2026年9月17日 12:40
已添加
remix_session
2026年9月17日 12:40
已添加
create_session
2026年9月17日 12:40
已添加
edit_session
2026年9月17日 12:40
已添加
get_session
2026年9月17日 12:40