comfyui-mcp 0.7.0 → 0.8.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.
Files changed (96) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +12 -0
  3. package/ROADMAP.md +15 -0
  4. package/dist/services/download-auth.d.ts +7 -0
  5. package/dist/services/download-auth.d.ts.map +1 -1
  6. package/dist/services/download-auth.js +26 -1
  7. package/dist/services/download-auth.js.map +1 -1
  8. package/dist/services/download-cache.d.ts +3 -1
  9. package/dist/services/download-cache.d.ts.map +1 -1
  10. package/dist/services/download-cache.js +45 -9
  11. package/dist/services/download-cache.js.map +1 -1
  12. package/dist/services/image-convert.d.ts +29 -0
  13. package/dist/services/image-convert.d.ts.map +1 -0
  14. package/dist/services/image-convert.js +218 -0
  15. package/dist/services/image-convert.js.map +1 -0
  16. package/dist/services/manifest.d.ts +63 -0
  17. package/dist/services/manifest.d.ts.map +1 -0
  18. package/dist/services/manifest.js +333 -0
  19. package/dist/services/manifest.js.map +1 -0
  20. package/dist/services/model-resolver.d.ts.map +1 -1
  21. package/dist/services/model-resolver.js +7 -1
  22. package/dist/services/model-resolver.js.map +1 -1
  23. package/dist/services/node-authoring.d.ts +5 -0
  24. package/dist/services/node-authoring.d.ts.map +1 -1
  25. package/dist/services/node-authoring.js +56 -0
  26. package/dist/services/node-authoring.js.map +1 -1
  27. package/dist/services/node-verify.d.ts +35 -0
  28. package/dist/services/node-verify.d.ts.map +1 -0
  29. package/dist/services/node-verify.js +138 -0
  30. package/dist/services/node-verify.js.map +1 -0
  31. package/dist/services/skill-cache.d.ts +26 -0
  32. package/dist/services/skill-cache.d.ts.map +1 -0
  33. package/dist/services/skill-cache.js +172 -0
  34. package/dist/services/skill-cache.js.map +1 -0
  35. package/dist/services/storage/azure-blob.d.ts +8 -0
  36. package/dist/services/storage/azure-blob.d.ts.map +1 -0
  37. package/dist/services/storage/azure-blob.js +146 -0
  38. package/dist/services/storage/azure-blob.js.map +1 -0
  39. package/dist/services/storage/hf.d.ts +7 -0
  40. package/dist/services/storage/hf.d.ts.map +1 -0
  41. package/dist/services/storage/hf.js +80 -0
  42. package/dist/services/storage/hf.js.map +1 -0
  43. package/dist/services/storage/http.d.ts +6 -0
  44. package/dist/services/storage/http.d.ts.map +1 -0
  45. package/dist/services/storage/http.js +41 -0
  46. package/dist/services/storage/http.js.map +1 -0
  47. package/dist/services/storage/index.d.ts +28 -0
  48. package/dist/services/storage/index.d.ts.map +1 -0
  49. package/dist/services/storage/index.js +42 -0
  50. package/dist/services/storage/index.js.map +1 -0
  51. package/dist/services/storage/s3.d.ts +12 -0
  52. package/dist/services/storage/s3.d.ts.map +1 -0
  53. package/dist/services/storage/s3.js +84 -0
  54. package/dist/services/storage/s3.js.map +1 -0
  55. package/dist/services/storage/types.d.ts +22 -0
  56. package/dist/services/storage/types.d.ts.map +1 -0
  57. package/dist/services/storage/types.js +2 -0
  58. package/dist/services/storage/types.js.map +1 -0
  59. package/dist/services/storage/utils.d.ts +6 -0
  60. package/dist/services/storage/utils.d.ts.map +1 -0
  61. package/dist/services/storage/utils.js +39 -0
  62. package/dist/services/storage/utils.js.map +1 -0
  63. package/dist/services/storage-upload.d.ts +18 -0
  64. package/dist/services/storage-upload.d.ts.map +1 -0
  65. package/dist/services/storage-upload.js +121 -0
  66. package/dist/services/storage-upload.js.map +1 -0
  67. package/dist/tools/image-convert.d.ts +3 -0
  68. package/dist/tools/image-convert.d.ts.map +1 -0
  69. package/dist/tools/image-convert.js +58 -0
  70. package/dist/tools/image-convert.js.map +1 -0
  71. package/dist/tools/index.d.ts.map +1 -1
  72. package/dist/tools/index.js +8 -0
  73. package/dist/tools/index.js.map +1 -1
  74. package/dist/tools/manifest.d.ts +3 -0
  75. package/dist/tools/manifest.d.ts.map +1 -0
  76. package/dist/tools/manifest.js +25 -0
  77. package/dist/tools/manifest.js.map +1 -0
  78. package/dist/tools/model-management.d.ts.map +1 -1
  79. package/dist/tools/model-management.js +9 -1
  80. package/dist/tools/model-management.js.map +1 -1
  81. package/dist/tools/node-authoring.d.ts.map +1 -1
  82. package/dist/tools/node-authoring.js +8 -2
  83. package/dist/tools/node-authoring.js.map +1 -1
  84. package/dist/tools/node-verify.d.ts +3 -0
  85. package/dist/tools/node-verify.d.ts.map +1 -0
  86. package/dist/tools/node-verify.js +42 -0
  87. package/dist/tools/node-verify.js.map +1 -0
  88. package/dist/tools/skill-generator.d.ts.map +1 -1
  89. package/dist/tools/skill-generator.js +16 -3
  90. package/dist/tools/skill-generator.js.map +1 -1
  91. package/dist/tools/storage-upload.d.ts +3 -0
  92. package/dist/tools/storage-upload.d.ts.map +1 -0
  93. package/dist/tools/storage-upload.js +57 -0
  94. package/dist/tools/storage-upload.js.map +1 -0
  95. package/package.json +5 -1
  96. package/scripts/gen-tool-docs.ts +6 -5
