comfyui-mcp 0.19.1 → 0.20.0

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/index.js CHANGED
@@ -7,6 +7,71 @@ import { logger } from "./utils/logger.js";
7
7
  import { JobWatcher } from "./services/job-watcher.js";
8
8
  import { parseCliArgs } from "./transport/cli.js";
9
9
  import { startHttpServer } from "./transport/http.js";
10
+ import { isLocalMode } from "./config.js";
11
+ import { ensurePanelInstalled } from "./services/panel-installer.js";
12
+ import { checkAndSelfUpdate } from "./services/self-update.js";
13
+ /**
14
+ * Fire-and-forget: ensure the ComfyUI sidebar panel is installed (install-if-
15
+ * missing) on MCP load. LOCAL-only, hard-timed-out, and never throws — it must
16
+ * never block or crash startup. Opt out with COMFYUI_MCP_PANEL_AUTOINSTALL=0.
17
+ * The explicit `install_panel(action='update')` tool refreshes nightly on demand.
18
+ */
19
+ function ensurePanelOnLoad() {
20
+ if (!isLocalMode())
21
+ return;
22
+ void ensurePanelInstalled()
23
+ .then((res) => {
24
+ switch (res.action) {
25
+ case "installed":
26
+ logger.info("Panel auto-install: installed the sidebar panel (nightly). RESTART ComfyUI to load it.", res);
27
+ break;
28
+ case "up-to-date":
29
+ logger.info("Panel auto-install: panel already present.", res);
30
+ break;
31
+ case "skipped-dev":
32
+ logger.info("Panel auto-install: skipped — dev install (symlink), managed manually.", res);
33
+ break;
34
+ case "skipped":
35
+ logger.debug("Panel auto-install: disabled via COMFYUI_MCP_PANEL_AUTOINSTALL.", res);
36
+ break;
37
+ default:
38
+ logger.debug("Panel auto-install: unavailable.", res);
39
+ }
40
+ })
41
+ .catch(() => { });
42
+ }
43
+ /**
44
+ * Fire-and-forget: on MCP load, check the npm registry and (for global/local
45
+ * installs) auto-update the package on disk, then surface a "reconnect to load
46
+ * vX" note — the running process can't hot-swap its own code. NEVER updates a
47
+ * dev (npm link) install, hard-timed-out, and never throws. Opt out with
48
+ * COMFYUI_MCP_AUTOUPDATE=0. Mirrors the panel auto-install ensure pattern.
49
+ */
50
+ function selfUpdateOnLoad() {
51
+ void checkAndSelfUpdate()
52
+ .then((res) => {
53
+ switch (res.action) {
54
+ case "updated":
55
+ logger.info(`Self-update: updated comfyui-mcp ${res.from} → ${res.to} (${res.mode}). ${res.note ?? ""}`, res);
56
+ break;
57
+ case "notify":
58
+ logger.info(`Self-update: ${res.note ?? `v${res.to} available.`}`, res);
59
+ break;
60
+ case "up-to-date":
61
+ logger.debug("Self-update: already on the latest version.", res);
62
+ break;
63
+ case "skipped-dev":
64
+ logger.info("Self-update: skipped — dev install (npm link / checkout).", res);
65
+ break;
66
+ case "skipped-disabled":
67
+ logger.debug("Self-update: disabled via COMFYUI_MCP_AUTOUPDATE.", res);
68
+ break;
69
+ default:
70
+ logger.debug("Self-update: unavailable.", res);
71
+ }
72
+ })
73
+ .catch(() => { });
74
+ }
10
75
  async function createConfiguredServer() {
11
76
  const server = new McpServer({
12
77
  name: "comfyui-mcp",
@@ -59,6 +124,10 @@ async function main() {
59
124
  await server.connect(transport);
60
125
  logger.info("ComfyUI MCP server running on stdio");
61
126
  }
127
+ // After the server is up: auto-ensure the sidebar panel (non-blocking).
128
+ ensurePanelOnLoad();
129
+ // ...and self-check the npm registry for a newer published version (non-blocking).
130
+ selfUpdateOnLoad();
62
131
  }
63
132
  main().catch((err) => {
64
133
  logger.error("Fatal error", err);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,299 @@
1
+ // Installs / updates / reinstalls the ComfyUI sidebar panel
2
+ // ("comfyui-agent-panel" on the Comfy Registry; repo comfyui-mcp-panel) into a
3
+ // LOCAL ComfyUI's custom_nodes, and auto-ensures it on MCP load.
4
+ //
5
+ // Policy (decided by the user):
6
+ // - on load → install if MISSING (install-if-missing only, see ensurePanelInstalled).
7
+ // - explicit `update` action → pull the latest nightly on demand.
8
+ // - target version is always "nightly" (the registry git-HEAD channel) — there
9
+ // is no clean semver to diff, so we never churn an existing install on load.
10
+ //
11
+ // SAFETY:
12
+ // - LOCAL-only: no COMFYUI_PATH → no-op cleanly (remote/cloud modes).
13
+ // - NEVER touch a dev install: custom_nodes/comfyui-mcp-panel is often a
14
+ // SYMLINK/junction to the developer's working repo. lstat → skip/refuse.
15
+ // - on-load ensure is fire-and-forget, hard-timed-out, and never throws.
16
+ // - opt-out env COMFYUI_MCP_PANEL_AUTOINSTALL=0/false disables auto-ensure.
17
+ // - install/update/reinstall queue via ComfyUI-Manager; ComfyUI must be
18
+ // RESTARTED to load the new/updated node (we never auto-restart).
19
+ import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
20
+ import { join } from "node:path";
21
+ import { config, isLocalMode } from "../config.js";
22
+ import { logger } from "../utils/logger.js";
23
+ import { parsePyproject } from "./node-authoring.js";
24
+ import { installCustomNode, updateCustomNode, reinstallCustomNode, } from "./node-management.js";
25
+ import { getSystemStats } from "../comfyui/client.js";
26
+ /** Comfy Registry id (also pyproject [project].name). Authoritative for detection. */
27
+ export const PANEL_REGISTRY_ID = "comfyui-agent-panel";
28
+ /** Always install/update/reinstall the panel from the registry git-HEAD channel. */
29
+ export const PANEL_VERSION = "nightly";
30
+ /**
31
+ * Fast-path directory names to probe first. The panel installs to a custom_nodes
32
+ * subdir named after the REPO ("comfyui-mcp-panel"), but the registry name is
33
+ * "comfyui-agent-panel" — so check both quickly, then fall back to a full scan.
34
+ * The pyproject `name == comfyui-agent-panel` match is always authoritative.
35
+ */
36
+ const FAST_PATH_DIRS = ["comfyui-mcp-panel", "comfyui-agent-panel"];
37
+ /** Hard cap so the on-load ensure can never block startup. */
38
+ const ENSURE_TIMEOUT_MS = 20_000;
39
+ export class PanelInstallError extends Error {
40
+ constructor(message) {
41
+ super(message);
42
+ this.name = "PanelInstallError";
43
+ }
44
+ }
45
+ export const defaultDeps = {
46
+ isLocalMode: () => isLocalMode(),
47
+ comfyuiPath: () => config.comfyuiPath,
48
+ env: () => process.env,
49
+ existsSync,
50
+ isSymlink: (p) => {
51
+ try {
52
+ return lstatSync(p).isSymbolicLink();
53
+ }
54
+ catch {
55
+ return false;
56
+ }
57
+ },
58
+ readdir: (p) => readdirSync(p),
59
+ readFile: (p) => readFileSync(p, "utf-8"),
60
+ isReachable: async () => {
61
+ try {
62
+ await getSystemStats();
63
+ return true;
64
+ }
65
+ catch {
66
+ return false;
67
+ }
68
+ },
69
+ install: (opts) => installCustomNode(opts),
70
+ update: (opts) => updateCustomNode(opts),
71
+ reinstall: (opts) => reinstallCustomNode(opts),
72
+ };
73
+ /**
74
+ * Scan <COMFYUI_PATH>/custom_nodes for a subdir whose pyproject.toml
75
+ * `[project].name == "comfyui-agent-panel"`. LOCAL-only: with no comfyuiPath
76
+ * (remote/cloud) returns applicable:false / installed:false.
77
+ */
78
+ export async function detectPanelInstall(deps = defaultDeps) {
79
+ const comfyPath = deps.comfyuiPath();
80
+ // LOCAL-only: in remote/cloud mode the local FS is the wrong filesystem to
81
+ // reason about, so detection is not applicable even if COMFYUI_PATH is set.
82
+ if (!deps.isLocalMode() || !comfyPath) {
83
+ return { applicable: false, installed: false, isDevSymlink: false };
84
+ }
85
+ const customNodes = join(comfyPath, "custom_nodes");
86
+ // P1a — DEV-JUNCTION GUARD, FIRST and INDEPENDENT of pyproject parsing.
87
+ // lstat the KNOWN panel target dirs directly: if either is a symlink/junction
88
+ // it is a dev install and must be protected from any mutation, EVEN when its
89
+ // pyproject.toml is missing, corrupt, or unreadable. (A missing/bad pyproject
90
+ // must never downgrade a junction to "not installed" — that would let
91
+ // install/reinstall clobber the developer's working repo.)
92
+ for (const name of FAST_PATH_DIRS) {
93
+ const dir = join(customNodes, name);
94
+ if (deps.isSymlink(dir)) {
95
+ let version;
96
+ const pyproject = join(dir, "pyproject.toml");
97
+ if (deps.existsSync(pyproject)) {
98
+ try {
99
+ version = parsePyproject(deps.readFile(pyproject)).version;
100
+ }
101
+ catch {
102
+ version = undefined;
103
+ }
104
+ }
105
+ return { applicable: true, installed: true, dir, version, isDevSymlink: true };
106
+ }
107
+ }
108
+ // Candidate dirs: fast-path names first, then any other subdir.
109
+ const candidates = FAST_PATH_DIRS.map((n) => join(customNodes, n));
110
+ if (deps.existsSync(customNodes)) {
111
+ let entries = [];
112
+ try {
113
+ entries = deps.readdir(customNodes);
114
+ }
115
+ catch {
116
+ entries = [];
117
+ }
118
+ for (const e of entries) {
119
+ const full = join(customNodes, e);
120
+ if (!candidates.includes(full))
121
+ candidates.push(full);
122
+ }
123
+ }
124
+ for (const dir of candidates) {
125
+ const pyproject = join(dir, "pyproject.toml");
126
+ if (!deps.existsSync(pyproject))
127
+ continue;
128
+ let parsed;
129
+ try {
130
+ parsed = parsePyproject(deps.readFile(pyproject));
131
+ }
132
+ catch {
133
+ continue;
134
+ }
135
+ if (parsed.projectName === PANEL_REGISTRY_ID) {
136
+ return {
137
+ applicable: true,
138
+ installed: true,
139
+ dir,
140
+ version: parsed.version,
141
+ isDevSymlink: deps.isSymlink(dir),
142
+ };
143
+ }
144
+ }
145
+ return { applicable: true, installed: false, isDevSymlink: false };
146
+ }
147
+ function isAutoInstallDisabled(env) {
148
+ const v = (env.COMFYUI_MCP_PANEL_AUTOINSTALL ?? "").trim().toLowerCase();
149
+ return v === "0" || v === "false" || v === "no" || v === "off";
150
+ }
151
+ function withTimeout(p, ms) {
152
+ return new Promise((resolve, reject) => {
153
+ const t = setTimeout(() => reject(new Error(`panel ensure timed out after ${ms}ms`)), ms);
154
+ p.then((v) => {
155
+ clearTimeout(t);
156
+ resolve(v);
157
+ }, (e) => {
158
+ clearTimeout(t);
159
+ reject(e);
160
+ });
161
+ });
162
+ }
163
+ async function ensureInner(deps) {
164
+ if (isAutoInstallDisabled(deps.env())) {
165
+ return {
166
+ action: "skipped",
167
+ reason: "COMFYUI_MCP_PANEL_AUTOINSTALL disabled",
168
+ };
169
+ }
170
+ if (!deps.isLocalMode()) {
171
+ return {
172
+ action: "unavailable",
173
+ reason: "Panel auto-install is local-only (remote/cloud mode active).",
174
+ };
175
+ }
176
+ if (!deps.comfyuiPath()) {
177
+ return {
178
+ action: "unavailable",
179
+ reason: "No local ComfyUI (COMFYUI_PATH unset); panel auto-install is local-only.",
180
+ };
181
+ }
182
+ if (!(await deps.isReachable())) {
183
+ return { action: "unavailable", reason: "ComfyUI is not reachable." };
184
+ }
185
+ const detection = await detectPanelInstall(deps);
186
+ if (detection.isDevSymlink) {
187
+ return {
188
+ action: "skipped-dev",
189
+ reason: "dev install (symlink) — managed manually",
190
+ dir: detection.dir,
191
+ installedVersion: detection.version,
192
+ };
193
+ }
194
+ if (!detection.installed) {
195
+ await deps.install({ id: PANEL_REGISTRY_ID, version: PANEL_VERSION });
196
+ return {
197
+ action: "installed",
198
+ reason: `Installed ${PANEL_REGISTRY_ID} (${PANEL_VERSION}).`,
199
+ restartRequired: true,
200
+ };
201
+ }
202
+ // Present already. We never diff nightly on load (no clean version), so we
203
+ // leave it untouched — the explicit `update` action refreshes on demand.
204
+ return {
205
+ action: "up-to-date",
206
+ dir: detection.dir,
207
+ installedVersion: detection.version,
208
+ };
209
+ }
210
+ /**
211
+ * The on-load policy engine. LOCAL + reachable only; install-if-missing.
212
+ * Hard-timed-out and swallows every error (returns `unavailable` on failure),
213
+ * so it can be fired-and-forgotten from startup without ever blocking/crashing.
214
+ */
215
+ export async function ensurePanelInstalled(opts = {}) {
216
+ const deps = opts.deps ?? defaultDeps;
217
+ try {
218
+ return await withTimeout(ensureInner(deps), opts.timeoutMs ?? ENSURE_TIMEOUT_MS);
219
+ }
220
+ catch (err) {
221
+ logger.debug("panel: ensure failed", {
222
+ err: err instanceof Error ? err.message : String(err),
223
+ });
224
+ return {
225
+ action: "unavailable",
226
+ reason: err instanceof Error ? err.message : String(err),
227
+ };
228
+ }
229
+ }
230
+ /** status action — never throws. */
231
+ export async function panelStatus(deps = defaultDeps) {
232
+ const detection = await detectPanelInstall(deps).catch(() => ({ applicable: false, installed: false, isDevSymlink: false }));
233
+ let note;
234
+ if (!detection.applicable) {
235
+ note = !deps.isLocalMode()
236
+ ? "Remote/cloud mode — panel install is managed on the ComfyUI host, not from here."
237
+ : "Panel management is local-only; no local ComfyUI (COMFYUI_PATH) is configured.";
238
+ }
239
+ else if (detection.isDevSymlink) {
240
+ note = "dev install (symlink) — managed manually; install/update/reinstall are refused.";
241
+ }
242
+ else if (!detection.installed) {
243
+ note = `Not installed. Run install_panel(action='install') to add the panel (${PANEL_VERSION}). Restart ComfyUI afterwards.`;
244
+ }
245
+ else {
246
+ note = `Installed${detection.version ? ` (${detection.version})` : ""}. Run install_panel(action='update') to pull the latest ${PANEL_VERSION}. Restart ComfyUI after updating.`;
247
+ }
248
+ return {
249
+ applicable: detection.applicable,
250
+ installed: detection.installed,
251
+ dir: detection.dir,
252
+ installedVersion: detection.version,
253
+ isDevSymlink: detection.isDevSymlink,
254
+ targetVersion: PANEL_VERSION,
255
+ note,
256
+ };
257
+ }
258
+ /**
259
+ * install/update/reinstall the panel. LOCAL-only and refuses dev symlinks.
260
+ * Targets version "nightly". Caller must RESTART ComfyUI to load the change.
261
+ */
262
+ export async function runPanelAction(action, deps = defaultDeps) {
263
+ // P1b — truly LOCAL-only. Refuse in remote/cloud mode even when COMFYUI_PATH
264
+ // is set: installCustomNode/reinstallCustomNode would queue Manager mutations
265
+ // against the REMOTE host while our symlink guard inspected the LOCAL disk —
266
+ // the wrong filesystem. The panel must be managed on the ComfyUI host itself.
267
+ if (!deps.isLocalMode()) {
268
+ throw new PanelInstallError(`Panel ${action} is local-only and is refused in remote/cloud mode ` +
269
+ `(a remote COMFYUI_URL / Comfy Cloud is active). Install the panel on ` +
270
+ `the ComfyUI host itself.`);
271
+ }
272
+ if (!deps.comfyuiPath()) {
273
+ throw new PanelInstallError(`Panel ${action} is local-only and requires a local ComfyUI install. ` +
274
+ `Set COMFYUI_PATH (this is a no-op in remote/cloud mode).`);
275
+ }
276
+ const detection = await detectPanelInstall(deps);
277
+ if (detection.isDevSymlink) {
278
+ throw new PanelInstallError(`Refusing to ${action} the panel: it is a dev install (symlink at ${detection.dir}) ` +
279
+ `— managed manually. Update it via your repo/git instead.`);
280
+ }
281
+ let result;
282
+ if (action === "install") {
283
+ result = await deps.install({ id: PANEL_REGISTRY_ID, version: PANEL_VERSION });
284
+ }
285
+ else if (action === "update") {
286
+ result = await deps.update({ id: PANEL_REGISTRY_ID });
287
+ }
288
+ else {
289
+ result = await deps.reinstall({ id: PANEL_REGISTRY_ID, version: PANEL_VERSION });
290
+ }
291
+ return {
292
+ action,
293
+ result,
294
+ restartRequired: true,
295
+ message: `Panel ${action} queued via ComfyUI-Manager (${PANEL_VERSION}). ` +
296
+ `RESTART ComfyUI to load the ${action === "update" ? "updated" : "new"} panel node.`,
297
+ };
298
+ }
299
+ //# sourceMappingURL=panel-installer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"panel-installer.js","sourceRoot":"","sources":["../../src/services/panel-installer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,467 @@
1
+ // Self-update for the comfyui-mcp npm package.
2
+ //
3
+ // On MCP server START we check the npm registry; if a newer version is
4
+ // published we auto-update the on-disk package, then tell the agent/user to
5
+ // RECONNECT — the running Node process cannot hot-swap its own code, so the new
6
+ // version only takes effect after the MCP client reconnects (/mcp) or the
7
+ // orchestrator restarts.
8
+ //
9
+ // This mirrors the SAFETY model of the panel on-load ensure
10
+ // (src/services/panel-installer.ts):
11
+ // - NEVER mutate a dev install. `npm link` makes the package resolve to the
12
+ // developer's working checkout; updating it would clobber their repo. We
13
+ // detect that (install mode "linked") and refuse, exactly like the panel's
14
+ // dev-junction guard.
15
+ // - opt-out env COMFYUI_MCP_AUTOUPDATE=0/false/no/off disables auto-update.
16
+ // - every probe + the npm spawn is hard-timed-out, captures+swallows errors,
17
+ // and NEVER throws — it can be fired-and-forgotten from startup without ever
18
+ // blocking or crashing the server.
19
+ // - we NEVER kill/restart the running MCP process; we only surface a
20
+ // "reconnect to load vX" note.
21
+ import { existsSync, lstatSync, readFileSync, realpathSync } from "node:fs";
22
+ import { execFile } from "node:child_process";
23
+ import { dirname, join, resolve } from "node:path";
24
+ import { fileURLToPath } from "node:url";
25
+ import { logger } from "../utils/logger.js";
26
+ /** npm package name — authoritative for the registry lookup and update command. */
27
+ export const PACKAGE_NAME = "comfyui-mcp";
28
+ /** Hard caps so nothing here can ever block startup. */
29
+ const REGISTRY_TIMEOUT_MS = 5_000;
30
+ const NPM_TIMEOUT_MS = 120_000;
31
+ function defaultPackageDir() {
32
+ // dist/services/self-update.js → packageDir = dist/.. (the package root).
33
+ const here = dirname(fileURLToPath(import.meta.url));
34
+ return resolve(here, "..", "..");
35
+ }
36
+ async function defaultGetLatestVersion() {
37
+ try {
38
+ const res = await fetch(`https://registry.npmjs.org/${PACKAGE_NAME}/latest`, {
39
+ signal: AbortSignal.timeout(REGISTRY_TIMEOUT_MS),
40
+ headers: { accept: "application/json" },
41
+ });
42
+ if (!res.ok)
43
+ return undefined;
44
+ const json = (await res.json());
45
+ return typeof json.version === "string" ? json.version : undefined;
46
+ }
47
+ catch {
48
+ return undefined;
49
+ }
50
+ }
51
+ function defaultRunNpm(args, cwd) {
52
+ return new Promise((resolveP) => {
53
+ // `npm` is a .cmd shim on Windows; execFile needs shell:true to run it.
54
+ // SAFE: every arg is a hard-coded constant (no interpolation of user input),
55
+ // so there is no shell-injection surface.
56
+ const isWin = process.platform === "win32";
57
+ const cmd = isWin ? "npm.cmd" : "npm";
58
+ try {
59
+ const child = execFile(cmd, args, { cwd, timeout: NPM_TIMEOUT_MS, windowsHide: true, shell: isWin }, (err) => resolveP({ ok: !err }));
60
+ child.on("error", () => resolveP({ ok: false }));
61
+ }
62
+ catch {
63
+ resolveP({ ok: false });
64
+ }
65
+ });
66
+ }
67
+ export const defaultDeps = {
68
+ packageDir: defaultPackageDir,
69
+ env: () => process.env,
70
+ existsSync,
71
+ isSymlink: (p) => {
72
+ try {
73
+ return lstatSync(p).isSymbolicLink();
74
+ }
75
+ catch {
76
+ return false;
77
+ }
78
+ },
79
+ realpath: (p) => {
80
+ try {
81
+ return realpathSync(p);
82
+ }
83
+ catch {
84
+ return undefined;
85
+ }
86
+ },
87
+ readFile: (p) => readFileSync(p, "utf-8"),
88
+ getLatestVersion: defaultGetLatestVersion,
89
+ runNpm: defaultRunNpm,
90
+ };
91
+ // ---------------------------------------------------------------------------
92
+ // semver compare (major.minor.patch with a basic prerelease ordering)
93
+ // ---------------------------------------------------------------------------
94
+ /** Compare two semver strings. Returns 1 if a>b, -1 if a<b, 0 if equal/unparseable. */
95
+ export function compareSemver(a, b) {
96
+ const parse = (v) => {
97
+ const m = /^v?(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z.-]+))?/.exec(v.trim());
98
+ if (!m)
99
+ return undefined;
100
+ return {
101
+ nums: [Number(m[1]), Number(m[2]), Number(m[3])],
102
+ pre: m[4] ?? "",
103
+ };
104
+ };
105
+ const pa = parse(a);
106
+ const pb = parse(b);
107
+ if (!pa || !pb)
108
+ return 0;
109
+ for (let i = 0; i < 3; i++) {
110
+ if (pa.nums[i] > pb.nums[i])
111
+ return 1;
112
+ if (pa.nums[i] < pb.nums[i])
113
+ return -1;
114
+ }
115
+ // Equal core. A version WITHOUT a prerelease tag outranks one WITH it.
116
+ if (pa.pre === pb.pre)
117
+ return 0;
118
+ if (pa.pre === "")
119
+ return 1;
120
+ if (pb.pre === "")
121
+ return -1;
122
+ return pa.pre > pb.pre ? 1 : -1;
123
+ }
124
+ /** True when `latest` is strictly newer than `current`. */
125
+ export function isNewer(latest, current) {
126
+ return compareSemver(latest, current) > 0;
127
+ }
128
+ // ---------------------------------------------------------------------------
129
+ // Install-mode detection
130
+ // ---------------------------------------------------------------------------
131
+ function readVersion(deps, dir) {
132
+ try {
133
+ const pkg = JSON.parse(deps.readFile(join(dir, "package.json")));
134
+ return typeof pkg.version === "string" ? pkg.version : undefined;
135
+ }
136
+ catch {
137
+ return undefined;
138
+ }
139
+ }
140
+ /**
141
+ * Split a path into segments, tolerant of mixed separators / Windows drives.
142
+ * Empty segments are KEPT so a leading "/" (POSIX absolute root) survives
143
+ * reconstruction (segs[0] === "" → rejoin yields "/home/...").
144
+ */
145
+ function segmentsOf(p) {
146
+ return p.replace(/\\/g, "/").split("/");
147
+ }
148
+ /**
149
+ * Classify how this package is installed by inspecting the resolved package dir:
150
+ * - linked → `npm link` / run-from-checkout (NOT under node_modules, or the
151
+ * dir is itself a symlink). DEV install — never auto-update.
152
+ * - npx → resolved inside an `_npx` cache dir (npx -y comfyui-mcp).
153
+ * - local → under a project's node_modules; the OUTERMOST host dir with a
154
+ * package.json is the project root (correctly handles pnpm/yarn nested
155
+ * `node_modules/.pnpm/<pkg>/node_modules/<pkg>` virtual-store layouts).
156
+ * - global → the canonical single-`node_modules` global layout (package sits
157
+ * directly inside node_modules, no project package.json above it).
158
+ * - unknown → couldn't classify confidently → caller MUST NOT auto-update.
159
+ *
160
+ * SAFE-FAIL: any uncertainty (realpath resolution failed, nested/ambiguous
161
+ * virtual-store layout with no identifiable project root) returns "unknown"
162
+ * (notify only) — NEVER "global". The dangerous wrong-direction failure is
163
+ * classifying a local install as global and running `npm i -g` against it, so
164
+ * the classifier only ever errs toward "unknown".
165
+ *
166
+ * Uses realpath to follow an `npm link` symlink to the developer's checkout, and
167
+ * lstat to catch the --preserve-symlinks case where the dir is the symlink.
168
+ */
169
+ export function detectInstallMode(deps = defaultDeps) {
170
+ let rawDir;
171
+ try {
172
+ rawDir = deps.packageDir();
173
+ }
174
+ catch {
175
+ return { mode: "unknown", packageDir: "", currentVersion: undefined, isDevLink: false };
176
+ }
177
+ // --preserve-symlinks: the dir we run from is itself the link → dev link.
178
+ const dirIsSymlink = deps.isSymlink(rawDir);
179
+ // Default Node resolves symlinks for import.meta.url, so a linked package's
180
+ // dir already points at the real checkout; realpath is a harmless no-op there.
181
+ // `undefined` means resolution FAILED — we must not trust the raw path for an
182
+ // updatable classification (safe-fail to "unknown" below).
183
+ const resolved = deps.realpath(rawDir);
184
+ const realpathFailed = resolved === undefined;
185
+ const real = resolved ?? rawDir;
186
+ const currentVersion = readVersion(deps, real) ?? readVersion(deps, rawDir);
187
+ const segs = segmentsOf(real);
188
+ const lower = segs.map((s) => s.toLowerCase());
189
+ // npx cache (npm's `_npx` directory) — always notify-only, so realpath
190
+ // uncertainty is harmless here.
191
+ if (lower.includes("_npx")) {
192
+ return { mode: "npx", packageDir: real, currentVersion, isDevLink: false };
193
+ }
194
+ // All `node_modules` segment indices (outermost → innermost).
195
+ const nmIndices = [];
196
+ for (let i = 0; i < lower.length; i++) {
197
+ if (lower[i] === "node_modules")
198
+ nmIndices.push(i);
199
+ }
200
+ if (dirIsSymlink || nmIndices.length === 0) {
201
+ // Not under node_modules (or it's a raw symlink): a working checkout, i.e.
202
+ // `npm link` / `npm run dev` / a git clone. DEV — never auto-update.
203
+ return { mode: "linked", packageDir: real, currentVersion, isDevLink: true };
204
+ }
205
+ // Under node_modules but realpath FAILED → we can't trust the on-disk
206
+ // location → safe-fail to unknown (notify only, never an update).
207
+ if (realpathFailed) {
208
+ return { mode: "unknown", packageDir: real, currentVersion, isDevLink: false };
209
+ }
210
+ // LOCAL: walk OUTWARD — the outermost node_modules whose containing dir has a
211
+ // package.json is the real project root. This makes a pnpm/yarn nested path
212
+ // <proj>/node_modules/.pnpm/<pkg>@x/node_modules/<pkg>
213
+ // resolve to <proj> (local), instead of the virtual-store folder (which has no
214
+ // package.json and would otherwise be misread as a global prefix).
215
+ for (const i of nmIndices) {
216
+ const host = segs.slice(0, i).join("/") || "/";
217
+ if (deps.existsSync(join(host, "package.json"))) {
218
+ return { mode: "local", packageDir: real, currentVersion, isDevLink: false, projectRoot: host };
219
+ }
220
+ }
221
+ // GLOBAL: only the canonical layout — a SINGLE node_modules with the package
222
+ // sitting directly inside it (`<prefix>/.../node_modules/comfyui-mcp`) and no
223
+ // project package.json above it (the npm prefix has none).
224
+ const lastNm = nmIndices[nmIndices.length - 1];
225
+ const packageIsDirectChild = lastNm === segs.length - 2;
226
+ if (nmIndices.length === 1 && packageIsDirectChild) {
227
+ return { mode: "global", packageDir: real, currentVersion, isDevLink: false };
228
+ }
229
+ // Ambiguous (nested/virtual-store layout with no identifiable project root)
230
+ // → safe-fail to unknown. NEVER "global".
231
+ return { mode: "unknown", packageDir: real, currentVersion, isDevLink: false };
232
+ }
233
+ /** Public, error-swallowing wrapper around the npm-registry probe. */
234
+ export async function getLatestPublishedVersion(deps = defaultDeps) {
235
+ try {
236
+ return await deps.getLatestVersion();
237
+ }
238
+ catch {
239
+ return undefined;
240
+ }
241
+ }
242
+ // ---------------------------------------------------------------------------
243
+ // Policy engine
244
+ // ---------------------------------------------------------------------------
245
+ function isAutoUpdateDisabled(env) {
246
+ const v = (env.COMFYUI_MCP_AUTOUPDATE ?? "").trim().toLowerCase();
247
+ return v === "0" || v === "false" || v === "no" || v === "off";
248
+ }
249
+ const RECONNECT_NOTE = "The running MCP server is still on the OLD code — RECONNECT (/mcp) or restart " +
250
+ "the orchestrator to load the new version.";
251
+ /**
252
+ * Build the `npm install` argv for a self-update. Every token is a CONSTANT —
253
+ * no user/dynamic value is ever interpolated into the command (the Windows path
254
+ * runs npm.cmd via shell:true, so injection-safety relies on this). `--no-audit
255
+ * --no-fund` keep it non-interactive and cut extra network/output.
256
+ */
257
+ function npmInstallArgs(mode) {
258
+ const base = mode === "global"
259
+ ? ["i", "-g", `${PACKAGE_NAME}@latest`]
260
+ : ["i", `${PACKAGE_NAME}@latest`];
261
+ return [...base, "--no-audit", "--no-fund"];
262
+ }
263
+ async function checkInner(deps) {
264
+ const info = detectInstallMode(deps);
265
+ // 1) DEV LINK — highest-priority safety guard. Never mutate a dev checkout,
266
+ // even if the user did not set the opt-out env.
267
+ if (info.isDevLink || info.mode === "linked") {
268
+ return {
269
+ action: "skipped-dev",
270
+ mode: info.mode,
271
+ from: info.currentVersion,
272
+ note: "Dev install (npm link / checkout) — self-update is disabled; update via git.",
273
+ };
274
+ }
275
+ // 2) Opt-out.
276
+ if (isAutoUpdateDisabled(deps.env())) {
277
+ return {
278
+ action: "skipped-disabled",
279
+ mode: info.mode,
280
+ from: info.currentVersion,
281
+ note: "Self-update disabled via COMFYUI_MCP_AUTOUPDATE.",
282
+ };
283
+ }
284
+ // 3) Registry probe.
285
+ const latest = await deps.getLatestVersion();
286
+ if (!latest) {
287
+ return {
288
+ action: "unavailable",
289
+ mode: info.mode,
290
+ from: info.currentVersion,
291
+ note: "npm registry unreachable (offline or timed out).",
292
+ };
293
+ }
294
+ // 4) Up to date (also covers an unreadable current version → don't churn).
295
+ if (!info.currentVersion || !isNewer(latest, info.currentVersion)) {
296
+ return {
297
+ action: "up-to-date",
298
+ mode: info.mode,
299
+ from: info.currentVersion,
300
+ to: latest,
301
+ };
302
+ }
303
+ // 5) Newer available. Only global/local can be safely self-replaced on disk.
304
+ if (info.mode === "global" || info.mode === "local") {
305
+ const args = npmInstallArgs(info.mode);
306
+ const { ok } = await deps.runNpm(args, info.mode === "local" ? info.projectRoot : undefined);
307
+ if (!ok) {
308
+ return {
309
+ action: "unavailable",
310
+ mode: info.mode,
311
+ from: info.currentVersion,
312
+ to: latest,
313
+ note: `npm update to ${latest} failed; staying on ${info.currentVersion}.`,
314
+ };
315
+ }
316
+ return {
317
+ action: "updated",
318
+ mode: info.mode,
319
+ from: info.currentVersion,
320
+ to: latest,
321
+ note: `Updated ${PACKAGE_NAME} ${info.currentVersion} → ${latest}. ${RECONNECT_NOTE}`,
322
+ };
323
+ }
324
+ // 6) npx / unknown — can't safely self-replace; notify only.
325
+ const how = info.mode === "npx"
326
+ ? "npx already fetches the latest on next run — restart to pick it up."
327
+ : "Could not classify the install; update manually.";
328
+ return {
329
+ action: "notify",
330
+ mode: info.mode,
331
+ from: info.currentVersion,
332
+ to: latest,
333
+ note: `${PACKAGE_NAME} ${latest} is available (current ${info.currentVersion}). ${how}`,
334
+ };
335
+ }
336
+ /**
337
+ * The on-load policy engine. Detects install mode, checks the registry, and (for
338
+ * global/local) self-updates on disk — then asks the user to RECONNECT. Swallows
339
+ * every error and NEVER throws, so it can be fired-and-forgotten from startup.
340
+ */
341
+ export async function checkAndSelfUpdate(opts = {}) {
342
+ const deps = opts.deps ?? defaultDeps;
343
+ try {
344
+ return await checkInner(deps);
345
+ }
346
+ catch (err) {
347
+ logger.debug("self-update: check failed", {
348
+ err: err instanceof Error ? err.message : String(err),
349
+ });
350
+ let mode = "unknown";
351
+ try {
352
+ mode = detectInstallMode(deps).mode;
353
+ }
354
+ catch {
355
+ /* ignore */
356
+ }
357
+ return {
358
+ action: "unavailable",
359
+ mode,
360
+ note: err instanceof Error ? err.message : String(err),
361
+ };
362
+ }
363
+ }
364
+ /** status action — never throws. Reports mode + current vs latest + notes. */
365
+ export async function selfUpdateStatus(deps = defaultDeps) {
366
+ let info;
367
+ try {
368
+ info = detectInstallMode(deps);
369
+ }
370
+ catch {
371
+ info = { mode: "unknown", packageDir: "", currentVersion: undefined, isDevLink: false };
372
+ }
373
+ const latest = await getLatestPublishedVersion(deps);
374
+ const autoUpdateDisabled = isAutoUpdateDisabled(deps.env());
375
+ const updateAvailable = !!latest && !!info.currentVersion && isNewer(latest, info.currentVersion);
376
+ let note;
377
+ if (info.isDevLink || info.mode === "linked") {
378
+ note = "Dev install (npm link / checkout) — self-update is disabled; update via git.";
379
+ }
380
+ else if (!latest) {
381
+ note = "npm registry unreachable; cannot determine the latest version.";
382
+ }
383
+ else if (!updateAvailable) {
384
+ note = `Up to date (${info.currentVersion}).`;
385
+ }
386
+ else if (info.mode === "npx") {
387
+ note = `${latest} available — npx fetches the latest on next run; restart to pick it up.`;
388
+ }
389
+ else if (info.mode === "unknown") {
390
+ note = `${latest} available — could not classify install; update manually.`;
391
+ }
392
+ else {
393
+ note =
394
+ `${latest} available (current ${info.currentVersion}). ` +
395
+ `Run self_update(action='update')${autoUpdateDisabled ? "" : " (or it auto-updates on start)"}. ${RECONNECT_NOTE}`;
396
+ }
397
+ return {
398
+ mode: info.mode,
399
+ packageDir: info.packageDir,
400
+ currentVersion: info.currentVersion,
401
+ latestVersion: latest,
402
+ updateAvailable,
403
+ isDevLink: info.isDevLink || info.mode === "linked",
404
+ autoUpdateDisabled,
405
+ note,
406
+ };
407
+ }
408
+ export class SelfUpdateError extends Error {
409
+ constructor(message) {
410
+ super(message);
411
+ this.name = "SelfUpdateError";
412
+ }
413
+ }
414
+ /**
415
+ * Explicit `update` action. Refuses on a dev link. Returns the same result shape
416
+ * as the on-load check. Unlike the on-load path this IGNORES the opt-out env
417
+ * (the user explicitly asked), but still never updates a dev link, npx, or
418
+ * unknown install.
419
+ */
420
+ export async function runSelfUpdate(deps = defaultDeps) {
421
+ const info = detectInstallMode(deps);
422
+ if (info.isDevLink || info.mode === "linked") {
423
+ throw new SelfUpdateError("Refusing to self-update a dev install (npm link / checkout). Update via git instead.");
424
+ }
425
+ const latest = await getLatestPublishedVersion(deps);
426
+ if (!latest) {
427
+ return {
428
+ action: "unavailable",
429
+ mode: info.mode,
430
+ from: info.currentVersion,
431
+ note: "npm registry unreachable (offline or timed out).",
432
+ };
433
+ }
434
+ if (!info.currentVersion || !isNewer(latest, info.currentVersion)) {
435
+ return { action: "up-to-date", mode: info.mode, from: info.currentVersion, to: latest };
436
+ }
437
+ if (info.mode === "global" || info.mode === "local") {
438
+ const args = npmInstallArgs(info.mode);
439
+ const { ok } = await deps.runNpm(args, info.mode === "local" ? info.projectRoot : undefined);
440
+ return ok
441
+ ? {
442
+ action: "updated",
443
+ mode: info.mode,
444
+ from: info.currentVersion,
445
+ to: latest,
446
+ note: `Updated ${PACKAGE_NAME} ${info.currentVersion} → ${latest}. ${RECONNECT_NOTE}`,
447
+ }
448
+ : {
449
+ action: "unavailable",
450
+ mode: info.mode,
451
+ from: info.currentVersion,
452
+ to: latest,
453
+ note: `npm update to ${latest} failed; staying on ${info.currentVersion}.`,
454
+ };
455
+ }
456
+ // npx / unknown
457
+ return {
458
+ action: "notify",
459
+ mode: info.mode,
460
+ from: info.currentVersion,
461
+ to: latest,
462
+ note: info.mode === "npx"
463
+ ? `${latest} available — npx fetches the latest on next run; restart to pick it up.`
464
+ : `${latest} available — could not classify install; update manually.`,
465
+ };
466
+ }
467
+ //# sourceMappingURL=self-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../src/services/self-update.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,8 @@ import { registerStorageUploadTools } from "./storage-upload.js";
39
39
  import { registerHealthCheckTools } from "./health-check.js";
40
40
  import { registerWorkflowLockTools } from "./workflow-lock.js";
41
41
  import { registerSkillsAccessTools } from "./skills-access.js";
42
+ import { registerInstallPanelTools } from "./install-panel.js";
43
+ import { registerSelfUpdateTools } from "./self-update.js";
42
44
  import { DefaultsManager } from "../services/defaults-manager.js";
43
45
  export async function registerAllTools(server) {
44
46
  // Hydrate persisted defaults before any tool registration so subsequent
@@ -84,6 +86,8 @@ export async function registerAllTools(server) {
84
86
  registerHealthCheckTools(server);
85
87
  registerWorkflowLockTools(server);
86
88
  registerSkillsAccessTools(server);
89
+ registerInstallPanelTools(server);
90
+ registerSelfUpdateTools(server);
87
91
  await registerAutoloadedWorkflows(server);
88
92
  }
89
93
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ import { panelStatus, runPanelAction, } from "../services/panel-installer.js";
3
+ import { errorToToolResult } from "../utils/errors.js";
4
+ export function registerInstallPanelTools(server) {
5
+ server.tool("install_panel", "Install, update, reinstall, or report status of the ComfyUI sidebar panel " +
6
+ "('comfyui-agent-panel' on the Comfy Registry; repo comfyui-mcp-panel) in the " +
7
+ "LOCAL ComfyUI's custom_nodes. Uses the same ComfyUI-Manager path as " +
8
+ "install_custom_node and always targets the 'nightly' (git-HEAD) channel. " +
9
+ "Local-only (no-op/refuses in remote/cloud mode) and NEVER modifies a dev " +
10
+ "install (a symlinked panel dir). After install/update/reinstall, ComfyUI must " +
11
+ "be RESTARTED to load the new/updated node — this tool does not auto-restart. " +
12
+ "The panel is also auto-installed-if-missing when the MCP server loads.", {
13
+ action: z
14
+ .enum(["status", "install", "update", "reinstall"])
15
+ .default("status")
16
+ .describe("status: report installed/version/dev-symlink (never errors). " +
17
+ "install: add the panel (nightly). update: pull the latest nightly. " +
18
+ "reinstall: uninstall + reinstall (nightly). install/update/reinstall " +
19
+ "refuse on a dev symlink and require a local COMFYUI_PATH."),
20
+ }, async ({ action }) => {
21
+ try {
22
+ if (action === "status") {
23
+ const status = await panelStatus();
24
+ return {
25
+ content: [
26
+ { type: "text", text: JSON.stringify(status, null, 2) },
27
+ ],
28
+ };
29
+ }
30
+ const result = await runPanelAction(action);
31
+ return {
32
+ content: [
33
+ { type: "text", text: JSON.stringify(result, null, 2) },
34
+ ],
35
+ };
36
+ }
37
+ catch (err) {
38
+ return errorToToolResult(err);
39
+ }
40
+ });
41
+ }
42
+ //# sourceMappingURL=install-panel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install-panel.js","sourceRoot":"","sources":["../../src/tools/install-panel.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,WAAW,EACX,cAAc,GACf,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,UAAU,yBAAyB,CAAC,MAAiB;IACzD,MAAM,CAAC,IAAI,CACT,eAAe,EACf,4EAA4E;QAC1E,+EAA+E;QAC/E,sEAAsE;QACtE,2EAA2E;QAC3E,2EAA2E;QAC3E,gFAAgF;QAChF,+EAA+E;QAC/E,wEAAwE,EAC1E;QACE,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;aAClD,OAAO,CAAC,QAAQ,CAAC;aACjB,QAAQ,CACP,+DAA+D;YAC7D,qEAAqE;YACrE,uEAAuE;YACvE,2DAA2D,CAC9D;KACJ,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;gBACxB,MAAM,MAAM,GAAG,MAAM,WAAW,EAAE,CAAC;gBACnC,OAAO;oBACL,OAAO,EAAE;wBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;qBACjE;iBACF,CAAC;YACJ,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;YAC5C,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACjE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { z } from "zod";
2
+ import { runSelfUpdate, selfUpdateStatus } from "../services/self-update.js";
3
+ import { errorToToolResult } from "../utils/errors.js";
4
+ export function registerSelfUpdateTools(server) {
5
+ server.tool("self_update", "Check or apply a self-update of the comfyui-mcp npm package against the npm " +
6
+ "registry. The server also auto-checks on start (opt out with " +
7
+ "COMFYUI_MCP_AUTOUPDATE=0). Detects the install mode: a dev install (npm " +
8
+ "link / source checkout) is NEVER updated; global/local installs are updated " +
9
+ "via npm; npx fetches latest on next run. The running process cannot hot-swap " +
10
+ "its own code — after an update you must RECONNECT (/mcp) or restart the " +
11
+ "orchestrator to load the new version. This tool does not auto-restart.", {
12
+ action: z
13
+ .enum(["status", "update"])
14
+ .default("status")
15
+ .describe("status: report install mode + current vs latest version + dev-link note " +
16
+ "(never errors). update: update to the latest published version " +
17
+ "(refuses on a dev link; no-op when already up to date or for npx)."),
18
+ }, async ({ action }) => {
19
+ try {
20
+ const result = action === "status" ? await selfUpdateStatus() : await runSelfUpdate();
21
+ return {
22
+ content: [
23
+ { type: "text", text: JSON.stringify(result, null, 2) },
24
+ ],
25
+ };
26
+ }
27
+ catch (err) {
28
+ return errorToToolResult(err);
29
+ }
30
+ });
31
+ }
32
+ //# sourceMappingURL=self-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"self-update.js","sourceRoot":"","sources":["../../src/tools/self-update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC7E,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,UAAU,uBAAuB,CAAC,MAAiB;IACvD,MAAM,CAAC,IAAI,CACT,aAAa,EACb,8EAA8E;QAC5E,+DAA+D;QAC/D,0EAA0E;QAC1E,8EAA8E;QAC9E,+EAA+E;QAC/E,0EAA0E;QAC1E,wEAAwE,EAC1E;QACE,MAAM,EAAE,CAAC;aACN,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;aAC1B,OAAO,CAAC,QAAQ,CAAC;aACjB,QAAQ,CACP,0EAA0E;YACxE,iEAAiE;YACjE,oEAAoE,CACvE;KACJ,EACD,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QACnB,IAAI,CAAC;YACH,MAAM,MAAM,GACV,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,gBAAgB,EAAE,CAAC,CAAC,CAAC,MAAM,aAAa,EAAE,CAAC;YACzE,OAAO;gBACL,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;iBACjE;aACF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;QAChC,CAAC;IACH,CAAC,CACF,CAAC;AACJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "comfyui-mcp",
3
- "version": "0.19.1",
3
+ "version": "0.20.0",
4
4
  "mcpName": "io.github.artokun/comfyui-mcp",
5
5
  "description": "MCP server + autonomous AI agent for ComfyUI — drive your live graph in natural language from a sidebar agent on Claude OR ChatGPT (your own subscription, no API key). Generate images, video & audio, author and run workflows, manage models and custom nodes. Also a Claude Code plugin with skills, slash commands, and installer packs.",
6
6
  "homepage": "https://comfyui-mcp.artokun.io/docs",