Ever since @Arthur_Soares posted his reverse-engineering project, I have been itching to put it to task. As today my wife and daughter were out all day – I set out creating an MCP server for Roon that (almost :-)) offers the same functionality as the Roon Remote client – with a lot more flexibility. A few words tell more than a thousand pictures:
Qobuz’s genres and sub-genres with their ids, for the shelf filter.
“Which kinds of jazz does Qobuz distinguish?”
works
4. The library and Focus
Tool
What it does
Example
Status
roon_library
The albums in the library with Roon’s Focus filters: stars, genre, label, artist, composer, producer, years, hi-res, live, played or not, recently added. Sorts: most played, newest, random.
“Five-star albums in my library.” / “A random ECM album from the seventies.”
works
roon_focus
The Focus panel itself: what the library, or a filtered part, is made of — counts per genre, label, artist, producer, decade, format.
“Which labels are my five-star albums on?” / “Who produced most of my hi-res jazz?”
works
roon_tracks
Focus on tracks: filters and sorts, each track with a key to play.
“My most played tracks.” / “Twenty random jazz tracks from my library.”
works
roon_artists
Focus on artists, or on composers.
“My most played artists.” / “Which classical composers do I have?”
works
roon_works
The compositions in the library, by composer, period, form or instrumentation.
“Which Bach works do I have most recordings of?”
works
roon_favorites
Albums with a heart in Roon, or the favourites at Qobuz.
“Show my Qobuz favourites.”
works
roon_listen_later
The Listen Later list: what still waits, optionally what has been heard since.
“What’s on my listen-later list?”
works
roon_playlists
All playlists Roon knows: own, Qobuz, editorial.
“Which playlists do I have in Roon?”
works
roon_playlist
The tracks of one playlist, each with a key.
“What’s in the playlist Hund?”
works
5. Listening history
Tool
What it does
Example
Status
roon_history
What was played in Roon, newest first.
“What did I play in Roon yesterday evening?”
works
roon_top
Most played albums, artists or tracks, counted over the whole history or since a date.
“What’s my most listened-to album this year?”
works
6. Playing
Tool
What it does
Example
Status
roon_play
Plays an album on a zone: now, next, or at the end of the queue. shuffle starts it shuffled.
“Play Revolver on the KEF.” / “Queue The Colour of Spring on the Ellipse.”
works
roon_play_tracks
Plays a hand-picked list of tracks, in the order given.
“Play ten deep cuts by the Beatles on the Ellipse.”
works
roon_play_playlist
Plays a playlist; shuffle starts it shuffled from the first track.
“Shuffle Baroque Qobuz on the KEF.”
works
roon_queue
A zone’s queue: what plays and what follows.
“What’s coming up on the KEF?”
works
roon_queue_clear
Clears what comes after the current track, or everything.
“Clear the queue on the Ellipse, keep this track.”
works
roon_control
Pause, play, stop, next, previous.
“Pause the KEF.” / “Next track.”
works
roon_seek
Jumps to a position in the track.
“Go to two minutes in.”
works
roon_settings
Shuffle, repeat and Roon Radio for the queue that is there.
“Repeat this track.” / “Turn Roon Radio off on the KEF.”
works
7. Zones
Tool
What it does
Example
Status
roon_zones
Roon’s zones and which are grouped.
“Which zones does Roon have?”
works
roon_now_playing
Per zone: state, track, format, position, volume, shuffle/repeat/radio, sleep timer, standby.
“What’s playing on Roon?”
works
roon_transfer
Moves what plays, with its queue and position, to another zone.
“Move the music from the KEF to the Ellipse.”
works
roon_group
Groups zones to play in sync; the first one keeps its music.
“Group the Ellipse with the KEF.”
works
roon_ungroup
Dissolves a group, or takes one member out.
“Ungroup the speakers.”
works
roon_volume
Sets a zone’s volume in that zone’s own scale.
“Volume 30 on the KEF.”
works
roon_sleep
Sleep timer: stop after N minutes, or cancel.
“Stop the KEF in 45 minutes.”
works
roon_standby
Puts a speaker in standby or wakes it.
“Switch the Mu-so off.”
works
8. Sound
Tool
What it does
Example
Status
roon_signal_path
What happens to the music that plays now: quality (lossless, enhanced, high, low), clipping, and each step from source to output.
“Is the Ellipse bit-perfect right now?”
works
roon_dsp
MUSE as configured per zone: DSP on or off, presets, and each part with its values (headroom, sample-rate conversion, crossfeed, EQ …).
“What DSP is set up on the KEF?”
works
roon_dsp_set
Switches the whole DSP, one part, or loads a preset. It does not edit EQ bands.
“Turn crossfeed on for the Ellipse.”
works
9. Changing the library
Tool
What it does
Example
Status
roon_listen_later_set
Puts an album or track on the Listen Later list, or takes it off.
“Save that one for later.”
works
roon_favorite
Puts a heart on an album or track, or removes it.
“Heart this album.”
works
roon_library_add
Adds a Qobuz album to the library.
“Add Now We Can Sing to my library.”
works
roon_playlist_create
Creates a playlist from a list of tracks.
“Save these ten tracks as a playlist called Sunday.”
Not in this shape or form – look at it as a proof of concept that is piggybacking on existing cloud infra I use for other projects. In theory I could wrap it as npm for running locally though.
The MCP part leans heavily on the reverse engineered client protocol. While @brian has more or less whitelisted personal use, distributing a product wrapped around it is different. That - and the reverse engineered code is set towards a moving target and could break at any time. Even in normal use – and since it actively writes back to Roon, there’s risks involved. Basically this is one AI building on top of another AI doing things they’re not supposed to…
I’ll have to think through where I want to go with this.
More fun: Roon on the Road. With the MCP firmly in place, I like to use it for playback in car (voice) and when traveling. I’m not terribly fond of ARC, and while the Roon phone app can control Roon outside of the network over Tailnet, it cannot play back music.
So I built a little bridge in Basso/Continuo (my Apple Music audio app, used here since most of the infra was already in place):
Present Squeeze endpoint to Roon
Stream audio via Basso Bridge
Play the stream in Basso iOS
Result: full Roon playback over Tailnet. Control via MCP (or Roon app if you prefer). Anyplace. Anywhere. Anytime.
I (roughly) get this now. I’m still a bit confused about how to get Claude on iOS (including CarPlay) to talk to an MCP server but I see now that MCP servers set up at Claude.ai sync to all Claude endpoints. I think I get how the pieces fit.
And yes – I would appreciate an official Roon MCP very much. Until then – I’m looking into releasing RoonMCP (will need a different name) in a way that can run locally and connects to Roon with its own extension.
I´m just starting to use Claude for fun but have created several trips already using it and sent all my approved results to fill the schedule data of these trips to a little Trips App in my iPhone and Mac thanks to their own MCP.
Will be great to use your RoonMCP in the same way.
One of the things that I use to do -manually, of course- is to create a Play List for the future concerts that I got tickets. I do that checking the latest gigs from the band at setlist.fm. It would be great to this using the MCP having these potential setlist created en Roon as Playlist to be used in home or with ARC.
I have rebuilt the MCP for local use (christened it Deep Roon MCP). If there’s any interest in toying with it yourself, I could wrap it up for release. Let me know.