deep-roon-mcp 0.3.2 → 0.3.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15525,7 +15525,7 @@ var require_lib2 = __commonJS({
15525
15525
  var version2;
15526
15526
  var init_package = __esm({
15527
15527
  "package.json"() {
15528
- version2 = "0.3.2";
15528
+ version2 = "0.3.6";
15529
15529
  }
15530
15530
  });
15531
15531
 
@@ -15852,6 +15852,11 @@ function field2(o, name) {
15852
15852
  for (const [k, v] of Object.entries(f)) if (k.endsWith("::" + name)) return v;
15853
15853
  return void 0;
15854
15854
  }
15855
+ function imageKey(c, o, name = "Image") {
15856
+ const url2 = field2(obj(c, field2(o, name)), "Url");
15857
+ const m = /^broker:\/\/\/image\/([^.]+)\./.exec(String(url2 ?? ""));
15858
+ return m ? m[1] : void 0;
15859
+ }
15855
15860
  function dateParts(v) {
15856
15861
  if (!Buffer.isBuffer(v) || v.length < 2) return void 0;
15857
15862
  const n = new BinaryReader(Uint8Array.from(v)).flexInt();
@@ -15953,6 +15958,8 @@ function albumRow(c, o) {
15953
15958
  if (flag(field2(o, "IsListenLater"))) r.listen_later = true;
15954
15959
  const p = field2(o, "Popularity");
15955
15960
  if (typeof p === "number") r.popularity = Math.round(p * 100) / 100;
15961
+ const img = imageKey(c, o);
15962
+ if (img) r.image = img;
15956
15963
  return r;
15957
15964
  }
15958
15965
  function resultRow(c, o) {
@@ -15962,6 +15969,8 @@ function resultRow(c, o) {
15962
15969
  const r = { kind: "artist", key: String(field2(o, "PerformerId") ?? ""), name: field2(o, "Name") ?? "" };
15963
15970
  const n = field2(o, "MainPerformerAlbumCount");
15964
15971
  if (typeof n === "number" && n > 0) r.albums_in_library = n;
15972
+ const img = imageKey(c, o, "Photo") ?? imageKey(c, o, "Avatar");
15973
+ if (img) r.image = img;
15965
15974
  return r;
15966
15975
  }
15967
15976
  if (t === "TrackLite" || t === "Track") {
@@ -15976,6 +15985,8 @@ function resultRow(c, o) {
15976
15985
  const l = field2(o, "LengthSeconds");
15977
15986
  if (typeof l === "number") r.length = duration3(l);
15978
15987
  r.source = sourceOf(o, al) ?? "library";
15988
+ const img = imageKey(c, al) ?? imageKey(c, o);
15989
+ if (img) r.image = img;
15979
15990
  return r;
15980
15991
  }
15981
15992
  return { kind: t, title: field2(o, "Title") ?? field2(o, "Name") ?? "" };
@@ -15996,6 +16007,7 @@ var init_graph = __esm({
15996
16007
  return (o?.fields?.$items ?? o?.$items ?? []).filter((x) => typeof x === "string");
15997
16008
  }, "strings");
15998
16009
  flag = /* @__PURE__ */ __name((v) => v === true || Buffer.isBuffer(v) && v.length > 1 && v[0] >= 1, "flag");
16010
+ __name(imageKey, "imageKey");
15999
16011
  __name(dateParts, "dateParts");
16000
16012
  yearOf = /* @__PURE__ */ __name((v) => dateParts(v)?.[0], "yearOf");
16001
16013
  __name(dateText, "dateText");
@@ -16357,6 +16369,8 @@ async function bio(key, max, wiki) {
16357
16369
  }
16358
16370
  const g = list("Genres").filter((x) => typeof x === "string");
16359
16371
  if (g.length) artist.genres = g;
16372
+ const img = imageKey(c, p, "Photo") ?? imageKey(c, p, "Avatar");
16373
+ if (img) artist.image = img;
16360
16374
  return {
16361
16375
  artist,
16362
16376
  texts,
@@ -16388,6 +16402,8 @@ async function discography(key, wanted) {
16388
16402
  if (typeof n === "number") artist.albums_in_library = n;
16389
16403
  const from = field2(p, "BirthPlace");
16390
16404
  if (from) artist.from = from;
16405
+ const img = imageKey(c, p, "Photo") ?? imageKey(c, p, "Avatar");
16406
+ if (img) artist.image = img;
16391
16407
  return { service: SERVICE_NAME[service2], artist, albums };
16392
16408
  });
16393
16409
  }
@@ -49384,6 +49400,8 @@ async function nowPlaying() {
49384
49400
  r.volume_max = v.max;
49385
49401
  if (v.is_muted) r.muted = true;
49386
49402
  }
49403
+ const img = off?.now_playing?.image_key;
49404
+ if (img) r.image = img;
49387
49405
  const outs = c.graph.findByType("Endpoint").filter((e) => {
49388
49406
  const zz = field2(e, "Zone");
49389
49407
  return isRef2(zz) && String(zz.$ref) === String(z2.oid);
@@ -49405,6 +49423,10 @@ async function nowPlaying() {
49405
49423
  r.title = field2(tr, "Title");
49406
49424
  r.artist = clean(field2(al, "PerformedBy"));
49407
49425
  r.album = field2(al, "Title");
49426
+ const tk = field2(tr, "TrackId");
49427
+ if (tk !== void 0 && tk !== null) r.track_key = String(tk);
49428
+ const ak = field2(al, "AlbumId");
49429
+ if (ak !== void 0 && ak !== null) r.album_key = String(ak);
49408
49430
  const f = field2(tr, "Format");
49409
49431
  if (f) r.format = f;
49410
49432
  const l = field2(tr, "LengthSeconds");
@@ -49661,7 +49683,7 @@ function registerReadTools(server, internal = true) {
49661
49683
  const reg = /* @__PURE__ */ __name(((name, cfg, cb) => R(name) ? server.registerTool.call(server, name, cfg, cb) : void 0), "reg");
49662
49684
  reg("roon_search", {
49663
49685
  title: "Search Roon",
49664
- description: 'Search Roon \u2014 the user\'s Roon library and the catalogues of the streaming services signed in (Qobuz, TIDAL) at once; each row says its `source` (library, Qobuz, TIDAL). Returns albums (with format, e.g. FLAC 96kHz 24bit), artists and tracks. `kind` narrows to album, track or artist \u2014 use `kind: "track"` with the song title (and artist) to find one specific track; a broad query without `kind` can fill up with artists. Albums and tracks carry a `key` for `roon_album`; artists carry a `key` for `roon_artist` and `roon_bio`. Albums say their `year`, and `in_library` when the user has them in Roon. Keys stay valid between calls.',
49686
+ description: 'Search Roon \u2014 the user\'s Roon library and the catalogues of the streaming services signed in (Qobuz, TIDAL) at once; each row says its `source` (library, Qobuz, TIDAL). Rows carry `image`, the key of the cover: the Core serves it at http://<core address>:9330/image/<key>.jpg, or scaled at /image/<key>.300.jpg (for clients that draw; a chat shows covers with roon_cover). The `image` of roon_now_playing is an official key, served at /api/image/<key>?scale=fit&width=600&height=600. Returns albums (with format, e.g. FLAC 96kHz 24bit), artists and tracks. `kind` narrows to album, track or artist \u2014 use `kind: "track"` with the song title (and artist) to find one specific track; a broad query without `kind` can fill up with artists. Albums and tracks carry a `key` for `roon_album`; artists carry a `key` for `roon_artist` and `roon_bio`. Albums say their `year`, and `in_library` when the user has them in Roon. Keys stay valid between calls.',
49665
49687
  inputSchema: { query: external_exports.string().min(1), kind: external_exports.enum(["album", "track", "artist"]).optional(), limit: limit(100, 30) },
49666
49688
  annotations: READ
49667
49689
  }, ({ query, kind, limit: n }) => run(() => search(query, n ?? 30, kind)));
@@ -49958,6 +49980,10 @@ function queueRow(c, oid) {
49958
49980
  if (album2) r.album = album2;
49959
49981
  const l = field2(tr, "LengthSeconds");
49960
49982
  if (typeof l === "number") r.length = duration3(l);
49983
+ const k = field2(tr, "TrackId");
49984
+ if (k !== void 0 && k !== null) r.key = String(k);
49985
+ const img = imageKey(c, al) ?? imageKey(c, tr);
49986
+ if (img) r.image = img;
49961
49987
  return r;
49962
49988
  }
49963
49989
  __name(queueRow, "queueRow");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "deep-roon-mcp",
3
- "version": "0.3.2",
3
+ "version": "0.3.6",
4
4
  "description": "An MCP server for Roon that reaches the parts the official API doesn't: reviews, biographies, Qobuz's and TIDAL's shelves, TIDAL's playlists, your history, search across your library and the streaming services",
5
5
  "license": "Apache-2.0",
6
6
  "author": "René Bouwmeester <21277119+renebouwmeester@users.noreply.github.com>",