ADR-0013: MusicBee Is Read Through the MusicBee Remote Plugin’s Protocol

StatusProposed — the protocol has been read and does what is needed; it has not been tried against a real MusicBee. See What would settle it
Date2026-10-10
ScopeHow the MusicBee driver learns of track changes and gets artwork.
RelatedADR-0006, ADR-0007, ADR-0010, ADR-0011

Context

MusicBee plays local files and has no cloud. Anything that reads it runs on or near the PC. Its extension point is a plugin: a .NET DLL loaded into MusicBee, with a notification when the track changes.

The drivers are to be portable Go with no .NET (ADR-0007).

Options considered

Our own MusicBee plugin that publishes to MQTT. Exact and immediate, and a small one exists to learn from. But it is .NET, loaded into MusicBee’s own process, with an MQTT client and TLS inside it.

The Windows media controls. MusicBee reports to them only through a third-party plugin last updated in 2024, with open bugs: missing art for most tracks, hotkey conflicts, a crash on portable installs.

The MusicBee Remote plugin’s protocol. An existing, maintained plugin (v1.5.0, August 2026) that exists so a phone can see and control MusicBee over the network, with its protocol documented in its repository. This is the same shape as the iTunes decision: someone else’s maintained remote-control surface, read by a small driver of ours.

Scrobbling. MusicBee can submit “now playing” to ListenBrainz through a plugin. Late, and with no art or pause state.

Decision

The MusicBee driver connects to the MusicBee Remote plugin and speaks its protocol. The plugin is installed in MusicBee; nothing of ours is.

Fallback: a plugin of our own, which would mean a .NET component and a new record extending ADR-0007.

Consequences

  • No .NET, and the driver runs on the relay rather than the PC.
  • The plugin has to be installed in MusicBee, and its port admitted by the PC’s firewall.
  • The driver depends on a third party’s protocol staying compatible. The plugin is actively maintained, and the protocol is versioned.
  • The driver speaks the plugin’s legacy protocol (V4), not its newer one; see the evidence below.

Evidence so far

2026-10-10 — the protocol documents, read at the repository’s main. Not yet tried against a running MusicBee.

The plugin serves two protocols on one TCP port (default 3000) and tells them apart by the first frame.

V4 (legacy)V6
In a releaseevery shipping version, including v1.5.0no — on main only, 181 commits past v1.5.0
Stabilityfrozen, “preserved byte-for-byte, not extended”“active development”
FramingJSON objects ended by CRLFJSON objects ended by newline, with an envelope and ids
Track changepushed: nowplayingtrack with artist, title, album, year, pathpushed: now_playing_changed, then re-query now_playing_state
Play statepushed: playerstate — Playing, Paused, Stoppedpushed: play_state_changed
Coverpushed: nowplayingcover, the image as base64a content hash on the track; fetched from GET /api/cover/{hash}
Keepalivethe server pingsthe client pings every 15 s
Accessan address filteroptional pairing, off by default

So, against the questions below: (1) yes, track changes are pushed in both; (2) title, artist and album are supplied, and the cover as base64 in V4; (3) yes, three states; (4) no authentication by default.

What this decides for the driver: it speaks V4. V4 is what the installed plugin has, it is frozen, and it pushes everything needed. V6 is the better protocol, with a typed track and a cover that can be cached by hash, but it is not released. Moving to it later would extend this record.

What would settle it

  1. The protocol pushes a message when the track changes, without polling. Yes, on paper.
  2. It supplies title, artist and album, and the cover, and in what form. Yes, on paper; the cover is base64 in V4.
  3. Play, pause and stop are distinguishable. Yes, on paper.
  4. Whether a client must authenticate, and how. Not by default.
  5. All of the above against a running MusicBee with the plugin installed.
  6. Whether the plugin’s address filter admits the relay by default.
  7. Behavior when MusicBee quits and restarts.

Sources