dsh-comfyui-mcp 0.0.0-stage → 0.1.6

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 dsh-comfyui-mcp contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,110 @@
1
- # Temporary Holding Version
1
+ # dsh-comfyui-mcp
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ 将 ComfyUI 接入 DSH,使用 DSH 官方 `@deepseek-ai/dsh-mcp-client` 注册 MCP 工具,并提供连接测试和可选的本地按需启动。
4
+
5
+ ## 上游与职责
6
+
7
+ ComfyUI 工具来自 [artokun/comfyui-mcp](https://github.com/artokun/comfyui-mcp),本包固定使用 **0.52.206**。上游负责工具发现、工作流执行、图片读取等业务能力。本包负责 DSH 插件封装、配置界面、连接探测及自有进程的生命周期;不将上游实现视为本项目原创。
8
+
9
+ ## 安装与配置
10
+
11
+ 需要 Node.js 22 及兼容的 DSH(当前声明为 `>=0.2.1-rc.3 <0.3.0`)。在 DSH 插件管理器中安装 `dsh-comfyui-mcp`(指定版本可填 `dsh-comfyui-mcp@0.1.6`),然后启用组件。也支持安装本地目录或 `.tgz`。不要另外添加同名 MCP 桥。
12
+
13
+ 打开「插件 → ComfyUI MCP」,点击「测试连接」探测现有服务。在同页下方的「运行配置」表单设置:
14
+
15
+ - `url`:默认 `http://127.0.0.1:8188`,支持已有 HTTP(S) 地址,不允许 URL 内嵌凭据。
16
+ - `autoStart`:默认关闭;开启后首次执行业务工具才允许启动本地 ComfyUI。
17
+ - `comfyuiDir`:包含 `main.py` 的绝对目录。
18
+ - `pythonPath`:已安装依赖的 Python 可执行文件绝对路径。
19
+ - `launchArgs`:额外参数数组,默认空。支持显存/精度选项、`--disable-xformers`、`--use-pytorch-cross-attention`、`--preview-method` 等白名单选项;拒绝监听地址、端口覆盖与参数缩写。
20
+ - `startupTimeoutMs`:默认 120000,范围 1000–600000 毫秒。
21
+
22
+ 本地启动仅接受回环 HTTP 地址,固定禁用浏览器自动打开、自定义节点和 API 节点。已有远程实例不受这些启动参数影响。模型与 Python 环境需由用户事先准备,本插件不自动安装或更新它们。
23
+
24
+ ## 工具懒加载
25
+
26
+ `lazyTools` 默认开启。代理最初只看到 `comfyui_load_tools`;需要生图、工作流、图片读取或运行管理时,调用它即可为当前代理加载 `runtime`、`list_tools`、`describe_tool`、`call_tool`。加载不会启动 ComfyUI 或加载模型,其他代理仍保持自己的加载状态。代理重建后可再次调用加载入口。
27
+
28
+ 在插件详情页「运行配置」顶部关闭「工具懒加载」并保存,即直接提供原来的 4 个工具。开关与 `autoStart` 独立:前者控制工具定义何时进入模型上下文,后者控制是否允许启动本地进程。配置在代理下一步执行时生效。
29
+
30
+ 这项优化将未使用 ComfyUI 时的 4 个工具定义减少为 1 个加载入口;首次使用会多一次工具调用。加载后不再节省这 4 个定义,也不承诺固定 token 降幅。工具动态增加由 Harness 的注册与会话记录机制处理;支持历史工具更新的模型路由可使用原生增量声明,其余路由使用当前工具列表,插件不直接改写请求字段。
31
+
32
+ ## 使用
33
+
34
+ `list_tools` 和 `describe_tool` 只发现工具,不启动 ComfyUI 或加载模型。先读取工具 schema,再用 `call_tool` 执行业务工具。原生 Krea2 API 工作流使用上游 `enqueue_workflow`;模型名称和工作流须匹配现有 ComfyUI 安装。结果保留上游 MCP 内容,包括图片和本地保存路径。本机 Krea 2 的提示词写法、采样参数与现成工作流见下文 [技能:krea2-image-prompt](#技能krea2-image-prompt)。
35
+
36
+ `runtime` 提供 `status`、`test`、`start`、`stop`、`free`。状态查询和连接测试不启动进程。开启按需启动且服务未运行时,页面显示「未运行 · 按需启动待命」;执行生图工具时才会启动。生成完成后使用 `stop` 释放插件自有进程;`free` 请求当前连接实例卸载模型,可能影响该实例的其他使用者。
37
+
38
+ ## 模型与工作流的决定权
39
+
40
+ 插件和上游都不替你选模型。四条路径的决定方各不相同:
41
+
42
+ - `enqueue_workflow`(`action:"enqueue"`):由调用方提交的 API 工作流决定,`UNETLoader` / `CLIPLoader` / `VAELoader` 里写什么文件就加载什么;seed 按原值使用,不随机化。
43
+ - `generate_image`(`action:"image"`):由上游自建 txt2img 图并**自动挑选 checkpoint**——读 safetensors 头部判断是否含文本编码器,跳过视频类模型;其余参数来自默认值(配置文件 → `COMFYUI_DEFAULT_*` 环境变量 → 运行时 `get_defaults`,优先级递增)。没有可用 checkpoint 时会直接报错。Krea 2 是 UNet + CLIP + VAE 三件套、不是 checkpoint 模型,因此**不走这条路径**。
44
+ - `enqueue_workflow`(`action:"run_template"`):由 pack 内的 `workflow.json` 决定,模型名是写死的常量;pack 依赖的自定义节点若被启动参数禁用则无法执行。
45
+ - `action:"rerun"`:复用历史中的工作流,seed 默认重新随机。
46
+
47
+ 默认值配置文件位于 `%XDG_CONFIG_HOME%`(缺省 `~/.config`)下的 `comfyui-mcp/config.json`。
48
+
49
+ ## 技能:krea2-image-prompt
50
+
51
+ `skills/krea2-image-prompt/` 是一份面向本机 Krea 2 Turbo 的出图技能,教会代理「本机这套模型该怎么写提示词、怎么拼工作流、怎么后处理」,覆盖 UI 图标、背景、空状态、角色立绘、纹理图案等位图素材场景。
52
+
53
+ ```
54
+ skills/krea2-image-prompt/
55
+ ├── SKILL.md # 入口:机器事实、采样参数、提示词硬规则、六段骨架、调用路径、故障速查
56
+ ├── reference/recipes.md # 分类配方(图标/背景/空状态/角色/图案/UI 整屏…)与实测结论
57
+ ├── reference/experiments.md # 对比实验记录与耗时基线
58
+ ├── reference/workflow.json # 可直接提交的 API 工作流(原生节点,无自定义节点依赖)
59
+ └── scripts/ # krea.py 出图、batch.py 批量、key.py 色键抠透明底
60
+ ```
61
+
62
+ **路径与发现机制。** DSH 的技能发现根有两类:用户级 `$DSH_HOME/skills`(缺省 `~/.dsh/skills`)与项目级 `<工作目录>/.agents/skills`;仓库里的 `skills/` 本身不是发现根。本技能属于「只有这台机器有对应 MCP」的那种,因此装到**用户级全局根**:真身留在 `skills/`(进版本库),`~/.dsh/skills/krea2-image-prompt` 是指向它的 **Windows 目录联结点(junction)**——单一副本,任意项目都能用,也不占用跨工具的 `~/.agents`。克隆本仓库到新机器、或仓库改名搬家后联结点失效,重建:
63
+
64
+ ```powershell
65
+ New-Item -ItemType Junction -Path "$HOME\.dsh\skills\krea2-image-prompt" -Target "<仓库路径>\skills\krea2-image-prompt"
66
+ ```
67
+
68
+ **触发方式。** 任务涉及「画图标 / 画背景 / 生成角色素材 / 做纹理」时自动加载;也可用 `skill` 工具或 `/krea2-image-prompt` 显式调用。
69
+
70
+ **直接使用脚本。**
71
+
72
+ ```sh
73
+ cd skills/krea2-image-prompt
74
+ python scripts/krea.py --prompt "a flat two-color vector icon of a whale" --w 1024 --h 1024
75
+ python scripts/key.py in.png out.png # 纯色底 → 透明 PNG
76
+ ```
77
+
78
+ 脚本通过 HTTP 直连 ComfyUI,服务地址取 `COMFY_URL` 环境变量,默认 `http://127.0.0.1:8188`。技能假定本机已备好 `krea2_turbo_fp8_scaled.safetensors`、`qwen3vl_4b_fp8_scaled.safetensors`、`qwen_image_vae.safetensors`,且不依赖任何自定义节点——因此插件按需启动时固定携带的 `--disable-all-custom-nodes` 不影响它。
79
+
80
+ **与启动方式的关系。** 服务若已由绘世等启动器在 `url` 上运行,插件只探测和连接,启动器里的端口、自定义节点、显存参数全部生效;只有插件**自己**拉起进程时才会追加自己的启动参数。技能里的实测数据来自插件自有启动的精简实例。
81
+
82
+ 技能目录属于仓库内资产,不在 `package.json` 的 `files` 白名单中,因此不随 npm 包分发。
83
+
84
+ ## 禁用、卸载与迁移
85
+
86
+ 通过 DSH 插件管理器禁用、重新启用或卸载。禁用/卸载关闭本插件连接并停止本插件启动的 ComfyUI;不会停止外部进程,也不删除模型、工作流或生成图片。
87
+
88
+ 旧部署迁移时,先停用旧 `mcp-local-comfyui`,再仅删除该条目及其停用覆盖,保留其他配置,然后安装本包。不要让两个 `serverName: comfyui` 桥同时运行。本包不自动改写用户配置。
89
+
90
+ ## 开发与打包
91
+
92
+ ```sh
93
+ npm install --ignore-scripts --omit=optional --legacy-peer-deps
94
+ npm run build
95
+ npm test
96
+ npm run pack:check
97
+ npm pack
98
+ ```
99
+
100
+ DSH 提供的 peer 包需在插件运行环境中可解析。安装发布包时由 DSH 管理依赖;任何待运行的依赖构建脚本都应先取得用户许可。包采用文件白名单,不包含模型、Python、工作流、生成图片、凭据或个人配置。图标由本机 Krea 2 Turbo 生成并缩放,SVG 内嵌同一位图;设计提示词保存在 `assets/icon-prompt.txt`,使用 DSH 的 `./icon` 导出。
101
+
102
+ ## 限制与安全
103
+
104
+ 上游依赖审计发现 `undici` 的已知高风险通告;本次保留用户指定的上游版本,未自动升级。仅连接受信任的 ComfyUI 服务;回环默认值不能替代服务端访问控制。上游部分工具可以管理文件、模型或依赖,执行安装/更新类操作前必须取得用户明确许可。
105
+
106
+ 自动测试覆盖配置保存、待命与故障状态、配置校验、不启动的探测、外部进程保护、并发启动与自有进程清理。已在 DSH Desktop 验证安装、重启后的配置页面、保存参数、本地启动及停止;Krea2 768 × 768 工作流执行成功,并通过 MCP 取回图片。插件管理器的卸载与重装操作已成功;真实运行期间禁用/卸载的完整清理验收尚未完成。真实进程测试需按测试文件中的环境变量显式启用,默认跳过。
107
+
108
+ ## 许可证
109
+
110
+ 本项目采用 MIT。上游 `comfyui-mcp` 为 MIT,版权归 Arthur R. Longbottom (artokun)。参见 `THIRD_PARTY_NOTICES.md`。依赖通过包管理器安装,不将上游依赖代码或模型整合进发布包;各依赖许可证继续适用。
@@ -0,0 +1,36 @@
1
+ # Third-party notices
2
+
3
+ ## comfyui-mcp 0.52.206
4
+
5
+ Source: https://github.com/artokun/comfyui-mcp
6
+
7
+ MIT License
8
+
9
+ Copyright (c) 2026 Arthur R. Longbottom (artokun)
10
+
11
+ Permission is hereby granted, free of charge, to any person obtaining a copy
12
+ of this software and associated documentation files (the "Software"), to deal
13
+ in the Software without restriction, including without limitation the rights
14
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15
+ copies of the Software, and to permit persons to whom the Software is
16
+ furnished to do so, subject to the following conditions:
17
+
18
+ The above copyright notice and this permission notice shall be included in all
19
+ copies or substantial portions of the Software.
20
+
21
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27
+ SOFTWARE.
28
+
29
+ ## Dependency distribution boundary
30
+
31
+ This tarball does not vendor node_modules, ComfyUI, Python, models or workflows.
32
+ Dependencies are resolved by the package manager and retain their own license
33
+ files. The MCP SDK is MIT. DSH integration packages are host-provided peers,
34
+ not copied DSH code. Repackaging those packages, Python environments or models
35
+ requires a separate review of the relevant licenses. Original SVG artwork in
36
+ this package uses this project's MIT license.
@@ -0,0 +1,5 @@
1
+ Krea 2 Turbo generated artwork, 2026-10-26.
2
+ Prompt: A minimal vector-style icon for a creative workflow bridge: three softly rounded indigo nodes connected by a single flowing turquoise ribbon forming an abstract C, one small four-point white sparkle at the upper right. Bold simple geometric silhouette, crisp edges, centered front view, generous padding, refined modern software brand mark, limited indigo and mint palette, completely flat warm off-white background, no text
3
+ Model: krea2_turbo_fp8_scaled.safetensors; seed 261026; 1024x1024; 8 steps; CFG 1; er_sde/simple.
4
+ Source: v016_00001_.png; icon.svg embeds the same raster artwork.
5
+ License: MIT, same as this plugin.
Binary file
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 256"><image width="256" height="256" href="data:image/png;base64,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"/></svg>
package/client.js ADDED
@@ -0,0 +1 @@
1
+ window.__ModuleLoader__.load({id:'dsh-comfyui-mcp',factory(require){const React=require('react'),h=React.createElement;return {inject:['slots','locale'],apply(ctx){ctx.locale.register('dsh-comfyui-mcp','zh',{title:'连接与运行状态',test:'测试连接',loading:'正在测试…',idle:'尚未测试',online:'连接成功',offline:'未连接',standby:'未运行 · 按需启动待命',owned:'本插件进程',external:'外部进程',hint:'测试只探测地址,不启动 ComfyUI 或加载模型。请在下方运行配置中编辑参数。',safety:'禁用或卸载仅停止本插件进程;保留模型、工作流与图片。',credit:'工具由 artokun/comfyui-mcp 0.52.206 提供。'});ctx.locale.register('dsh-comfyui-mcp','en',{title:'Connection & runtime',test:'Test connection',loading:'Testing…',idle:'Not tested',online:'Connected',offline:'Offline',standby:'Not running · on-demand ready',owned:'Plugin-owned process',external:'External process',hint:'Testing never starts ComfyUI or loads models. Edit runtime parameters in the form below.',safety:'Disabling/uninstalling stops only plugin-owned processes; models, workflows and images are retained.',credit:'Tools powered by artokun/comfyui-mcp 0.52.206.'});const t=ctx.locale.bind('dsh-comfyui-mcp');function Status(){const [s,set]=React.useState(),[busy,setBusy]=React.useState(false);React.useSyncExternalStore(fn=>ctx.locale.subscribe(fn),()=>ctx.locale.getSnapshot());async function test(){setBusy(true);try{const r=await fetch('/api/dsh-comfyui/status',{cache:'no-store'});if(!r.ok)throw Error('HTTP '+r.status);set(await r.json());}catch(e){set({running:false,error:e.message});}finally{setBusy(false);}}const standby=!!s&&!s.running&&s.autoStart===true&&!s.owned&&!s.lastError&&s.error==='fetch failed';return h('section',{className:'dcm-status'},h('style',null,'.dcm-status{border:1px solid var(--dsw-alias-border-l1);border-radius:12px;padding:20px;color:var(--dsw-alias-label-primary);font-size:14px}.dcm-status .dcm-row{display:flex;justify-content:space-between;align-items:center;gap:16px}.dcm-status .dcm-badge{font-size:12px;background:var(--dsw-alias-bg-layer-2);padding:6px 10px;border-radius:20px}.dcm-status h3{font-size:15px;margin:0 0 16px}.dcm-status p{line-height:1.7;color:var(--dsw-alias-label-secondary)}.dcm-status button{font:inherit;padding:9px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-base);cursor:pointer}.dcm-status pre{white-space:pre-wrap;overflow-wrap:anywhere}.dcm-status small{color:var(--dsw-alias-label-secondary)}'),h('div',{className:'dcm-row'},h('h3',null,t('title')),h('span',{className:'dcm-badge',role:'status'},busy?t('loading'):!s?t('idle'):s.running?t('online')+' · '+t(s.owned?'owned':'external'):t(standby?'standby':'offline'))),h('p',null,'工具发现不会启动 ComfyUI 或加载模型。'),s?.error&&!standby?h('pre',{role:'alert'},s.error):null,s?.lastError?h('pre',null,s.lastError):null,h('button',{onClick:test,disabled:busy},t(busy?'loading':'test')),h('p',null,t('hint')),h('p',null,t('safety')),h('small',null,t('credit')));}function ConfigPage({view,form}){const initial=form?.state?.value;const [draft,setDraft]=React.useState(null),[busy,setBusy]=React.useState(false),[message,setMessage]=React.useState('');const zh=ctx.locale.getLocale().id!=='en';const text=(a,b)=>zh?a:b;const fields=['lazyTools','url','autoStart','comfyuiDir','pythonPath','launchArgs','startupTimeoutMs'];const defaults={lazyTools:true,url:'http://127.0.0.1:8188',autoStart:false,comfyuiDir:'',pythonPath:'',launchArgs:[],startupTimeoutMs:120000};if(view==='summary')return text('ComfyUI 连接与本地按需启动参数','ComfyUI connection and local on-demand startup');if(!initial)return h('p',{role:'status'},text('配置尚未就绪或不可用','Configuration is loading or unavailable'));const values=draft||Object.fromEntries(fields.map(k=>[k,k==='launchArgs'?JSON.stringify(initial[k]??defaults[k]):initial[k]??defaults[k]]));async function save(e){e.preventDefault();setBusy(true);setMessage('');try{const v={...values,launchArgs:JSON.parse(values.launchArgs),startupTimeoutMs:Number(values.startupTimeoutMs)};if(!Array.isArray(v.launchArgs)||v.launchArgs.some(x=>typeof x!=='string'))throw Error('launchArgs must be a JSON string array');if(!Number.isFinite(v.startupTimeoutMs)||v.startupTimeoutMs<1000||v.startupTimeoutMs>600000)throw Error('startupTimeoutMs: 1000–600000');const ok=await form.mutate(fields.map(k=>({op:'set',path:[k],value:v[k]})),form.state.revision);setMessage(ok?text('配置已保存','Configuration saved'):text('保存失败或配置已变更,请重新打开页面后重试','Save failed or configuration changed; reopen this page and retry'));if(ok)setDraft(null);}catch(e){setMessage(e.message);}finally{setBusy(false);}}return h('form',{className:'dcm-config',onSubmit:save},h('style',null,'.dcm-config{max-width:760px;font-size:14px}.dcm-config .dcm-lazy-row{display:flex;align-items:center;justify-content:space-between;gap:16px;border-bottom:1px solid var(--dsw-alias-border-l1);padding-bottom:18px;margin-bottom:20px}.dcm-lazy-row p{margin:6px 0 0;font-size:13px;line-height:1.7;color:var(--dsw-alias-label-secondary)}.dcm-config .dcm-switch{flex-shrink:0;display:flex;justify-content:flex-end;width:36px;height:20px;padding:2px;border:0;border-radius:20px;background:var(--dsw-alias-brand-primary)}.dcm-switch::after{content:"";width:16px;height:16px;border-radius:50%;background:var(--dsw-alias-bg-base)}.dcm-config .dcm-switch[aria-checked=false]{background:var(--dsw-alias-state-idle-primary);justify-content:flex-start}.dcm-config button:disabled{opacity:.5;cursor:not-allowed}.dcm-config label{display:block;margin:18px 0 6px}.dcm-config input,.dcm-config select,.dcm-config textarea{display:block;box-sizing:border-box;width:100%;padding:9px 12px;margin-top:6px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;background:var(--dsw-alias-bg-base);color:var(--dsw-alias-label-primary);font:inherit}.dcm-config button{font:inherit;padding:9px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:7px;background:var(--dsw-alias-brand-primary);color:var(--dsw-alias-bg-base)}'),h('div',{className:'dcm-lazy-row'},h('div',null,h('span',{id:'dcm-lazy-label'},text('工具懒加载','Lazy tool loading')),h('p',{id:'dcm-lazy-help'},values.lazyTools?text('仅保留加载入口,需要时再展开 4 个 ComfyUI 工具;不启动服务。','Keep one loader; expose four ComfyUI tools on demand without starting the service.'):text('直接提供 4 个 ComfyUI 工具,省去首次加载调用。','Expose four ComfyUI tools immediately; skip the initial loading call.'))),h('button',{className:'dcm-switch',type:'button',role:'switch','aria-checked':values.lazyTools,'aria-labelledby':'dcm-lazy-label','aria-describedby':'dcm-lazy-help',disabled:busy||!form.state.writable,onClick:()=>setDraft({...values,lazyTools:!values.lazyTools})})),...fields.filter(k=>k!=='lazyTools').map(k=>h('label',{key:k},text({url:'ComfyUI 地址',autoStart:'允许本地按需启动',comfyuiDir:'ComfyUI 目录',pythonPath:'Python 可执行文件',launchArgs:'额外启动参数',startupTimeoutMs:'启动超时(毫秒)'}[k],{url:'ComfyUI address',autoStart:'Allow local on-demand startup',comfyuiDir:'ComfyUI directory',pythonPath:'Python executable',launchArgs:'Extra launch arguments',startupTimeoutMs:'Startup timeout (ms)'}[k]),k==='autoStart'?h('select',{value:String(values[k]),disabled:busy||!form.state.writable,onChange:e=>setDraft({...values,[k]:e.target.value==='true'})},h('option',{value:'false'},text('关闭:仅连接现有服务','Off: existing service only')),h('option',{value:'true'},text('开启:首次执行工具时启动','On: start on first tool execution'))):h(k==='launchArgs'?'textarea':'input',{type:k==='startupTimeoutMs'?'number':'text',rows:k==='launchArgs'?3:undefined,placeholder:k==='comfyuiDir'?text('包含 main.py 的目录','Directory containing main.py'):k==='pythonPath'?text('Python 的完整路径','Full Python path'):undefined,value:values[k],disabled:busy||!form.state.writable,onChange:e=>setDraft({...values,[k]:e.target.value})}))),h('p',null,text('仅保存时更新配置;不会安装模型或 Python 依赖。启动参数为 JSON 数组。','Only Save updates configuration. No models or Python dependencies are installed. Launch arguments are a JSON array.')),h('button',{type:'submit',disabled:busy||!form.state.writable},busy?text('保存中…','Saving…'):text('保存配置','Save configuration')),h('p',{role:'status'},message));}function UnifiedPage({scope}){const state=React.useSyncExternalStore(fn=>scope.subscribe(fn),()=>scope.getSnapshot());return h('div',{className:'dcm-page',style:{maxWidth:760}},h(Status),h('section',{style:{border:'1px solid var(--dsw-alias-border-l1)',borderRadius:12,padding:20,marginTop:24}},h('h3',{style:{fontSize:15,margin:'0 0 16px'}},ctx.locale.getLocale().id==='en'?'Runtime configuration · DSH configuration form':'运行配置 · DSH 官方配置表单'),h('p',{style:{lineHeight:1.7,color:'var(--dsw-alias-label-secondary)'}},ctx.locale.getLocale().id==='en'?'This page uses DSH configuration snapshots, revisions and atomic saves.':'表单与连接状态位于同一插件详情页,使用 DSH 官方配置快照、修订号及原子保存操作。'),h(ConfigPage,{view:'page',form:{state,mutate:(ops,revision)=>scope.mutate(ops,revision)}})));}ctx.inject(['configForms'],c=>{const forms=c.configForms;c.effect(()=>forms.whileServed(['dsh-comfyui-mcp'],()=>c.slots.inject('plugins.bundle.config',()=>c.slots.register({name:'plugins.bundle.config',key:'dsh-comfyui-mcp'},()=>h(UnifiedPage,{scope:forms.get('dsh-comfyui-mcp')})))),'comfyui.config-page');});}};}});
@@ -0,0 +1,28 @@
1
+ import { createRuntime, validateConfig } from './runtime.mjs';
2
+
3
+ export function createConfiguredRuntime(readConfig, factory = createRuntime) {
4
+ let runtime, signature, closed = false, pending = Promise.resolve();
5
+ function run(action) {
6
+ const task = pending.then(async () => {
7
+ if (closed) throw Error('Runtime is closing');
8
+ const config = validateConfig(readConfig());
9
+ const next = JSON.stringify(config);
10
+ if (signature !== next) {
11
+ await runtime?.close();
12
+ runtime = factory(config);
13
+ signature = next;
14
+ }
15
+ return action === 'config' ? runtime.config : runtime[action]();
16
+ });
17
+ pending = task.catch(() => {});
18
+ return task;
19
+ }
20
+ return {
21
+ run,
22
+ async close() {
23
+ closed = true;
24
+ await pending;
25
+ await runtime?.close();
26
+ },
27
+ };
28
+ }
@@ -0,0 +1,4 @@
1
+ - insert:
2
+ - id: dsh-comfyui-mcp
3
+ name: dsh-comfyui-mcp
4
+ config: {}
package/index.mjs ADDED
@@ -0,0 +1,28 @@
1
+ import z from '@deepseek-ai/schemastery';
2
+ import * as mcp from '@deepseek-ai/dsh-mcp-client';
3
+ import { createServer } from 'node:http';
4
+ import { randomBytes } from 'node:crypto';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { createConfiguredRuntime } from './configured-runtime.mjs';
7
+ import { installLazyTools } from './lazy-tools.mjs';
8
+ export const name='dsh-comfyui-mcp';
9
+ export const inject=['tools','webServer','agents'];
10
+ export const Config=z.object({
11
+ lazyTools:z.boolean().default(true).description('Load the four ComfyUI tools only when requested by each agent. Does not start ComfyUI.'),
12
+ url:z.string().default('http://127.0.0.1:8188').description('ComfyUI HTTP(S) address; default is loopback.'),
13
+ autoStart:z.boolean().default(false).description('Allow local on-demand startup. Discovery and connection tests never start ComfyUI.'),
14
+ comfyuiDir:z.string().default('').description('Absolute directory containing main.py. Required for local startup.'),
15
+ pythonPath:z.string().default('').description('Absolute Python executable path. No automatic dependency installation.'),
16
+ launchArgs:z.array(String).default([]).description('Additional ComfyUI arguments; network binding overrides are forbidden.'),
17
+ startupTimeoutMs:z.number().min(1000).max(600000).default(120000)
18
+ }).volatile();
19
+ export async function apply(ctx,config){
20
+ const runtime=createConfiguredRuntime(()=>config.get());const token=randomBytes(32).toString('hex');let disposed=false;
21
+ const control=createServer(async(req,res)=>{res.setHeader('Content-Type','application/json');try{if(req.method!=='POST'||req.headers.authorization!=='Bearer '+token){res.writeHead(403);return res.end('{}');}const action=req.url.slice(1);if(!['status','start','stop','free','config'].includes(action))throw Error('Unknown action');const value=await runtime.run(action);res.end(JSON.stringify(value));}catch(e){res.writeHead(500);res.end(JSON.stringify({error:e.message}));}});
22
+ await new Promise((resolve,reject)=>{control.once('error',reject);control.listen(0,'127.0.0.1',resolve);});
23
+ ctx.effect(()=>async()=>{disposed=true;await runtime.close();control.closeAllConnections();await new Promise(r=>control.close(r));},'comfyui.runtime');
24
+ ctx.effect(()=>ctx.webServer.register({kind:'exact',path:'/api/dsh-comfyui/status',handler:async(req,res)=>{res.setHeader('Content-Type','application/json');res.setHeader('Cache-Control','no-store');if(req.method!=='GET'){res.writeHead(405);return res.end('{}');}try{const s=await runtime.run('status');res.end(JSON.stringify(s));}catch(e){res.writeHead(500);res.end(JSON.stringify({error:e.message}));}}}),'comfyui.status-route');
25
+ await mcp.apply(ctx,mcp.Config({transport:'stdio',serverName:'comfyui',command:process.execPath,args:[fileURLToPath(new URL('./server.mjs',import.meta.url))],env:{ELECTRON_RUN_AS_NODE:'1',DSH_COMFY_CONTROL:'http://127.0.0.1:'+control.address().port,DSH_COMFY_TOKEN:token},toolCallTimeoutMs:1800000,failOnStartupError:true}));
26
+ if(disposed)throw Error('Plugin disposed during startup');
27
+ installLazyTools(ctx,config);
28
+ }
package/lazy-tools.mjs ADDED
@@ -0,0 +1,36 @@
1
+ const NAMES=['runtime','list_tools','describe_tool','call_tool'].map(n=>'mcp__comfyui__'+n);
2
+ export function installLazyTools(ctx,config){
3
+ const states=new Map();
4
+ function attach(agent){
5
+ if(states.has(agent))return states.get(agent);
6
+ const state={loaded:false,mode:undefined,disposers:[]};states.set(agent,state);
7
+ state.dispose=agent.ctx.effect(()=>()=>{for(const dispose of state.disposers.splice(0).reverse())dispose();states.delete(agent);},'comfyui.lazy-tools');
8
+ return state;
9
+ }
10
+ function reconcile(agent){
11
+ const state=attach(agent),lazy=config.get().lazyTools!==false;
12
+ if(state.mode===lazy)return state;
13
+ for(const dispose of state.disposers.splice(0).reverse())dispose();
14
+ state.mode=lazy;
15
+ if(!lazy){for(const name of NAMES){const definition=ctx.tools.get(name);if(!definition)throw Error('ComfyUI bridge unavailable: '+name);state.disposers.push(agent.ctx.tools.register({...definition}));}return state;}
16
+ state.disposers.push(agent.ctx.tools.restrict({deny:NAMES}));
17
+ const load=()=>{
18
+ if(state.loaded)return;
19
+ const definitions=NAMES.map(name=>{const definition=ctx.tools.get(name);if(!definition)throw Error('ComfyUI bridge unavailable: '+name);return definition;});
20
+ const installed=[];
21
+ try{for(const definition of definitions)installed.push(agent.ctx.tools.register({...definition}));}
22
+ catch(error){for(const dispose of installed.reverse())dispose();throw error;}
23
+ state.disposers.push(...installed);state.loaded=true;
24
+ };
25
+ if(state.loaded){state.loaded=false;load();}
26
+ state.disposers.push(agent.ctx.tools.register({
27
+ name:'comfyui_load_tools',description:'Load ComfyUI image generation, workflow, image retrieval and runtime tools for this agent. Does not start ComfyUI or load models.',parameters:{type:'object',properties:{},additionalProperties:false},
28
+ output:{schema:{type:'object',properties:{tools:{type:'array',items:{type:'string'}}},required:['tools'],additionalProperties:false},render:(_,value)=>[{type:'text',text:JSON.stringify(value)}]},
29
+ execute:async()=>{load();return {tools:NAMES};}
30
+ }));return state;
31
+ }
32
+ ctx.on('agent/created',({agent})=>{reconcile(agent);});
33
+ ctx.on('agent/pre-step',({agent},next)=>{reconcile(agent);return next();});
34
+ for(const agent of ctx.agents.list())reconcile(agent);
35
+ ctx.effect(()=>()=>{for(const state of [...states.values()])state.dispose();},'comfyui.lazy-tools-owner');
36
+ }
package/locale/en.json ADDED
@@ -0,0 +1 @@
1
+ {"meta":{"title":"ComfyUI MCP","description":"Connect ComfyUI through the official MCP bridge with safe on-demand local startup. Tools powered by artokun/comfyui-mcp."}}
package/locale/zh.json ADDED
@@ -0,0 +1 @@
1
+ {"meta":{"title":"ComfyUI MCP","description":"通过官方 MCP 桥连接 ComfyUI,支持安全的本地按需启动。工具由 artokun/comfyui-mcp 提供。"}}
package/package.json CHANGED
@@ -1,6 +1,73 @@
1
1
  {
2
2
  "name": "dsh-comfyui-mcp",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.6",
4
+ "description": "ComfyUI connection and safe on-demand lifecycle for DSH; powered by artokun/comfyui-mcp.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/Kaczev/dsh-comfyui-mcp.git"
10
+ },
11
+ "homepage": "https://github.com/Kaczev/dsh-comfyui-mcp#readme",
12
+ "bugs": {
13
+ "url": "https://github.com/Kaczev/dsh-comfyui-mcp/issues"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public",
17
+ "registry": "https://registry.npmjs.org/"
18
+ },
19
+ "engines": {
20
+ "node": ">=22",
21
+ "dsh": ">=0.2.1-rc.3 <0.3.0"
22
+ },
23
+ "exports": {
24
+ ".": "./index.mjs",
25
+ "./package.json": "./package.json",
26
+ "./client": "./client.js",
27
+ "./icon": "./assets/icon.svg",
28
+ "./locale/*.json": "./locale/*.json"
29
+ },
30
+ "files": [
31
+ "index.mjs",
32
+ "lazy-tools.mjs",
33
+ "runtime.mjs",
34
+ "configured-runtime.mjs",
35
+ "server.mjs",
36
+ "client.js",
37
+ "cordis.patch.yml",
38
+ "assets/icon.svg",
39
+ "assets/icon.png",
40
+ "assets/icon-prompt.txt",
41
+ "locale",
42
+ "LICENSE",
43
+ "THIRD_PARTY_NOTICES.md",
44
+ "README.md"
45
+ ],
46
+ "dsh": {
47
+ "bundle": {
48
+ "patch": "./cordis.patch.yml"
49
+ },
50
+ "client": {
51
+ "platform": "web",
52
+ "immediately": true,
53
+ "inject": [
54
+ "@deepseek-ai/dsh-client-ui-plugin-manager",
55
+ "@deepseek-ai/dsh-client-ui-settings"
56
+ ]
57
+ }
58
+ },
59
+ "scripts": {
60
+ "check": "node --check index.mjs && node --check runtime.mjs && node --check configured-runtime.mjs && node --check server.mjs && node --check client.js && node --check lazy-tools.mjs",
61
+ "test": "node --test test/*.test.mjs",
62
+ "build": "npm run check",
63
+ "pack:check": "npm pack --dry-run --json"
64
+ },
65
+ "dependencies": {
66
+ "comfyui-mcp": "0.52.206",
67
+ "@modelcontextprotocol/sdk": "~1.32.1"
68
+ },
69
+ "peerDependencies": {
70
+ "@deepseek-ai/dsh-mcp-client": "0.2.1-rc.3",
71
+ "@deepseek-ai/schemastery": "~3.18.5"
72
+ }
73
+ }
package/runtime.mjs ADDED
@@ -0,0 +1,92 @@
1
+ import path from 'node:path';
2
+ import fs from 'node:fs';
3
+ import { spawn } from 'node:child_process';
4
+ import { setTimeout as delay } from 'node:timers/promises';
5
+
6
+ export function validateConfig(input = {}) {
7
+ const c = { url: 'http://127.0.0.1:8188', autoStart: false, comfyuiDir: '', pythonPath: '', launchArgs: [], startupTimeoutMs: 120000, ...input };
8
+ const u = new URL(c.url);
9
+ if (!['http:', 'https:'].includes(u.protocol) || u.username || u.password || u.search || u.hash) throw Error('Use an HTTP(S) address without credentials, query or fragment.');
10
+ c.url = u.href.endsWith('/') ? u.href.slice(0, -1) : u.href;
11
+ if (typeof c.autoStart !== 'boolean') throw Error('autoStart must be boolean');
12
+ if (!Array.isArray(c.launchArgs) || c.launchArgs.some(a => typeof a !== 'string')) throw Error('launchArgs must be an array of strings');
13
+ if (c.autoStart) {
14
+ if (!['127.0.0.1', 'localhost', '[::1]'].includes(u.hostname) || u.protocol !== 'http:' || u.pathname !== '/') throw Error('Local startup requires a loopback HTTP origin.');
15
+ if (!path.isAbsolute(c.comfyuiDir) || !path.isAbsolute(c.pythonPath)) throw Error('Local startup requires absolute ComfyUI and Python paths.');
16
+ }
17
+ // argparse accepts long-option abbreviations. Only explicitly supported non-network options are allowed.
18
+ const flags = new Set(['--use-pytorch-cross-attention', '--disable-xformers', '--lowvram', '--novram', '--highvram', '--normalvram', '--cpu', '--force-fp32', '--force-fp16', '--fp16-vae', '--fp32-vae', '--bf16-vae', '--cpu-vae', '--preview-method']);
19
+ for (let i = 0; i < c.launchArgs.length; i++) {
20
+ const a = c.launchArgs[i];
21
+ if (!flags.has(a)) throw Error('Unsupported launch argument: ' + a);
22
+ if (a === '--preview-method' && !['none', 'auto', 'latent2rgb', 'taesd'].includes(c.launchArgs[++i])) throw Error('Invalid preview method');
23
+ }
24
+ if (!Number.isFinite(c.startupTimeoutMs) || c.startupTimeoutMs < 1000 || c.startupTimeoutMs > 600000) throw Error('Startup timeout must be 1000–600000 ms.');
25
+ return c;
26
+ }
27
+ export async function probe(url) {
28
+ try {
29
+ const r = await fetch(url + '/system_stats', { signal: AbortSignal.timeout(2500) });
30
+ if (!r.ok) throw Error('HTTP ' + r.status);
31
+ const body = await r.json();
32
+ if (!body.system && !body.devices) throw Error('Not a ComfyUI system_stats response');
33
+ return { running: true };
34
+ } catch (e) { return { running: false, error: e.message }; }
35
+ }
36
+ export function createRuntime(input, { spawnProcess = spawn, probeAddress = probe } = {}) {
37
+ const c = validateConfig(input);
38
+ let child, starting, closing = false, lastError;
39
+ const owned = () => !!child && child.exitCode === null && child.signalCode === null;
40
+ async function status() { return { ...await probeAddress(c.url), owned: owned(), pid: owned() ? child.pid : undefined, url: c.url, autoStart: c.autoStart, lastError }; }
41
+ async function waitExit(p, ms) {
42
+ if (p.exitCode !== null || p.signalCode !== null) return;
43
+ await new Promise(resolve => {
44
+ const done = () => { clearTimeout(timer); p.removeListener('exit', done); resolve(); };
45
+ const timer = setTimeout(done, ms);
46
+ p.once('exit', done);
47
+ });
48
+ }
49
+ async function terminate() {
50
+ if (!owned()) return { stopped: false, reason: 'No owned process; external instances are never stopped.' };
51
+ const p = child;
52
+ p.kill(); await waitExit(p, 8000);
53
+ if (owned()) { p.kill('SIGKILL'); await waitExit(p, 2000); }
54
+ if (owned()) throw Error('Owned ComfyUI process could not be stopped: ' + p.pid);
55
+ return { stopped: true, pid: p.pid };
56
+ }
57
+ async function start() {
58
+ if (closing) throw Error('Runtime is closing');
59
+ if (starting) return starting;
60
+ starting = (async () => {
61
+ if ((await probeAddress(c.url)).running) return { running: true, started: false, owned: owned() };
62
+ if (!c.autoStart) throw Error('ComfyUI is offline; local on-demand startup is disabled.');
63
+ if (owned()) throw Error('Owned process exists but is not responding.');
64
+ const main = path.join(c.comfyuiDir, 'main.py');
65
+ fs.accessSync(main); fs.accessSync(c.pythonPath);
66
+ if (closing) throw Error('Runtime is closing');
67
+ const u = new URL(c.url);
68
+ child = spawnProcess(c.pythonPath, [main, '--listen', u.hostname === '[::1]' ? '::1' : '127.0.0.1', '--port', u.port || '80', '--disable-auto-launch', '--disable-all-custom-nodes', '--disable-api-nodes', ...c.launchArgs], { cwd: c.comfyuiDir, env: { ...process.env, PYTHONIOENCODING: 'utf-8' }, windowsHide: true, stdio: ['ignore', 'inherit', 'inherit'] });
69
+ let failure;
70
+ child.on('error', e => { failure = e; });
71
+ const end = Date.now() + c.startupTimeoutMs;
72
+ while (Date.now() < end) {
73
+ if (closing) throw Error('Runtime is closing');
74
+ if (failure) throw failure;
75
+ if (!owned()) throw Error('ComfyUI exited before becoming ready; inspect DSH stderr logs.');
76
+ if ((await probeAddress(c.url)).running) { lastError = undefined; return { running: true, started: true, owned: true, pid: child.pid }; }
77
+ await delay(500);
78
+ }
79
+ throw Error('ComfyUI startup timed out; inspect DSH stderr logs.');
80
+ })().catch(async e => { lastError = e.message; await terminate(); throw e; }).finally(() => { starting = undefined; });
81
+ return starting;
82
+ }
83
+ async function stop() { closing = true; try { await starting?.catch(() => {}); return await terminate(); } finally { closing = false; } }
84
+ async function close() { closing = true; await starting?.catch(() => {}); return terminate(); }
85
+ async function free() {
86
+ if (!(await status()).running) return { freed: false };
87
+ const r = await fetch(c.url + '/free', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ unload_models: true, free_memory: true }), signal: AbortSignal.timeout(10000) });
88
+ if (!r.ok) throw Error('Free failed: HTTP ' + r.status);
89
+ return { freed: true };
90
+ }
91
+ return { status, start, stop, close, free, config: c };
92
+ }
package/server.mjs ADDED
@@ -0,0 +1,22 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
4
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
5
+ import { ListToolsRequestSchema,CallToolRequestSchema } from '@modelcontextprotocol/sdk/types.js';
6
+ import { createRequire } from 'node:module';
7
+ const require=createRequire(import.meta.url);let backend,connecting,closing=false;
8
+ async function control(action){const r=await fetch(process.env.DSH_COMFY_CONTROL+'/'+action,{method:'POST',headers:{authorization:'Bearer '+process.env.DSH_COMFY_TOKEN},signal:AbortSignal.timeout(action==='start'?610000:15000)});const data=await r.json();if(!r.ok)throw Error(data.error);return data;}
9
+ let backendConfig;
10
+ async function connect(){const c=await control('config');const key=JSON.stringify(c);if(backend&&backendConfig!==key){await backend.close();backend=undefined;}if(backend)return backend;if(connecting)return connecting;return connecting=(async()=>{const client=new Client({name:'dsh-comfyui-upstream',version:'0.1.0'});const transport=new StdioClientTransport({command:process.execPath,args:[require.resolve('comfyui-mcp'),'--compact'],env:{...process.env,ELECTRON_RUN_AS_NODE:'1',COMFYUI_URL:c.url,COMFYUI_PATH:c.comfyuiDir||'',COMFYUI_PYTHON:c.pythonPath||''},stderr:'inherit'});try{await client.connect(transport);if(closing){await client.close();throw Error('Closing');}backend=client;backendConfig=key;return client;}catch(e){await transport.close();throw e;}})().finally(()=>connecting=undefined);}
11
+ const obj=properties=>({type:'object',properties,additionalProperties:false});const text=value=>({content:[{type:'text',text:JSON.stringify(value)}]});
12
+ const server=new Server({name:'dsh-comfyui-mcp',version:'0.1.0'},{capabilities:{tools:{}}});
13
+ server.setRequestHandler(ListToolsRequestSchema,async()=>({tools:[
14
+ {name:'runtime',description:'ComfyUI lifecycle and connection test. Status/test do not start ComfyUI; stop only terminates this plugin’s process. Stop after generation to release GPU/RAM.',inputSchema:obj({action:{type:'string',enum:['status','test','start','stop','free']}})},
15
+ {name:'list_tools',description:'Discover artokun/comfyui-mcp tools without starting ComfyUI or loading models.',inputSchema:obj({search:{type:'string'},category:{type:'string'}})},
16
+ {name:'describe_tool',description:'Read an upstream tool schema without starting ComfyUI.',inputSchema:{...obj({name:{type:'string'}}),required:['name']}},
17
+ {name:'call_tool',description:'Execute an upstream ComfyUI tool; starts local ComfyUI only when configured. Read describe_tool first. Use enqueue_workflow for native Krea2 API workflows. Never install/update models or Python dependencies without explicit user permission. Returns MCP content including images and saved paths.',inputSchema:{...obj({name:{type:'string'},args:{type:'object',additionalProperties:true}}),required:['name']}}
18
+ ]}));
19
+ server.setRequestHandler(CallToolRequestSchema,async({params})=>{try{const a=params.arguments??{};if(params.name==='runtime')return text(await control(a.action==='test'?'status':a.action||'status'));if(!['list_tools','describe_tool','call_tool'].includes(params.name))throw Error('Unknown tool');if(params.name==='call_tool')await control('start');return await(await connect()).callTool({name:params.name,arguments:a},undefined,{timeout:1800000});}catch(e){return {isError:true,content:[{type:'text',text:e.message}]};}});
20
+ async function shutdown(){if(closing)return;closing=true;await connecting?.catch(()=>{});await backend?.close();await server.close();process.exit(0);}
21
+ process.on('SIGINT',shutdown);process.on('SIGTERM',shutdown);process.stdin.on('end',shutdown);
22
+ await server.connect(new StdioServerTransport());