# Strudel MCP Server
> π΅ Open source MCP server for AI-powered music generation with Strudel.cc
>
> **Status:** Actively developed | Experimental | Contributions welcome
<a href="https://glama.ai/mcp/servers/@williamzujkowski/strudel-mcp-server">
<img width="380" height="200" src="https://glama.ai/mcp/servers/@williamzujkowski/strudel-mcp-server/badge" alt="Strudel Server MCP server" />
</a>
[](https://github.com/williamzujkowski/strudel-mcp-server/actions)
[](https://www.npmjs.com/package/@williamzujkowski/strudel-mcp-server)
[]()
[](LICENSE)
An experimental Model Context Protocol (MCP) server that enables Claude to control [Strudel.cc](https://strudel.cc/) for AI-assisted music generation, live coding, and algorithmic composition.
**Current State:** Functional but under active development. Core features work reliably, but expect rough edges. Test coverage is at 69% with 712 tests passing (743 total, 31 skipped). See [open issues](https://github.com/williamzujkowski/strudel-mcp-server/issues) for known limitations.
## Table of Contents
- [Features](#-features)
- [Installation](#-installation)
- [Quick Start](#-quick-start)
- [Available Tools](#-available-tools-52)
- [Usage Examples](#-usage-examples)
- [Architecture](#-architecture)
- [Advanced Usage](#-advanced-usage)
- [Configuration](#-configuration)
- [Troubleshooting](#-troubleshooting)
- [Development](#-development)
- [Contributing](#-contributing)
## β¨ Features
### πΉ Complete Music Control
- **52 MCP Tools**: Comprehensive suite for music creation and manipulation
- **Real Browser Automation**: Direct control of Strudel.cc through Playwright
- **Live Audio Analysis**: Real-time frequency analysis via Web Audio API
- **Pattern Generation**: AI-powered creation across 8+ music genres
- **Music Theory Engine**: Scales, chords, progressions, euclidean rhythms
- **Session Management**: Save, load, undo/redo with pattern storage
### π§ Testing & Development Status
- β
**Test Suite**: 712 tests passing (743 total, 31 skipped)
- β οΈ **Code Coverage**: 69% statement coverage (goal: 80%)
- β
**Browser Integration**: Works with live Strudel.cc website
- β
**Audio Analysis**: Real-time FFT analysis functional
- β
**Pattern Generation**: Core music generation features working
- β
**OIDC Publishing**: Secure npm publishing with provenance attestation
**Not Production-Ready:** This is experimental software under active development. Use for exploration and experimentation. Expect breaking changes, bugs, and incomplete features. See [CONTRIBUTING.md](CONTRIBUTING.md) to help improve it.
### πΌ Example Patterns
Explore 14 curated example patterns across 7 genres in [`patterns/examples/`](patterns/examples/):
- **Techno**: Hard techno, minimal techno
- **House**: Deep house, tech house
- **Drum & Bass**: Liquid, neurofunk
- **Ambient**: Dark ambient, drone
- **Trap**: Modern trap, cloud trap
- **Jungle**: Classic jungle, ragga jungle
- **Jazz**: Bebop, modal jazz
Each example includes pattern code, BPM, key, and description. See [`patterns/examples/README.md`](patterns/examples/README.md) for details.
## π¦ Installation
### From npm
```bash
npm install -g @williamzujkowski/strudel-mcp-server
```
### From Source
```bash
# Clone repository
git clone https://github.com/williamzujkowski/strudel-mcp-server.git
cd strudel-mcp-server
# Install dependencies
npm install
# Install Chromium for browser automation
npx playwright install chromium
# Build the project
npm run build
```
## π― Quick Start
### 1. Add to Claude
```bash
# If installed globally
claude mcp add strudel strudel-mcp
# If built from source
claude mcp add strudel node /path/to/strudel-mcp-server/dist/index.js
```
### 2. Start Using
```bash
claude chat
```
Then ask Claude:
- "Initialize Strudel and create a techno beat"
- "Generate a jazz chord progression in F major"
- "Create a drum & bass pattern at 174 BPM"
## π οΈ Available Tools (52)
### Core Control (10 tools)
| Tool | Description | Example |
|------|-------------|---------|
| `init` | Initialize Strudel in browser | "Initialize Strudel" |
| `write` | Write pattern to editor | "Write pattern: s('bd*4')" |
| `play` | Start playback | "Play the pattern" |
| `stop` | Stop playback | "Stop playing" |
| `clear` | Clear editor | "Clear the editor" |
| `get_pattern` | Get current pattern | "Show current pattern" |
| `append` | Add to pattern | "Add hi-hats" |
| `insert` | Insert at line | "Insert at line 2" |
| `replace` | Replace text | "Replace bd with sn" |
| `pause` | Pause playback | "Pause" |
### Pattern Generation & Manipulation (10 tools)
| Tool | Description | Options |
|------|-------------|---------|
| `generate_pattern` | Complete patterns | techno, house, dnb, ambient, trap, jungle, jazz |
| `generate_drums` | Drum patterns | All styles + complexity (0-1) |
| `generate_bassline` | Bass patterns | techno, house, dnb, acid, dub, funk, jazz |
| `generate_melody` | Melodic lines | Any scale, custom length |
| `generate_variation` | Pattern variations | subtle, moderate, extreme, glitch |
| `transpose` | Transpose notes | Β±12 semitones |
| `reverse` | Reverse pattern | - |
| `stretch` | Time stretch | Factor 0.1-10 |
| `quantize` | Quantize to grid | 1/4, 1/8, 1/16, etc. |
| `humanize` | Add timing variation | Amount 0-1 |
### Music Theory (6 tools)
| Tool | Description | Options |
|------|-------------|---------|
| `generate_scale` | Generate scales | major, minor, modes, pentatonic, blues |
| `generate_chord_progression` | Chord progressions | pop, jazz, blues, rock, folk |
| `generate_euclidean` | Euclidean rhythms | hits/steps/sound |
| `generate_polyrhythm` | Polyrhythms | Multiple patterns |
| `generate_fill` | Generate drum fills | All styles, 1-4 bars |
| `apply_scale` | Apply scale to notes | Any scale |
### Effects (4 tools)
| Tool | Description |
|------|-------------|
| `add_effect` | Add audio effect (reverb, delay, etc.) |
| `remove_effect` | Remove an effect from the chain |
| `set_tempo` | Set BPM (60-200) |
| `add_swing` | Add swing feel (0-1 amount) |
### Session Management (5 tools)
| Tool | Description |
|------|-------------|
| `save` | Save pattern with tags |
| `load` | Load saved pattern |
| `list` | List all patterns |
| `undo` | Undo last action |
| `redo` | Redo action |
### Pattern History (3 tools)
| Tool | Description |
|------|-------------|
| `list_history` | Browse pattern history with timestamps and previews |
| `restore_history` | Restore a previous pattern by ID |
| `compare_patterns` | Compare two patterns showing line-by-line differences |
### Audio Analysis (6 tools)
| Tool | Description |
|------|-------------|
| `analyze` | Basic audio analysis (frequency, playing state) |
| `analyze_spectrum` | FFT spectral analysis |
| `analyze_rhythm` | Rhythm complexity analysis |
| `detect_tempo` | BPM detection |
| `detect_key` | Musical key detection |
| `validate_pattern_runtime` | Validate pattern with browser error checking |
### UX & Browser Control (6 tools)
| Tool | Description |
|------|-------------|
| `compose` | One-shot pattern generation with auto-play |
| `status` | Get current browser/playback state |
| `diagnostics` | Detailed system diagnostics |
| `show_browser` | Bring browser window to foreground |
| `screenshot` | Capture browser screenshot |
| `show_errors` | Display captured console errors |
### Performance (2 tools)
| Tool | Description |
|------|-------------|
| `performance_report` | Timing metrics and bottleneck analysis |
| `memory_usage` | Memory consumption statistics |
## π΅ Usage Examples
### Basic Pattern Creation
**Create a Simple Beat**
```
You: Initialize Strudel and create a simple techno beat
Claude: [Initializes browser]
[Generates and writes pattern]
[Starts playback]
Pattern created:
setcpm(130)
stack(
s("bd*4"),
s("~ cp ~ cp"),
s("hh*8").gain(0.4)
).gain(0.8)
```
**Generate a Bassline**
```
You: Add a techno bassline in C
Claude: [Generates bassline]
[Appends to current pattern]
Added: note("c2 c2 c2 c2").s("sawtooth").cutoff(800)
```
### Advanced Music Generation
**Jazz Composition**
```
You: Create a jazz progression in F major with a walking bass
Claude: Generated progression: "Gm7" "C7" "Fmaj7"
Pattern:
stack(
note("Gm7" "C7" "Fmaj7").struct("1 ~ ~ ~").s("piano"),
note("g2 c2 f2").s("sine").gain(0.7)
)
```
**Drum & Bass Track**
```
You: Generate a complete drum & bass track at 174 BPM
Claude: [Creates multi-layer pattern with drums, bass, and pads]
// dnb pattern in C at 174 BPM
setcpm(174)
stack(
// Drums
s("bd ~ ~ [bd bd] ~ ~ bd ~, ~ ~ cp ~ ~ cp ~ ~").fast(2),
// Bass
note("c1 ~ ~ c2 ~ c1 ~ ~").s("square").cutoff(400),
// Pads (atmospheric)
note("c3 eb3 g3 bb3").s("sawtooth")
.attack(2).release(4).room(0.8).gain(0.6)
)
```
### Real-Time Manipulation
**Live Audio Analysis**
```
You: Analyze what's playing and show me the frequency breakdown
Claude: Audio Analysis Results:
{
"connected": true,
"features": {
"average": 78.5,
"peak": 180,
"peakFrequency": 120,
"bass": 145,
"mid": 82,
"treble": 45,
"isPlaying": true,
"brightness": "balanced"
}
}
Strong bass presence detected - typical for techno/house patterns.
```
**Pattern Variations**
```
You: Create a glitchy variation of the current pattern
Claude: [Applies glitch transformation]
Added: .sometimes(x => x.chop(8).rev).rarely(x => x.speed(-1))
```
### Multi-Track Composition
**Layered Ambient Track**
```
You: Create an ambient soundscape with multiple layers
Claude: [Generates complex multi-layer pattern]
setcpm(90)
stack(
// Deep bass drone
note("c1").s("sine").attack(4).release(8).gain(0.5),
// Texture pad
note("c3 eb3 g3").s("sawtooth")
.attack(2).release(6).room(0.9).gain(0.4),
// Sparse percussion
s("bd ~ ~ ~, ~ ~ ~ hh:8").room(0.9).gain(0.3),
// Melodic sparkles
note("c5 g5 eb5 bb5").struct("~ 1 ~ 1 ~ ~ 1 ~")
.s("triangle").delay(0.5).room(0.8).gain(0.3)
)
```
### Session Management
**Save and Load Patterns**
```
You: Save this pattern as "techno-groove-1" with tags "techno" and "experimental"
Claude: Pattern saved as "techno-groove-1"
---
You: List all my techno patterns
Claude: Saved patterns with tag "techno":
β’ techno-groove-1 [techno, experimental] - 2025-10-23T19:30:00.000Z
β’ acid-bassline [techno, acid] - 2025-10-23T18:15:00.000Z
---
You: Load "acid-bassline"
Claude: Loaded pattern "acid-bassline"
[Pattern written to editor]
```
### Music Theory Applications
**Generate Euclidean Rhythms**
```
You: Create a 5/8 euclidean rhythm with kick drum
Claude: Generated Euclidean rhythm (5/8)
Pattern: s("bd").struct("1 ~ 1 ~ 1 1 ~ 1")
```
**Complex Polyrhythms**
```
You: Generate a polyrhythm with kick (4/16), snare (7/16), and hi-hat (3/16)
Claude: Generated polyrhythm
stack(
s("bd").euclid(4, 16),
s("cp").euclid(7, 16),
s("hh").euclid(3, 16)
)
```
### Integration with LLM Agents
**AI-Assisted Composition**
```
You: Analyze the mood of my current pattern and suggest complementary elements
Claude: [Analyzes pattern structure and audio features]
Your pattern has:
- Energetic rhythm (130 BPM)
- Strong bass presence
- Minimal melodic content
Suggestions:
1. Add arpeggiated synth for movement
2. Include occasional breaks/fills
3. Layer atmospheric pad for depth
Would you like me to add any of these?
You: Add an arpeggiated synth in C minor
Claude: [Generates and adds]
note("c4 eb4 g4 bb4 c5").struct("1 1 1 1 1 1 1 1")
.s("triangle").delay(0.25).room(0.3).gain(0.5)
```
## π§ͺ Testing
All tools have been tested with real Strudel.cc interaction:
```bash
# Run integration tests
npm run test:integration
# Run browser tests
node tests/strudel-integration.js
# Test results: 435/444 tests passing (98.0%), including 19/19 browser integration tests
```
See [BROWSER_TEST_RESULTS.md](BROWSER_TEST_RESULTS.md) for detailed test results.
## βοΈ Configuration
### config.json
```json
{
"headless": false, // Set true for background operation
"strudel_url": "https://strudel.cc/",
"patterns_dir": "./patterns",
"audio_analysis": {
"fft_size": 2048,
"smoothing": 0.8
}
}
```
## ποΈ Architecture
### System Overview
The Strudel MCP Server is built with a modular architecture that separates concerns and enables robust music generation:
```
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Claude AI β
β (MCP Client) β
βββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββββββ
β MCP Protocol (stdio)
β
βββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββββββ
β EnhancedMCPServerFixed β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Tool Request Handler β β
β β - Validates inputs β β
β β - Routes to appropriate service β β
β β - Handles errors gracefully β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββ¬βββββββββββββ¬βββββββββββββ¬ββββββββββββ¬βββββββββββββββ
β β β β
ββββββΌβββββ βββββΌβββββ βββββΌβββββ ββββΌβββββββ
β Strudel β β Music β βPattern β β Pattern β
βControllerβ β Theory β βGeneratorβ β Store β
ββββββ¬βββββ ββββββββββ ββββββββββ βββββββββββ
β
ββββββΌβββββββββββββββββββββββββββββ
β Playwright Browser β
β ββββββββββββββββββββββββββββ β
β β Strudel.cc Website β β
β β ββββββββββββββββββββββ β β
β β β CodeMirror Editor β β β
β β ββββββββββββββββββββββ β β
β β ββββββββββββββββββββββ β β
β β β Audio Context β β β
β β β + Web Audio API β β β
β β ββββββββββ¬ββββββββββββ β β
β βββββββββββββΌβββββββββββββββ β
ββββββββββββββββΌβββββββββββββββββββ
β
βββββββββΌβββββββββ
β Audio Analyzer β
β - FFT Analysisβ
β - Frequency β
β - Spectral β
ββββββββββββββββββ
```
### Core Components
#### 1. **EnhancedMCPServerFixed** (`src/server/EnhancedMCPServerFixed.ts`)
Main MCP server implementation handling:
- **40+ Tool Definitions**: Complete API surface for music control
- **Request Routing**: Directs tool calls to appropriate handlers
- **State Management**: Tracks initialization, undo/redo stacks, pattern cache
- **Error Handling**: Graceful degradation and informative error messages
- **Lazy Initialization**: Browser starts only when needed
Key Features:
```typescript
- Pattern caching before browser init
- Undo/redo stack management
- Session history tracking
- Generated pattern storage
- Safe fallback mechanisms
```
#### 2. **StrudelController** (`src/StrudelController.ts`)
Browser automation layer using Playwright:
- **Browser Management**: Chromium instance lifecycle
- **Editor Control**: CodeMirror manipulation via DOM
- **Playback Control**: Keyboard shortcuts for play/stop
- **Performance Optimizations**:
- Editor content caching (100ms TTL)
- Direct CodeMirror API access
- Resource blocking (images, fonts)
- Fast DOM content loading
```typescript
// Example: Optimized pattern writing
async writePattern(pattern: string) {
await this.page.evaluate((newPattern) => {
const editor = document.querySelector('.cm-content');
const view = editor.__view;
view.dispatch({
changes: { from: 0, to: view.state.doc.length, insert: newPattern }
});
}, pattern);
}
```
#### 3. **AudioAnalyzer** (`src/AudioAnalyzer.ts`)
Real-time audio analysis via Web Audio API injection:
- **FFT Analysis**: 1024-point FFT for spectral data
- **Frequency Bands**: Bass, low-mid, mid, high-mid, treble
- **Analysis Caching**: 50ms TTL for performance
- **Features Extracted**:
- Average amplitude
- Peak frequency
- Spectral centroid
- Playing state detection
- Frequency distribution
```typescript
Features provided:
- average: Overall amplitude (0-255)
- peak: Maximum amplitude
- peakFrequency: Dominant frequency in Hz
- bass/mid/treble: Band-specific amplitudes
- brightness: Timbral classification
- isPlaying: Boolean playback state
```
#### 4. **MusicTheory** (`src/services/MusicTheory.ts`)
Music theory engine providing:
- **15+ Scales**: Major, minor, modes, pentatonic, blues, whole-tone
- **Chord Progressions**: Pop, jazz, blues, rock, folk, EDM
- **Euclidean Rhythms**: Mathematical rhythm generation
- **Arpeggio Generation**: Multiple patterns (up, down, random)
- **Note Transposition**: Semitone-based pitch shifting
Supported scales:
```typescript
major, minor, dorian, phrygian, lydian, mixolydian,
aeolian, locrian, pentatonic, blues, chromatic,
wholetone, harmonic_minor, melodic_minor
```
#### 5. **PatternGenerator** (`src/services/PatternGenerator.ts`)
AI-powered pattern creation:
- **Genre Templates**: Techno, house, DnB, trap, ambient, jazz
- **Drum Patterns**: 4 complexity levels per genre
- **Basslines**: 8 different styles
- **Melody Generation**: Scale-based with musical intervals
- **Variations**: Subtle, moderate, extreme, glitch, evolving
- **Fills**: 1-4 bar drum fills
Example generation:
```typescript
generateCompletePattern('techno', 'C', 130)
β Multi-layer pattern with drums, bass, chords, melody
```
#### 6. **PatternStore** (`src/PatternStore.ts`)
Persistent pattern storage:
- **JSON-based**: Simple file storage
- **Metadata**: Name, tags, timestamp, audio features
- **Tag Filtering**: Organize by genre, mood, project
- **Sorted Retrieval**: Most recent first
### Directory Structure
```
strudel-mcp-server/
βββ src/
β βββ server/
β β βββ EnhancedMCPServer.ts # Original implementation
β β βββ EnhancedMCPServerFixed.ts # Production version
β βββ services/
β β βββ MusicTheory.ts # Theory engine
β β βββ PatternGenerator.ts # Pattern creation
β βββ utils/
β β βββ Logger.ts # Logging utility
β βββ types/
β β βββ index.ts # TypeScript types
β βββ StrudelController.ts # Browser automation
β βββ AudioAnalyzer.ts # Audio analysis
β βββ PatternStore.ts # Pattern persistence
β βββ index.ts # Entry point
βββ tests/
β βββ browser-test.js # Browser integration
β βββ integration.test.js # Integration tests
β βββ manual-test.js # Manual testing
β βββ mcp-tools.test.ts # MCP tool tests
β βββ strudel-integration.js # Full integration
βββ patterns/ # Saved patterns
βββ config.json # Server configuration
βββ package.json # Dependencies
βββ tsconfig.json # TypeScript config
```
### Data Flow
1. **Tool Invocation**
```
Claude β MCP Protocol β EnhancedMCPServerFixed
```
2. **Pattern Generation** (without browser)
```
Server β PatternGenerator β MusicTheory β Pattern String
```
3. **Pattern Execution** (with browser)
```
Server β StrudelController β Playwright β Strudel.cc
```
4. **Audio Analysis**
```
Strudel.cc β Web Audio API β AudioAnalyzer β Feature Data
```
### Performance Characteristics
| Operation | Latency | Notes |
|-----------|---------|-------|
| Pattern Generation | <100ms | Pure computation |
| Browser Init | ~3s | One-time cost |
| Pattern Write | ~50ms | With caching |
| Play/Stop | ~100ms | Keyboard shortcuts |
| Audio Analysis | ~20ms | With 50ms cache |
| Pattern Save | ~10ms | File I/O |
### Optimization Strategies
1. **Caching**
- Editor content: 100ms TTL
- Audio analysis: 50ms TTL
- Generated patterns: Until browser init
2. **Resource Blocking**
- Images, fonts, media blocked
- Only load essential JavaScript/CSS
3. **Direct API Access**
- CodeMirror view manipulation
- Keyboard shortcuts over button clicks
4. **Lazy Loading**
- Browser starts only when needed
- Services initialized on-demand
## πΉ Pattern Examples
### Minimal Techno (Verified Working)
```javascript
setcpm(130)
stack(
s("bd*4").gain(0.9),
s("~ cp ~ cp").room(0.2),
s("hh*16").gain(0.4).pan(sine.range(-0.5, 0.5)),
note("c2 c2 eb2 c2").s("sawtooth").cutoff(800)
).swing(0.05)
```
### Drum & Bass (Verified Working)
```javascript
setcpm(174)
stack(
s("bd ~ ~ [bd bd] ~ ~ bd ~, ~ ~ sn:3 ~ ~ sn:3 ~ ~").fast(2),
s("hh*16").gain(0.5),
note("e1 ~ ~ e2 ~ e1 ~ ~").s("sine:2").lpf(200)
)
```
### Generated Jazz Progression
```javascript
// Jazz ii-V-I in F
stack(
note("Gm7" "C7" "Fmaj7").struct("1 ~ ~ ~").s("piano"),
note("g2 c2 f2").s("sine").gain(0.7)
)
```
## π³ Docker Support
```bash
# Build image
docker build -t strudel-mcp .
# Run container
docker run -it --rm strudel-mcp
# Or use docker-compose
docker-compose up
```
## π§ Development
### Setup Development Environment
```bash
# Clone the repository
git clone https://github.com/williamzujkowski/strudel-mcp-server.git
cd strudel-mcp-server
# Install dependencies
npm install
# Install Playwright browsers
npx playwright install chromium
# Build the project
npm run build
```
### Available Scripts
```bash
# Development mode with hot reload
npm run dev
# Build TypeScript to dist/
npm run build
# Start production server
npm start
# Run all tests
npm test
# Run integration tests with real browser
npm run test:integration
# Run browser-specific tests
npm run test:browser
# Validate MCP protocol compliance
npm run validate
# Lint code
npm run lint
# Format code
npm run format
# Clean build artifacts
npm clean
```
### Publishing to npm
See [NPM_PUBLISHING.md](NPM_PUBLISHING.md) for complete publishing instructions.
**Quick publish via GitHub Release:**
```bash
npm version patch # or minor, major
git push && git push --tags
gh release create v$(node -p "require('./package.json').version") --generate-notes
```
The package uses OIDC trusted publishing with provenance attestation for supply chain security.
### Project Structure
```
src/
βββ server/
β βββ EnhancedMCPServer.ts # Original implementation
β βββ EnhancedMCPServerFixed.ts # Production version with caching
β
βββ services/
β βββ MusicTheory.ts # Music theory engine
β β - 15+ scales (major, minor, modes, etc.)
β β - Chord progressions (jazz, pop, blues, etc.)
β β - Euclidean rhythm generation
β β - Arpeggio generation
β β
β βββ PatternGenerator.ts # Pattern creation service
β - Genre-specific drum patterns
β - Bassline generation
β - Melody composition
β - Pattern variations
β - Complete track generation
β
βββ utils/
β βββ Logger.ts # Logging utility
β βββ PerformanceMonitor.ts # Performance tracking
β βββ PatternValidator.ts # Pattern syntax validation
β βββ ErrorRecovery.ts # Error handling & recovery
β
βββ types/
β βββ index.ts # TypeScript type definitions
β
βββ StrudelController.ts # Browser automation
β - Chromium management via Playwright
β - CodeMirror editor manipulation
β - Playback control
β - Pattern validation
β - Error recovery
β
βββ AudioAnalyzer.ts # Real-time audio analysis
β - Web Audio API injection
β - FFT spectral analysis
β - Frequency band detection
β - Playing state monitoring
β
βββ PatternStore.ts # Pattern persistence
β - JSON-based storage
β - Tag-based organization
β - Metadata tracking
β - List caching
β
βββ index.ts # Application entry point
```
### Adding New Tools
To add a new MCP tool:
1. **Define the tool** in `getTools()` method:
```typescript
{
name: 'my_new_tool',
description: 'Description of what it does',
inputSchema: {
type: 'object',
properties: {
param1: { type: 'string', description: 'Parameter description' },
param2: { type: 'number', description: 'Numeric parameter' }
},
required: ['param1']
}
}
```
2. **Implement the handler** in `executeTool()` switch statement:
```typescript
case 'my_new_tool':
// Your implementation here
return await this.someService.doSomething(args.param1, args.param2);
```
3. **Add necessary service methods** if needed:
```typescript
// In appropriate service file
async doSomething(param1: string, param2?: number): Promise<string> {
// Implementation
return `Result: ${param1}`;
}
```
4. **Test the tool**:
```bash
# Build
npm run build
# Test via MCP
echo '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"my_new_tool","arguments":{"param1":"test"}},"id":2}' | node dist/index.js
```
### Testing Strategy
#### 1. Unit Tests
```bash
# Run with Jest
npm test
# Watch mode
npm run test:watch
```
#### 2. Integration Tests
```bash
# Full integration with real browser
npm run test:integration
# This tests:
# - Browser initialization
# - Pattern generation
# - Audio analysis
# - Pattern storage
# - All 40+ tools
```
#### 3. Manual Testing
```bash
# Development mode
npm run dev
# In another terminal
claude mcp add strudel-dev node $(pwd)/dist/index.js
claude chat
# Then interact with Claude
```
### Code Quality
**TypeScript Configuration**
```json
// tsconfig.json
{
"compilerOptions": {
"strict": true, // Strict type checking
"esModuleInterop": true, // Better module compatibility
"target": "ES2020", // Modern JavaScript
"module": "ES2020", // ES modules
"moduleResolution": "node"
}
}
```
**Linting & Formatting**
```bash
# ESLint
npm run lint
# Prettier
npm run format
# Pre-commit hooks recommended
```
### Debugging
**Enable Debug Logging**
```bash
# Set DEBUG environment variable
DEBUG=strudel:* npm start
# Or specific modules
DEBUG=strudel:controller npm start
DEBUG=strudel:audio npm start
```
**VS Code Launch Configuration**
```json
{
"type": "node",
"request": "launch",
"name": "Debug MCP Server",
"program": "${workspaceFolder}/dist/index.js",
"preLaunchTask": "npm: build",
"console": "integratedTerminal",
"env": {
"DEBUG": "strudel:*"
}
}
```
**Playwright Debugging**
```typescript
// In StrudelController.ts
this.browser = await chromium.launch({
headless: false, // See the browser
devtools: true, // Open DevTools
slowMo: 100 // Slow down actions
});
```
### Performance Monitoring
The server includes built-in performance monitoring:
```typescript
// Access performance metrics
You: Show me performance metrics
Claude: Performance Report:
{
"averageLatency": {
"init": "3.2s",
"write": "52ms",
"play": "105ms",
"analyze": "18ms"
},
"cacheHitRate": "85%",
"totalOperations": 1247,
"bottlenecks": [
{"tool": "init", "avgTime": 3200, "calls": 1},
{"tool": "write", "avgTime": 52, "calls": 156}
]
}
```
### Contributing Guidelines
1. **Fork the repository**
```bash
git clone https://github.com/YOUR_USERNAME/strudel-mcp-server.git
```
2. **Create a feature branch**
```bash
git checkout -b feature/my-new-feature
```
3. **Make your changes**
- Follow existing code style
- Add tests for new features
- Update documentation
- Ensure all tests pass
4. **Commit with meaningful messages**
```bash
git commit -m "feat: Add support for custom scale generation"
```
Follow [Conventional Commits](https://www.conventionalcommits.org/):
- `feat:` New feature
- `fix:` Bug fix
- `docs:` Documentation changes
- `refactor:` Code refactoring
- `test:` Adding tests
- `chore:` Maintenance tasks
5. **Push and create PR**
```bash
git push origin feature/my-new-feature
```
Then create a Pull Request on GitHub with:
- Clear description of changes
- Link to related issues
- Screenshots/examples if relevant
### Release Process
```bash
# 1. Update version in package.json
npm version patch # or minor/major
# 2. Update CHANGELOG.md
# Add entry for new version
# 3. Build and test
npm run build
npm test
npm run test:integration
# 4. Commit version bump
git add .
git commit -m "chore: Bump version to X.Y.Z"
# 5. Create git tag
git tag vX.Y.Z
# 6. Push to GitHub
git push origin main --tags
# 7. Publish to npm (if you have access)
npm publish --access public
# 8. Create GitHub release
gh release create vX.Y.Z --generate-notes
```
### Docker Development
```bash
# Build development image
docker build -t strudel-mcp:dev .
# Run with volume mount for hot reload
docker run -it --rm \
-v $(pwd)/src:/app/src \
-v $(pwd)/patterns:/app/patterns \
strudel-mcp:dev
# Run tests in container
docker run -it --rm strudel-mcp:dev npm test
```
### Environment Variables
```bash
# Logging level
LOG_LEVEL=debug # debug, info, warn, error
# Performance monitoring
ENABLE_PERF_MONITORING=true
# Pattern storage
PATTERNS_DIR=./patterns
# Browser configuration
HEADLESS=false
BROWSER_TIMEOUT=15000
# Audio analysis
FFT_SIZE=1024
SMOOTHING=0.8
```
## π Performance
- **Pattern Generation**: <100ms
- **Browser Initialization**: ~3 seconds
- **Pattern Writing**: Instant
- **Playback Start**: ~500ms
- **Audio Analysis**: Real-time
- **Memory Usage**: <150MB
## π Advanced Usage
### Custom Music Theory
**Create Custom Scales**
```typescript
// The MusicTheory service supports 15+ built-in scales
// You can request any combination:
You: Generate a lydian scale starting on D
Claude: D lydian scale: D, E, F#, G#, A, B, C#
```
**Complex Chord Progressions**
```typescript
You: Create a jazz ii-V-I progression in Bb with extended voicings
Claude: Generated jazz progression in Bb: "Cm7" "F7" "Bbmaj7"
Pattern:
note("Cm7" "F7" "Bbmaj7")
.struct("1 ~ ~ ~")
.s("sawtooth")
.add(note("7")) // Add 7th extensions
.room(0.4)
```
### Advanced Rhythm Techniques
**Euclidean Patterns**
```
You: Create a complex polyrhythm using euclidean patterns:
- Bass drum: 7 hits in 16 steps
- Snare: 5 hits in 16 steps
- Hi-hat: 11 hits in 16 steps
Claude: [Generates mathematically perfect polyrhythm]
stack(
s("bd").euclid(7, 16),
s("cp").euclid(5, 16),
s("hh").euclid(11, 16)
)
```
**Generative Variations**
```
You: Create 3 variations of my current pattern: subtle, moderate, and glitchy
Claude: [Generates three variants]
Version 1 (subtle):
original.sometimes(x => x.fast(2))
Version 2 (moderate):
original.every(4, x => x.rev).sometimes(x => x.fast(2))
Version 3 (glitchy):
original.sometimes(x => x.chop(8).rev).rarely(x => x.speed(-1))
```
### Performance Optimization Tips
**Pattern Caching**
```
// The server caches patterns intelligently:
// - Generated patterns stored before browser init
// - Editor content cached for 100ms
// - Audio analysis cached for 50ms
// For fastest performance:
1. Generate patterns before initializing browser
2. Initialize once and reuse the session
3. Batch multiple changes together
```
**Headless Mode**
```json
// In config.json:
{
"headless": true, // Faster, no GUI
"strudel_url": "https://strudel.cc/",
"patterns_dir": "./patterns"
}
```
### Integration Patterns
**Workflow Automation**
```
You: Create a complete track:
1. Start with techno drums at 130 BPM
2. Add acid bassline in E
3. Layer ambient pads
4. Save as "track-001" with tags "techno", "acid", "experimental"
Claude: [Executes full workflow]
[Initializes browser]
[Generates drum pattern]
[Adds bassline]
[Layers pads]
[Saves with metadata]
Complete! Pattern saved as "track-001"
```
**Audio-Reactive Composition**
```
You: Monitor the audio and suggest adjustments based on frequency balance
Claude: [Analyzes current playback]
Analysis shows:
- Bass: 180 (strong)
- Mid: 45 (weak)
- Treble: 30 (weak)
Recommendations:
1. Reduce bass gain by 20%
2. Add mid-range melodic content
3. Include hi-hat pattern for treble
Apply changes? [Yes/No]
```
### Advanced Pattern Manipulation
**Dynamic Transformations**
```
You: Apply these transformations in sequence:
1. Transpose up 3 semitones
2. Add 10% humanization
3. Apply reverb with 0.6 room size
4. Every 4th cycle, reverse the pattern
Claude: [Applies transformations]
Final pattern:
[original]
.transpose(3)
.nudge(rand.range(-0.1, 0.1))
.room(0.6)
.every(4, x => x.rev)
```
**Conditional Logic**
```
You: Create a pattern that evolves:
- Bars 1-4: Simple kick pattern
- Bars 5-8: Add snare
- Bars 9-16: Add full drum kit
- Then loop with variations
Claude: [Generates evolving pattern]
s("bd*4")
.struct("1 ~ ~ ~")
.mask("<1 1 1 1 0 0 0 0>/4") // First 4 bars
.stack(
s("~ cp ~ cp")
.mask("<0 0 0 0 1 1 1 1>/8") // Bars 5-8
)
// Full complexity from bar 9
.every(8, x => x.sometimes(y => y.fast(2)))
```
## π Troubleshooting
### Common Issues
#### Browser doesn't open
**Symptom**: `Error: Browser not initialized` or Chromium launch fails
**Solutions**:
```bash
# Install Chromium for Playwright
npx playwright install chromium
# If that fails, try installing all browsers
npx playwright install
# Check Playwright installation
npx playwright --version
# For Linux, install dependencies
sudo npx playwright install-deps chromium
```
#### Audio analysis returns "not connected"
**Symptom**: Audio analysis shows `connected: false`
**Solutions**:
1. Ensure pattern is playing first:
```
You: Play the pattern, wait 2 seconds, then analyze
```
2. Reinitialize the browser:
```
You: Stop, close the browser, reinitialize, and try again
```
3. Check audio context activation:
- Audio contexts require user interaction on some systems
- The browser window must be visible (not headless) for first run
#### Pattern syntax errors
**Symptom**: Pattern doesn't play or shows errors in console
**Solutions**:
```
Common issues:
1. Missing quotes: s(bd*4) β s("bd*4")
2. Unmatched parentheses: stack(s("bd")) β stack(s("bd")))
3. Invalid note names: note("h2") β note("c2")
Test with minimal pattern first:
s("bd*4")
Then build complexity gradually.
```
#### MCP connection issues
**Symptom**: Claude can't find the server or tools
**Solutions**:
```bash
# Verify server is built
npm run build
# Check if server responds
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | node dist/index.js
# Should return JSON with 40+ tools
# Reinstall MCP server in Claude
claude mcp remove strudel
claude mcp add strudel node $(pwd)/dist/index.js
# Restart Claude
claude chat
```
#### Performance issues / Slow response
**Symptom**: Operations take longer than expected
**Solutions**:
1. **Enable caching** (default, but verify):
- Editor caching: 100ms TTL
- Audio analysis: 50ms TTL
2. **Use headless mode** for faster operation:
```json
// config.json
{ "headless": true }
```
3. **Batch operations**:
```
Instead of:
- Add drums
- Add bass
- Add melody
Do:
- Generate complete pattern with drums, bass, and melody
```
4. **Reduce browser overhead**:
- Close other browser instances
- Disable browser DevTools
- Use resource blocking (enabled by default)
#### Patterns not saving
**Symptom**: `save` command fails or patterns don't persist
**Solutions**:
```bash
# Check patterns directory exists
ls -la ./patterns
# Create manually if needed
mkdir -p ./patterns
# Verify write permissions
touch ./patterns/test.json
rm ./patterns/test.json
# Check for invalid pattern names
# Valid: "techno-beat-1", "my_pattern", "track001"
# Invalid: "pattern/with/slashes", "name:with:colons"
```
### Platform-Specific Issues
#### macOS
```bash
# Keyboard shortcut uses Meta (Cmd) key
# Already handled by ControlOrMeta
# If Chromium crashes on M1/M2:
npx playwright install chromium --with-deps
```
#### Linux
```bash
# Install system dependencies
sudo npx playwright install-deps chromium
# If running in Docker/headless environment:
# Ensure config.json has headless: true
```
#### Windows
```bash
# Use PowerShell or Git Bash
# Paths should use forward slashes in config.json
# If Chromium doesn't launch:
npx playwright install chromium
```
### Debugging Tips
**Enable Verbose Logging**
```bash
# Set environment variable
DEBUG=* node dist/index.js
# Or in Claude:
You: Enable detailed logging for the next operation
```
**Check Browser State**
```
You: Show me the current browser initialization state
and any cached patterns
Claude: Browser state:
- Initialized: true
- Cached patterns: 2
- Undo stack depth: 5
- Last operation: write_pattern (2.5s ago)
```
**Validate Pattern Syntax**
```
You: Before playing, validate this pattern syntax:
s("bd*4, ~ cp ~ cp")
Claude: [Checks syntax]
Valid Strudel pattern.
Ready to play.
```
### Getting Help
If you encounter issues not covered here:
1. **Check existing issues**: [GitHub Issues](https://github.com/williamzujkowski/strudel-mcp-server/issues)
2. **Run integration tests**: `npm run test:integration`
3. **Enable debug mode**: `DEBUG=* npm start`
4. **Consult Strudel docs**: [Strudel.cc documentation](https://strudel.cc/learn)
5. **Create new issue**: Include error messages, OS, Node version, and steps to reproduce
## π€ Contributing
**We need your help!** This project is actively developed and welcomes contributions of all kinds:
### Ways to Contribute
- **Report Bugs**: Found an issue? [Open a bug report](https://github.com/williamzujkowski/strudel-mcp-server/issues/new)
- **Suggest Features**: Have ideas? [Create a feature request](https://github.com/williamzujkowski/strudel-mcp-server/issues/new)
- **Improve Docs**: Fix typos, add examples, clarify confusing sections
- **Write Tests**: Help us reach 80% coverage (currently 52%)
- **Fix Issues**: Check [open issues](https://github.com/williamzujkowski/strudel-mcp-server/issues) for bugs to fix
- **Add Features**: Implement new tools or improve existing ones
### Quick Start for Contributors
1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes and add tests
4. Ensure tests pass (`npm test`)
5. Commit with clear messages (`git commit -m 'fix: resolve audio analysis bug'`)
6. Push to your fork (`git push origin feature/amazing-feature`)
7. Open a Pull Request
**First time contributor?** Look for issues labeled `good-first-issue` or `help-wanted`.
### Feedback Welcome
- Questions? Open a [Discussion](https://github.com/williamzujkowski/strudel-mcp-server/discussions)
- Found something confusing? Tell us!
- Have a use case we haven't considered? Share it!
We review PRs promptly and welcome contributors of all skill levels. See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed setup instructions.
## π License
MIT License - see [LICENSE](LICENSE) file
## π Acknowledgments
- [Strudel.cc](https://strudel.cc) - Amazing live coding environment
- [TidalCycles](https://tidalcycles.org) - Pattern language inspiration
- [Anthropic](https://anthropic.com) - Claude AI and MCP protocol
- [Playwright](https://playwright.dev) - Reliable browser automation
---
**v2.2.0** - Open Source | Experimental | [Report Issues](https://github.com/williamzujkowski/strudel-mcp-server/issues) | [Contribute](https://github.com/williamzujkowski/strudel-mcp-server/pulls)
*This project is under active development. Core features work, but expect bugs and breaking changes. Not recommended for production use.*