The agent isn't controlling another Strudel session. It's playing in yours.
Strudel WebMCP lets a browser agent join the exact live Strudel REPL a human is already performing with. You type, select code, and drag inline sliders as normal; the agent reads and edits that same unsaved CodeMirror document, evaluates its changes in the same running scheduler, and can record what the result sounds like — under a permission dial you own. No embedded LLM, no MCP server, no WebSocket bridge, no session ID.
Live demo: https://strudel-webmcp.vercel.app Repository: https://github.com/alliecatowo/strudel-webmcp
Why WebMCP
Live coding is a bad fit for every earlier agent-integration shape, because the thing an agent needs to touch — the unsaved editor buffer, the exact cursor and selection, the inline slider values, the scheduler that is playing right now — exists in one browser tab and changes every second. A file-based or bridged integration has to keep a second copy of that in sync, and the copy is stale the moment a slider moves.
WebMCP has no second copy. The tool call is a method on the same page, over the same document, in the same tab the human is looking at. Nothing to install, nothing to configure, no bridge that can drift.
That makes something ordinary that was previously very hard: a human dragging a filter-cutoff slider with the mouse while an agent, in the same instant, rewrites a different line of the same unsaved buffer — and neither can clobber the other's most recent change.
What the agent can do
Thirteen tools, registered through document.modelContext.registerTool (src/webmcp/tools.ts), all backed by one adapter over the live (src/strudel/adapter.ts):
- Read live context: playback state, cursor, the human's current selection, what is sounding now, the agent mode, and any pending proposal, solo or recording.
- Read the exact current source, unsaved edits included, optionally by line range.
- Apply precise range edits, or replace the whole source — in review mode both become proposals.
- Evaluate through Strudel's own Update path (host.editor.evaluate()), so an agent edit becomes audible exactly the way a human's does, without stopping the clock; or solo just a range; or audition a pending proposal.
- Play, stop, and select-and-scroll to a range so the human sees what the agent means.
- Record the live output — master, or one .analyze("id") voice — and get dBFS and band analysis back, plus a playable take left in the page.
- List and extend the sound registry the running scheduler actually resolves s("...") against.
- Snapshot the source as a named version; switch the editor theme.
Every mutating tool requires the codeHash from a previous read, computed fresh from the live document, and is refused with STALE_CODE if anything changed since — including a slider drag, because Strudel's slider widgets rewrite the source's numeric literals directly. The human's most recent edit always wins.
The permission dial has three positions. Read: the agent can look, record and point, nothing else. Review: every edit arrives as a proposal with a diff the human auditions, accepts or discards — the source is unchanged until you say so. Live: edits apply directly.
What people and agents can do together
You keep performing. The agent reads the exact state you're in — down to the characters you have selected — and makes structural edits to the lines you didn't ask it to leave alone, then evaluates them into the same running pattern. Both of you act through the one Strudel instance; the audio reflects both immediately because neither owns a separate copy.
In review mode the agent pitches instead of acting: "swap the kick for a different one" appears as a diff you can hear before it lands. And the agent has ears: ask "is the bass too loud?" and it records four seconds of the live output, answers from measured dBFS band energy, and suggests a concrete gain change.
Who this is for
Live coders, algorave performers, and people learning music through code — an audience for whom the editor buffer is the whole instrument, and for whom anything that isn't that exact buffer is useless mid-performance. Today, getting an agent into that instrument means standing up an MCP server, a bridge, and usually a modified frontend before a single note changes. That is real friction for a hobbyist or student and dead weight for a performer who wants a second pair of hands for eight bars.
The claim is direct: browser-native creative tools shouldn't need to embed a model or ship a dedicated connector to be legible to an agent. The page can expose the instrument the human already has open. Strudel is the proof; the pattern — unsaved live document, precise agent edits, human-owned permission dial — applies to any browser-native creative or editing tool with real-time state worth exposing.
Live coding is a specialized audience, but the engine underneath it is not niche: @strudel/core, the pattern engine every Strudel-based tool depends on, drew about 30,000 npm downloads in the 30 days ending August 29, 2026, and the wider @strudel/* family this project embeds — mini-notation, transpiler, WebAudio backend, CodeMirror integration, the REPL itself — adds roughly 76,000 more over the same window. The seam this project adds is generic to any of those downstream tools, not specific to this demo's drum pattern.
Compared with the existing Strudel MCP bridges
Existing Strudel MCP projects drive Strudel through an MCP server, a WebSocket or SSE bridge, and often a special frontend or a session ID copied between browser and agent. They work. The difference is what it takes to start: a connector, a bridge, session synchronization, and MCP configuration on one side; opening the page on the other. Here the page publishes its own controls, and the browser agent already accompanying the user joins the REPL with no external bridge, no session ID, no agent-specific server, and no second source of truth.
Why this is different from "AI + music"
Most "AI + music" demos are generation: describe a vibe, get a clip, no instrument in the loop. Most WebMCP demos so far are forms and dashboards. This is neither. It is a person and a browser agent performing through the same live instrument — one typing, selecting, dragging and listening; the other reading exact state, making precise edits, evaluating, and pointing back into the source. The review-mode propose/audition/accept loop goes further: the agent gets a way to pitch a change and let the human hear it before committing, which has no analogue in a form-filling demo.
How it's built
A static site — no server, no bridge — wrapping the official Strudel REPL and CodeMirror editor. The adapter is the only code that touches @strudel/repl internals; the tools, schemas, registration and error helpers sit above it. Unit tests (Vitest) cover hashing, position and offset conversion, edit validation, stale-hash rejection, source-size bounds and error normalization. Playwright end-to-end tests run against the real <strudel-editor>, including one that physically moves an inline slider and confirms a stale agent write against the pre-slider hash is rejected, and a modes suite covering read denials, the proposal lifecycle, solo, both recording modes, samples, snapshots and themes.
Try it
Open https://strudel-webmcp.vercel.app in a WebMCP-capable browser, confirm "WebMCP ready · 13 tools" in the status strip, press Play. Then ask your agent:
Keep the bass and kick exactly where I left them. Make the hats evolve over eight bars instead of staying static.
Then turn the header dial to Review and ask: "Swap the kick for a different one — but let me check it first." The proposal/diff bar appears before anything sounds different.
Every sound in the demo video is generated live by Strudel's own Web Audio engine from the pattern that ships in this repo (src/demo-pattern.ts) — synths and the built-in RolandTR909 drum bank, captured from the app's audio graph while it played. AGPL-3.0.
Built With
- codemirror
- live-coding
- playwright
- strudel
- typescript
- vercel
- vitest
- webaudio
- webmcp
Log in or sign up for Devpost to join the conversation.