Skip to main content
Glama

Strudel MCP Server

šŸŽµ Open source MCP server for AI-powered music generation with Strudel.cc

Status: Actively developed | Experimental | Contributions welcome

CI npm version Tools License

An experimental Model Context Protocol (MCP) server that enables Claude to control 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 52% with 435 out of 444 tests passing. See open issues for known limitations.

Table of Contents

Related MCP server: FluidSynth MCP Server

✨ Features

šŸŽ¹ Complete Music Control

  • 40+ 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: 435 of 444 tests passing (97.9% pass rate)

  • āš ļø Code Coverage: 52% 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

  • āš ļø Error Handling: Basic retry logic implemented, improvements ongoing

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 to help improve it.

šŸ“¦ Installation

From npm

npm install -g @williamzujkowski/strudel-mcp-server

From Source

# 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

# 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

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 (40+)

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 (10 tools)

Tool

Description

Styles/Options

generate_pattern

Complete patterns

techno, house, dnb, ambient, trap, jungle

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

generate_fill

Drum fills

All styles, 1-4 bars

transpose

Transpose notes

±12 semitones

reverse

Reverse pattern

-

stretch

Time stretch

Factor 0.1-10

humanize

Add timing variation

Amount 0-1

Music Theory (10 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

apply_scale

Apply scale to notes

Any scale

quantize

Quantize to grid

1/4, 1/8, 1/16, etc

Audio & Effects (5 tools)

Tool

Description

Returns

analyze

Audio analysis

Frequency data, playing state

analyze_spectrum

FFT analysis

Spectral data

add_effect

Add audio effect

Effect chain

set_tempo

Set BPM

60-200 BPM

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

šŸŽµ 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:

# 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 for detailed test results.

āš™ļø Configuration

config.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:

- 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

// 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

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:

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:

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)

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)

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

// 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

# 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

# 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

# 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

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:

{ 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'] } }
  1. Implement the handler in executeTool() switch statement:

case 'my_new_tool': // Your implementation here return await this.someService.doSomething(args.param1, args.param2);
  1. Add necessary service methods if needed:

// In appropriate service file async doSomething(param1: string, param2?: number): Promise<string> { // Implementation return `Result: ${param1}`; }
  1. Test the tool:

# 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

# Run with Jest npm test # Watch mode npm run test:watch

2. Integration Tests

# 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

# 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

// 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

# ESLint npm run lint # Prettier npm run format # Pre-commit hooks recommended

Debugging

Enable Debug Logging

# 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

{ "type": "node", "request": "launch", "name": "Debug MCP Server", "program": "${workspaceFolder}/dist/index.js", "preLaunchTask": "npm: build", "console": "integratedTerminal", "env": { "DEBUG": "strudel:*" } }

Playwright Debugging

// 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:

// 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

    git clone https://github.com/YOUR_USERNAME/strudel-mcp-server.git
  2. Create a feature branch

    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

    git commit -m "feat: Add support for custom scale generation"

    Follow Conventional Commits:

    • feat: New feature

    • fix: Bug fix

    • docs: Documentation changes

    • refactor: Code refactoring

    • test: Adding tests

    • chore: Maintenance tasks

  5. Push and create PR

    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

# 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

# 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

# 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

// 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

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

// 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:

# 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:

# 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:

    // 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:

# 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

# Keyboard shortcut uses Meta (Cmd) key # Already handled by ControlOrMeta # If Chromium crashes on M1/M2: npx playwright install chromium --with-deps

Linux

# Install system dependencies sudo npx playwright install-deps chromium # If running in Docker/headless environment: # Ensure config.json has headless: true

Windows

# 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

# 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

  2. Run integration tests: npm run test:integration

  3. Enable debug mode: DEBUG=* npm start

  4. Consult Strudel docs: Strudel.cc documentation

  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

  • Suggest Features: Have ideas? Create a feature request

  • Improve Docs: Fix typos, add examples, clarify confusing sections

  • Write Tests: Help us reach 80% coverage (currently 52%)

  • Fix Issues: Check open 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

  • 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 for detailed setup instructions.

šŸ“„ License

MIT License - see LICENSE file

šŸ™ Acknowledgments


v2.2.0 - Open Source | Experimental | Report Issues | Contribute

This project is under active development. Core features work, but expect bugs and breaking changes. Not recommended for production use.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/williamzujkowski/strudel-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server