Pawlsa MCP
MCP server for ALSA & PipeWire
Ask AI about Pawlsa MCP
Powered by Claude Β· Grounded in docs
I know everything about Pawlsa MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
MCP server for Linux audio systems. Exposes ALSA hardware/MIDI state and PipeWire graph as MCP resources and tools over stdio.
Built to give AI assistants (Claude, etc.) direct read/write access to audio routing, mixer levels, and device enumeration on Linux.
What it does
Resources (read-only state):
- ALSA sound cards, PCM devices, mixer elements, device hints, MIDI sequencer ports
- PipeWire nodes, ports, and links with live state from registry listeners
Tools (mutations):
pw_link_create/pw_link_destroyβ route audio between PipeWire portsmixer_set_volume/mixer_set_switchβ control ALSA mixer elements (volume, mute)play_wavβ play a WAV file through ALSA (default device: pipewire)play_pcmβ play base64-encoded raw PCM samples (s16le, s32le, f32le, f64le)
Requirements
- Linux with PipeWire and ALSA
libasound2-dev/alsa-liblibpipewire-0.3-dev/pipewire- Rust 2024 edition (1.85+)
Build
cargo build --release
Usage with Claude Code
Add to ~/.claude/claude_desktop_config.json (or your MCP config):
{
"mcpServers": {
"pawlsa": {
"command": "/path/to/pawlsa-mcp"
}
}
}
Then use /mcp in Claude Code to connect. Resources are available via ReadMcpResourceTool and tools appear as mcp__pawlsa__*.
Usage with MCP Inspector
npx @modelcontextprotocol/inspector -- cargo run
Output format
Resources use a specialized columnar format that balances token use with visual clarity for users.
Mostly this is because we couldn't get json or other formats to readable in the claude code output. If the mime type ever gets respected this could switch to json.
id, state, media.class, node.name, node.description, ports(in/out) β 29, suspended, N/A, Dummy-Driver, N/A, 0/0 β 63, suspended, Audio/Sink, alsa_output.usb-..., PCM2902 Audio Codec Analog Stereo, 2/2
,separates columnsβseparates rows- Both pass through JSON strings without escaping (unlike
\n/\t) - Header row names fields once, then data rows follow
Architecture
βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
β Tokio Runtime β reads β PW Thread (std::thread) β
β βββββββββββ β
β PawlsaServer β Arc< β MainLoop + Context β
β ServerHandler impl β RwLock β Core + Registry β
β read_resource() β <PwSt β β
β call_tool() ββββββββββ€βΊ ate>> β Registry listener: β
β β β global β bind proxy β
β ALSA calls inline β pw:: β info β update state β
β (sync, fast) β chan β global_remove β rm β
β β nel β β
β ββββββββββΊβ Command handler: β
β β β CreateLink / Destroy β
βββββββββββββββββββββββββββ ββββββββββββββββββββββββββββ
License
MIT
