Skip to main content
Glama
README.md
# strudel-ai

Local **HTTP + MCP** tool for AI agents to write/edit [Strudel](https://strudel.cc) code, offline-render WAV audio, and get a structured “hearing” report (waveform, spectrogram, dB envelopes, bands, onsets, estimated BPM).

Sibling project to cryptid-crawler — finished sounds can be copied into the game later.

License: **AGPL-3.0-or-later** (inherits from Strudel / superdough).

## Quick start

```bash
cd ~/Projects/strudel-ai
npm install
npm run smoke          # render + analyze a tiny pattern
npm start              # HTTP on http://127.0.0.1:8787
npm run mcp            # MCP stdio server for Cursor
```

## Agent loop

1. `POST /sessions` → create session  
2. `PUT /sessions/:id/code` → write Strudel  
3. `POST /sessions/:id/render-analyze` → WAV + hearing report  
4. Read `hearing.summary` / artifacts; `PATCH /sessions/:id/code` to edit  
5. `GET /sessions/:id/diff?from=1&to=2` → code + metric deltas  

Same ops exist as MCP tools: `session_create`, `code_set`, `code_patch`, `render_analyze`, `hearing_get`, `session_diff`, `artifact_paths`, …

## HTTP surface

| Method | Path | Purpose |
|--------|------|---------|
| GET | `/health` | liveness |
| POST | `/sessions` | create |
| GET | `/sessions` | list |
| GET | `/sessions/:id` | meta |
| PUT | `/sessions/:id/code` | new full revision |
| PATCH | `/sessions/:id/code` | search/replace or unified diff |
| GET | `/sessions/:id/code` | read code |
| POST | `/sessions/:id/render` | offline WAV |
| POST | `/sessions/:id/analyze` | hearing pack |
| POST | `/sessions/:id/render-analyze` | both |
| GET | `/sessions/:id/revisions/:n/hearing` | JSON report |
| GET | `/sessions/:id/revisions/:n/artifacts/:name` | png/wav/json |
| GET | `/sessions/:id/diff?from=&to=` | code + hearing delta |
| POST | `/sessions/:id/open` | open Strudel.cc REPL + play WAV (mpv/xdg-open) |

Pass `"open": true` on `render-analyze` to do that automatically when finished.

```bash
# CLI: open code in Strudel editor + play media
npm run open -- out/ps1_pistol.strudel.js out/ps1_pistol.wav
npm run open -- <sessionId>
```

### Example

```bash
SID=$(curl -s -X POST http://127.0.0.1:8787/sessions -H 'content-type: application/json' -d '{"title":"demo"}' | jq -r .id)

curl -s -X PUT http://127.0.0.1:8787/sessions/$SID/code \
  -H 'content-type: application/json' \
  -d '{"code":"note(\"c3 e3 g3 c4\").s(\"sawtooth\").gain(0.4)"}' | jq .currentRevision

curl -s -X POST http://127.0.0.1:8787/sessions/$SID/render-analyze \
  -H 'content-type: application/json' \
  -d '{"cycles":2,"cps":0.5}' | jq '.hearing.summary'
```

## Cursor MCP config

Add to your MCP settings (stdio):

```json
{
  "mcpServers": {
    "strudel-ai": {
      "command": "npx",
      "args": ["tsx", "src/cli.ts", "mcp"],
      "cwd": "/home/agbowman99/Projects/strudel-ai"
    }
  }
}
```

## Notes

- Default sample bank is `github:tidalcycles/dirt-samples` (override with `STRUDEL_AI_SAMPLES`). Synths (`sawtooth`, `sine`, …) come from `superdough`.
- `@kabelsalat/web` is patched on `postinstall` so Node can import `SalatRepl`.
- Session data lives in `./sessions/` (gitignored).
- Architecture diagram: mermaid-lite project **Strudel AI** (`ml show "Strudel AI"`).