deep-roon-mcp 0.3.0 → 0.3.2
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.
- package/dist/deep-roon-mcp.js +17 -7
- package/package.json +1 -1
package/dist/deep-roon-mcp.js
CHANGED
|
@@ -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.
|
|
15528
|
+
version2 = "0.3.2";
|
|
15529
15529
|
}
|
|
15530
15530
|
});
|
|
15531
15531
|
|
|
@@ -49397,7 +49397,10 @@ async function nowPlaying() {
|
|
|
49397
49397
|
if (r.state === "stopped") return r;
|
|
49398
49398
|
const np = obj(c, field2(z2, "NowPlaying"));
|
|
49399
49399
|
const tr = obj(c, field2(items(c, field2(np, "Tracks"))[0], "Track"));
|
|
49400
|
-
|
|
49400
|
+
const lines = off?.now_playing?.three_line;
|
|
49401
|
+
const t = String(field2(tr, "Title") ?? "").toLowerCase(), l1 = String(lines?.line1 ?? "").toLowerCase();
|
|
49402
|
+
const stream = !!l1 && !!t && !l1.includes(t) && !t.includes(l1);
|
|
49403
|
+
if (tr && field2(tr, "Title") && !stream) {
|
|
49401
49404
|
const al = obj(c, field2(tr, "Album"));
|
|
49402
49405
|
r.title = field2(tr, "Title");
|
|
49403
49406
|
r.artist = clean(field2(al, "PerformedBy"));
|
|
@@ -49407,7 +49410,6 @@ async function nowPlaying() {
|
|
|
49407
49410
|
const l = field2(tr, "LengthSeconds");
|
|
49408
49411
|
if (typeof l === "number") r.length = duration3(l);
|
|
49409
49412
|
} else {
|
|
49410
|
-
const lines = off?.now_playing?.three_line;
|
|
49411
49413
|
if (lines?.line1) {
|
|
49412
49414
|
r.title = lines.line1;
|
|
49413
49415
|
if (lines.line2) r.artist = lines.line2;
|
|
@@ -49418,7 +49420,7 @@ async function nowPlaying() {
|
|
|
49418
49420
|
const pos = field2(z2, "SeekPosition");
|
|
49419
49421
|
if (typeof pos === "number") r.position = duration3(pos);
|
|
49420
49422
|
const left = field2(obj(c, field2(z2, "Queue")), "TrackCountRemaining");
|
|
49421
|
-
if (typeof left === "number") r.tracks_left_in_queue = left;
|
|
49423
|
+
if (typeof left === "number" && !r.source) r.tracks_left_in_queue = left;
|
|
49422
49424
|
return r;
|
|
49423
49425
|
});
|
|
49424
49426
|
return { zones: out };
|
|
@@ -49866,6 +49868,14 @@ async function playTracks(keys, zoneName, how) {
|
|
|
49866
49868
|
__name(playTracks, "playTracks");
|
|
49867
49869
|
var BUTTONS = { pause: "Pause", play: "Play", playpause: "PlayPause", stop: "Stop", next: "Next", previous: "Previous" };
|
|
49868
49870
|
async function control2(zoneName, action) {
|
|
49871
|
+
if (action === "release") {
|
|
49872
|
+
return withCore(async (c) => {
|
|
49873
|
+
const z2 = findZone(c, zoneName);
|
|
49874
|
+
c.remoting.callMethodNoReply(z2.oid, formatMethodSignature("Zone", "Suspend", []), Buffer.alloc(0));
|
|
49875
|
+
log(`control: Suspend on ${z2.name}`);
|
|
49876
|
+
return { ok: true, zone: z2.name, action };
|
|
49877
|
+
});
|
|
49878
|
+
}
|
|
49869
49879
|
const m = BUTTONS[action];
|
|
49870
49880
|
if (!m) throw new RoonError(`Unknown action; choose from ${Object.keys(BUTTONS).join(", ")}`, "invalid");
|
|
49871
49881
|
const r = await withCore(async (c) => {
|
|
@@ -50128,10 +50138,10 @@ function registerControlTools(server, internal = true) {
|
|
|
50128
50138
|
}, ({ keys, zone: zn, mode: m }) => run(() => playTracks(keys, zn, m ?? "now")));
|
|
50129
50139
|
reg("roon_control", {
|
|
50130
50140
|
title: "Transport",
|
|
50131
|
-
description: "The buttons of a Roon zone: pause, play (resume), playpause, stop, next, previous. Only on an explicit request, never as a probe.",
|
|
50132
|
-
inputSchema: { zone, action: external_exports.enum(["pause", "play", "playpause", "stop", "next", "previous"]) },
|
|
50141
|
+
description: "The buttons of a Roon zone: pause, play (resume), playpause, stop, next, previous \u2014 and release: let go of the audio device right away (what Roon does by itself a few seconds after a pause), so another source can use the speaker. Only on an explicit request, never as a probe.",
|
|
50142
|
+
inputSchema: { zone, action: external_exports.enum(["pause", "play", "playpause", "stop", "next", "previous", "release"]) },
|
|
50133
50143
|
annotations: PLAYS
|
|
50134
|
-
}, ({ zone: zn, action }) => run(() => internal ? control2(zn, action) : control(zn, action)));
|
|
50144
|
+
}, ({ zone: zn, action }) => run(() => internal ? control2(zn, action) : action === "release" ? Promise.reject(new Error("release needs Roon's internal protocol (switched off)")) : control(zn, action)));
|
|
50135
50145
|
reg("roon_seek", {
|
|
50136
50146
|
title: "Seek",
|
|
50137
50147
|
description: "Jump to a position in the track that plays on a Roon zone, in seconds from the start. Only on an explicit request.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "deep-roon-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.2",
|
|
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>",
|