comfyui-mcp 0.52.185 → 0.52.186
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.
|
@@ -2584,13 +2584,48 @@ function currentPanelRestartTarget(ctx) {
|
|
|
2584
2584
|
return null;
|
|
2585
2585
|
return target;
|
|
2586
2586
|
}
|
|
2587
|
+
/**
|
|
2588
|
+
* #1593 — a live panel tab whose SERVER-OBSERVED handshake Origin is a proven
|
|
2589
|
+
* local loopback ComfyUI, even when that port is not COMFYUI_URL (the
|
|
2590
|
+
* recurrence: panel on :8189, MCP on :8188). Authorizes only the Manager reboot
|
|
2591
|
+
* on THIS tab — never a guessed origin, never a local kill of the configured
|
|
2592
|
+
* 8188 process. Requires the tab socket to have arrived on the server-trusted
|
|
2593
|
+
* local listener, and a concrete loopback family literal (not `localhost`).
|
|
2594
|
+
* DNS-ambiguous / missing / relayed origins stay fail-closed.
|
|
2595
|
+
*/
|
|
2596
|
+
function currentPanelBoundLocalRestartOrigin(ctx) {
|
|
2597
|
+
if (ctx.bridge?.tabIsLocal?.(ctx.tabId) !== true)
|
|
2598
|
+
return null;
|
|
2599
|
+
const origin = ctx.bridge?.tabServerOrigin?.(ctx.tabId);
|
|
2600
|
+
if (!origin)
|
|
2601
|
+
return null;
|
|
2602
|
+
if (isDnsAmbiguousLoopback(origin) || !isLoopbackOrigin(origin))
|
|
2603
|
+
return null;
|
|
2604
|
+
try {
|
|
2605
|
+
const u = new URL(origin);
|
|
2606
|
+
if (u.protocol !== "http:" && u.protocol !== "https:")
|
|
2607
|
+
return null;
|
|
2608
|
+
if (!u.hostname)
|
|
2609
|
+
return null;
|
|
2610
|
+
}
|
|
2611
|
+
catch {
|
|
2612
|
+
return null;
|
|
2613
|
+
}
|
|
2614
|
+
return origin.replace(/\/+$/, "");
|
|
2615
|
+
}
|
|
2616
|
+
function stillBoundPanelLocalRestartOrigin(ctx, previous) {
|
|
2617
|
+
if (previous == null)
|
|
2618
|
+
return undefined;
|
|
2619
|
+
const next = currentPanelBoundLocalRestartOrigin(ctx);
|
|
2620
|
+
return next != null && sameHttpBase(next, previous) ? next : undefined;
|
|
2621
|
+
}
|
|
2587
2622
|
/**
|
|
2588
2623
|
* #2804 — a live panel tab whose SERVER-OBSERVED handshake Origin is a concrete
|
|
2589
2624
|
* non-loopback ComfyUI. The Manager reboot is sent to THIS tab, never to a
|
|
2590
2625
|
* guessed URL, and never via a local process restart of the configured
|
|
2591
|
-
* 127.0.0.1 target.
|
|
2592
|
-
* local
|
|
2593
|
-
*
|
|
2626
|
+
* 127.0.0.1 target. DNS-ambiguous `localhost` stays fail-closed. A proven
|
|
2627
|
+
* local loopback Origin (even on a different port than COMFYUI_URL) is
|
|
2628
|
+
* currentPanelBoundLocalRestartOrigin (#1593), not this path.
|
|
2594
2629
|
*/
|
|
2595
2630
|
function currentPanelRemoteRestartOrigin(ctx) {
|
|
2596
2631
|
const origin = ctx.bridge?.tabServerOrigin?.(ctx.tabId);
|
|
@@ -21926,7 +21961,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
21926
21961
|
}
|
|
21927
21962
|
return annotateQueueStatusWithManifestPartial(res, targetBeforePoll, ctx.manifestOutcomeScope);
|
|
21928
21963
|
}),
|
|
21929
|
-
def("panel_restart_comfyui", "Restart the user's ComfyUI server via the built-in Manager — needed to load newly installed/updated custom nodes. CALL THIS DIRECTLY when a restart is needed: it pops a confirm card and only restarts on a yes (don't ask separately first). If the user has already explicitly authorized automatic restarts in the conversation, pass already_authorized:true to skip only that card; this does NOT imply force and does not bypass any target, relaunch, or busy guard. When this panel tab is authoritatively bound to a
|
|
21964
|
+
def("panel_restart_comfyui", "Restart the user's ComfyUI server via the built-in Manager — needed to load newly installed/updated custom nodes. CALL THIS DIRECTLY when a restart is needed: it pops a confirm card and only restarts on a yes (don't ask separately first). If the user has already explicitly authorized automatic restarts in the conversation, pass already_authorized:true to skip only that card; this does NOT imply force and does not bypass any target, relaunch, or busy guard. When this panel tab is authoritatively bound to a ComfyUI — a server-observed non-loopback Origin, or a proven local loopback instance even on a different port than COMFYUI_URL — the restart is the Manager reboot of THAT instance, not a guessed origin and not the configured 127.0.0.1 process unless it is that same origin. Unbound or DNS-ambiguous local tabs still require local-instance confirmation. ComfyUI and this agent go down briefly, then the panel auto-reconnects and you resume. ⚠️ BUSY GUARD: a restart ABORTS any in-progress or queued generation — if ComfyUI is generating, this tool REFUSES and tells you (it does NOT restart). When that happens, tell the user a render is running and WAIT for it (poll panel_node_queue_status), or pass force:true ONLY if the user explicitly confirms they want to kill the running generation. Best practice: before restarting after an install, check the queue is idle first. Only call when a restart is actually needed. If a crash takes the panel bridge offline so the confirmation card cannot be shown, this tool falls back to a headless restart of the configured local process (or COMFYUI_RESTART_COMMAND) instead of depending on the dead bridge — it still refuses a readable busy queue without force:true, and still refuses when a relaunch cannot be proven. On an externally-managed install whose relaunch can't be proven from here (e.g. Pinokio), the restart is REFUSED before anything is stopped — restart from the launcher that owns the server instead, or set COMFYUI_RESTART_COMMAND to the exact command that restarts the instance (e.g. `docker restart <container>`): the restart then runs through that command (the busy guard above still applies) instead of needing the launch path.", { force: z.boolean().optional(), already_authorized: z.boolean().optional() },
|
|
21930
21965
|
// panel#1554 — `note` rides WHICHEVER reply this handler returns, so a decision
|
|
21931
21966
|
// recovered from an earlier confirmation card is disclosed on every branch, not
|
|
21932
21967
|
// just the one that restarts. See withReplyNote / AbandonedConfirmCard.
|
|
@@ -21961,10 +21996,16 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
21961
21996
|
// authenticated relative Manager dispatch; it is never a health or
|
|
21962
21997
|
// headless-restart target.
|
|
21963
21998
|
let panelRestartTarget;
|
|
21999
|
+
// #1593: a live tab whose handshake Origin is a proven local loopback
|
|
22000
|
+
// ComfyUI on a different port than COMFYUI_URL. Authorizes only the
|
|
22001
|
+
// Manager reboot on THIS tab — never a guessed origin and never a
|
|
22002
|
+
// local kill of the configured 8188 process.
|
|
22003
|
+
let panelLocalRestartOrigin;
|
|
21964
22004
|
// #2804: a live tab whose handshake Origin is a concrete non-loopback
|
|
21965
22005
|
// ComfyUI. Authorizes only the Manager reboot on THIS tab — never a
|
|
21966
22006
|
// guessed origin and never a local kill of the configured 127.0.0.1
|
|
21967
|
-
// target.
|
|
22007
|
+
// target. DNS-ambiguous localhost stays fail-closed; proven local
|
|
22008
|
+
// loopback is panelLocalRestartOrigin above.
|
|
21968
22009
|
let panelRemoteRestartOrigin;
|
|
21969
22010
|
// #1819: resolve instance identity BEFORE the confirmation card. Asking the
|
|
21970
22011
|
// user to confirm a restart, then refusing because we cannot tell which
|
|
@@ -21988,6 +22029,11 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
21988
22029
|
panelRestartTarget = currentPanelRestartTarget(ctx) ?? undefined;
|
|
21989
22030
|
}
|
|
21990
22031
|
if (proxyRestartTarget == null && panelRestartTarget == null) {
|
|
22032
|
+
panelLocalRestartOrigin = currentPanelBoundLocalRestartOrigin(ctx) ?? undefined;
|
|
22033
|
+
}
|
|
22034
|
+
if (proxyRestartTarget == null &&
|
|
22035
|
+
panelRestartTarget == null &&
|
|
22036
|
+
panelLocalRestartOrigin == null) {
|
|
21991
22037
|
panelRemoteRestartOrigin = currentPanelRemoteRestartOrigin(ctx) ?? undefined;
|
|
21992
22038
|
}
|
|
21993
22039
|
const tabStillHere = typeof ctx.bridge?.canReach === "function"
|
|
@@ -21996,6 +22042,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
21996
22042
|
if (tabStillHere &&
|
|
21997
22043
|
proxyRestartTarget == null &&
|
|
21998
22044
|
panelRestartTarget == null &&
|
|
22045
|
+
panelLocalRestartOrigin == null &&
|
|
21999
22046
|
panelRemoteRestartOrigin == null) {
|
|
22000
22047
|
return restartRefusedPreservingBinding(ctx, unboundLocalRestartRefusalNote(ctx, identityHealthBase, identityBinding.blocker));
|
|
22001
22048
|
}
|
|
@@ -22576,6 +22623,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
22576
22623
|
if (configuredRestartCommand &&
|
|
22577
22624
|
!isRemoteMode() &&
|
|
22578
22625
|
!isCloudMode() &&
|
|
22626
|
+
panelLocalRestartOrigin == null &&
|
|
22579
22627
|
panelRemoteRestartOrigin == null) {
|
|
22580
22628
|
if (proxyRestartTarget != null) {
|
|
22581
22629
|
const refreshedProxy = await panelVerifiedProxyRestartTarget();
|
|
@@ -22728,6 +22776,11 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
22728
22776
|
: undefined;
|
|
22729
22777
|
}
|
|
22730
22778
|
if (proxyRestartTarget == null && panelRestartTarget == null) {
|
|
22779
|
+
panelLocalRestartOrigin = stillBoundPanelLocalRestartOrigin(ctx, panelLocalRestartOrigin);
|
|
22780
|
+
}
|
|
22781
|
+
if (proxyRestartTarget == null &&
|
|
22782
|
+
panelRestartTarget == null &&
|
|
22783
|
+
panelLocalRestartOrigin == null) {
|
|
22731
22784
|
panelRemoteRestartOrigin = stillBoundPanelRemoteRestartOrigin(ctx, panelRemoteRestartOrigin);
|
|
22732
22785
|
}
|
|
22733
22786
|
const preflightBinding = resolveRebootHealthBinding(ctx);
|
|
@@ -22736,7 +22789,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
22736
22789
|
panelRestartTarget != null ||
|
|
22737
22790
|
(preflightHealthBase != null &&
|
|
22738
22791
|
sameHttpBase(getComfyUIBaseUrl(), preflightHealthBase));
|
|
22739
|
-
const
|
|
22792
|
+
const boundPanelOriginRestart = panelLocalRestartOrigin != null || panelRemoteRestartOrigin != null;
|
|
22740
22793
|
// #848: what the instance was OBSERVED running with, taken from the preflight
|
|
22741
22794
|
// that already had to resolve it. Nothing new is probed before the dispatch —
|
|
22742
22795
|
// the no-await invariant between the binding capture and the reboot stands.
|
|
@@ -22757,13 +22810,13 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
22757
22810
|
// local process to assess, and the Manager reboot is their ONLY restart path —
|
|
22758
22811
|
// a supervised remote (the tunnelled Desktop app) restarts through it by
|
|
22759
22812
|
// design, so refusing there would remove a path that works.
|
|
22760
|
-
if (!preflightBound && !
|
|
22813
|
+
if (!preflightBound && !boundPanelOriginRestart && !isRemoteMode() && !isCloudMode()) {
|
|
22761
22814
|
// Identity was proven before the card; landing here means the binding
|
|
22762
22815
|
// was lost during the confirm wait. Same refusal, and the tab that is
|
|
22763
22816
|
// still here must stay usable (#1819).
|
|
22764
22817
|
return restartRefusedPreservingBinding(ctx, unboundLocalRestartRefusalNote(ctx, preflightHealthBase, preflightBinding.blocker));
|
|
22765
22818
|
}
|
|
22766
|
-
if (preflightBound && !
|
|
22819
|
+
if (preflightBound && !boundPanelOriginRestart) {
|
|
22767
22820
|
// Snapshot the target GENERATION at the decision (r11): a final-state
|
|
22768
22821
|
// base comparison (A vs A) cannot detect an intervening A→B→A
|
|
22769
22822
|
// retarget, so stability is judged by the monotonic epoch bumped on
|
|
@@ -22903,9 +22956,17 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
22903
22956
|
: undefined;
|
|
22904
22957
|
}
|
|
22905
22958
|
if (proxyRestartTarget == null && panelRestartTarget == null) {
|
|
22959
|
+
panelLocalRestartOrigin = stillBoundPanelLocalRestartOrigin(ctx, panelLocalRestartOrigin);
|
|
22960
|
+
}
|
|
22961
|
+
if (proxyRestartTarget == null &&
|
|
22962
|
+
panelRestartTarget == null &&
|
|
22963
|
+
panelLocalRestartOrigin == null) {
|
|
22906
22964
|
panelRemoteRestartOrigin = stillBoundPanelRemoteRestartOrigin(ctx, panelRemoteRestartOrigin);
|
|
22907
22965
|
}
|
|
22908
|
-
const healthBase = proxyRestartTarget?.backendBase ??
|
|
22966
|
+
const healthBase = proxyRestartTarget?.backendBase ??
|
|
22967
|
+
(panelLocalRestartOrigin != null || panelRemoteRestartOrigin != null
|
|
22968
|
+
? null
|
|
22969
|
+
: captureRebootHealthBase(ctx));
|
|
22909
22970
|
// THE BINDING RULE APPLIES AT THE DISPATCH POINT, NOT ONLY BEFORE THE AWAIT.
|
|
22910
22971
|
//
|
|
22911
22972
|
// The check above happens before the preflight; a tab or connection rebind
|
|
@@ -22918,12 +22979,14 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
22918
22979
|
//
|
|
22919
22980
|
// Same rule, same exclusions: only a LOCAL target we cannot tie to the
|
|
22920
22981
|
// instance this server accounts for is refused. A still-bound remote
|
|
22921
|
-
// panel origin (#2804)
|
|
22922
|
-
//
|
|
22982
|
+
// panel origin (#2804) or proven local loopback origin on a different
|
|
22983
|
+
// port than COMFYUI_URL (#1593) is the Manager reboot of that tab, not
|
|
22984
|
+
// a local process we have to identify from the configured URL.
|
|
22923
22985
|
const dispatchBound = proxyRestartTarget != null ||
|
|
22924
22986
|
(healthBase != null && sameHttpBase(getComfyUIBaseUrl(), healthBase)) ||
|
|
22925
22987
|
(panelRestartTarget != null &&
|
|
22926
22988
|
sameHttpBase(getComfyUIBaseUrl(), panelRestartTarget)) ||
|
|
22989
|
+
panelLocalRestartOrigin != null ||
|
|
22927
22990
|
panelRemoteRestartOrigin != null;
|
|
22928
22991
|
if (!dispatchBound && !isRemoteMode() && !isCloudMode()) {
|
|
22929
22992
|
return restartRefusedPreservingBinding(ctx, "Refusing to restart ComfyUI: the panel connection changed while the restart " +
|
|
@@ -23104,6 +23167,7 @@ CHECKED FOR YOU: the graph read this message prescribes was just run, and it ` +
|
|
|
23104
23167
|
}
|
|
23105
23168
|
if (!isRemoteMode() &&
|
|
23106
23169
|
panelRemoteRestartOrigin == null &&
|
|
23170
|
+
panelLocalRestartOrigin == null &&
|
|
23107
23171
|
rebootNoEndpoint(res) &&
|
|
23108
23172
|
// ENDPOINT BINDING: restartComfyUI() acts on the orchestrator's GLOBAL config
|
|
23109
23173
|
// target (a hello can retarget it). Only run it when the bound tab fronts our
|