An ensemble performance space where AI agents jam together and make music.
Hootenanny exposes music creation tools via MCP, letting Claude, Gemini, and other tool callers generate, arrange, and play music collaboratively. Connect your favorite AI coding assistant and start making music.
Generate MIDI β Orpheus creates musical sequences from nothing:
orpheus_generate({
temperature: 1.0,
max_tokens: 512,
tags: ["ambient", "exploration"]
})
// β { job_id: "abc123..." } // Async - poll when readyWrite music in ABC notation β Human-readable music β MIDI:
abc_to_midi({
abc: `X:1
T:Midnight Blues
K:Em
E2 G A B2 | B2 A G E2 |
G2 E D E2 | E4 z2 |`,
tempo_override: 72,
transpose: -2
})
// β { artifact_id: "...", content_hash: "..." }Continue where you left off β Extend existing MIDI:
orpheus_continue({
input_hash: "hash_of_your_midi...",
temperature: 1.1,
num_variations: 3
})Bridge sections β Smooth transitions between parts:
orpheus_bridge({
section_a_hash: "verse_hash...",
section_b_hash: "chorus_hash...",
max_tokens: 128
})Render to audio β MIDI + SoundFont β WAV:
midi_render({
input_hash: "midi_hash...",
soundfont_hash: "sf2_hash...",
sample_rate: 44100
})Play on a timeline β DAW-style transport with beat-based timing:
timeline_region_create({
position: 0, // Start at beat 0
duration: 8, // 8 beats long
behavior_type: "play_audio",
content_id: "artifact_123"
})
play({})
tempo({ bpm: 120 })Detect beats β Analyze audio for rhythm:
beats_detect({ audio_hash: "wav_hash..." })
// β Beat positions, downbeats, frame-level activationsQuery with Trustfall β Find artifacts by lineage, tags, vibes:
graph_query({
query: `{
Artifact(tag: "type:midi") {
id @output
creator @output
tags { tag @output @filter(op: "has_substring", value: ["jazzy"]) }
}
}`
})# Clone and build
git clone https://github.com/anthropics/hootenanny
cd hootenanny
cargo build --release
# Start the services
./target/release/hootenanny & # Control plane (port 5580)
./target/release/holler serve & # MCP gateway (port 8080)
./target/release/chaosgarden & # Audio daemon
# Configure Claude Code
# Add to your MCP config:
{
"mcpServers": {
"holler": {
"command": "/path/to/holler",
"args": ["mcp"]
}
}
}Requirements:
- Rust 1.75+
- Linux with PipeWire (audio playback)
- GPU services for generation (Orpheus, etc.) β see Infrastructure Setup
- Python 3.10+ with
mido,numpy(for vibeweaver kernel)
Organized by prefix for discoverability. Call help() to explore.
| Prefix | Domain | Key Tools |
|---|---|---|
orpheus_* |
MIDI generation | generate, continue, bridge |
abc_* |
ABC notation | validate, to_midi |
midi_* |
MIDI operations | render, classify, info |
audio_* |
Audio I/O | output_attach, input_attach, monitor |
musicgen_* |
Textβaudio | generate |
yue_* |
Lyricsβsong | generate |
beats_detect |
Rhythm analysis | Beat/downbeat detection |
audio_analyze |
CLAP embeddings | Classification, similarity |
timeline_* |
Playback | region_create, region_move, clear |
play/pause/stop/seek/tempo |
Transport | DAW controls |
artifact_* |
Storage | upload, list, get |
job_* |
Async jobs | poll, list, cancel |
graph_* |
Queries | query, context, bind, connect |
kernel_* |
Python | eval, session, reset |
config/status/storage_stats |
System | Diagnostics |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β AI Agents β
β (Claude Code, Gemini, custom MCP clients) β
ββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β HTTP/SSE (MCP Protocol)
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β HOLLER β
β MCP β ZMQ Gateway β
β β’ Routes tool calls to backends β’ CLI for manual testing β
β β’ Broadcasts events via SSE β’ Dynamic tool discovery β
ββββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ
β ZMQ (hooteproto / Cap'n Proto)
βββββββββββββββββββΌββββββββββββββββββ
βΌ βΌ βΌ
ββββββββββββββββββββββββ βββββββββββββββ ββββββββββββββββββββββββββββββββββ
β HOOTENANNY β β VIBEWEAVER β β CHAOSGARDEN β
β (Control Plane) β β (Python) β β (Realtime Audio) β
β β β β β β
β β’ Job orchestration β β β’ Kernel β β β’ PipeWire integration β
β β’ Artifact store β β β’ Sessions β β β’ Timeline playback β
β β’ GPU service calls β β β’ Rules β β β’ Beat-synced transport β
β β’ Trustfall queries β β β β β’ Audio graph routing β
ββββββββββββ¬ββββββββββββ ββββββββ¬βββββββ ββββββββββββββββββββββββββββββββββ
β β
ββββββββββ¬ββββββββββββ
βΌ
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β GPU SERVICES (HTTP) β
β Orpheus :2000 β MusicGen :2006 β CLAP :2007 β YuE :2008 β BeatThis :2012 β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
| Crate | Purpose |
|---|---|
| holler | MCP gateway β routes HTTP/SSE to ZMQ backends |
| hootenanny | Control plane β jobs, artifacts, GPU clients, queries |
| hooteproto | Wire protocol β Cap'n Proto schemas over ZMQ |
| chaosgarden | Audio daemon β PipeWire, timeline, transport |
| vibeweaver | Python kernel β PyO3 embedded interpreter |
| cas | Content-addressed storage β BLAKE3 hashing |
| abc | ABC notation parser and MIDI converter |
| audio-graph-mcp | Trustfall adapter for unified queries |
| hooteconf | Layered configuration loading |
Async by default β Slow tools return job_id immediately:
job = orpheus_generate({...}) // Returns instantly
result = job_poll({ // Wait for completion
job_ids: [job.job_id],
timeout_ms: 60000
})Content-addressable β BLAKE3 hashing, automatic dedup. Share hashes, not bytes.
Artifact-centric β Every piece of content gets lineage tracking:
artifact_upload({
file_path: "/path/to/file.mid",
mime_type: "audio/midi",
parent_id: "artifact_that_inspired_this",
tags: ["variation", "take-2"]
})Beat-based timing β Timeline uses beats, not seconds:
// Position 4 = beat 4, duration 2 = 2 beats
timeline_region_create({ position: 4, duration: 2, ... })Lazy Pirate β Services start in any order. ZMQ handles reconnection.
# Install dependencies
cargo install cargo-watch just
# Run with auto-reload
cargo watch -x 'run -p holler -- serve'
# Run tests
cargo test --workspace
# Build all
cargo build --releaseLayered config loading: system β user β project β env vars.
# ~/.config/hootenanny/config.toml
[infra.bind]
http_bind_addr = "127.0.0.1:8080"
zmq_router = "tcp://0.0.0.0:5580"
[bootstrap.models]
orpheus = "http://127.0.0.1:2000"
musicgen = "http://127.0.0.1:2006"
[bootstrap.media]
soundfont_dirs = ["~/midi/SF2", "/usr/share/sounds/sf2"]- Add Cap'n Proto schema in
crates/hooteproto/schemas/tools.capnp - Add Rust types in
crates/hooteproto/src/request.rs - Implement dispatch in
crates/hootenanny/src/api/typed_dispatcher.rs - Register in
crates/holler/src/tools_registry.rs
See CLAUDE.md for detailed guidelines.
Experimental research software exploring human-AI music collaboration. We use it daily β expect rough edges.
Working:
- β MIDI generation (Orpheus: generate, continue, bridge)
- β ABC notation β MIDI conversion
- β Audio rendering with SoundFonts
- β Timeline playback via PipeWire
- β Async job system with parallel generation
- β Artifact tracking with lineage
- β Trustfall queries across the graph
- β Python kernel for scripting
Evolving:
- π Multi-agent coordination patterns
- π Real-time collaboration features
- π Audio input/recording
- π MIDI device integration
Built collaboratively with Claude and Gemini. Contributions welcome.
See BOTS.md for coding guidelines β the same instructions we give our AI collaborators.
MIT
Contributors: Amy Tobey, π€ Claude, π Gemini