tonearmd-mcp
Provides tools for interacting with a Roon music system, including reading playback state, searching the library, playing music, controlling transport, transferring playback between zones, and pinning zones.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@tonearmd-mcpwhat's playing right now?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
tonearmd-mcp
An MCP server that lets Claude read your Roon state, search your library, and put music on — by talking to tonearm's daemon.
Requires a running tonearmd
This server has no Roon credentials of its own and never talks to Roon
directly. tonearmd owns the only Roon connection, which is what keeps Roon
pairing to a single approval. Install and pair tonearm first; this server
connects to its unix socket at $XDG_RUNTIME_DIR/tonearm/sock.
Related MCP server: lms-mcp-server
Install
git clone https://github.com/ssandys/tonearmd-mcp.git
cd tonearmd-mcp
npm installThen point your MCP client at it:
{
"mcpServers": {
"tonearm": {
"command": "node",
"args": ["/absolute/path/to/tonearmd-mcp/src/server.js"]
}
}
}Running it on the network
By default the MCP client spawns this over stdio, on the same machine as
tonearmd. To let MCP clients elsewhere on your LAN drive the same daemon:
node src/server.js --http # 0.0.0.0:9340
node src/server.js --http 9999 # another port
node src/server.js --http 127.0.0.1:9999On first start it generates a key at ~/.config/tonearm-mcp/key (mode 0600)
and prints it once. On every later start it prints where to find it instead —
read it back with cat ~/.config/tonearm-mcp/key. Point remote clients at the
URL with that key as a bearer token:
{
"mcpServers": {
"tonearm": {
"type": "http",
"url": "http://your-tonearm-box:9340/mcp",
"headers": { "Authorization": "Bearer <the key>" }
}
}
}To run it as a service, copy systemd/tonearmd-mcp.service to
~/.config/systemd/user/, adjust ExecStart to your checkout path, then
systemctl --user enable --now tonearmd-mcp.
This is plain HTTP, for a LAN you trust. Anything already on the network can read the key and your listening history. That is a deliberate trade: TLS here would mean certificates every MCP client has to trust. If your network has guests or devices you don't trust, put a reverse proxy terminating TLS in front of it rather than exposing this directly.
All sessions share one zone. Two clients asking for music at once get one zone
and last-writer-wins, not two streams — see docs/FOLLOWUPS.md item 2.
Requests carrying a non-localhost Origin header are refused with a bare 403,
as DNS-rebinding protection — so a browser-based MCP client on the LAN needs a
reverse proxy in front of this server; non-browser clients send no Origin
and are unaffected.
Tools
Tool | Arguments | What it does |
| — | What is playing, whether its zone is pinned, and which zones exist |
|
| Albums and tracks matching the query, each with a |
|
| Plays a search result in the followed zone |
|
|
|
|
| Moves what is playing to another zone, keeping position |
|
| Changes which zone the bar widget follows |
Play and transport act on the zone the widget is following. To put music in a
different room, play it and then tonearm_transfer it there.
How search works
A Roon search does not return albums — it returns category rows (Artists,
Albums, Composers, Tracks, Works). This server descends into Albums
and Tracks, capped at ten each, and returns a flat list of candidates so
Claude can pick rather than guess.
Each candidate carries an opaque ref encoding the walk that found it. Playing
one re-runs that walk rather than holding a browse cursor open, because a
Claude turn can take minutes and a held cursor goes stale. The ref also records
the title it was minted with, and playing refuses if the row at that position
no longer matches — so a shifted result is an error you can see, never a
different album playing quietly.
Running the tests
npm test101 tests, no network and no daemon required — the fixtures are real daemon replies captured from a live Roon Core.
License
MIT. The only dependencies are @modelcontextprotocol/sdk and zod.
This server cannot be deployed
Maintenance
Related MCP Connectors
Control Sonos from any MCP client. No bridge hardware; connects over OAuth — no API key to paste.
Full Spotify Web API coverage - albums, artists, playlists, player controls, and more.
Search MusicBrainz artists, releases, works, labels; resolve ISRC/ISWC/barcode; fetch cover art.
MCP server for Yoto: manage cards, tracks, icons and family devices from any MCP client.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server to control the Roon music player, enabling AI agents to search music, manage playback, and adjust volume across zones.918 npm2MIT
- FlicenseNot gradedqualityCmaintenanceEnables natural-language querying and control of a Lyrion Music Server, including music library searches, album playback, player controls, and play-history tracking.-
- AlicenseAqualityBmaintenanceEnables controlling Spotify playback and building LLM-reasoned playlists from any MCP client, reusing an existing spotify_player session with no OAuth.14MIT
- AlicenseAqualityBmaintenanceEnables controlling Bluesound/BluOS players with transport, volume, multi-room grouping, presets, and search/play across streaming services like TIDAL and TuneIn.19MIT