{"id":50754543,"url":"https://github.com/williamzujkowski/live-coding-music-mcp","last_synced_at":"2026-06-28T07:00:25.977Z","repository":{"id":310427256,"uuid":"1039800691","full_name":"williamzujkowski/live-coding-music-mcp","owner":"williamzujkowski","description":"A Model Context Protocol (MCP) server that gives Claude direct control over Strudel.cc for AI-assisted music generation and live coding.","archived":false,"fork":false,"pushed_at":"2026-05-22T04:58:28.000Z","size":1135,"stargazers_count":201,"open_issues_count":1,"forks_count":24,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-05-22T13:50:09.845Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/williamzujkowski.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-18T02:07:52.000Z","updated_at":"2026-05-22T12:14:19.000Z","dependencies_parsed_at":"2026-04-04T02:01:24.327Z","dependency_job_id":null,"html_url":"https://github.com/williamzujkowski/live-coding-music-mcp","commit_stats":null,"previous_names":["williamzujkowski/strudel-mcp-server","williamzujkowski/live-coding-music-mcp"],"tags_count":8,"template":false,"template_full_name":"williamzujkowski/template","purl":"pkg:github/williamzujkowski/live-coding-music-mcp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamzujkowski%2Flive-coding-music-mcp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamzujkowski%2Flive-coding-music-mcp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamzujkowski%2Flive-coding-music-mcp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamzujkowski%2Flive-coding-music-mcp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/williamzujkowski","download_url":"https://codeload.github.com/williamzujkowski/live-coding-music-mcp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/williamzujkowski%2Flive-coding-music-mcp/sbom","scorecard":{"id":1245567,"data":{"date":"2026-04-04T00:01:27Z","repo":{"name":"github.com/williamzujkowski/strudel-mcp-server","commit":"d0ffb2ba0cfcb85a080973b1bc310b97af6ed27f"},"scorecard":{"version":"v5.1.1","commit":"cd152cb6742c5b8f2f3d2b5193b41d9c50905198"},"score":5.3,"checks":[{"name":"Security-Policy","score":10,"reason":"security policy file detected","details":["Info: security policy file detected: SECURITY.md:1","Info: Found linked content: SECURITY.md:1","Info: Found disclosure, vulnerability, and/or timelines in security policy: SECURITY.md:1","Info: Found text in security policy: SECURITY.md:1"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#security-policy"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":10,"reason":"30 commit(s) and 26 issue activity found in the last 90 days -- score normalized to 10","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#dangerous-workflow"}},{"name":"Dependency-Update-Tool","score":10,"reason":"update tool detected","details":["Info: detected update tool: Dependabot: .github/dependabot.yml:1"],"documentation":{"short":"Determines if the project uses a dependency update tool.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#dependency-update-tool"}},{"name":"Code-Review","score":0,"reason":"Found 1/25 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Warn: topLevel 'contents' permission set to 'write': .github/workflows/publish.yml:20","Info: topLevel permissions set to 'read-all': .github/workflows/scorecard.yml:9","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":4,"reason":"dependency not pinned by hash detected -- score normalized to 4","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/williamzujkowski/strudel-mcp-server/scorecard.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/scorecard.yml:21: update your workflow using https://app.stepsecurity.io/secureworkflow/williamzujkowski/strudel-mcp-server/scorecard.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/williamzujkowski/strudel-mcp-server/scorecard.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/scorecard.yml:30: update your workflow using https://app.stepsecurity.io/secureworkflow/williamzujkowski/strudel-mcp-server/scorecard.yml/main?enable=pin","Warn: containerImage not pinned by hash: Dockerfile:2","Warn: containerImage not pinned by hash: Dockerfile:22","Warn: npmCommand not pinned by hash: .github/workflows/publish.yml:44","Info:   4 out of   7 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned","Info:   0 out of   2 containerImage dependencies pinned","Info:   3 out of   4 npmCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#pinned-dependencies"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#license"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#cii-best-practices"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#signed-releases"}},{"name":"Packaging","score":10,"reason":"packaging workflow detected","details":["Info: Project packages its releases by way of GitHub Actions.: .github/workflows/publish.yml:24"],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#packaging"}},{"name":"Vulnerabilities","score":0,"reason":"13 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-f886-m6hf-6m8v","Warn: Project is vulnerable to: GHSA-2qvq-rjwj-gvw9","Warn: Project is vulnerable to: GHSA-2w6w-674q-4c4q","Warn: Project is vulnerable to: GHSA-3mfm-83xf-c92r","Warn: Project is vulnerable to: GHSA-442j-39wm-28r2","Warn: Project is vulnerable to: GHSA-7rx3-28cr-v5wh","Warn: Project is vulnerable to: GHSA-9cx6-37pm-9jff","Warn: Project is vulnerable to: GHSA-xhpv-hc6g-r9c6","Warn: Project is vulnerable to: GHSA-xjpj-3mr7-gcpf","Warn: Project is vulnerable to: GHSA-27v5-c462-wpq7","Warn: Project is vulnerable to: GHSA-j3q9-mxjg-w52f","Warn: Project is vulnerable to: GHSA-3v7f-55p6-f55p","Warn: Project is vulnerable to: GHSA-c2c7-rcm5-vvqj"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 6 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#sast"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":3,"reason":"branch protection is not maximal on development and all release branches","details":["Info: 'allow deletion' disabled on branch 'main'","Info: 'force pushes' disabled on branch 'main'","Warn: 'branch protection settings apply to administrators' is disabled on branch 'main'","Warn: branch 'main' does not require approvers","Warn: codeowners review is not required on branch 'main'","Info: status check found to merge onto on branch 'main'","Warn: PRs are not required to make changes on branch 'main'; or we don't have data to detect it.If you think it might be the latter, make sure to run Scorecard with a PAT or use Repo Rules (that are always public) instead of Branch Protection settings"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#branch-protection"}},{"name":"CI-Tests","score":8,"reason":"5 out of 6 merged PRs checked by a CI test -- score normalized to 8","details":null,"documentation":{"short":"Determines if the project runs tests before pull requests are merged.","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#ci-tests"}},{"name":"Contributors","score":0,"reason":"project has 0 contributing companies or organizations -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project has a set of contributors from multiple organizations (e.g., companies).","url":"https://github.com/ossf/scorecard/blob/cd152cb6742c5b8f2f3d2b5193b41d9c50905198/docs/checks.md#contributors"}}]},"last_synced_at":"2026-04-04T02:11:38.871Z","repository_id":310427256,"created_at":"2026-04-04T02:11:38.871Z","updated_at":"2026-04-04T02:11:38.871Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34880189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-11T04:00:24.044Z","updated_at":"2026-06-28T07:00:25.967Z","avatar_url":"https://github.com/williamzujkowski.png","language":"TypeScript","funding_links":[],"categories":["MCP Servers for Creative Work"],"sub_categories":["Music \u0026 Live Coding"],"readme":"# live-coding-music-mcp\n\n\u003e 🎵 MCP server for AI-assisted live-coding music via [strudel.cc](https://strudel.cc/)\n\u003e\n\u003e **Unofficial fan project.** Not affiliated with, or endorsed by, the [Strudel project](https://codeberg.org/uzu/strudel). This adapter exists to make live-coding music accessible to beginners who want to try pattern-based music without learning the whole ecosystem first.\n\u003e\n\u003e **Status:** Beta | 86% statement coverage | Published to npm | Actively developed\n\n\u003ca href=\"https://glama.ai/mcp/servers/@williamzujkowski/live-coding-music-mcp\"\u003e\n  \u003cimg width=\"380\" height=\"200\" src=\"https://glama.ai/mcp/servers/@williamzujkowski/live-coding-music-mcp/badge\" alt=\"live-coding-music-mcp server\" /\u003e\n\u003c/a\u003e\n\n[![CI](https://github.com/williamzujkowski/live-coding-music-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/williamzujkowski/live-coding-music-mcp/actions)\n[![npm version](https://img.shields.io/npm/v/@williamzujkowski/live-coding-music-mcp.svg)](https://www.npmjs.com/package/@williamzujkowski/live-coding-music-mcp)\n[![Nerq Trust](https://nerq.ai/badge/live-coding-music-mcp)](https://nerq.ai/kya/live-coding-music-mcp)\n[![Tools](https://img.shields.io/badge/tools-27-green.svg)]()\n[![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue.svg)](LICENSE)\n\nA Model Context Protocol (MCP) server that drives [Strudel.cc](https://strudel.cc/) from Claude for AI-assisted live-coding music, pattern generation, and algorithmic composition.\n\n**Current State: Beta.** The core workflow (init → compose → playback → analyze) works reliably with real audio output. 1709 tests pass, 86.32% statement coverage / 75.93% branch coverage. CI is hardened with OpenSSF Scorecard, SHA-pinned actions, CODEOWNERS, Dependabot, and lint as a blocking gate.\n\n**What \"Beta\" means here:**\n- Tool schemas are stable within minor versions; breaking changes require a major bump\n- Multi-session is supported as of v3.0.0 ([#108](https://github.com/williamzujkowski/live-coding-music-mcp/issues/108)) — named sessions get isolated browser, history, and audio-capture state\n- Upstream `@strudel/*` dependencies pinned to known-good versions; Dependabot bumps gated on CI\n- Expect hands-on iteration for non-standard patterns — report rough edges, they get fixed\n\n## Table of Contents\n\n- [Features](#features)\n- [Installation](#installation)\n- [Quick Start](#quick-start)\n- [Quick Reference](#quick-reference)\n- [Available Tools](#available-tools)\n- [Usage Examples](#usage-examples)\n- [Architecture](#architecture)\n- [Advanced Usage](#advanced-usage)\n- [Configuration](#configuration)\n- [Security](#security)\n- [Troubleshooting](#troubleshooting)\n- [Development](#development)\n- [Contributing](#contributing)\n\n## Features\n\n### Music control\n- **27 MCP tools** covering pattern editing, playback, audio analysis, generation, history, sessions, MIDI import/export, and Gemini-backed assists. Each tool is enum-parameterized to keep the protocol surface small: `pattern_store({ action })`, `edit_pattern({ mode })`, `transform({ op })`, `analyze({ include })`, `history({ action })`, `playback({ action })`, `effect({ action })`, `shape({ dimension })`, `audio_capture({ action })`, `browser_window({ action })`, `generate_part({ role })`, `generate_rhythm({ type })`, `music_theory({ query })`, `session({ action })`, `ai_assist({ task })`, ... The 58 legacy single-verb aliases that forwarded to these were removed in v4.0.0 ([#178](https://github.com/williamzujkowski/live-coding-music-mcp/issues/178)).\n- **4 MCP resources** for catalog browsing without burning tool calls: `strudel://examples`, `strudel://patterns`, `strudel://styles`, `strudel://docs/tools`.\n- **Real browser automation** of Strudel.cc through Playwright.\n- **Multi-session support** — every browser-touching tool accepts an optional `session_id`; sessions have isolated browser pages, undo/redo/history stacks, and audio-capture services.\n- **Audio analysis** via Web Audio API (FFT spectrum, tempo detection, key detection, rhythm complexity).\n- **Template-based pattern generation** across 8 genres (techno, house, dnb, ambient, trap, jungle, jazz, experimental); optional Gemini-backed `ai_assist` for feedback, suggestions, and jamming.\n- **Music theory helpers**: 15+ scales, 8+ chord progression styles, euclidean and polyrhythm generation.\n- **Pattern persistence**: JSON-backed save/load with tags + the in-memory edit history (undo/redo/restore/compare).\n- **Result envelope** on every `tools/call`: clients branch on `{ ok, errorCategory, isRetryable }` instead of parsing free-text.\n\n### Testing \u0026 CI status\n- **1709 passing tests** across unit, integration, and example-validation suites; 20 skipped (browser, gated by Playwright).\n- **86.32% statement coverage / 75.93% branch coverage**.\n- **Lint blocking in CI**: 0 errors, ~163 warnings (mostly `any` in test mocks).\n- **OIDC trusted publishing** to npm with SLSA build provenance attestation on every release.\n\n**Not Production-Ready:** This is experimental software under active development. Use for exploration and experimentation. Expect breaking changes, bugs, and incomplete features. See [the Contributing section](#contributing) to help improve it.\n\n### Example patterns\n\n18 example patterns ship in [`patterns/examples/`](patterns/examples/), grouped by genre:\n\n- **Techno**: hard-techno, minimal-techno\n- **House**: deep-house, tech-house\n- **Drum \u0026 Bass**: liquid-dnb, neurofunk\n- **Ambient**: dark-ambient, drone\n- **Trap**: modern-trap, cloud-trap\n- **Jungle**: classic-jungle, ragga-jungle\n- **Jazz**: bebop, modal-jazz\n- **Longform** (multi-minute pieces): dark-ambient-journey, driving-techno, liquid-dnb-roller, nu-jazz-session\n\nEach example is a JSON file with pattern code, BPM, key, and a description. See [`patterns/examples/README.md`](patterns/examples/README.md) for details. Agents can also list these via the `strudel://examples` MCP resource without making any tool calls.\n\n## Migrating from `@williamzujkowski/strudel-mcp-server`\n\nThis project was renamed from `@williamzujkowski/strudel-mcp-server` to `@williamzujkowski/live-coding-music-mcp` to make the unofficial fan-project status unambiguous (see [#97](https://github.com/williamzujkowski/live-coding-music-mcp/issues/97)). The old package is deprecated on npm.\n\n**If you were using the old package:**\n\n```bash\n# Remove old\nnpm uninstall -g @williamzujkowski/strudel-mcp-server\n\n# Install new\nnpm install -g @williamzujkowski/live-coding-music-mcp\n```\n\n**Update your MCP client config.** The `bin` name changed from `strudel-mcp` to `live-coding-music-mcp`:\n\n```jsonc\n// BEFORE\n{\n  \"mcpServers\": {\n    \"strudel\": { \"command\": \"strudel-mcp\" }\n  }\n}\n\n// AFTER\n{\n  \"mcpServers\": {\n    \"live-coding-music\": { \"command\": \"live-coding-music-mcp\" }\n  }\n}\n```\n\nThe MCP server's internal identity string also changed from `strudel-mcp-enhanced` to `live-coding-music-mcp`. If you have a client that keys on that string (logs, allowlists, permission policies), update it accordingly.\n\nAll tool names and schemas are unchanged.\n\n## Installation\n\n### Prerequisites\n\n| Requirement | Version | Notes |\n|-------------|---------|-------|\n| Node.js | 22.x+ | LTS required |\n| npm | 10+ | Comes with Node.js |\n| Chromium | Latest | Auto-installed by Playwright |\n| Audio output | Any | Required for playback (speakers/headphones) |\n\n**Optional:** Docker for containerized deployment.\n\n### From npm\n```bash\nnpm install -g @williamzujkowski/live-coding-music-mcp\n\n# Install browser (required once)\nnpx playwright install chromium\n```\n\n### From Source\n```bash\n# Clone repository\ngit clone https://github.com/williamzujkowski/live-coding-music-mcp.git\ncd live-coding-music-mcp\n\n# Install dependencies\nnpm install\n\n# Install Chromium for browser automation\nnpx playwright install chromium\n\n# Build the project\nnpm run build\n```\n\n## Quick Start\n\nGet from install to your first generated pattern in under two minutes.\n\n### 1. Install\n\n```bash\nnpm install -g @williamzujkowski/live-coding-music-mcp\nnpx playwright install chromium   # one-time\n```\n\nBuilding from source instead? See [Installation → From Source](#from-source).\n\n### 2. Configure your MCP client\n\n#### Claude Desktop\n\nEdit your Claude Desktop config file:\n\n| OS | Config path |\n|---|---|\n| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |\n| Windows | `%APPDATA%\\Claude\\claude_desktop_config.json` |\n| Linux | `~/.config/Claude/claude_desktop_config.json` |\n\nAdd the server:\n\n```json\n{\n  \"mcpServers\": {\n    \"live-coding-music\": {\n      \"command\": \"live-coding-music-mcp\"\n    }\n  }\n}\n```\n\nRestart Claude Desktop. The server appears under the 🔌 plug icon.\n\n#### Claude Code (CLI)\n\n```bash\n# If installed globally\nclaude mcp add strudel live-coding-music-mcp\n\n# If built from source\nclaude mcp add strudel node /path/to/live-coding-music-mcp/dist/index.js\n```\n\n### 3. Verify the server responds\n\n```bash\n# From a global install\necho '{\"jsonrpc\":\"2.0\",\"method\":\"tools/list\",\"id\":1}' | live-coding-music-mcp\n\n# From source\nnpm run validate\n```\n\nYou should see a JSON response listing **26 tools**. If you see fewer, the build is out of date — run `npm run build`.\n\n### 4. Make your first sound\n\nIn Claude, ask:\n\n\u003e Initialize Strudel and compose a techno beat.\n\n**What you'll see:** A Chromium window opens (visibly — this is the live editor, not a hidden process) and lands on strudel.cc. Claude calls `init`, then `compose({ style: \"techno\" })`. A 4-on-the-floor pattern appears in the CodeMirror editor and starts playing through your speakers.\n\nPrefer headless mode (no browser window)? Set `\"headless\": true` in `config.json` before the first `init` call — see [Configuration](#configuration). Note that audio analysis (tempo / key detection) is more reliable in headed mode; headless audio sampling is best-effort.\n\n### 5. Where to go next\n\n- [Quick Reference](#quick-reference) below: tool cheat sheet for common operations.\n- [Usage Examples](#usage-examples): multi-step workflows (composition, audio analysis, AI-assisted jamming).\n- [`patterns/examples/`](patterns/examples/): 18 ready-to-play patterns across 7 genres plus 4 longform pieces. Agents can browse them via the `strudel://examples` MCP resource without burning tool calls.\n\n## Quick Reference\n\nCommon operations as one-line tool calls:\n\n| Action | Tool call |\n|---|---|\n| Initialize browser | `init` |\n| Create a techno beat in one shot | `compose({ style: \"techno\" })` |\n| Play pattern | `playback({ action: \"play\" })` |\n| Stop playback | `playback({ action: \"stop\" })` |\n| Get current pattern | `get_pattern` |\n| Analyze audio (all features) | `analyze({ include: [\"all\"] })` |\n| Detect tempo only | `analyze({ include: [\"tempo\"] })` |\n| Save pattern | `pattern_store({ action: \"save\", name: \"my-pattern\" })` |\n| Undo last edit | `history({ action: \"undo\" })` |\n| Edit current pattern | `edit_pattern({ mode: \"write\", pattern: \"...\" })` |\n| Create an isolated session | `session({ action: \"create\", session_id: \"live-1\" })` |\n\nThe legacy single-verb tools (`play`, `stop`, `save`, `undo`, `write`, `generate_pattern`, ...) were deprecated aliases during the `3.0.x` line and were removed in v4.0.0 ([#178](https://github.com/williamzujkowski/live-coding-music-mcp/issues/178)). Use the consolidated tools above.\n\n**One-shot workflow:**\n```\ncompose with style: \"dnb\", key: \"Am\", tempo: 174, auto_play: true\n```\n\n## Available Tools\n\n\u003c!-- TOOLS:START --\u003e\n\n**27 tools** across 14 categories:\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eSetup\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `init` | Initialize Strudel in browser |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003ePattern Editing\u003c/strong\u003e (2)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `edit_pattern` | Mutate the current session pattern.  |\n| `get_pattern` | Get current pattern code |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003ePlayback\u003c/strong\u003e (2)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `playback` | Control transport on the current session.  |\n| `set_tempo` | Set BPM |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eStorage\u003c/strong\u003e (2)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `pattern_store` | Persist patterns to disk and read them back.  |\n| `import_midi` | Convert a .mid file into a playable Strudel pattern (Phase 1: literal transcription, #201).  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eHistory\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `history` | Navigate or inspect the pattern edit history.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eGeneration\u003c/strong\u003e (3)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `compose` | Generate, write, and play a complete pattern in one step. Auto-initializes default browser if needed. |\n| `generate_part` | Generate a single instrumental layer and append it to the current session pattern.  |\n| `generate_rhythm` | Generate a rhythmic pattern and append it to the current session.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eMusic Theory\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `music_theory` | Music-theory queries.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eTransform\u003c/strong\u003e (3)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `transform` | Apply a single transform op to the current session pattern.  |\n| `effect` | Add or remove a Strudel effect on the current session pattern.  |\n| `shape` | Shape the current pattern along one of three high-level dimensions.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eAI\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `ai_assist` | Gemini-backed pattern assistance.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eAnalysis\u003c/strong\u003e (6)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `analyze` | Audio analysis on the currently-playing pattern.  |\n| `validate_pattern_runtime` | Validate pattern with runtime error checking (monitors Strudel console for errors) |\n| `validate_pattern_local` | Validate pattern syntax against the in-process StrudelEngine (no browser required) |\n| `analyze_pattern_local` | Static analysis (events/cycle, complexity, optional BPM) without browser playback |\n| `query_pattern_events` | Enumerate events the pattern would emit between two cycle indices (max 16 cycles) |\n| `transpile_pattern` | Transpile pattern source via StrudelEngine; returns transpiled code or syntax error |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eSession\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `session` | Manage isolated Strudel browser sessions (multi-session, #108).  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eExport\u003c/strong\u003e (2)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `export_midi` | Export current pattern to MIDI file. Parses note(), n(), and chord() functions. |\n| `browser_window` | Interact with the visible Strudel browser window.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eAudio\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `audio_capture` | Record audio output from the live Strudel session.  |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\u003csummary\u003e\u003cstrong\u003eDebug\u003c/strong\u003e (1)\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `diagnostics` | Inspect server and browser state.  |\n\n\u003c/details\u003e\n\n_Auto-generated from source. 27 tools registered._\n\n\u003c!-- TOOLS:END --\u003e\n\n## Usage Examples\n\n### Basic Pattern Creation\n\n**Create a Simple Beat**\n```\nYou: Initialize Strudel and create a simple techno beat\n\nClaude: [Initializes browser]\n        [Generates and writes pattern]\n        [Starts playback]\n\nPattern created:\nsetcpm(130)\nstack(\n  s(\"bd*4\"),\n  s(\"~ cp ~ cp\"),\n  s(\"hh*8\").gain(0.4)\n).gain(0.8)\n```\n\n**Generate a Bassline**\n```\nYou: Add a techno bassline in C\n\nClaude: [Generates bassline]\n        [Appends to current pattern]\n\nAdded: note(\"c2 c2 c2 c2\").s(\"sawtooth\").cutoff(800)\n```\n\n### Advanced Music Generation\n\n**Jazz Composition**\n```\nYou: Create a jazz progression in F major with a walking bass\n\nClaude: Generated progression: \"Gm7\" \"C7\" \"Fmaj7\"\n\nPattern:\nstack(\n  note(\"Gm7\" \"C7\" \"Fmaj7\").struct(\"1 ~ ~ ~\").s(\"piano\"),\n  note(\"g2 c2 f2\").s(\"sine\").gain(0.7)\n)\n```\n\n**Drum \u0026 Bass Track**\n```\nYou: Generate a complete drum \u0026 bass track at 174 BPM\n\nClaude: [Creates multi-layer pattern with drums, bass, and pads]\n\n// dnb pattern in C at 174 BPM\nsetcpm(174)\nstack(\n  // Drums\n  s(\"bd ~ ~ [bd bd] ~ ~ bd ~, ~ ~ cp ~ ~ cp ~ ~\").fast(2),\n\n  // Bass\n  note(\"c1 ~ ~ c2 ~ c1 ~ ~\").s(\"square\").cutoff(400),\n\n  // Pads (atmospheric)\n  note(\"c3 eb3 g3 bb3\").s(\"sawtooth\")\n    .attack(2).release(4).room(0.8).gain(0.6)\n)\n```\n\n### Real-Time Manipulation\n\n**Live Audio Analysis**\n```\nYou: Analyze what's playing and show me the frequency breakdown\n\nClaude: Audio Analysis Results:\n{\n  \"connected\": true,\n  \"features\": {\n    \"average\": 78.5,\n    \"peak\": 180,\n    \"peakFrequency\": 120,\n    \"bass\": 145,\n    \"mid\": 82,\n    \"treble\": 45,\n    \"isPlaying\": true,\n    \"brightness\": \"balanced\"\n  }\n}\n\nStrong bass presence detected - typical for techno/house patterns.\n```\n\n**Pattern Variations**\n```\nYou: Create a glitchy variation of the current pattern\n\nClaude: [Applies glitch transformation]\n\nAdded: .sometimes(x =\u003e x.chop(8).rev).rarely(x =\u003e x.speed(-1))\n```\n\n### Multi-Track Composition\n\n**Layered Ambient Track**\n```\nYou: Create an ambient soundscape with multiple layers\n\nClaude: [Generates complex multi-layer pattern]\n\nsetcpm(90)\nstack(\n  // Deep bass drone\n  note(\"c1\").s(\"sine\").attack(4).release(8).gain(0.5),\n\n  // Texture pad\n  note(\"c3 eb3 g3\").s(\"sawtooth\")\n    .attack(2).release(6).room(0.9).gain(0.4),\n\n  // Sparse percussion\n  s(\"bd ~ ~ ~, ~ ~ ~ hh:8\").room(0.9).gain(0.3),\n\n  // Melodic sparkles\n  note(\"c5 g5 eb5 bb5\").struct(\"~ 1 ~ 1 ~ ~ 1 ~\")\n    .s(\"triangle\").delay(0.5).room(0.8).gain(0.3)\n)\n```\n\n### Session Management\n\n**Save and Load Patterns**\n```\nYou: Save this pattern as \"techno-groove-1\" with tags \"techno\" and \"experimental\"\n\nClaude: Pattern saved as \"techno-groove-1\"\n\n---\n\nYou: List all my techno patterns\n\nClaude: Saved patterns with tag \"techno\":\n• techno-groove-1 [techno, experimental] - 2025-10-23T19:30:00.000Z\n• acid-bassline [techno, acid] - 2025-10-23T18:15:00.000Z\n\n---\n\nYou: Load \"acid-bassline\"\n\nClaude: Loaded pattern \"acid-bassline\"\n[Pattern written to editor]\n```\n\n### Music Theory Applications\n\n**Generate Euclidean Rhythms**\n```\nYou: Create a 5/8 euclidean rhythm with kick drum\n\nClaude: Generated Euclidean rhythm (5/8)\n\nPattern: s(\"bd\").struct(\"1 ~ 1 ~ 1 1 ~ 1\")\n```\n\n**Complex Polyrhythms**\n```\nYou: Generate a polyrhythm with kick (4/16), snare (7/16), and hi-hat (3/16)\n\nClaude: Generated polyrhythm\n\nstack(\n  s(\"bd\").euclid(4, 16),\n  s(\"cp\").euclid(7, 16),\n  s(\"hh\").euclid(3, 16)\n)\n```\n\n### Integration with LLM Agents\n\n**AI-Assisted Composition**\n```\nYou: Analyze the mood of my current pattern and suggest complementary elements\n\nClaude: [Analyzes pattern structure and audio features]\n\nYour pattern has:\n- Energetic rhythm (130 BPM)\n- Strong bass presence\n- Minimal melodic content\n\nSuggestions:\n1. Add arpeggiated synth for movement\n2. Include occasional breaks/fills\n3. Layer atmospheric pad for depth\n\nWould you like me to add any of these?\n\nYou: Add an arpeggiated synth in C minor\n\nClaude: [Generates and adds]\n\nnote(\"c4 eb4 g4 bb4 c5\").struct(\"1 1 1 1 1 1 1 1\")\n  .s(\"triangle\").delay(0.25).room(0.3).gain(0.5)\n```\n\n## Testing\n\nTools are exercised against real Strudel.cc interaction through the browser test suite; those are skipped in CI (require Playwright + audio) but run locally:\n\n```bash\n# Run integration tests\nnpm run test:integration\n\n# Run browser tests\nnode tests/strudel-integration.js\n\n# Run npm test to see current pass/fail/skip counts\n```\n\n## Configuration\n\n### config.json\n```json\n{\n  \"headless\": false,        // Set true for background operation\n  \"strudel_url\": \"https://strudel.cc/\",\n  \"patterns_dir\": \"./patterns\",\n  \"audio_analysis\": {\n    \"fft_size\": 1024,       // power of 2 in [32, 32768]; default 1024\n    \"smoothing\": 0.8        // number in [0, 1]; default 0.8\n  }\n}\n```\n\n`audio_analysis.fft_size` tunes the FFT bin count on the `AnalyserNode` attached to Strudel's audio graph — larger = better frequency resolution at higher CPU cost. `smoothing` is the analyser's `smoothingTimeConstant` (higher = steadier spectrum, more lag). Invalid values fall back to defaults with a warning; the frequency-band boundaries inside `analyze` rescale automatically so band Hz coverage stays consistent across FFT sizes.\n\n## Architecture\n\nThe server is a thin MCP dispatcher (`src/server/server.ts`, ~510 lines) over twelve per-domain tool modules (`src/server/tools/*.ts`), six services (MusicTheory, PatternGenerator, SessionManager, AudioCaptureService, GeminiService, MIDIExportService, StrudelEngine), two controllers (StrudelController for Playwright, AudioAnalyzer for Web Audio API), and a JSON-on-disk PatternStore. Browser automation hits the CodeMirror editor on strudel.cc directly via `editor.__view.dispatch(...)` rather than keyboard simulation — about 80% faster.\n\nFor the full breakdown — component diagram, per-component responsibilities, directory layout, data flow, and optimization strategies — see **[ARCHITECTURE.md](ARCHITECTURE.md)**.\n\n## Pattern Examples\n\n### Minimal Techno (Verified Working)\n```javascript\nsetcpm(130)\nstack(\n  s(\"bd*4\").gain(0.9),\n  s(\"~ cp ~ cp\").room(0.2),\n  s(\"hh*16\").gain(0.4).pan(sine.range(-0.5, 0.5)),\n  note(\"c2 c2 eb2 c2\").s(\"sawtooth\").cutoff(800)\n).swing(0.05)\n```\n\n### Drum \u0026 Bass (Verified Working)\n```javascript\nsetcpm(174)\nstack(\n  s(\"bd ~ ~ [bd bd] ~ ~ bd ~, ~ ~ sn:3 ~ ~ sn:3 ~ ~\").fast(2),\n  s(\"hh*16\").gain(0.5),\n  note(\"e1 ~ ~ e2 ~ e1 ~ ~\").s(\"sine:2\").lpf(200)\n)\n```\n\n### Generated Jazz Progression\n```javascript\n// Jazz ii-V-I in F\nstack(\n  note(\"Gm7\" \"C7\" \"Fmaj7\").struct(\"1 ~ ~ ~\").s(\"piano\"),\n  note(\"g2 c2 f2\").s(\"sine\").gain(0.7)\n)\n```\n\n## Docker Support\n\n```bash\n# Build image\ndocker build -t live-coding-music-mcp .\n\n# Run container\ndocker run -it --rm live-coding-music-mcp\n\n# Or use docker-compose\ndocker-compose up\n```\n\n## Development\n\nFor development setup, scripts, debugging, adding new tools, and the release process, see **[DEVELOPMENT.md](DEVELOPMENT.md)**.\n\nQuick links:\n- [Setup](DEVELOPMENT.md#setup) — `git clone` to `npm test`\n- [Adding new tools](DEVELOPMENT.md#adding-new-tools) — module pattern + envelope helpers\n- [Release process](DEVELOPMENT.md#release-process) — `gh release create` triggers the publish workflow\n- [Contributing](DEVELOPMENT.md#contributing) — commit conventions and PR flow\n\nThe [Configuration](#configuration) section above covers runtime config (`config.json`). [ARCHITECTURE.md](ARCHITECTURE.md) covers the system design.\n\n## Performance\n\nMeasured against the current `StrudelController` cache + Strudel.cc on a developer machine:\n\n| Operation | Latency |\n|---|---|\n| Browser initialization | 1.5–2 s (with resource blocking) |\n| Pattern write | 50–80 ms (cached CodeMirror editor access) |\n| Pattern read (cached) | 10–15 ms |\n| Play / pause / stop | 100–150 ms |\n| Audio analysis (single FFT) | 10–15 ms |\n| Tempo detection | \u003c100 ms (onset-based; degraded under headless audio) |\n| Key detection | \u003c100 ms (Krumhansl-Schmuckler) |\n| Pattern generation | \u003c100 ms (template-based) |\n| Process resident memory | ~120–150 MB |\n\n## Advanced Usage\n\n### Custom Music Theory\n\n**Create Custom Scales**\n```typescript\n// The MusicTheory service supports 15+ built-in scales\n// You can request any combination:\n\nYou: Generate a lydian scale starting on D\n\nClaude: D lydian scale: D, E, F#, G#, A, B, C#\n```\n\n**Complex Chord Progressions**\n```typescript\nYou: Create a jazz ii-V-I progression in Bb with extended voicings\n\nClaude: Generated jazz progression in Bb: \"Cm7\" \"F7\" \"Bbmaj7\"\n\nPattern:\nnote(\"Cm7\" \"F7\" \"Bbmaj7\")\n  .struct(\"1 ~ ~ ~\")\n  .s(\"sawtooth\")\n  .add(note(\"7\"))  // Add 7th extensions\n  .room(0.4)\n```\n\n### Advanced Rhythm Techniques\n\n**Euclidean Patterns**\n```\nYou: Create a complex polyrhythm using euclidean patterns:\n     - Bass drum: 7 hits in 16 steps\n     - Snare: 5 hits in 16 steps\n     - Hi-hat: 11 hits in 16 steps\n\nClaude: [Generates mathematically perfect polyrhythm]\n\nstack(\n  s(\"bd\").euclid(7, 16),\n  s(\"cp\").euclid(5, 16),\n  s(\"hh\").euclid(11, 16)\n)\n```\n\n**Generative Variations**\n```\nYou: Create 3 variations of my current pattern: subtle, moderate, and glitchy\n\nClaude: [Generates three variants]\n\nVersion 1 (subtle):\noriginal.sometimes(x =\u003e x.fast(2))\n\nVersion 2 (moderate):\noriginal.every(4, x =\u003e x.rev).sometimes(x =\u003e x.fast(2))\n\nVersion 3 (glitchy):\noriginal.sometimes(x =\u003e x.chop(8).rev).rarely(x =\u003e x.speed(-1))\n```\n\n### Performance Optimization Tips\n\n**Pattern Caching**\n```\n// The server caches patterns intelligently:\n// - Generated patterns stored before browser init\n// - Editor content cached for 100ms\n// - Audio analysis cached for 50ms\n\n// For fastest performance:\n1. Generate patterns before initializing browser\n2. Initialize once and reuse the session\n3. Batch multiple changes together\n```\n\n**Headless Mode**\n```json\n// In config.json:\n{\n  \"headless\": true,  // Faster, no GUI\n  \"strudel_url\": \"https://strudel.cc/\",\n  \"patterns_dir\": \"./patterns\"\n}\n```\n\n### Integration Patterns\n\n**Workflow Automation**\n```\nYou: Create a complete track:\n     1. Start with techno drums at 130 BPM\n     2. Add acid bassline in E\n     3. Layer ambient pads\n     4. Save as \"track-001\" with tags \"techno\", \"acid\", \"experimental\"\n\nClaude: [Executes full workflow]\n        [Initializes browser]\n        [Generates drum pattern]\n        [Adds bassline]\n        [Layers pads]\n        [Saves with metadata]\n\nComplete! Pattern saved as \"track-001\"\n```\n\n**Audio-Reactive Composition**\n```\nYou: Monitor the audio and suggest adjustments based on frequency balance\n\nClaude: [Analyzes current playback]\n\nAnalysis shows:\n- Bass: 180 (strong)\n- Mid: 45 (weak)\n- Treble: 30 (weak)\n\nRecommendations:\n1. Reduce bass gain by 20%\n2. Add mid-range melodic content\n3. Include hi-hat pattern for treble\n\nApply changes? [Yes/No]\n```\n\n### Advanced Pattern Manipulation\n\n**Dynamic Transformations**\n```\nYou: Apply these transformations in sequence:\n     1. Transpose up 3 semitones\n     2. Add 10% humanization\n     3. Apply reverb with 0.6 room size\n     4. Every 4th cycle, reverse the pattern\n\nClaude: [Applies transformations]\n\nFinal pattern:\n[original]\n  .transpose(3)\n  .nudge(rand.range(-0.1, 0.1))\n  .room(0.6)\n  .every(4, x =\u003e x.rev)\n```\n\n**Conditional Logic**\n```\nYou: Create a pattern that evolves:\n     - Bars 1-4: Simple kick pattern\n     - Bars 5-8: Add snare\n     - Bars 9-16: Add full drum kit\n     - Then loop with variations\n\nClaude: [Generates evolving pattern]\n\ns(\"bd*4\")\n  .struct(\"1 ~ ~ ~\")\n  .mask(\"\u003c1 1 1 1 0 0 0 0\u003e/4\")  // First 4 bars\n  .stack(\n    s(\"~ cp ~ cp\")\n      .mask(\"\u003c0 0 0 0 1 1 1 1\u003e/8\")  // Bars 5-8\n  )\n  // Full complexity from bar 9\n  .every(8, x =\u003e x.sometimes(y =\u003e y.fast(2)))\n```\n\n## Security\n\n### Pattern Validation\n\nAll patterns are validated before execution:\n- **Dangerous gain levels** (\u003e2.0) are flagged\n- **Eval blocks** are rejected\n- **Path traversal** attacks are blocked in PatternStore\n\n### Browser Sandboxing\n\n- Playwright runs Chromium in sandbox mode\n- No access to local filesystem from browser context\n- Resource blocking prevents loading external content\n\n### Known Limitations\n\n- **No authentication**: The MCP server trusts all incoming requests\n- **Local only**: Designed for local development, not network deployment\n- **Pattern execution**: Patterns execute in browser context with audio access\n\n### Reporting Security Issues\n\nFound a vulnerability? Please [open a security issue](https://github.com/williamzujkowski/live-coding-music-mcp/security/advisories/new) or email the maintainer directly. Do not disclose publicly until patched.\n\n## Troubleshooting\n\n### Common Issues\n\n#### Browser doesn't open\n**Symptom**: `Error: Browser not initialized` or Chromium launch fails\n\n**Solutions**:\n```bash\n# Install Chromium for Playwright\nnpx playwright install chromium\n\n# If that fails, try installing all browsers\nnpx playwright install\n\n# Check Playwright installation\nnpx playwright --version\n\n# For Linux, install dependencies\nsudo npx playwright install-deps chromium\n```\n\n#### Audio analysis returns \"not connected\"\n**Symptom**: Audio analysis shows `connected: false`\n\n**Solutions**:\n1. Ensure pattern is playing first:\n   ```\n   You: Play the pattern, wait 2 seconds, then analyze\n   ```\n\n2. Reinitialize the browser:\n   ```\n   You: Stop, close the browser, reinitialize, and try again\n   ```\n\n3. Check audio context activation:\n   - Audio contexts require user interaction on some systems\n   - The browser window must be visible (not headless) for first run\n\n#### Pattern syntax errors\n**Symptom**: Pattern doesn't play or shows errors in console\n\n**Solutions**:\n```\nCommon issues:\n1. Missing quotes: s(bd*4) → s(\"bd*4\")\n2. Unmatched parentheses: stack(s(\"bd\")) → stack(s(\"bd\")))\n3. Invalid note names: note(\"h2\") → note(\"c2\")\n\nTest with minimal pattern first:\ns(\"bd*4\")\n\nThen build complexity gradually.\n```\n\n#### MCP connection issues\n**Symptom**: Claude can't find the server or tools\n\n**Solutions**:\n```bash\n# Verify server is built\nnpm run build\n\n# Check if server responds\necho '{\"jsonrpc\":\"2.0\",\"method\":\"tools/list\",\"id\":1}' | node dist/index.js\n\n# Should return JSON with 26 tools\n\n# Reinstall MCP server in Claude\nclaude mcp remove strudel\nclaude mcp add strudel node $(pwd)/dist/index.js\n\n# Restart Claude\nclaude chat\n```\n\n#### Performance issues / Slow response\n**Symptom**: Operations take longer than expected\n\n**Solutions**:\n1. **Enable caching** (default, but verify):\n   - Editor caching: 100ms TTL\n   - Audio analysis: 50ms TTL\n\n2. **Use headless mode** for faster operation:\n   ```json\n   // config.json\n   { \"headless\": true }\n   ```\n\n3. **Batch operations**:\n   ```\n   Instead of:\n   - Add drums\n   - Add bass\n   - Add melody\n\n   Do:\n   - Generate complete pattern with drums, bass, and melody\n   ```\n\n4. **Reduce browser overhead**:\n   - Close other browser instances\n   - Disable browser DevTools\n   - Use resource blocking (enabled by default)\n\n#### Patterns not saving\n**Symptom**: `pattern_store({ action: \"save\" })` fails or patterns don't persist\n\n**Solutions**:\n```bash\n# Check patterns directory exists\nls -la ./patterns\n\n# Create manually if needed\nmkdir -p ./patterns\n\n# Verify write permissions\ntouch ./patterns/test.json\nrm ./patterns/test.json\n\n# Check for invalid pattern names\n# Valid: \"techno-beat-1\", \"my_pattern\", \"track001\"\n# Invalid: \"pattern/with/slashes\", \"name:with:colons\"\n```\n\n### Platform-Specific Issues\n\n#### macOS\n```bash\n# Keyboard shortcut uses Meta (Cmd) key\n# Already handled by ControlOrMeta\n\n# If Chromium crashes on M1/M2:\nnpx playwright install chromium --with-deps\n```\n\n#### Linux\n```bash\n# Install system dependencies\nsudo npx playwright install-deps chromium\n\n# If running in Docker/headless environment:\n# Ensure config.json has headless: true\n```\n\n#### Windows\n```bash\n# Use PowerShell or Git Bash\n# Paths should use forward slashes in config.json\n\n# If Chromium doesn't launch:\nnpx playwright install chromium\n```\n\n### Debugging Tips\n\n**Enable Verbose Logging**\n```bash\n# Set environment variable\nDEBUG=* node dist/index.js\n\n# Or in Claude:\nYou: Enable detailed logging for the next operation\n```\n\n**Check Browser State**\n```\nYou: Show me the current browser initialization state\n     and any cached patterns\n\nClaude: Browser state:\n- Initialized: true\n- Cached patterns: 2\n- Undo stack depth: 5\n- Last operation: edit_pattern (2.5s ago)\n```\n\n**Validate Pattern Syntax**\n```\nYou: Before playing, validate this pattern syntax:\n     s(\"bd*4, ~ cp ~ cp\")\n\nClaude: [Checks syntax]\nValid Strudel pattern.\nReady to play.\n```\n\n### Getting Help\n\nIf you encounter issues not covered here:\n\n1. **Check existing issues**: [GitHub Issues](https://github.com/williamzujkowski/live-coding-music-mcp/issues)\n2. **Run integration tests**: `npm run test:integration`\n3. **Enable debug mode**: `DEBUG=* npm start`\n4. **Consult Strudel docs**: [Strudel.cc documentation](https://strudel.cc/learn)\n5. **Create new issue**: Include error messages, OS, Node version, and steps to reproduce\n\n## Contributing\n\nPRs welcome — bug fixes, docs, tests, new tools. See **[CONTRIBUTING.md](CONTRIBUTING.md)** for the contribution guide and **[DEVELOPMENT.md](DEVELOPMENT.md)** for setup and workflow.\n\nFor non-trivial work, open a GitHub issue first ([issue policy in CLAUDE.md](CLAUDE.md#github-issues-workflow)). For typos and small fixes, a PR directly is fine.\n\n[GitHub Discussions](https://github.com/williamzujkowski/live-coding-music-mcp/discussions) are open for use-case questions and design conversations.\n\n## License\n\n**AGPL-3.0-or-later** — see [LICENSE](LICENSE) for the full text.\n\nThis project depends on `@strudel/core`, `@strudel/mini`, `@strudel/tonal`, and `@strudel/transpiler`, which are AGPL-3.0 licensed by the upstream [Strudel project](https://codeberg.org/uzu/strudel). Since we `import` from those packages and redistribute the combined work via npm, this project must be distributed under the same copyleft terms. If you fork or redistribute, you must keep the AGPL license and provide source access to any network-accessible users (AGPL §13).\n\nEarlier versions of this package (including `@williamzujkowski/strudel-mcp-server` prior to deprecation) shipped with an MIT declaration — that was incorrect given the AGPL dependencies. v2.0.0 of `@williamzujkowski/live-coding-music-mcp` corrects the license to AGPL-3.0-or-later. v1.0.0 of this package is deprecated; install v2.0.0 or later (current: v4.0.0).\n\n## Acknowledgments\n\n- [Strudel.cc](https://strudel.cc) — pattern-based live coding environment (this project is a fan adapter, not affiliated)\n- [TidalCycles](https://tidalcycles.org) — original pattern language Strudel descends from\n- [Anthropic](https://anthropic.com) — Claude and the MCP protocol\n- [Playwright](https://playwright.dev) — browser automation\n\n---\n\n**v4.0.0** — Open source, AGPL-3.0-or-later, experimental | [Report issues](https://github.com/williamzujkowski/live-coding-music-mcp/issues) | [Contribute](https://github.com/williamzujkowski/live-coding-music-mcp/pulls)\n\n*This project is under active development. Core features work, but expect bugs and breaking changes. Not recommended for production use.*","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliamzujkowski%2Flive-coding-music-mcp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwilliamzujkowski%2Flive-coding-music-mcp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwilliamzujkowski%2Flive-coding-music-mcp/lists"}