{"name":"io.github.adewale/keyboardia","slug":"adewale-keyboardia","title":"Keyboardia","description":"Create, co-edit, analyze, publish, and export collaborative step-sequencer sessions through MCP.","url":"https://mcp.market/server/adewale-keyboardia","rating":null,"grade":"B","score":81,"certified":false,"status":"active","category":"other","tags":[],"presence":{"score":29,"stars":3,"forks":0,"downloads_week":null,"last_push_at":"2026-09-23T23:41:44.000Z","license":"MIT"},"uptime":{"percent":100,"checks":28,"ok":28,"last_checked_at":"2026-11-04T05:40:30.177Z","last_ok_at":"2026-11-04T05:40:30.177Z","latency_ms":235},"claimed":false,"transport":"remote","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/adewale/keyboardia","website":"https://keyboardia.dev/","version":"1.1.0","remotes":[{"type":"streamable-http","url":"https://keyboardia.dev/mcp"}],"packages":[],"tools":[{"name":"analyze_session","description":"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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","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."}},"required":["session_id"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"create_session","description":"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.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"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."},"name":{"type":"string","minLength":1,"maxLength":100,"description":"Optional display name for the new session."},"tempo":{"description":"Starting tempo in BPM. Defaults to Keyboardia's own default.","type":"number","minimum":60,"maximum":180}},"required":["idempotency_key"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"edit_session","description":"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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","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."},"edit":{"oneOf":[{"type":"object","properties":{"operation":{"type":"string","const":"add_track"},"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."},"sample_id":{"type":"string","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"],"description":"The canonical Keyboardia instrument ID. Use one of the enumerated values exactly."},"name":{"description":"Optional display name. The instrument name is used when omitted.","type":"string","minLength":1,"maxLength":32}},"required":["operation","track_id","sample_id"],"additionalProperties":false,"description":"Add one track. Retrying the same track_id and definition is a no-op; a conflicting reuse is rejected."},{"type":"object","properties":{"operation":{"type":"string","const":"set_track_instrument"},"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."},"sample_id":{"type":"string","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"],"description":"The canonical Keyboardia instrument ID. Use one of the enumerated values exactly."}},"required":["operation","track_id","sample_id"],"additionalProperties":false,"description":"Replace only an existing track's sound source while preserving its name, pattern, mix, and timing."},{"type":"object","properties":{"operation":{"type":"string","const":"set_track_pan"},"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."},"pan":{"type":"number","minimum":-1,"maximum":1,"description":"Normalized equal-power stereo position: -1 left, 0 center, 1 right."}},"required":["operation","track_id","pan"],"additionalProperties":false,"description":"Set one existing track's normalized stereo position without changing its notes or level."},{"type":"object","properties":{"operation":{"type":"string","const":"set_steps"},"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."},"changes":{"minItems":1,"maxItems":128,"type":"array","items":{"type":"object","properties":{"step":{"type":"integer","minimum":0,"maximum":127,"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."}},"required":["step","value"],"additionalProperties":false},"description":"Assignments for named steps only. Every unmentioned step is preserved."}},"required":["operation","track_id","changes"],"additionalProperties":false,"description":"Change only the listed steps on an existing track. Read get_session first to obtain its track_id and step_count."},{"type":"object","properties":{"operation":{"type":"string","const":"set_tempo"},"tempo":{"type":"number","minimum":60,"maximum":180,"description":"Session tempo in beats per minute (60-180)."}},"required":["operation","tempo"],"additionalProperties":false,"description":"Set the session-wide tempo without changing any track."}],"description":"Exactly one narrow session edit."}},"required":["session_id","edit"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false,"description":"The target session and one retry-safe edit to apply."}},{"name":"export_midi","description":"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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","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."}},"required":["session_id"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"get_session","description":"Read the current tempo and compact track patterns from an existing Keyboardia session.","write_action":false,"price_micros":0,"input_schema":{"type":"object","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."}},"required":["session_id"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"publish_session","description":"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.","write_action":true,"price_micros":0,"input_schema":{"type":"object","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."}},"required":["session_id"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}},{"name":"remix_session","description":"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.","write_action":false,"price_micros":0,"input_schema":{"type":"object","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."}},"required":["session_id"],"$schema":"https://json-schema.org/draft/2020-12/schema","additionalProperties":false}}],"scan":{"score":81,"grade":"B","scanned_at":"2026-09-24T12:03:39.039Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-24T12:03:38.925Z","components":{"code":{"score":-1,"max":25,"notes":["remote-only server, no package to scan"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 741ms"]},"poisoning":{"score":15,"max":15,"notes":["7 tool descriptions checked"]},"auth":{"score":3,"max":15,"notes":["open endpoint exposes 2 write-action tools with no auth"]},"maintenance":{"score":15,"max":15,"notes":["last push 1 days ago"]},"identity":{"score":8,"max":10,"notes":["registry namespace matches repository owner","GitHub account older than a year"]}},"findings":[{"id":"auth.open-write","severity":"high","component":"auth","title":"Write-action tools reachable without authentication"}],"inputs":{"probes":[{"url":"https://keyboardia.dev/mcp","reachable":true,"authRequired":false,"latencyMs":741,"serverInfo":{"name":"keyboardia","version":"1.1.0"}}],"packages":[],"repo":{"found":true,"owner":"adewale","repo":"keyboardia","archived":false,"pushedAt":"2026-09-23T23:41:44Z","stars":3,"forks":0,"openIssues":13,"ownerType":"User","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/43644?v=4","ownerCreatedAt":"2009-01-01T18:15:32Z","license":"MIT"},"icon":{"url":"https://keyboardia.dev/keyboardia.svg","source":"site"},"presence":{"stars":3,"forks":0,"downloadsWeek":null,"license":"MIT","lastPushAt":"2026-09-23T23:41:44.000Z","score":29}}}},"grade_history":[],"reviews":[]}