comfyui-mcp 0.50.21 → 0.50.23

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.
@@ -11,7 +11,12 @@
11
11
  // with `fetchImage` / `uploadImageHttp` added so our existing image tools
12
12
  // keep working in cloud mode.
13
13
  import { getApiKey, getCloudUrl } from "../config.js";
14
- import { ComfyUIError, ConnectionError } from "../utils/errors.js";
14
+ // Shared with the headless client on purpose: one ceiling, one delivery-doubt
15
+ // rule. The cloud client is a parallel implementation, and the last two rounds of
16
+ // hardening (the 0.50.11 timeout ceiling, the delivery-doubt disclosure) reached
17
+ // only its twin — which is exactly how a parallel implementation rots.
18
+ import { comfyHttpTimeoutSeconds, defaultComfyTimeoutSignal, deliveryDoubt, isTimeoutAbort, } from "./fetch.js";
19
+ import { ComfyUIError, ConnectionError, describeFetchFailure } from "../utils/errors.js";
15
20
  import { logger } from "../utils/logger.js";
16
21
  function cloudUrl(path) {
17
22
  const base = getCloudUrl().replace(/\/+$/, "");
@@ -30,8 +35,14 @@ async function cloudFetch(path, init) {
30
35
  ...authHeaders(baseHeaders),
31
36
  ...(init?.headers ?? {}),
32
37
  };
38
+ const method = String(init?.method ?? "GET").toUpperCase();
39
+ // A CEILING, not a policy — the same one comfyuiFetch got in 0.50.11, which this
40
+ // client never inherited. Without it a cloud request that never answers hangs the
41
+ // tool call forever: no timeout, no error, nothing for the caller to act on. A
42
+ // caller's own signal always wins.
43
+ const signal = init?.signal ?? defaultComfyTimeoutSignal();
33
44
  try {
34
- const res = await fetch(url, { ...init, headers });
45
+ const res = await fetch(url, { ...init, headers, signal });
35
46
  if (!res.ok) {
36
47
  const body = await res.text().catch(() => "");
37
48
  throw new ComfyUIError(`Cloud API error: ${res.status} ${res.statusText} — ${body.slice(0, 500)}`, "CLOUD_API_ERROR", { url, status: res.status });
@@ -41,7 +52,24 @@ async function cloudFetch(path, init) {
41
52
  catch (err) {
42
53
  if (err instanceof ComfyUIError)
43
54
  throw err;
44
- throw new ConnectionError(`Failed to reach Comfy Cloud at ${url}: ${err instanceof Error ? err.message : err}`);
55
+ // Our own ceiling firing is not the same event as a caller's abort, and must
56
+ // not be reported as one. Only rewrite when WE supplied the signal.
57
+ if (init?.signal === undefined && isTimeoutAbort(err)) {
58
+ throw new ConnectionError(`No reply from Comfy Cloud within ${comfyHttpTimeoutSeconds()}s — while requesting ` +
59
+ `${url} (${method}).` +
60
+ deliveryDoubt(undefined, method) +
61
+ ` Raise COMFYUI_MCP_HTTP_TIMEOUT_S if the cloud is simply slow.`);
62
+ }
63
+ // "Failed to reach" was a claim, not an observation. A transport error on a
64
+ // POST to /api/prompt does not establish that the submission never landed —
65
+ // and a blind retry there bills a SECOND cloud render. Same three states as
66
+ // the headless client: delivered, definitely not delivered, unknown.
67
+ const { message, code } = describeFetchFailure(err);
68
+ const wrapped = new ConnectionError(`Could not complete the ${method} to Comfy Cloud at ${url}: ${message}.` +
69
+ deliveryDoubt(code, method));
70
+ if (code)
71
+ wrapped.code = code;
72
+ throw wrapped;
45
73
  }
46
74
  }
47
75
  export async function enqueuePrompt(workflow, extraData) {
@@ -73,13 +101,47 @@ export async function getHistory(promptId) {
73
101
  }
74
102
  return {};
75
103
  }
104
+ /** HTTP statuses that mean "this cloud has no such endpoint" rather than "the
105
+ * request failed". Only these may fall back to the placeholder. */
106
+ const ENDPOINT_ABSENT_STATUSES = new Set([404, 405, 501]);
107
+ /**
108
+ * #1070 — the catch here used to swallow EVERYTHING and return an invented
109
+ * device, so an expired API key, a 402, a DNS failure, a timeout and a network
110
+ * partition all came back looking like a successful health check.
111
+ *
112
+ * That mattered more than a mislabelled outcome usually does, for two reasons.
113
+ * `get_system_stats (action:"health")` is the remedy our own error messages send
114
+ * people to — it is named in describeComfyFetchFailure, in the timeout text, and
115
+ * in this file's messages — so in cloud mode the remedy could not return a
116
+ * negative result. And health-check.ts / local-models-fallback.ts both call this
117
+ * as a REACHABILITY PROBE, which the placeholder answered "yes" to unconditionally.
118
+ *
119
+ * It also fabricated data rather than merely mislabelling it: `vram_total: 0` is
120
+ * not a reading, and a caller sizing a job against it is reading an invention.
121
+ *
122
+ * Three states now, not two:
123
+ * - answered → return what the endpoint said
124
+ * - endpoint ABSENT (404) → the placeholder, which is the case this was written
125
+ * for, but named so a reader can see it is not a reading
126
+ * - could not ask → propagate, because that is a real failure
127
+ */
76
128
  export async function getSystemStats() {
77
129
  try {
78
130
  const res = await cloudFetch("/system_stats");
79
131
  return (await res.json());
80
132
  }
81
- catch {
82
- logger.info("Cloud: /system_stats unavailable, returning placeholder");
133
+ catch (err) {
134
+ const status = err instanceof ComfyUIError && err.details && typeof err.details === "object"
135
+ ? err.details.status
136
+ : undefined;
137
+ if (typeof status !== "number" || !ENDPOINT_ABSENT_STATUSES.has(status)) {
138
+ // Auth, billing, transport, timeout — a real failure. The caller asked
139
+ // whether the cloud is reachable; inventing a GPU is not an answer.
140
+ throw err;
141
+ }
142
+ logger.info("Cloud: /system_stats not implemented by this cloud, returning placeholder", {
143
+ status,
144
+ });
83
145
  return {
84
146
  system: {
85
147
  os: "cloud",
@@ -89,7 +151,9 @@ export async function getSystemStats() {
89
151
  },
90
152
  devices: [
91
153
  {
92
- name: "Comfy Cloud GPU",
154
+ // Named, not silent: these are placeholders, not measurements. The
155
+ // "Comfy Cloud GPU" prefix is kept so anything matching on it still does.
156
+ name: "Comfy Cloud GPU (no stats endpoint — values below are placeholders, not readings)",
93
157
  type: "cloud",
94
158
  index: 0,
95
159
  vram_total: 0,
@@ -159,8 +223,33 @@ export async function getLogs() {
159
223
  export async function fetchImage(filename, type = "output", subfolder = "") {
160
224
  const params = new URLSearchParams({ filename, type, subfolder });
161
225
  const url = cloudUrl(`/api/view?${params.toString()}`);
162
- // /api/view returns either bytes or a 302 to a signed URL.
163
- const res = await fetch(url, { headers: authHeaders(), redirect: "follow" });
226
+ // /api/view returns either bytes or a 302 to a signed URL, which is why this
227
+ // does NOT go through cloudFetch: it needs redirect-following and raw bytes
228
+ // rather than the JSON envelope. That exemption is also how it kept the bare,
229
+ // signal-less `fetch` that #1069 removed from cloudFetch one call over — a
230
+ // download from a wedged cloud hung the tool call with nothing to act on.
231
+ let res;
232
+ try {
233
+ res = await fetch(url, {
234
+ headers: authHeaders(),
235
+ redirect: "follow",
236
+ signal: defaultComfyTimeoutSignal(),
237
+ });
238
+ }
239
+ catch (err) {
240
+ if (isTimeoutAbort(err)) {
241
+ throw new ConnectionError(`No reply from Comfy Cloud within ${comfyHttpTimeoutSeconds()}s while downloading ` +
242
+ `"${filename}" — ${url} (GET). Nothing was learned about the image from this: a ` +
243
+ `timeout is not a "not found". Raise COMFYUI_MCP_HTTP_TIMEOUT_S if the cloud is ` +
244
+ `simply slow.`);
245
+ }
246
+ // A read, so no delivery doubt applies — re-requesting an image is safe.
247
+ const { message, code } = describeFetchFailure(err);
248
+ const wrapped = new ConnectionError(`Could not download "${filename}" from Comfy Cloud at ${url}: ${message}.`);
249
+ if (code)
250
+ wrapped.code = code;
251
+ throw wrapped;
252
+ }
164
253
  if (!res.ok) {
165
254
  throw new ComfyUIError(`Cloud /api/view ${res.status} for "${filename}"`, "CLOUD_API_ERROR", { status: res.status });
166
255
  }
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-client.js","sourceRoot":"","sources":["../../src/comfyui/cloud-client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cloud-client.js","sourceRoot":"","sources":["../../src/comfyui/cloud-client.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,11 @@ function targetOf(input) {
13
13
  return String(input);
14
14
  }
15
15
  }
16
+ /** The request's HTTP method, uppercased. `init.method` wins over a Request's own,
17
+ * matching what fetch itself does when both are supplied. */
18
+ function methodOf(input, init) {
19
+ return String(init.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
20
+ }
16
21
  /**
17
22
  * What the CONNECTED panels front, for the drift comparison below (#952).
18
23
  *
@@ -96,10 +101,69 @@ function describeTargetDrift(target) {
96
101
  * the browser is on, while these calls go to the configured COMFYUI_URL. That is
97
102
  * not a bug, but it is invisible unless the failure names the address — and,
98
103
  * where the bridge can tell us, says whether the two actually differ.
104
+ *
105
+ * Header for the three pieces below: the never-delivered code set, the delivery
106
+ * doubt it gates, and describeComfyFetchFailure itself.
99
107
  */
100
- function describeComfyFetchFailure(err, target) {
108
+ /**
109
+ * Failure codes that prove the request was NEVER DELIVERED.
110
+ *
111
+ * Each one fires before any byte of the request could reach the application: the
112
+ * connection was refused, the name never resolved, the TLS handshake failed, or
113
+ * the URL was rejected locally. On these the server cannot have acted, so saying
114
+ * so is accurate and a retry is safe.
115
+ *
116
+ * Everything else is deliberately NOT listed. ECONNRESET, EPIPE, "socket hang up"
117
+ * and UND_ERR_SOCKET all fire on an ESTABLISHED connection, which is precisely the
118
+ * case where ComfyUI may have received and acted on the request before the socket
119
+ * died. The default for an unrecognised code is therefore "may have been
120
+ * delivered": a spurious "verify first" costs one extra read, while a spurious
121
+ * "it never arrived" costs a duplicate render.
122
+ */
123
+ const NEVER_DELIVERED_CODES = new Set([
124
+ "ECONNREFUSED",
125
+ "ENOTFOUND",
126
+ "EAI_AGAIN",
127
+ "ERR_INVALID_URL",
128
+ "ERR_UNSUPPORTED_PROTOCOL",
129
+ "UNABLE_TO_VERIFY_LEAF_SIGNATURE",
130
+ "DEPTH_ZERO_SELF_SIGNED_CERT",
131
+ "SELF_SIGNED_CERT_IN_CHAIN",
132
+ "CERT_HAS_EXPIRED",
133
+ "ERR_TLS_CERT_ALTNAME_INVALID",
134
+ ]);
135
+ /**
136
+ * The transport-failure twin of describeComfyTimeout's OUTCOME UNKNOWN.
137
+ *
138
+ * A timeout on a POST already warned that /prompt may have queued the render
139
+ * before the reply was lost. A CONNECTION ERROR on that same POST carries the
140
+ * identical risk — an ECONNRESET after the server accepted and enqueued the
141
+ * prompt is indistinguishable, at this layer, from one before it — yet the
142
+ * message said only "confirm the server is up", which reads as "it never got
143
+ * there". The caller retries and the render is queued twice, on the single most
144
+ * expensive operation this client makes.
145
+ *
146
+ * Only suppressed when the code POSITIVELY proves non-delivery, or the method is
147
+ * a read. See NEVER_DELIVERED_CODES for why the default runs the other way.
148
+ */
149
+ export function deliveryDoubt(code, method) {
150
+ if (method === "GET" || method === "HEAD")
151
+ return "";
152
+ if (code !== undefined && NEVER_DELIVERED_CODES.has(code))
153
+ return "";
154
+ // Says only what is known. Claiming "the connection was established" would be an
155
+ // overclaim for an unrecognised code — the same folding this function exists to
156
+ // undo, merely pointed the other way.
157
+ return (` This ${method} may already have been received and acted on: a transport failure ` +
158
+ `does not establish that the request never arrived. Do NOT blindly re-issue it; ` +
159
+ `check the server's state first (for a queued prompt, queue (action:"list") and ` +
160
+ `get_history (action:"list")).`);
161
+ }
162
+ function describeComfyFetchFailure(err, target, method) {
101
163
  const { message, code } = describeFetchFailure(err);
102
- const wrapped = new Error(`${message} — while requesting ${target}. ` +
164
+ const wrapped = new Error(`${message} — while requesting ${target} (${method}).` +
165
+ deliveryDoubt(code, method) +
166
+ ` ` +
103
167
  `That is the headless ComfyUI target (COMFYUI_URL); a CONNECTED sidebar panel does not imply this address is reachable, ` +
104
168
  `because the panel talks to whichever ComfyUI its browser tab is on.` +
105
169
  describeTargetDrift(target) +
@@ -132,15 +196,15 @@ function describeComfyFetchFailure(err, target) {
132
196
  * request.
133
197
  */
134
198
  const DEFAULT_COMFY_HTTP_TIMEOUT_S = 120;
135
- function comfyHttpTimeoutSeconds() {
199
+ export function comfyHttpTimeoutSeconds() {
136
200
  const raw = Number(process.env.COMFYUI_MCP_HTTP_TIMEOUT_S);
137
201
  return Number.isFinite(raw) && raw > 0 ? raw : DEFAULT_COMFY_HTTP_TIMEOUT_S;
138
202
  }
139
- function defaultComfyTimeoutSignal() {
203
+ export function defaultComfyTimeoutSignal() {
140
204
  return AbortSignal.timeout(Math.round(comfyHttpTimeoutSeconds() * 1000));
141
205
  }
142
206
  /** True for an abort raised by AbortSignal.timeout (not a caller's own abort). */
143
- function isTimeoutAbort(err) {
207
+ export function isTimeoutAbort(err) {
144
208
  return err instanceof Error && (err.name === "TimeoutError" || err.name === "AbortError");
145
209
  }
146
210
  /**
@@ -154,7 +218,7 @@ function isTimeoutAbort(err) {
154
218
  */
155
219
  function describeComfyTimeout(input, init) {
156
220
  const target = targetOf(input);
157
- const method = String(init.method ?? (input instanceof Request ? input.method : "GET")).toUpperCase();
221
+ const method = methodOf(input, init);
158
222
  const seconds = comfyHttpTimeoutSeconds();
159
223
  const mutating = method !== "GET" && method !== "HEAD";
160
224
  const err = new Error(`No reply from ComfyUI within ${seconds}s — while requesting ${target} (${method}). ` +
@@ -213,7 +277,7 @@ export async function comfyuiFetch(input, init = {}) {
213
277
  // replacing that text would be a downgrade.
214
278
  if (!isBareFetchFailure(err))
215
279
  throw err;
216
- throw describeComfyFetchFailure(err, targetOf(input));
280
+ throw describeComfyFetchFailure(err, targetOf(input), methodOf(input, init));
217
281
  }
218
282
  }
219
283
  //# sourceMappingURL=fetch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/comfyui/fetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../src/comfyui/fetch.ts"],"names":[],"mappings":"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"}
@@ -2520,8 +2520,33 @@ refusalCause) {
2520
2520
  : ` It has no graph command fence; whether graph reads work is unknown, because the ` +
2521
2521
  `read that would have told us is the one that failed.`) +
2522
2522
  ` This is not a rebind — it is an unknown.` +
2523
- `\n\nWHAT TO DO: retry in a moment a busy or mid-reconnect panel often answers on ` +
2524
- `the next attempt. If it keeps failing: ${RELOAD_TAB_REMEDY}` +
2523
+ // #1071WHY the read failed decides the remedy, exactly as the
2524
+ // no_identity case below already does. Bucketing them would hand half the
2525
+ // callers an instruction they cannot act on.
2526
+ //
2527
+ // - REFUSED BY THE FENCE: retrying is provably useless. This rebind reads
2528
+ // workflow_list, which the panel fences, so the fence being wrong is
2529
+ // precisely what makes the read fail — every time, forever. A reporter
2530
+ // called this five times over twenty minutes on "retry in a moment" and
2531
+ // lost the canvas for the rest of the task. workflow_open is the one
2532
+ // command the fence EXEMPTS, so it still runs while everything else is
2533
+ // refused, and it now re-derives the fence from its own reply.
2534
+ // - ANY OTHER CAUSE (a dead tab, a transport drop, a busy panel): the
2535
+ // panel is not answering at all, so reopening would fail too and
2536
+ // retrying really is the reachable move.
2537
+ (/workflow instance mismatch/i.test(r.detail)
2538
+ ? `\n\nWHAT TO DO: reopen the workflow you want with panel_open_workflow(<path>). ` +
2539
+ `The panel refused the read because of the FENCE itself, so retrying this call ` +
2540
+ `cannot work — it needs the very read the fence blocks. The panel's fence EXEMPTS ` +
2541
+ `workflow_open, so it still runs while everything else is refused, and it ` +
2542
+ `re-derives this session's fence from its own reply. Note panel_list_workflows is ` +
2543
+ `fenced too, so if you do not already know the path, ask the user rather than ` +
2544
+ `guessing. If the canvas you want is an UNSAVED one (a blank workflow you just ` +
2545
+ `created), there is no path to reopen and opening anything else would abandon it — ` +
2546
+ `that case needs the tab refresh below, not a reopen. If reopening also fails: ` +
2547
+ `${RELOAD_TAB_REMEDY}`
2548
+ : `\n\nWHAT TO DO: retry in a moment — a busy or mid-reconnect panel often answers ` +
2549
+ `on the next attempt. If it keeps failing: ${RELOAD_TAB_REMEDY}`) +
2525
2550
  `\n\nUNDERLYING CAUSE (quoted verbatim — disregard any rebind advice inside it; ` +
2526
2551
  `rebinding is what just failed): ${r.detail}`,
2527
2552
  };
@@ -2621,18 +2646,52 @@ async function refreshOpenWorkflowUuid(ctx, requestedPath, openResult) {
2621
2646
  : null;
2622
2647
  if (!requestedIdentity || requestedIdentity !== openedIdentity)
2623
2648
  return;
2649
+ // THREE outcomes for this corroborating read, not two — and conflating the last
2650
+ // two is #1071 (also #932/#1043).
2651
+ //
2652
+ // `workflow_list` is NOT exempt from the panel's fence (activeWorkflowFenceApplies
2653
+ // exempts only canvas-independent ops, workflow_open/new, and non-active-targeted
2654
+ // rename/close). So in exactly the state this refresh exists to repair — a session
2655
+ // fenced to a workflow instance that is no longer active — the read is REFUSED by
2656
+ // the stale fence, the old code took the `return` / `catch`, and the fence was
2657
+ // never refreshed. The recovery was gated behind the one call the wedge blocks.
2658
+ //
2659
+ // The open reply already carries what is needed. The panel publishes
2660
+ // `workflow_uuid` there only after a FINAL SYNCHRONOUS check that `target` is
2661
+ // still the active workflow (#716, activeWorkflowUuidForOpenReply) — omitting it
2662
+ // otherwise, expressly so "the MCP keeps its existing fence fail-closed". It is a
2663
+ // fence-quality value the panel went out of its way to prove; using it when the
2664
+ // read cannot be made is what it is for.
2665
+ let list = null;
2666
+ let readable = false;
2624
2667
  try {
2625
- const list = parseToolResultJson(await ctx.call({ cmd: "workflow_list" }, 6000));
2626
- if (!list || !activeMatchesOpenRefreshTarget(list.active, requestedPath))
2627
- return;
2628
- // Prefer the just-read active UUID; use the command's correlated response as
2629
- // a compatibility fallback only after that same active-target confirmation.
2630
- refreshWorkflowUuid(ctx, list.active) || refreshWorkflowUuid(ctx, parseToolResultJson(openResult));
2668
+ const res = await ctx.call({ cmd: "workflow_list" }, 6000);
2669
+ if (!res?.isError) {
2670
+ list = parseToolResultJson(res);
2671
+ readable = list !== null;
2672
+ }
2631
2673
  }
2632
2674
  catch {
2633
- // A failed read must not convert a confirmed open into a failure, nor should
2634
- // it clear the old stamp. The next mutation remains safely fenced.
2675
+ readable = false;
2676
+ }
2677
+ if (readable) {
2678
+ // ANSWERED. It either confirms our target is active — prefer the just-read
2679
+ // value, which is fresher than the reply — or it names a DIFFERENT active
2680
+ // workflow, in which case another tab won the slot and adopting our target's
2681
+ // uuid would fence this session to a canvas that is not mounted. Adopt nothing.
2682
+ if (!activeMatchesOpenRefreshTarget(list.active, requestedPath))
2683
+ return;
2684
+ refreshWorkflowUuid(ctx, list.active) || refreshWorkflowUuid(ctx, parsedOpen);
2685
+ return;
2635
2686
  }
2687
+ // COULD NOT ASK — the wedged case. Fall back to the reply's proven uuid rather
2688
+ // than leaving the session fenced to a dead instance forever. This is strictly
2689
+ // safer than the alternative it replaces: a stamp the panel proved against its
2690
+ // own active workflow can only authorize commands naming the canvas that is
2691
+ // actually mounted, whereas doing nothing here guarantees every subsequent
2692
+ // command is refused. A reply that carries no uuid (the panel could not prove
2693
+ // it) still refreshes nothing, so fail-closed is preserved.
2694
+ refreshWorkflowUuid(ctx, parsedOpen);
2636
2695
  }
2637
2696
  /** Exact resolved-path check for an open receipt. A filename/basename is not a
2638
2697
  * workflow identity: `other/foo.json` must never confirm `wanted/foo.json`. */