A Model Context Protocol (MCP) server for Strudel, enabling AI agents to interact with the Strudel live coding environment through browser automation.
- 🎹 16 MCP Tools for complete Strudel control
- 🌐 Browser Automation via Playwright for real-time interaction
- 🔌 WebMCP Support — client-side
navigator.modelContextintegration for Chrome 146+ AI agents - 💾 Pattern Storage with tagging and session management
- 📝 History Management with undo/redo support
- 🔊 Audio Analysis (basic features)
- 🧪 Comprehensive Test Suite with 10+ test files
strudel_init- Initialize browser sessionstrudel_write- Write pattern to editorstrudel_get_pattern- Read current patternstrudel_play- Start playbackstrudel_stop- Stop playbackstrudel_clear- Clear editor
strudel_append- Append code to patternstrudel_insert- Insert at specific linestrudel_replace- Replace text in pattern
strudel_save- Save pattern with tagsstrudel_load- Load saved patternstrudel_list- List saved patterns
strudel_analyze- Basic audio analysisstrudel_status- Get current statusstrudel_screenshot- Capture screenshotstrudel_undo/strudel_redo- History management
- Node.js 18.0.0 or higher
- npm or yarn
- Docker and Docker Compose (optional, for containerized deployment)
# Clone the repository
git clone https://github.com/TheEmilz/strudelMCP.git
cd strudelMCP
# Install dependencies
npm install
# Install Playwright browsers
npx playwright install chromium
# Build the project
npm run build# Clone the repository
git clone https://github.com/TheEmilz/strudelMCP.git
cd strudelMCP
# Install dependencies and build (required before Docker build)
npm install
npm run build
# Start with Docker Compose
docker compose up -dAdd to your MCP client configuration (e.g., Claude Desktop):
{
"mcpServers": {
"strudel": {
"command": "node",
"args": ["/path/to/strudelMCP/dist/index.js"]
}
}
}The server can also run in a Docker container and be accessed via HTTP/SSE, making it accessible from external agents.
# Start the server
docker-compose up -d
# View logs
docker-compose logs -f
# Stop the server
docker-compose downThe server will be available at:
- HTTP endpoint:
http://localhost:3000 - SSE endpoint:
http://localhost:3000/sse - Health check:
http://localhost:3000/health
# Build the image
docker build -t strudel-mcp-server .
# Run the container
docker run -d \
-p 3000:3000 \
-v $(pwd)/patterns:/app/patterns \
-e STRUDEL_HEADLESS=true \
-e STRUDEL_TRANSPORT=http \
--name strudel-mcp \
strudel-mcp-serverSTRUDEL_TRANSPORT: Transport mode (stdio,http, orstreamable-http/web). Default:stdioSTRUDEL_PORT: HTTP server port (only for HTTP transports). Default:3000STRUDEL_HEADLESS: Run browser in headless mode. Default:falseSTRUDEL_URL: Strudel URL to connect to. Default:https://strudel.cc/NODE_ENV: Node environment. Default:development
WebMCP is a proposed web standard by Google that exposes structured tools to AI agents directly in the browser via the navigator.modelContext API. strudelMCP includes a ready-to-use WebMCP client page that registers all Strudel tools so Chrome's AI agent can compose music.
- Chrome version 146.0.7672.0 or higher
- Enable the flag:
chrome://flags/#enable-webmcp-testing→ Enabled, then relaunch Chrome - Optionally: install the Model Context Tool Inspector Extension to inspect and test tools
# 1. Build the project
npm run build
# 2. Start the server in streamable-http mode
STRUDEL_TRANSPORT=streamable-http node dist/index.js
# 3. Open in Chrome 146+ with the webMCP flag enabled
# Navigate to: http://localhost:3000/webmcp/index.htmlThe WebMCP page embeds the Strudel REPL and registers 8 tools via navigator.modelContext.provideContext():
| Tool | Description |
|---|---|
write_pattern |
Write a Strudel pattern to the editor |
get_pattern |
Read the current pattern from the editor |
play_pattern |
Start audio playback |
stop_pattern |
Stop audio playback |
clear_editor |
Clear all code from the editor |
append_pattern |
Append code to the end of the current pattern |
replace_text |
Find and replace text in the current pattern |
get_status |
Get current editor and playback status |
The WebMCP page (webmcp/index.html) uses the imperative API:
navigator.modelContext.provideContext({
tools: [
{
name: 'write_pattern',
description: 'Write a Strudel pattern to the editor...',
inputSchema: { type: 'object', properties: { pattern: { type: 'string' } }, required: ['pattern'] },
execute: async ({ pattern }) => {
// Interacts with the embedded CodeMirror editor
return { content: [{ type: 'text', text: `Pattern written` }] };
}
},
// ... more tools
]
});The Chrome AI agent can then discover and call these tools directly from the browser — no server-side MCP transport needed for the tool interaction itself.
- Install the extension
- Open
http://localhost:3000/webmcp/index.htmlin Chrome 146+ - Click the extension icon to see registered tools
- Execute tools manually, or provide a Gemini API key to test with natural language prompts
The server also supports the MCP Streamable HTTP transport for programmatic MCP clients.
STRUDEL_TRANSPORT=streamable-http node dist/index.js
# Or: STRUDEL_TRANSPORT=web node dist/index.jsGET /— Redirects to WebMCP client pageGET /webmcp/index.html— WebMCP client page (for Chrome's AI agent)POST /mcp— JSON-RPC messages (initialize, tool calls)GET /mcp— SSE stream for server-initiated messages (requiresmcp-session-idheader)DELETE /mcp— Terminate a session (requiresmcp-session-idheader)GET /health— Health check endpoint
The Streamable HTTP transport includes CORS headers for cross-origin browser access:
Access-Control-Allow-Origin: *Access-Control-Allow-Methods: GET, POST, DELETE, OPTIONSAccess-Control-Allow-Headers: Content-Type, mcp-session-id, Last-Event-IDAccess-Control-Expose-Headers: mcp-session-id
docker run -d \
-p 3000:3000 \
-v $(pwd)/patterns:/app/patterns \
-e STRUDEL_HEADLESS=true \
-e STRUDEL_TRANSPORT=streamable-http \
--name strudel-mcp \
strudel-mcp-serverWhen running in Docker with HTTP transport, you can connect to the MCP server using the SSE endpoints:
SSE Connection: http://localhost:3000/sse
POST Messages: http://localhost:3000/messages?sessionId=<session-id>
Note: The Docker build process includes these steps:
- Build the TypeScript code locally first (
npm run build) - Copy the compiled
distfolder andnode_modulesinto the container - Playwright browsers are installed during the build, but may fail in restricted network environments
If you encounter certificate errors during the Playwright installation, the server will still start successfully, but you'll need to ensure Playwright browsers are available. The build process continues even if Playwright installation fails.
Before building: Make sure to run npm run build locally to generate the dist folder.
// 1. Initialize Strudel
strudel_init()
// 2. Write a pattern
strudel_write({
pattern: 's("bd hh sd hh")'
})
// 3. Play the pattern
strudel_play()
// 4. Save the pattern
strudel_save({
name: "simple-beat",
tags: ["basic", "drums"]
})
// 5. Stop playback
strudel_stop()npm run build # Compile TypeScript
npm run dev # Watch modenpm test # Run unit tests
npm run test:integration # Run integration testsThe project includes 10+ test files:
tests/unit/browser.test.js- Browser automation teststests/unit/storage.test.js- Pattern storage teststests/unit/tools.test.js- MCP tools teststests/unit/schemas.test.js- Schema validation teststests/unit/history.test.js- History management teststests/unit/patterns.test.js- Pattern examples teststests/unit/streamable-http.test.js- Streamable HTTP transport teststests/unit/webmcp.test.js- WebMCP client page tests
tests/integration/browser.test.js- Browser integration teststests/integration/workflow.test.js- End-to-end workflow tests
tests/fixtures/strudel-embed.html- Embedded Strudel test pagetests/fixtures/strudel-iframe.html- iframe integration test pagetests/fixtures/patterns.js- Example patterns library
npm run lintThe server supports three transport modes:
┌─────────────────────────────────────┐
│ MCP Client (AI) │
└────────────┬────────────────────────┘
│ stdio
┌────────────▼────────────────────────┐
│ MCP Server (index.ts) │
│ ┌──────────────────────────────┐ │
│ │ Tool Request Handler │ │
│ └────────┬─────────────────────┘ │
└───────────┼─────────────────────────┘
│
┌───────┴────────┐
│ │
┌───▼────┐ ┌─────▼──────┐
│ Browser│ │ Storage │
│ (Play- │ │ (Pattern │
│ wright)│ │ files) │
└────────┘ └────────────┘
┌─────────────────────────────────────┐
│ External MCP Client (Agent) │
└────────────┬────────────────────────┘
│ HTTP/SSE
┌────────────▼────────────────────────┐
│ Docker Container │
│ ┌────────────────────────────────┐ │
│ │ Express HTTP Server + SSE │ │
│ │ (Port 3000) │ │
│ └──────────┬─────────────────────┘ │
│ ┌──────────▼─────────────────────┐ │
│ │ MCP Server (index.ts) │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ Tool Request Handler │ │ │
│ │ └────────┬─────────────────┘ │ │
│ └───────────┼────────────────────┘ │
└──────────────┼──────────────────────┘
│
┌───────┴────────┐
│ │
┌───▼────┐ ┌─────▼──────┐
│ Browser│ │ Storage │
│ (Play- │ │ (Pattern │
│ wright)│ │ files) │
└────────┘ └────────────┘
┌─────────────────────────────────────┐
│ Chrome Beta / Browser MCP Client │
│ (webMCP agent) │
└────────────┬────────────────────────┘
│ Streamable HTTP (POST/GET/DELETE /mcp)
│ + CORS headers
┌────────────▼────────────────────────┐
│ Express HTTP Server │
│ ┌────────────────────────────────┐ │
│ │ StreamableHTTPServerTransport │ │
│ │ (per-session, stateful) │ │
│ └──────────┬─────────────────────┘ │
│ ┌──────────▼─────────────────────┐ │
│ │ MCP Server (index.ts) │ │
│ │ ┌──────────────────────────┐ │ │
│ │ │ Tool Request Handler │ │ │
│ │ └────────┬─────────────────┘ │ │
│ └───────────┼────────────────────┘ │
└──────────────┼──────────────────────┘
│
┌───────┴────────┐
│ │
┌───▼────┐ ┌─────▼──────┐
│ Browser│ │ Storage │
│ (Play- │ │ (Pattern │
│ wright)│ │ files) │
└────────┘ └────────────┘
- index.ts - MCP server entry point with stdio, HTTP/SSE, and Streamable HTTP transports
- browser.ts - Playwright-based browser automation
- tools.ts - MCP tool definitions and handlers
- storage.ts - Pattern persistence and management
The server can be configured via constructor options:
const browser = new StrudelBrowser({
headless: false, // Show browser window
strudelUrl: 'https://strudel.cc/'
});
const storage = new PatternStorage('./patterns');Patterns are saved as JSON files in the patterns/ directory:
{
"id": "pattern_1234567890_abc123",
"name": "my-pattern",
"code": "s(\"bd hh sd hh\")",
"tags": ["drums", "basic"],
"timestamp": 1234567890000
}The server uses Playwright with Chromium for browser automation. It interacts with:
- The official Strudel.cc website
- Embedded Strudel REPL (
@strudel/embed) - Custom HTML pages with Strudel iframes
The server uses the stdio transport for communication but can be extended to support Server-Sent Events (SSE) for bidirectional communication by using the appropriate MCP SDK transport.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
npm test) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details
- Strudel - The live coding environment
- Model Context Protocol - The MCP specification
- williamzujkowski/strudel-mcp-server - Reference implementation
- Playwright - Browser automation
- Strudel - Main Strudel repository
- MCP TypeScript SDK
- Playwright
Active Development - This project is functional but under active development. Core features work reliably, but expect some rough edges and breaking changes.