package/CHANGELOG.md CHANGED
@@ -4,6 +4,57 @@ All notable changes to this project are documented here. This project adheres to
4
4
  [Semantic Versioning](https://semver.org/) and the format follows
5
5
  [Keep a Changelog](https://keepachangelog.com/).
6
6
 
7
+ ## [0.8.0] - 2026-05-26
8
+
9
+ Completes the custom-node authoring lifecycle, adds cloud storage I/O and
10
+ declarative setup, and adds node discovery — all built and reviewed in a
11
+ codex implement→review→fix loop.
12
+
13
+ ### Added
14
+
15
+ - **`apply_manifest`** — declarative environment setup from an inline object or
16
+ a JSON/YAML manifest: `pip` packages, `custom_nodes` (registry ids or git URLs
17
+ with `@ref`), and `models`. Idempotent, per-item structured report; `apt`
18
+ entries are accepted but skipped (manual/root). Local-only.
19
+ - **`verify_custom_node`** — the "test" step of the author loop: restarts ComfyUI
20
+ (with a bounded readiness wait) and confirms a pack's `NODE_CLASS_MAPPINGS`
21
+ class_types registered in `/object_info` (a failed import simply never appears).
22
+ - **`scaffold_custom_node`** now also emits `.comfyignore`/`.gitignore` and, with
23
+ `with_ci`, a `.github/workflows/publish_action.yml` (Comfy-Org/publish-node-action).
24
+ - **`convert_image`** — re-encode a generated image (by `asset_id` or output-dir
25
+ path) to PNG/JPEG/WebP via `sharp`; returns inline base64 + optional file write
26
+ (output-dir confined), and reports bytes saved.
27
+ - **Cloud storage** — model downloads may be `s3://` or Azure Blob URLs
28
+ (`download_model` gains `s3` auth); new **`upload_output`** pushes a generated
29
+ output to S3 / Azure / HTTP / Hugging Face and returns URL(s).
30
+ - **`download_model` `auth`** — per-request `bearer`/`basic`/`header`/`query`
31
+ authentication for gated/private hosts (carried over and extended).
32
+ - **`comfy-researcher` agent** — turns a problem statement into ranked custom-node
33
+ pack recommendations (searches the Registry, evaluates, delegates deep dives to
34
+ `comfy-explorer`).
35
+ - **Cached `generate_node_skill`** — read-through cache keyed by source@version
36
+ (`COMFYUI_SKILL_CACHE_DIR`; `refresh` to bypass), so repeat analyses are instant.
37
+
38
+ ### Security
39
+
40
+ - `apply_manifest` rejects pip argv-option injection; realpath/symlink-safe path
41
+ containment for manifest model paths, `convert_image`, and upload sources;
42
+ `convert_image` caps source size + sharp pixels.
43
+ - Cloud storage: Azure SAS / AWS presigned secrets redacted from logs/errors;
44
+ Azure URL-vs-env account mismatch rejected; HF-CLI remote-path argv hardening;
45
+ manual redirect handling (no cross-origin auth replay or upload-redirect SSRF).
46
+
47
+ ### Fixed
48
+
49
+ - `generate_node_skill` cache resolves the current pack version before lookup
50
+ (no stale docs served after a pack updates) and writes atomically (temp +
51
+ rename with a content-hash check).
52
+
53
+ ### Dependencies
54
+
55
+ - Added `yaml` (manifest parsing), `sharp` (image conversion), `@aws-sdk/client-s3`
56
+ and `@azure/storage-blob` (cloud storage). `npm audit`: 0 high vulnerabilities.
57
+
7
58
  ## [0.7.0] - 2026-05-25
8
59
 
9
60
  Stability + authoring release: hardens model downloads and the ComfyUI process
@@ -120,6 +171,7 @@ subprocess fallback where the API can't do the job.
120
171
 
121
172
  Earlier releases predate this changelog.
122
173
 
174
+ [0.8.0]: https://github.com/artokun/comfyui-mcp/releases/tag/v0.8.0
123
175
  [0.7.0]: https://github.com/artokun/comfyui-mcp/releases/tag/v0.7.0
124
176
  [0.6.1]: https://github.com/artokun/comfyui-mcp/releases/tag/v0.6.1
125
177
  [0.6.0]: https://github.com/artokun/comfyui-mcp/releases/tag/v0.6.0
package/README.md CHANGED
@@ -658,6 +658,18 @@ MIT — see [LICENSE](./LICENSE) for details.
658
658
 
659
659
  The full, structured changelog lives in [CHANGELOG.md](./CHANGELOG.md). Recent highlights:
660
660
 
661
+ ### 0.8.0 — 2026-05-26
662
+
663
+ **Lifecycle + I/O + discovery.**
664
+
665
+ - **`apply_manifest`** — declarative env setup (pip / custom_nodes / models) from an inline or JSON/YAML manifest; idempotent.
666
+ - **`verify_custom_node`** — restart + `/object_info` load-check that a scaffolded/installed pack's node types actually registered.
667
+ - **`scaffold_custom_node`** — now also emits `.comfyignore`/`.gitignore` and (with `with_ci`) a GitHub publish workflow.
668
+ - **`convert_image`** — re-encode outputs to PNG/JPEG/WebP via `sharp`.
669
+ - **Cloud storage** — `s3://` / Azure-Blob model downloads + a new **`upload_output`** (S3/Azure/HTTP/HF).
670
+ - **`comfy-researcher` agent** — problem → ranked custom-node recommendations; **`generate_node_skill`** is now cached (source@version).
671
+ - **Security** — pip/argv-injection guards, realpath/symlink-safe path containment, cloud-credential + SAS/presigned redaction, redirect-SSRF hardening.
672
+
661
673
  ### 0.7.0 — 2026-05-25
662
674
 
663
675
  **Stability + authoring.**
package/ROADMAP.md CHANGED
@@ -10,6 +10,21 @@ Comfy Registry.
10
10
 
11
11
  ---
12
12
 
13
+ ## Status — 2026-05-26
14
+
15
+ - **Released:** `0.7.0` on npm — Theme E stability/hardening (E1–E4, E7, E2-auth), custom-node
16
+ authoring tools, experimental agent-panel backend, hosted docs.
17
+ - **Complete (on main, unreleased → queued for `0.8.0`):** Theme E additive (E5 `apply_manifest`,
18
+ E6/E2b cloud storage, E8 `convert_image`), Theme C (C3 `verify_custom_node`, C5 scaffold CI),
19
+ Theme D (D1 `comfy-researcher` + skill cache). **Epics A, C, D, E are closed.**
20
+ - **Pending release:** cut **`0.8.0`** for the unreleased surface above — `comfyui-mcp-yrp` (see beads).
21
+ - **Blocked:** **Theme B** (embedded agent panel UI, B3–B6) is gated on the upstream
22
+ **`@comfyorg/extension-api`** package being published to npm (PRs #12142–#12145 still open). The
23
+ panel *backend* POC (B1/B2) already shipped. Tracked by a watch bead under Epic B; resume the
24
+ codex build loop on B once the package lands.
25
+
26
+ ---
27
+
13
28
  ## ✅ Shipped (0.6.x)
14
29
  - comfy-cli capability port (custom-node mgmt, snapshots, bisect, workflow deps, install/update,
15
30
  models, workspace/env, API nodes, manager config) — tools surface ~70+.
@@ -13,6 +13,13 @@ export type DownloadAuth = {
13
13
  type: "query";
14
14
  query_param: string;
15
15
  query_value: string;
16
+ } | {
17
+ type: "s3";
18
+ access_key_id: string;
19
+ secret_access_key: string;
20
+ session_token?: string;
21
+ region?: string;
22
+ endpoint?: string;
16
23
  };
17
24
  export interface DownloadRequestAuth {
18
25
  url: string;
@@ -1 +1 @@
1
- {"version":3,"file":"download-auth.d.ts","sourceRoot":"","sources":["../../src/services/download-auth.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhE,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAyCD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,oBAAoB,GAAE,MAAM,EAAO,GAClC,MAAM,CAaR;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,YAAY,GAClB,mBAAmB,CAgCrB"}
1
+ {"version":3,"file":"download-auth.d.ts","sourceRoot":"","sources":["../../src/services/download-auth.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC7D;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,GAC3D;IACE,IAAI,EAAE,IAAI,CAAC;IACX,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEN,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACjC;AAyDD,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,oBAAoB,GAAE,MAAM,EAAO,GAClC,MAAM,CAcR;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,YAAY,GAClB,mBAAmB,CAuCrB"}
@@ -3,6 +3,8 @@ const TOKEN_QUERY_RE = /token|key|secret|signature|auth|password|credential/i;
3
3
  const REDACTED = "[REDACTED]";
4
4
  const HEADER_NAME_RE = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/;
5
5
  const ASCII_CONTROL_RE = /[\x00-\x1F\x7F]/;
6
+ const AZURE_BLOB_HOST_SUFFIX = ".blob.core.windows.net";
7
+ const AWS_PRESIGNED_QUERY_RE = /^x-amz-/i;
6
8
  function rejectControlChars(label, value) {
7
9
  if (ASCII_CONTROL_RE.test(value)) {
8
10
  throw new ValidationError(`${label} cannot contain ASCII control characters.`);
@@ -25,17 +27,34 @@ function validateDownloadAuth(auth) {
25
27
  rejectControlChars("Header auth header_value", auth.header_value);
26
28
  return;
27
29
  }
30
+ if (auth.type === "s3") {
31
+ rejectControlChars("S3 access_key_id", auth.access_key_id);
32
+ rejectControlChars("S3 secret_access_key", auth.secret_access_key);
33
+ if (auth.session_token)
34
+ rejectControlChars("S3 session_token", auth.session_token);
35
+ if (auth.region)
36
+ rejectControlChars("S3 region", auth.region);
37
+ if (auth.endpoint)
38
+ rejectControlChars("S3 endpoint", auth.endpoint);
39
+ return;
40
+ }
28
41
  if (auth.query_param.length === 0) {
29
42
  throw new ValidationError("Query auth query_param must be a non-empty string.");
30
43
  }
31
44
  rejectControlChars("Query auth query_param", auth.query_param);
32
45
  }
46
+ function shouldRedactAllQueryValues(parsed) {
47
+ if (parsed.hostname.endsWith(AZURE_BLOB_HOST_SUFFIX))
48
+ return true;
49
+ return [...parsed.searchParams.keys()].some((key) => AWS_PRESIGNED_QUERY_RE.test(key));
50
+ }
33
51
  export function redactUrlForLogs(url, extraSensitiveParams = []) {
34
52
  try {
35
53
  const parsed = new URL(url);
54
+ const redactAll = shouldRedactAllQueryValues(parsed);
36
55
  const sensitive = new Set(extraSensitiveParams.map((p) => p.toLowerCase()));
37
56
  for (const key of [...parsed.searchParams.keys()]) {
38
- if (sensitive.has(key.toLowerCase()) || TOKEN_QUERY_RE.test(key)) {
57
+ if (redactAll || sensitive.has(key.toLowerCase()) || TOKEN_QUERY_RE.test(key)) {
39
58
  parsed.searchParams.set(key, REDACTED);
40
59
  }
41
60
  }
@@ -68,6 +87,12 @@ export function applyDownloadAuth(url, auth) {
68
87
  headers: { [auth.header_name]: auth.header_value },
69
88
  };
70
89
  }
90
+ if (auth.type === "s3") {
91
+ return {
92
+ url,
93
+ headers: {},
94
+ };
95
+ }
71
96
  const parsed = new URL(url);
72
97
  parsed.searchParams.set(auth.query_param, auth.query_value);
73
98
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"download-auth.js","sourceRoot":"","sources":["../../src/services/download-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"download-auth.js","sourceRoot":"","sources":["../../src/services/download-auth.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,5 @@
1
1
  import { copyFile, link, mkdir, readdir, rename, rm, stat, utimes } from "node:fs/promises";
2
+ import { type CloudStorageAuth } from "./storage/index.js";
2
3
  export declare const downloadCacheFs: {
3
4
  copyFile: typeof copyFile;
4
5
  link: typeof link;
@@ -14,6 +15,7 @@ export interface DownloadCacheOptions {
14
15
  headers: Record<string, string>;
15
16
  targetPath: string;
16
17
  logUrl?: string;
18
+ storageAuth?: CloudStorageAuth;
17
19
  }
18
20
  export interface DownloadCacheResult {
19
21
  targetPath: string;
@@ -21,6 +23,6 @@ export interface DownloadCacheResult {
21
23
  cachePath?: string;
22
24
  materializedBy?: "hardlink" | "copy";
23
25
  }
24
- export declare function downloadUrlToFile(url: string, targetPath: string, headers: Record<string, string>, logUrl?: string): Promise<void>;
26
+ export declare function downloadUrlToFile(url: string, targetPath: string, headers: Record<string, string>, logUrl?: string, storageAuth?: CloudStorageAuth): Promise<void>;
25
27
  export declare function downloadWithCache(options: DownloadCacheOptions): Promise<DownloadCacheResult>;
26
28
  //# sourceMappingURL=download-cache.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"download-cache.d.ts","sourceRoot":"","sources":["../../src/services/download-cache.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,OAAO,EACP,MAAM,EACN,EAAE,EACF,IAAI,EACJ,MAAM,EACP,MAAM,kBAAkB,CAAC;AAa1B,eAAO,MAAM,eAAe;;;;;;;;;CAS3B,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;CACtC;AA+ID,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAqB9B"}
1
+ {"version":3,"file":"download-cache.d.ts","sourceRoot":"","sources":["../../src/services/download-cache.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,OAAO,EACP,MAAM,EACN,EAAE,EACF,IAAI,EACJ,MAAM,EACP,MAAM,kBAAkB,CAAC;AAQ1B,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAO5B,eAAO,MAAM,eAAe;;;;;;;;;CAS3B,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,gBAAgB,CAAC;CAChC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;CACtC;AAoLD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,EACf,WAAW,GAAE,gBAAqB,GACjC,OAAO,CAAC,IAAI,CAAC,CAEf;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,oBAAoB,GAC5B,OAAO,CAAC,mBAAmB,CAAC,CAgC9B"}
@@ -8,8 +8,10 @@ import { pipeline } from "node:stream/promises";
8
8
  import { ModelError } from "../utils/errors.js";
9
9
  import { logger } from "../utils/logger.js";
10
10
  import { redactUrlForLogs } from "./download-auth.js";
11
+ import { downloadCloudUrlToFile, supportsCloudDownload, } from "./storage/index.js";
11
12
  const DEFAULT_CACHE_DIR = join(homedir(), ".comfyui-mcp", "cache");
12
13
  const HASH_CHARS = 32;
14
+ const MAX_HTTP_REDIRECTS = 5;
13
15
  const inflight = new Map();
14
16
  export const downloadCacheFs = {
15
17
  copyFile,
@@ -46,10 +48,44 @@ async function touch(path) {
46
48
  const now = new Date();
47
49
  await downloadCacheFs.utimes(path, now, now);
48
50
  }
49
- async function streamUrlToFile(url, targetPath, headers, logUrl = redactUrlForLogs(url)) {
50
- const res = await fetch(url, { headers });
51
+ async function streamUrlToFile(url, targetPath, headers, logUrl = redactUrlForLogs(url), storageAuth = {}) {
52
+ if (supportsCloudDownload(url)) {
53
+ await downloadCloudUrlToFile(url, targetPath, storageAuth);
54
+ return;
55
+ }
56
+ let currentUrl = url;
57
+ let currentHeaders = headers;
58
+ let res;
59
+ for (let redirectCount = 0;; redirectCount += 1) {
60
+ res = await fetch(currentUrl, { headers: currentHeaders, redirect: "manual" });
61
+ if (res.status < 300 || res.status >= 400)
62
+ break;
63
+ if (redirectCount >= MAX_HTTP_REDIRECTS) {
64
+ throw new ModelError("Download redirect limit exceeded", {
65
+ url: redactUrlForLogs(currentUrl),
66
+ status: res.status,
67
+ });
68
+ }
69
+ const location = res.headers.get("location");
70
+ if (!location)
71
+ break;
72
+ let nextUrl;
73
+ try {
74
+ nextUrl = new URL(location, currentUrl).toString();
75
+ }
76
+ catch {
77
+ throw new ModelError("Download redirect location is invalid", {
78
+ url: redactUrlForLogs(currentUrl),
79
+ status: res.status,
80
+ });
81
+ }
82
+ const sameOrigin = new URL(nextUrl).origin === new URL(currentUrl).origin;
83
+ currentUrl = nextUrl;
84
+ if (!sameOrigin)
85
+ currentHeaders = {};
86
+ }
51
87
  if (!res.ok) {
52
- throw new ModelError(`Download failed: ${res.status} ${res.statusText}`, { url: logUrl, status: res.status });
88
+ throw new ModelError(`Download failed: ${res.status} ${res.statusText}`, { url: currentUrl === url ? logUrl : redactUrlForLogs(currentUrl), status: res.status });
53
89
  }
54
90
  if (!res.body) {
55
91
  throw new ModelError("Download response has no body", { url: logUrl });
@@ -58,7 +94,7 @@ async function streamUrlToFile(url, targetPath, headers, logUrl = redactUrlForLo
58
94
  const fileStream = createWriteStream(targetPath);
59
95
  await pipeline(nodeStream, fileStream);
60
96
  }
61
- async function downloadIntoCache(url, headers, logUrl) {
97
+ async function downloadIntoCache(url, headers, logUrl, storageAuth = {}) {
62
98
  const target = cachePathForUrl(url);
63
99
  const key = target;
64
100
  const existing = inflight.get(key);
@@ -78,7 +114,7 @@ async function downloadIntoCache(url, headers, logUrl) {
78
114
  }
79
115
  const tmp = join(cacheDir(), `.${basename(target)}.${process.pid}.${randomUUID()}.tmp`);
80
116
  try {
81
- await streamUrlToFile(url, tmp, headers, logUrl);
117
+ await streamUrlToFile(url, tmp, headers, logUrl, storageAuth);
82
118
  await downloadCacheFs.rename(tmp, target);
83
119
  await touch(target);
84
120
  return target;
@@ -137,13 +173,13 @@ async function evictLruIfNeeded() {
137
173
  break;
138
174
  }
139
175
  }
140
- export async function downloadUrlToFile(url, targetPath, headers, logUrl) {
141
- await streamUrlToFile(url, targetPath, headers, logUrl);
176
+ export async function downloadUrlToFile(url, targetPath, headers, logUrl, storageAuth = {}) {
177
+ await streamUrlToFile(url, targetPath, headers, logUrl, storageAuth);
142
178
  }
143
179
  export async function downloadWithCache(options) {
144
180
  const logUrl = options.logUrl ?? redactUrlForLogs(options.url);
145
181
  try {
146
- const cachePath = await downloadIntoCache(options.url, options.headers, logUrl);
182
+ const cachePath = await downloadIntoCache(options.url, options.headers, logUrl, options.storageAuth);
147
183
  const materializedBy = await materializeCacheFile(cachePath, options.targetPath);
148
184
  await evictLruIfNeeded();
149
185
  return {
@@ -160,7 +196,7 @@ export async function downloadWithCache(options) {
160
196
  url: logUrl,
161
197
  error: err instanceof Error ? err.message : String(err),
162
198
  });
163
- await downloadUrlToFile(options.url, options.targetPath, options.headers, logUrl);
199
+ await downloadUrlToFile(options.url, options.targetPath, options.headers, logUrl, options.storageAuth);
164
200
  return { targetPath: options.targetPath, usedCache: false };
165
201
  }
166
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"download-cache.js","sourceRoot":"","sources":["../../src/services/download-cache.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"download-cache.js","sourceRoot":"","sources":["../../src/services/download-cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export type ConvertImageFormat = "png" | "jpeg" | "webp";
2
+ export interface ConvertImageOptions {
3
+ asset_id?: string;
4
+ path?: string;
5
+ format: ConvertImageFormat;
6
+ quality?: number;
7
+ progressive?: boolean;
8
+ lossless?: boolean;
9
+ effort?: number;
10
+ out_path?: string;
11
+ }
12
+ export interface ConvertImageResult {
13
+ content: Array<{
14
+ type: "text";
15
+ text: string;
16
+ } | {
17
+ type: "image";
18
+ data: string;
19
+ mimeType: string;
20
+ }>;
21
+ format: ConvertImageFormat;
22
+ mimeType: string;
23
+ sourceBytes: number;
24
+ outputBytes: number;
25
+ bytesSaved: number;
26
+ outPath?: string;
27
+ }
28
+ export declare function convertImage(opts: ConvertImageOptions): Promise<ConvertImageResult>;
29
+ //# sourceMappingURL=image-convert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-convert.d.ts","sourceRoot":"","sources":["../../src/services/image-convert.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAEzD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,kBAAkB,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,KAAK,CACV;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAC9B;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CACpD,CAAC;IACF,MAAM,EAAE,kBAAkB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AA4ND,wBAAsB,YAAY,CAChC,IAAI,EAAE,mBAAmB,GACxB,OAAO,CAAC,kBAAkB,CAAC,CA8C7B"}
@@ -0,0 +1,218 @@
1
+ import { lstat, mkdir, readFile, realpath, stat, writeFile } from "node:fs/promises";
2
+ import { dirname, isAbsolute, relative, resolve, sep } from "node:path";
3
+ import sharp from "sharp";
4
+ import { config } from "../config.js";
5
+ import { AssetRegistry } from "./asset-registry.js";
6
+ import { getOutputImage } from "./image-management.js";
7
+ import { ValidationError } from "../utils/errors.js";
8
+ const MIME_BY_FORMAT = {
9
+ png: "image/png",
10
+ jpeg: "image/jpeg",
11
+ webp: "image/webp",
12
+ };
13
+ const SUPPORTED_SOURCE_MIME = /^image\/(png|jpe?g|webp)$/i;
14
+ const DEFAULT_MAX_SOURCE_BYTES = 64 * 1024 * 1024;
15
+ const DEFAULT_LIMIT_INPUT_PIXELS = 100_000_000;
16
+ function getOutputDir() {
17
+ if (!config.comfyuiPath) {
18
+ throw new ValidationError("COMFYUI_PATH is not configured. Set the COMFYUI_PATH environment variable.");
19
+ }
20
+ return resolve(config.comfyuiPath, "output");
21
+ }
22
+ function parsePositiveIntEnv(name, fallback) {
23
+ const raw = process.env[name];
24
+ if (raw === undefined || raw.trim() === "")
25
+ return fallback;
26
+ const parsed = Number(raw);
27
+ return Number.isFinite(parsed) && parsed > 0 ? Math.floor(parsed) : fallback;
28
+ }
29
+ function maxSourceBytes() {
30
+ return parsePositiveIntEnv("COMFYUI_CONVERT_IMAGE_MAX_SOURCE_BYTES", DEFAULT_MAX_SOURCE_BYTES);
31
+ }
32
+ function limitInputPixels() {
33
+ return parsePositiveIntEnv("COMFYUI_CONVERT_IMAGE_LIMIT_INPUT_PIXELS", DEFAULT_LIMIT_INPUT_PIXELS);
34
+ }
35
+ function resolveOutputPath(path, label) {
36
+ if (path.trim().length === 0) {
37
+ throw new ValidationError(`${label} must be a non-empty path.`);
38
+ }
39
+ const outputDir = getOutputDir();
40
+ const resolved = isAbsolute(path) ? resolve(path) : resolve(outputDir, path);
41
+ if (resolved === outputDir || !resolved.startsWith(outputDir + sep)) {
42
+ throw new ValidationError(`${label} must stay within the ComfyUI output directory.`);
43
+ }
44
+ return resolved;
45
+ }
46
+ async function realOutputRoot() {
47
+ return realpath(getOutputDir());
48
+ }
49
+ function isInsideOrEqual(root, candidate) {
50
+ const rel = relative(root, candidate);
51
+ return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
52
+ }
53
+ function assertInsideRealOutputDir(root, candidate, label, opts = {}) {
54
+ if (!isInsideOrEqual(root, candidate) || (!opts.allowRoot && candidate === root)) {
55
+ throw new ValidationError(`${label} must stay within the ComfyUI output directory.`);
56
+ }
57
+ }
58
+ async function validateExistingOutputAncestors(root, parent, label) {
59
+ const outputDir = getOutputDir();
60
+ let cursor = parent;
61
+ while (cursor !== outputDir && cursor.startsWith(outputDir + sep)) {
62
+ try {
63
+ const info = await lstat(cursor);
64
+ if (info.isSymbolicLink()) {
65
+ const realCursor = await realpath(cursor);
66
+ assertInsideRealOutputDir(root, realCursor, label, { allowRoot: true });
67
+ }
68
+ else if (!info.isDirectory()) {
69
+ throw new ValidationError(`${label} parent is not a directory: ${cursor}`);
70
+ }
71
+ return;
72
+ }
73
+ catch (err) {
74
+ if (err instanceof ValidationError)
75
+ throw err;
76
+ cursor = dirname(cursor);
77
+ }
78
+ }
79
+ }
80
+ async function resolveSourcePath(path) {
81
+ const lexicalPath = resolveOutputPath(path, "path");
82
+ const root = await realOutputRoot();
83
+ const sourcePath = await realpath(lexicalPath).catch(() => undefined);
84
+ if (!sourcePath) {
85
+ throw new ValidationError(`Source image not found: ${lexicalPath}`);
86
+ }
87
+ assertInsideRealOutputDir(root, sourcePath, "path");
88
+ const info = await stat(sourcePath).catch(() => undefined);
89
+ if (!info?.isFile()) {
90
+ throw new ValidationError(`Source image not found: ${sourcePath}`);
91
+ }
92
+ const maxBytes = maxSourceBytes();
93
+ if (info.size > maxBytes) {
94
+ throw new ValidationError(`Source image is too large (${info.size} bytes). Maximum is ${maxBytes} bytes.`);
95
+ }
96
+ return { path: sourcePath, size: info.size };
97
+ }
98
+ async function resolveWritableOutputPath(path) {
99
+ const targetPath = resolveOutputPath(path, "out_path");
100
+ const root = await realOutputRoot();
101
+ const parent = dirname(targetPath);
102
+ await validateExistingOutputAncestors(root, parent, "out_path");
103
+ await mkdir(parent, { recursive: true });
104
+ const realParent = await realpath(parent);
105
+ assertInsideRealOutputDir(root, realParent, "out_path", { allowRoot: true });
106
+ try {
107
+ const info = await lstat(targetPath);
108
+ if (info.isSymbolicLink()) {
109
+ const realTarget = await realpath(targetPath);
110
+ assertInsideRealOutputDir(root, realTarget, "out_path");
111
+ }
112
+ }
113
+ catch (err) {
114
+ if (err instanceof ValidationError)
115
+ throw err;
116
+ // Missing target is fine; writeFile will create it.
117
+ }
118
+ return targetPath;
119
+ }
120
+ async function resolveSource(opts) {
121
+ if (opts.asset_id) {
122
+ const record = AssetRegistry.get(opts.asset_id);
123
+ if (!record) {
124
+ throw new ValidationError(`No asset found for id "${opts.asset_id}". It may have expired or never been registered.`);
125
+ }
126
+ const validType = record.type === "output" || record.type === "input" || record.type === "temp";
127
+ const fetchType = validType
128
+ ? record.type
129
+ : "output";
130
+ const image = await getOutputImage(record.filename, fetchType, record.subfolder);
131
+ if (!SUPPORTED_SOURCE_MIME.test(image.mimeType)) {
132
+ throw new ValidationError(`Asset "${opts.asset_id}" is not a supported image (mime: ${image.mimeType}).`);
133
+ }
134
+ return {
135
+ label: `asset ${opts.asset_id} (${record.filename})`,
136
+ bytes: Buffer.from(image.base64, "base64"),
137
+ };
138
+ }
139
+ if (!opts.path) {
140
+ throw new ValidationError("convert_image requires either asset_id or path.");
141
+ }
142
+ const source = await resolveSourcePath(opts.path);
143
+ return {
144
+ label: source.path,
145
+ bytes: await readFile(source.path),
146
+ };
147
+ }
148
+ function buildEncoder(input, opts) {
149
+ const image = sharp(input, { limitInputPixels: limitInputPixels() });
150
+ if (opts.format === "png") {
151
+ return image.png({ quality: opts.quality });
152
+ }
153
+ if (opts.format === "jpeg") {
154
+ return image.jpeg({
155
+ quality: opts.quality,
156
+ progressive: opts.progressive,
157
+ });
158
+ }
159
+ return image.webp({
160
+ quality: opts.quality,
161
+ lossless: opts.lossless,
162
+ effort: opts.effort,
163
+ });
164
+ }
165
+ function validateEncodeOptions(opts) {
166
+ if (opts.quality !== undefined &&
167
+ (!Number.isInteger(opts.quality) || opts.quality < 1 || opts.quality > 100)) {
168
+ throw new ValidationError("quality must be an integer between 1 and 100.");
169
+ }
170
+ if (opts.effort !== undefined &&
171
+ (!Number.isInteger(opts.effort) || opts.effort < 0 || opts.effort > 6)) {
172
+ throw new ValidationError("effort must be an integer between 0 and 6.");
173
+ }
174
+ }
175
+ export async function convertImage(opts) {
176
+ if (Boolean(opts.asset_id) === Boolean(opts.path)) {
177
+ throw new ValidationError("Provide exactly one image source: asset_id or path.");
178
+ }
179
+ validateEncodeOptions(opts);
180
+ const source = await resolveSource(opts);
181
+ const converted = await buildEncoder(source.bytes, opts).toBuffer();
182
+ const mimeType = MIME_BY_FORMAT[opts.format];
183
+ const outPath = opts.out_path
184
+ ? await resolveWritableOutputPath(opts.out_path)
185
+ : undefined;
186
+ if (outPath) {
187
+ await writeFile(outPath, converted);
188
+ }
189
+ const sourceBytes = source.bytes.length;
190
+ const outputBytes = converted.length;
191
+ const bytesSaved = sourceBytes - outputBytes;
192
+ const summary = {
193
+ source: source.label,
194
+ format: opts.format,
195
+ mime_type: mimeType,
196
+ source_bytes: sourceBytes,
197
+ output_bytes: outputBytes,
198
+ bytes_saved: bytesSaved,
199
+ out_path: outPath,
200
+ };
201
+ return {
202
+ content: [
203
+ { type: "text", text: JSON.stringify(summary, null, 2) },
204
+ {
205
+ type: "image",
206
+ data: converted.toString("base64"),
207
+ mimeType,
208
+ },
209
+ ],
210
+ format: opts.format,
211
+ mimeType,
212
+ sourceBytes,
213
+ outputBytes,
214
+ bytesSaved,
215
+ outPath,
216
+ };
217
+ }
218
+ //# sourceMappingURL=image-convert.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"image-convert.js","sourceRoot":"","sources":["../../src/services/image-convert.ts"],"names":[],"mappings":"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"}