io.github.konni-arcadia/moontide
NPM · MOONTIDE-MCP
Claude steers live music by writing Strudel code played in a browser page
Available components
Last scanned (20 hours ago)
Scores higher than 90% of npm servers
Category Entertainment and Games
How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. How we score → Why this is hard to score →
Supply Chain Security81
- No malware found by supply-chain analysis.Pass
- CVE check failed: a known high-severity CVE affects zod 4.6.5, a direct dependency. A fixed version is available. View diagnostics → Fail
- No install/post-install scripts declared.Pass
- 30 of 94 dependencies flagged as unhealthy. View diagnostics → Partial
Provenance & Transparency100
- Source repository is publicly reachable at the declared URL. View diagnostics → Pass
- Cryptographically verified build provenance (signed, bound to konni-arcadia/moontide). View diagnostics → Pass
- Clear OSI-approved license (AGPL-3.0-or-later).Pass
- Actively maintained (last published 17 days ago).Pass
- Publishes a security disclosure policy (SECURITY.md).Pass
Schema Quality & AI Usability79
- 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
- AI-judged instruction clarity (excellent).Pass
- Context-footprint check failed: tool/resource definitions use about 4869 tokens (~194/item across 25 items; 15 tools + 10 resources), over budget; trim descriptions and params. See how to fix → Fail
- Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management70
- Stability observed for 21 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
- 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
- 100% of tool parameters carry a description.Pass
Tool Safety100
- No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
- We read all 15 captured tool definition(s), and no name or description among them implies an irreversible operation.Pass
- An AI judge read all 17 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
- Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.
- 3 Nov 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 63 to 67. That category is still filling its 30-day observation window: 19 days of observed history at the previous scan, 20 at this one. The score rises as the window fills, whether or not the server changes.
- 31 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 53 to 57. That category is still filling its 30-day observation window: 16 days of observed history at the previous scan, 17 at this one. The score rises as the window fills, whether or not the server changes.
- 29 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 47 to 50. That category is still filling its 30-day observation window: 14 days of observed history at the previous scan, 15 at this one. The score rises as the window fills, whether or not the server changes.
- 27 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 40 to 43. That category is still filling its 30-day observation window: 12 days of observed history at the previous scan, 13 at this one. The score rises as the window fills, whether or not the server changes.
- 25 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 33 to 37. That category is still filling its 30-day observation window: 10 days of observed history at the previous scan, 11 at this one. The score rises as the window fills, whether or not the server changes.
- 24 Oct 26 −5
- CVE-2023-54404 affects this package: high ▼ security
- Known CVEs: pass → fail ▼ security
- 23 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 27 to 30. That category is still filling its 30-day observation window: 8 days of observed history at the previous scan, 9 at this one. The score rises as the window fills, whether or not the server changes.
- 21 Oct 26 +1
No change was recorded against any check on this day. Stability & Change Management went from 20 to 23. That category is still filling its 30-day observation window: 6 days of observed history at the previous scan, 7 at this one. The score rises as the window fills, whether or not the server changes.
Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.
Captured 4 Nov 2026 · Analysed npm/moontide-mcp@2.2.0
Provenance Verified
A signed build attestation was found and verified, binding this exact artifact to the source repository it claims to come from.
| Result | Verified |
|---|---|
| Ecosystem | npm |
| Reason | Verified |
| Discovered via | Registry attestation endpoint |
| Source repo | konni-arcadia/moontide |
| Certificate issuer | https://token.actions.githubusercontent.com |
| Certificate SAN | https://github.com/konni-arcadia/moontide/.github/workflows/release.yml@refs/tags/v2.2.0 |
| Rekor log index | 3296321816 |
| Predicate type | SLSA build provenance https://slsa.dev/provenance/v1 |
| Subject digest | sha512:882a198680e9d290c0af05431b4af1f52fb6637fafb97f85c6f7e9ac960579b5cbf0c60cba62ae5c5c58291b20cafdd958c93edd1f38bdfa1a5b896d2 |
Background: How many MCP packages publish verified provenance →
Vulnerabilities 1 finding
| ID | CVE | Severity | Vector | Fix available |
|---|---|---|---|---|
| GHSA-mrhx-c7xc-m3w5 | CVE-2023-54404 | high | CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H | yes |
Background: What a vulnerability scan can and cannot prove →
Dependencies 94 packages
| Packages resolved | 94 |
|---|---|
| Stale | 30 |
| Tree resolution | Complete |
Background: SBOMs and build attestations, explained →
The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →
answer_request ~169
Closes a request typed in the Moontide page without changing the music. Use outcome answered when the request was answered in words, declined when it will not or cannot be done. Give one sentence of at most 200 characters; the page shows it under the request. A change that answers a request names it with answering on set_code, edit_code or restore_version instead. An id that is not an open request is refused and nothing changes.
| Name | Type | Req | Description |
|---|---|---|---|
| id | string | yes | The id of the page request to close, from its request line |
| outcome | string | yes | answered when the request was answered in words, declined when it will not or cannot be done |
| text | string | yes | One sentence for the user, at most 200 characters; the page shows it under the request |
No output schema declared.
No examples provided.
edit_code ~648
Changes part of the code that will play by exact text replacement, sending only the change. Use it to change an existing piece; use set_code for a new piece or a rewrite of most of its lines. Each edit has old_string, new_string and optional replace_all, as in your own Edit tool. Every old_string must match exactly once (or set replace_all), and every edit is matched against the code as it is before this call, so edits must not overlap and one edit cannot match text another edit writes. An edit that matches nowhere, matches more than once, overlaps another edit or changes nothing refuses the whole call with the reason and the edit number: nothing is applied and nothing reaches the page. CRLF counts as LF. The edits apply to the newest code that will play: the change waiting for its bar or phrase line when one waits (get_code shows the code playing until then), otherwise the code playing now with the user's evaluated hand edits; text typed in the page but not evaluated is replaced, as with set_code. Pass base, the version number get_code shows, to have the edit refused when the music moved on since. at, phraseCycles and label work as in set_code, and the edited program goes through the same checks, history entry and notices. The reply gives the version, when the change takes over and the changed lines with a few lines around them, not the whole program; get_code returns it. Put all replacements for one change in a single call: a second edit_code sent before the first reply is refused. It edits music that already plays, so before Moontide is started it is refused and starts nothing: use set_code first. Call get_code before changing existing music.
| Name | Type | Req | Description |
|---|---|---|---|
| answering | string | – | The id of the page request this change answers, from its request line; the page shows that request as applied only when the change names it here |
| at | string | – | When the change takes over: 'now' (the default) within a fraction of a second, 'bar' on the next bar line, 'phrase' on the next phrase line (4 cycles, counted from Play). The code is checked at once;… |
| base | integer | – | The version number get_code shows (#N); the edit is refused when another version plays now |
| edits | array | yes | The replacements, 1 to 50, applied all together or not at all |
| glideBars | integer | – | Whole bars, 1 to 64, to move the tempo smoothly from the tempo that plays to the one this code sets with setcps or setcpm; with at, it starts at the line. Refused when nothing plays, no tempo is set… |
| label | string | – | A few words saying what this change is, for example "added a bass"; shown by list_history |
| phraseCycles | integer | – | How many cycles one phrase lasts, for at: 'phrase' (2 to 64, default 4) |
No output schema declared.
No examples provided.
favorite_version ~98
Keeps a version as a named favorite, by its id from list_history (the version playing now is the one shown as v{id} in the page top bar). Favorites are never dropped from the history. Favoriting the same id again renames it. List favorites with list_history and favorites: true.
| Name | Type | Req | Description |
|---|---|---|---|
| id | integer | yes | Version id from list_history |
| name | string | yes | Name to keep it under, in the user's words |
No output schema declared.
No examples provided.
get_code ~99
Reads the Strudel code currently playing in the Moontide page, i.e. the last code the page confirmed, including edits the user evaluated by hand; returns 'Nothing is playing yet.' before anything played, with a template of a song structure to start from. Before Moontide is started it says so and starts nothing; after the start its reply also names the page address, the port and the tab title. Call it before every change.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
get_midi_instruments ~287
When the user has described their instruments, call this before writing MIDI code. Lists the MIDI instruments the user described in instruments.json, as facts: for each one its id, model, exact port name, whether it is connected right now, its channels and their roles, how many sounds it has, its bank select, its reset, whether it follows MIDI clock and its controls. Pass instrument (an id from that list) to get that instrument's full sound list, with the program number sent for each sound and its bank when it has one. A sound is chosen in the code with the sound option of .midi(). An instrument with a sound catalog shows how many sounds the catalog holds and its categories; search_midi_sounds finds them. For an instrument with a rhythm channel it says how a kit goes out and which drum map applies; with instrument set it lists each drum map as note numbers and drum names, a kit's own map only when it differs from the model's, and says when a kit has no known map. Drum notes are written as note numbers in the code. It also says which instruments the user switched off in the page: their notes are silent, and .midi() code newly aimed at them is refused until the user switches them on.
| Name | Type | Req | Description |
|---|---|---|---|
| instrument | string | – | An instrument id from instruments.json, to list its sounds |
No output schema declared.
No examples provided.
get_strudel_reference ~131
Returns the Strudel reference for @strudel/repl 1.3.0, the version the Moontide page loads: facts about what exists and how to write it, not what to choose. Topics: tidal-differences, mini-notation, functions, effects, sounds, theory, transitions, structure, midi. Call it without a topic for the index. Strudel is JavaScript, not TidalCycles: read tidal-differences before writing Strudel from Tidal habits.
| Name | Type | Req | Description |
|---|---|---|---|
| topic | string | – | One topic to return; omit it to get the index of topics |
No output schema declared.
No examples provided.
list_history ~182
Lists the versions of the music that played, newest first, one per row: "#id — time (UTC) — origin — \"label\" — first line of code". Ids never change. Rows without "#" mark where a Claude session started. The newest version row is usually what plays now; "the previous version" is the next version row down, "3 changes ago" is three version rows below the newest. Pass limit to see more than 20. Pass filter to find a version by a word from its label, code or favorite name; pass favorites: true to list favorites.
| Name | Type | Req | Description |
|---|---|---|---|
| favorites | boolean | – | true to list only favorites |
| filter | string | – | Only versions whose label, code or favorite name contains this text (case-insensitive) |
| limit | integer | – | How many versions to list, newest first (default 20) |
No output schema declared.
No examples provided.
restore_version ~212
Plays a past version again, by its id from list_history, in one call: it takes over within a fraction of a second without stopping the music, with the same checks as set_code. The restore is added to the history as a new version ("restored from #id"); nothing is rewritten. Returns the code as confirmed by the page. A restore always takes over at once and replaces a change that waits for a bar or phrase line. The old version replaces the music at once; when the user asked for gradual changes this session, bring it in with set_code and a transition instead. Like set_code, it starts Moontide first when it is not started yet, but only for an id that exists in the history.
| Name | Type | Req | Description |
|---|---|---|---|
| answering | string | – | The id of the page request this change answers, from its request line; the page shows that request as applied only when the change names it here |
| id | integer | yes | Version id from list_history, for example 41 for #41 |
No output schema declared.
No examples provided.
save_midi_catalog ~437
Saves a sound catalog that you drafted from a sound list the user gave you (for example the maker's PDF list), into the user's Moontide data folder (catalogs/<model id>.json), never into Moontide itself. The catalog extends the model named by model. Send the sounds grouped as the list prints them, at most 500 per call: the first call starts the draft (source, programNumbering, and overwrite when it replaces a catalog), later calls add parts with append: true, with more: true while parts remain. The last part checks the whole draft and returns a summary that shows three sounds with their program as sent and as numbered from 1, and saves nothing. Show that summary to the user, then call again with model and confirmed: true, and nothing else, only after they say yes. The draft lives only in this session; a restart of the server loses it. For a model whose rhythm channels take a bank, a group of drum kits takes role: rhythm and may give noteMap; its kits are saved in the catalog's kits list.
| Name | Type | Req | Description |
|---|---|---|---|
| append | boolean | – | true to add this part to the draft of the model; absent or false starts a new draft |
| banks | array | – | The sounds of this part, grouped by bank and category; at most 500 sounds in the call |
| confirmed | boolean | – | true only after the user said yes to the summary; send it with model and nothing else |
| model | string | yes | The id of the model the catalog extends: a model Moontide ships or one saved with save_midi_model |
| more | boolean | – | true while more parts remain; absent or false on the last part |
| overwrite | boolean | – | true to replace an existing catalog of the model; read when a draft starts |
| programNumbering | string | – | How the list numbers programs: from-1 when the first program is printed as 1; required when a draft starts |
| source | string | – | The document title and version the list comes from; required when a draft starts |
No output schema declared.
No examples provided.
save_midi_model ~510
Saves an instrument model that you drafted from a page of the instrument's manual the user pasted, into the user's Moontide data folder (models/<id>.json), never into Moontide itself. First call it with confirmed: false: it checks the model and returns a summary (channels, sounds with their program numbers as sent and as numbered in a manual from 1, controls, reset bytes, notes) and saves nothing. Show that summary to the user, and call it again with the same model and confirmed: true only after they say yes. It refuses an id of a model Moontide ships, and an existing model unless overwrite is true. Fields: id (lowercase letters, digits, dashes or underscores, at most 32), name, channels { melodic, rhythm } (lists of channels 1-16), bankSelect (none, msb or msb-lsb), rhythmBank (optional: true when the instrument chooses drum kits by bank select and program change; every rhythm sound then needs a bank), drumMaps (optional, at most 8: [{ id, name, notes: [{ note 0-127, name }] }] typed from the instrument's manual), drumMap (optional: the id of the map of kits without their own; general-midi is built in), a rhythm sound's noteMap (optional: a map id, or null when no map is known for that kit), defaultVolume (0-127), clock (optional: true when the instrument follows MIDI clock, so Moontide sends it the clock, Start and Stop), reset (optional: sysex with at most 4 messages, each { kind: roland-dt1, model, address, data } as hex bytes or { kind: raw, bytes } from F0 to F7 and at most 32 bytes, and waitMs), controls ([{ id, name, cc, min, max, default }]), sounds { melodic, rhythm } ([{ name, program 0-127 as sent, bank { msb, lsb } when the instrument needs one }]) and notes (facts about the instrument, at most 10).
| Name | Type | Req | Description |
|---|---|---|---|
| confirmed | boolean | yes | false to check and summarize without saving; true only after the user said yes to the summary |
| model | object | yes | The drafted model, as a JSON object |
| overwrite | boolean | – | true to replace an existing user model with the same id |
No output schema declared.
No examples provided.
search_midi_sounds ~235
Searches the sound catalog of one instrument: a list of the model's sounds kept in the user's data folder, built from a patch-name file or a sound list the user owns. It finds sounds by words in the name or the category, in any order, with case and spaces ignored. It returns at most 25 matches: the exact name first, then names that start with the words, then names that contain them, then matches in the category only. Each match gives the name as the sound option of .midi() takes it, the program as sent (0-127), the bank when there is one and the category. It says how many more matched. A drum kit is marked (drum kit) and gives its drum map, or says the map is unknown.
| Name | Type | Req | Description |
|---|---|---|---|
| category | string | – | Only sounds of this category; case and spaces do not matter |
| instrument | string | yes | An instrument id from instruments.json whose model has a sound catalog |
| query | string | – | Words to find in the sound name or its category, in any order; case and spaces do not matter |
No output schema declared.
No examples provided.
set_code ~671
Replaces the music in the Moontide page with new Strudel code; the new pattern takes over within a fraction of a second, mid-cycle, without stopping the music. To change part of an existing piece, edit_code sends only the change; set_code is for a new piece or a rewrite of most of its lines. With at: 'bar' or at: 'phrase' the code is checked at once and takes over on the next bar line or the next phrase line instead (a bar is one cycle of 4 beats; a phrase is 4 cycles, or phraseCycles, counted from Play); the reply gives the cycle and about how many seconds, a newer change replaces a waiting one, and Stop cancels it. When the tempo changes, the reply gives it in BPM. Every call runs the whole program again, so a getTime() anchor restarts at each change; a transition that must keep running takes .timeline(id), which keeps its anchor as long as the code keeps the same id (see the transitions topic). Double-quoted and backtick strings are parsed as mini-notation wherever they appear, helpers included, while single-quoted strings stay plain JavaScript (see the tidal-differences topic). When Moontide is not started yet, set_code starts it first: its page opens in a new browser tab and the call waits up to 30 seconds for that page to connect. Before changing existing music, call get_code and build on what it returns, including hand edits. Keep what the user said matters; if a small request needs a full rewrite and the user said what matters, ask first, otherwise rewrite and say so. When a request is vague, act on your own reading of it instead of asking first. Returns the code as confirmed by the page. Pass a short label saying what changed; every version that plays is kept in the history. Then tell the user in one line what you chose: the musical terms, plus a short image in plain words.
| Name | Type | Req | Description |
|---|---|---|---|
| answering | string | – | The id of the page request this change answers, from its request line; the page shows that request as applied only when the change names it here |
| at | string | – | When the change takes over: 'now' (the default) within a fraction of a second, 'bar' on the next bar line, 'phrase' on the next phrase line (4 cycles, counted from Play). The code is checked at once;… |
| code | string | yes | Complete Strudel code to play |
| glideBars | integer | – | Whole bars, 1 to 64, to move the tempo smoothly from the tempo that plays to the one this code sets with setcps or setcpm; with at, it starts at the line. Refused when nothing plays, no tempo is set… |
| label | string | – | A few words saying what this change is, for example "added a bass"; shown by list_history |
| phraseCycles | integer | – | How many cycles one phrase lasts, for at: 'phrase' (2 to 64, default 4) |
No output schema declared.
No examples provided.
set_page_requests ~170
Switches how requests the user types in the Moontide page reach you. State on returns the command to run now with your Monitor tool, so each request arrives as soon as it is sent. State off says how to stop that monitor, after which requests wait on the Moontide server and arrive in the reply of your next other Moontide tool. Call it when the user asks, in any words, to turn page requests on or off, to take requests from the Moontide page right away, or to stop. The page-requests-on and page-requests-off prompts do the same where the client offers MCP prompts.
| Name | Type | Req | Description |
|---|---|---|---|
| state | string | yes | on to receive each page request right away, off to let them wait for the reply of your next other Moontide tool |
No output schema declared.
No examples provided.
start ~154
Starts Moontide: its web server on this computer and its page, which opens in a new browser tab; one click in that tab turns the sound on. Call it when the user asks, in any words, to start or open Moontide, or asks which tab or port is yours. Calling it again is safe: it gives the page address, the port and the tab title, and opens a new tab only when no page is connected. set_code starts Moontide by itself, and so does restore_version for a version that exists, so there is no need to call it before them. edit_code changes music that already plays and starts nothing. The start prompt does the same where the client offers MCP prompts.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
stop ~62
Stops all sound in the Moontide page right away, even when the current code is broken. The code stays in the editor; get_code still returns it, and the next set_code starts playing again. Before Moontide is started it says so and starts nothing.
Input schema present but exposes no named parameters.
No output schema declared.
No examples provided.
How do I install the io.github.konni-arcadia/moontide MCP server?
io.github.konni-arcadia/moontide runs locally as an npm package, launched with npx -y moontide-mcp. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.
npm · moontide-mcp
claude mcp add konni-arcadia-moontide -- npx -y moontide-mcp
What is the io.github.konni-arcadia/moontide MCP server?
io.github.konni-arcadia/moontide is an MCP server listed in the public MCP registry as io.github.konni-arcadia/moontide. Claude steers live music by writing Strudel code played in a browser page. This page covers its npm package (moontide-mcp).
Is the io.github.konni-arcadia/moontide MCP server safe to use?
io.github.konni-arcadia/moontide scores 86 out of 100 on VerifyMCP. We recorded 1 known advisory against it as of 4 November 2026. It declares no install or post-install scripts. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.
What tools does the io.github.konni-arcadia/moontide MCP server expose?
io.github.konni-arcadia/moontide exposes 15 tools: get_code, get_strudel_reference, set_code, edit_code, list_history, and 10 more. Their descriptions and schemas cost roughly 4,065 tokens of context every time the server is loaded.
Is the io.github.konni-arcadia/moontide MCP server still maintained?
io.github.konni-arcadia/moontide is still listed as active in the MCP registry. We last reached this channel on 4 November 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.
What licence is the io.github.konni-arcadia/moontide MCP server under?
io.github.konni-arcadia/moontide declares the AGPL-3.0-or-later licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.