ComfyUI Core Knowledge
Workflow JSON Format (API Format)
ComfyUI workflows are JSON objects mapping string node IDs to node definitions:
{
"1": {
"class_type": "CheckpointLoaderSimple",
"inputs": { "ckpt_name": "sd_xl_base_1.0.safetensors" },
"_meta": { "title": "Load Checkpoint" }
},
"2": {
"class_type": "CLIPTextEncode",
"inputs": { "text": "a cat", "clip": ["1", 1] },
"_meta": { "title": "Positive Prompt" }
}
}
Key Rules
- Node IDs are strings of integers (
"1", "2", etc.)
class_type is the exact Python class name of the node
inputs contains both widget values (scalars) and connections (arrays)
- Connections use the format
["sourceNodeId", outputIndex] — a 2-element array where:
- First element: string node ID of the source node
- Second element: integer index into the source node's
output list (0-based)
_meta is optional, used for display titles only
Connection Examples
"model": ["1", 0] // Connect to node 1's first output (MODEL)
"clip": ["1", 1] // Connect to node 1's second output (CLIP)
"vae": ["1", 2] // Connect to node 1's third output (VAE)
"positive": ["2", 0] // Connect to node 2's first output (CONDITIONING)
"samples": ["5", 0] // Connect to node 5's first output (LATENT)
"images": ["6", 0] // Connect to node 6's first output (IMAGE)
Important: API Format vs Web UI Format
- API format (for execution/analysis):
{ "1": { class_type, inputs }, "2": { ... } } — compact, used by enqueue_workflow, validate_workflow, modify_workflow, etc.
- Web UI format (for saving and frontend editing):
{ "nodes": [...], "links": [...] } — includes layout positions, sizes, groups, and visual metadata so ComfyUI's canvas can open and edit it
- Execution tools expect and return API format
- Save in Web UI format so saved workflows stay readable and editable in the ComfyUI frontend. A raw API-format save is NOT canvas-editable — it "exists" in the library but loads blank in the canvas, which strands users (and tempts agents into creating yet another new workflow instead of reopening the old one). Because of this,
save_workflow auto-converts API-format input to Web UI format with a generated layout — but prefer passing real Web UI format (from get_workflow format="ui") since a generated layout loses the original node positions/groups
get_workflow defaults to format="api" for analysis/execution; use format="ui" when loading a workflow to re-save or edit in the canvas
- Muted/bypassed nodes are preserved with
_meta.mode: "muted" — these are inactive but visible for understanding the workflow
- Get/Set virtual wire nodes are preserved with
_meta.title and Constant key for tracing data flow
Workflow Library Tools
analyze_workflow(filename) — use this first to understand any saved workflow. Returns a structured text summary with sections, node IDs, key settings, virtual wires, and connection graph. No raw JSON — just what you need to reason about the workflow. Supports views: summary (default), overview (mermaid), detail (section mermaid), list, flat.
list_workflows — list all saved workflows in ComfyUI's user library
get_workflow(filename) — load raw workflow JSON. Only use when you need the actual JSON for enqueue_workflow, modify_workflow, or save_workflow. Use analyze_workflow instead for understanding. For save_workflow, request format="ui" so the workflow stays editable in the frontend.
save_workflow(filename, workflow) — save a workflow to the user library. Pass Web UI format ({ nodes, links }) so it keeps its real layout in ComfyUI's canvas. API-format graphs are accepted and are auto-converted to Web UI format (with a generated layout) precisely because a raw API-format save is not canvas-editable — the frontend cannot open it. When re-saving an existing workflow, load it with get_workflow format="ui" and edit that, so positions/groups survive.
Data Types
ComfyUI nodes pass typed data through connections:
| Type |
Description |
Common Source |
MODEL |
Diffusion model weights |
CheckpointLoaderSimple (output 0) |
CLIP |
Text encoder |
CheckpointLoaderSimple (output 1) |
VAE |
Variational autoencoder |
CheckpointLoaderSimple (output 2) |
CONDITIONING |
Encoded text prompt |
CLIPTextEncode (output 0) |
LATENT |
Latent space tensor |
EmptyLatentImage, KSampler, VAEEncode |
IMAGE |
Pixel image tensor (BHWC) |
VAEDecode, LoadImage, SaveImage |
MASK |
Single-channel mask |
LoadImage (output 1) |
UPSCALE_MODEL |
Upscaling model |
UpscaleModelLoader |
Standard Pipeline Patterns
Text-to-Image (txt2img)
CheckpointLoaderSimple → MODEL, CLIP, VAE
├─ CLIP → CLIPTextEncode (positive) → CONDITIONING
├─ CLIP → CLIPTextEncode (negative) → CONDITIONING
│
EmptyLatentImage → LATENT
│
KSampler (model, positive, negative, latent_image) → LATENT
│
VAEDecode (samples, vae) → IMAGE
│
SaveImage (images)
Node IDs typically: 1=Checkpoint, 2=Positive, 3=Negative, 4=EmptyLatent, 5=KSampler, 6=VAEDecode, 7=SaveImage
Image-to-Image (img2img)
Same as txt2img but replace EmptyLatentImage with:
LoadImage → IMAGE
VAEEncode (pixels, vae) → LATENT → KSampler.latent_image
Set KSampler.denoise to 0.5–0.8 (lower = closer to input image).
Upscale
LoadImage → IMAGE
UpscaleModelLoader → UPSCALE_MODEL
ImageUpscaleWithModel (upscale_model, image) → IMAGE
SaveImage (images)
Inpaint
LoadImage (image) → IMAGE → VAEEncode → LATENT
LoadImage (mask) → MASK
SetLatentNoiseMask (samples, mask) → LATENT → KSampler.latent_image
MCP Tool Usage Guide
Quick Generation
create_workflow with template "txt2img" and your params
enqueue_workflow with the returned JSON — returns prompt_id immediately
- Poll
get_job_status with the prompt_id until done is true
- Use
list_output_images (limit 1) to find the generated image, then Read to display it
Inspect & Modify
get_node_info — query what nodes are available and their schemas
modify_workflow — patch an existing workflow (set_input, add_node, remove_node, connect, insert_between)
visualize_workflow — see a workflow as a mermaid diagram
Reverse Engineering
visualize_workflow — workflow JSON → mermaid diagram
mermaid_to_workflow — mermaid diagram → workflow JSON (uses /object_info for schema resolution)
Model Management
list_local_models — see what's installed
search_models — find models on HuggingFace
download_model — download to ComfyUI's models directory
Important: Never ask the user to manually download models. If a required model is missing, proactively search for it and download it yourself:
- Check
list_local_models first
- If missing, search HuggingFace via
search_models or CivitAI via their REST API
- Use
download_model to install it directly to the correct subfolder
CivitAI API (when CIVITAI_API_TOKEN env var is available):
- Search:
GET https://civitai.com/api/v1/models?query={query}&types=Checkpoint&sort=Most+Downloaded&limit=5
- Details:
GET https://civitai.com/api/v1/models/{modelId}
- Download:
GET https://civitai.com/api/download/models/{modelVersionId}?token={token}
CivitAI is preferred for fine-tuned models, community-rated checkpoints, and specialized LoRAs.
HuggingFace is preferred for official/base models (SDXL, Flux, SD 1.5).
Custom Nodes
search_custom_nodes — search the ComfyUI Registry
get_node_pack_details — get details about a specific pack
generate_node_skill — auto-generate a skill file for a node pack
Workflow Execution
enqueue_workflow submits to ComfyUI's queue and returns prompt_id + queue position immediately. It does NOT block.
Background Progress Monitoring
After enqueuing one or more workflows, use a background Bash task to monitor progress silently:
# Single job
Bash(run_in_background: true):
node "${CLAUDE_PLUGIN_ROOT}/scripts/monitor-progress.mjs" <prompt_id>
# Multiple jobs (batch)
Bash(run_in_background: true):
node "${CLAUDE_PLUGIN_ROOT}/scripts/monitor-progress.mjs" <id1> <id2> <id3>
The script connects to ComfyUI's WebSocket and reports:
- Step-by-step progress (e.g.,
KSampler step 12/20 (60%))
- Success with output filenames and timing
- Errors with node details and messages
Standard generation pattern:
create_workflow or build workflow JSON + enqueue_workflow (repeat for batch)
- Start background monitor with all prompt_ids
- Continue conversation — results appear when jobs finish
- Use
list_output_images or Read to display the generated images
Do NOT poll get_job_status in a loop. The background monitor replaces polling entirely.
Fallback: If the monitor script is unavailable, use get_job_status to poll until done is true.
Queue Management
get_queue — shows running/pending job counts and prompt_ids
get_job_status — check if a specific prompt_id is running, pending, or done
cancel_job — interrupt a running job (pass optional prompt_id to target a specific one)
cancel_queued_job — remove a specific pending job from the queue by prompt_id
clear_queue — remove all pending jobs (does NOT stop the currently running job)
When to use queue tools:
- To check status:
get_job_status for a quick boolean check (prefer background monitor for ongoing tracking)
- To abort:
cancel_job stops what's running now; cancel_queued_job removes a pending one
- To start fresh:
clear_queue then optionally cancel_job
Monitoring & Recovery
get_system_stats — GPU, VRAM, Python version, OS details
get_queue — see running/pending jobs (also listed above under Queue Management)
When ComfyUI is unresponsive or crashed:
- Try
get_system_stats — if it fails, ComfyUI is down
- Use
restart_comfyui to restart it (preserves launch args from prior stop_comfyui)
- If restart fails (no saved process info), use
start_comfyui or ask the user to start it manually
- After ComfyUI is back, re-enqueue any failed/lost workflows
When a job appears hung (monitor shows [STALL]):
- Check
get_system_stats — look at VRAM usage (OOM causes hangs)
- Try
cancel_job to interrupt the stuck job
- If cancel fails, use
restart_comfyui to force-restart
- Use
clear_vram after restart to free GPU memory before retrying
KSampler Parameters
| Parameter |
Type |
Common Values |
seed |
int |
Random (0 to 2^48). Omit to auto-randomize. |
steps |
int |
20 (standard), 4-8 (turbo/lightning models) |
cfg |
float |
7-8 (SD 1.5/SDXL), 1.0 (Flux), 3.5 (turbo) |
sampler_name |
string |
"euler", "euler_ancestral", "dpmpp_2m", "dpmpp_sde" |
scheduler |
string |
"normal", "karras", "sgm_uniform" |
denoise |
float |
1.0 (txt2img), 0.5-0.8 (img2img), 0.75-0.9 (inpaint) |
Mermaid Visualization Conventions
The visualize_workflow tool produces mermaid flowcharts with:
- Subgraphs grouping nodes by category:
loading, conditioning, sampling, image, output
- Edge labels showing data types:
-->|MODEL|, -->|CLIP|, -->|LATENT|, etc.
- Node labels showing class_type and optionally widget values
- Direction:
LR (left-to-right) by default, TB (top-to-bottom) for large workflows
The mermaid_to_workflow tool parses mermaid back into workflow JSON, using connection type labels to resolve the correct input/output slots via /object_info schemas.
Common Mistakes to Avoid
- Wrong connection format: Use
["1", 0] not [1, 0] — node IDs are strings
- Web UI format: Don't pass
{ nodes: [], links: [] } — use API format
- Missing VAE: CheckpointLoaderSimple has 3 outputs — MODEL(0), CLIP(1), VAE(2)
- Wrong output index: Check the node's output list order via
get_node_info
- Seed handling:
enqueue_workflow randomizes seeds by default unless disable_random_seed: true
1---2name: comfyui-core3description: Core ComfyUI knowledge — workflow format, node types, pipeline patterns, and MCP tool usage4---5
6# ComfyUI Core Knowledge
7
8## Workflow JSON Format (API Format)
9
10ComfyUI workflows are JSON objects mapping **string node IDs** to node definitions:
11
12```json
13{
14 "1": {
15 "class_type": "CheckpointLoaderSimple",
16 "inputs": { "ckpt_name": "sd_xl_base_1.0.safetensors" },
17 "_meta": { "title": "Load Checkpoint" }
18 },
19 "2": {
20 "class_type": "CLIPTextEncode",
21 "inputs": { "text": "a cat", "clip": ["1", 1] },
22 "_meta": { "title": "Positive Prompt" }
23 }
24}
25```
26
27### Key Rules
28
29- **Node IDs** are strings of integers (`"1"`, `"2"`, etc.)
30- **`class_type`** is the exact Python class name of the node
31- **`inputs`** contains both widget values (scalars) and connections (arrays)
32- **Connections** use the format `["sourceNodeId", outputIndex]` — a 2-element array where:
33 - First element: string node ID of the source node
34 - Second element: integer index into the source node's `output` list (0-based)
35- **`_meta`** is optional, used for display titles only
36
37### Connection Examples
38
39```json
40"model": ["1", 0] // Connect to node 1's first output (MODEL)
41"clip": ["1", 1] // Connect to node 1's second output (CLIP)
42"vae": ["1", 2] // Connect to node 1's third output (VAE)
43"positive": ["2", 0] // Connect to node 2's first output (CONDITIONING)
44"samples": ["5", 0] // Connect to node 5's first output (LATENT)
45"images": ["6", 0] // Connect to node 6's first output (IMAGE)
46```
47
48### Important: API Format vs Web UI Format
49
50- **API format** (for execution/analysis): `{ "1": { class_type, inputs }, "2": { ... } }` — compact, used by `enqueue_workflow`, `validate_workflow`, `modify_workflow`, etc.
51- **Web UI format** (for saving and frontend editing): `{ "nodes": [...], "links": [...] }` — includes layout positions, sizes, groups, and visual metadata so ComfyUI's canvas can open and edit it
52- Execution tools expect and return **API format**
53- **Save in Web UI format** so saved workflows stay readable and editable in the ComfyUI frontend. A raw API-format save is NOT canvas-editable — it "exists" in the library but loads blank in the canvas, which strands users (and tempts agents into creating yet another new workflow instead of reopening the old one). Because of this, `save_workflow` auto-converts API-format input to Web UI format with a generated layout — but prefer passing real Web UI format (from `get_workflow format="ui"`) since a generated layout loses the original node positions/groups <!-- API-vs-UI save-format clarification adapted from 1696762169/comfyui-mcp@3da56c9 -->
54- `get_workflow` defaults to `format="api"` for analysis/execution; use `format="ui"` when loading a workflow to re-save or edit in the canvas
55- Muted/bypassed nodes are preserved with `_meta.mode: "muted"` — these are inactive but visible for understanding the workflow
56- Get/Set virtual wire nodes are preserved with `_meta.title` and `Constant` key for tracing data flow
57
58### Workflow Library Tools
59
60- **`analyze_workflow(filename)`** — **use this first** to understand any saved workflow. Returns a structured text summary with sections, node IDs, key settings, virtual wires, and connection graph. No raw JSON — just what you need to reason about the workflow. Supports views: summary (default), overview (mermaid), detail (section mermaid), list, flat.
61- **`list_workflows`** — list all saved workflows in ComfyUI's user library
62- **`get_workflow(filename)`** — load raw workflow JSON. Only use when you need the actual JSON for `enqueue_workflow`, `modify_workflow`, or `save_workflow`. Use `analyze_workflow` instead for understanding. **For `save_workflow`, request `format="ui"`** so the workflow stays editable in the frontend.
63- **`save_workflow(filename, workflow)`** — save a workflow to the user library. **Pass Web UI format (`{ nodes, links }`)** so it keeps its real layout in ComfyUI's canvas. API-format graphs are accepted and are **auto-converted to Web UI format** (with a generated layout) precisely because a raw API-format save is not canvas-editable — the frontend cannot open it. When re-saving an existing workflow, load it with `get_workflow format="ui"` and edit that, so positions/groups survive.
64
65## Data Types
66
67ComfyUI nodes pass typed data through connections:
68
69| Type | Description | Common Source |
70|------|-------------|---------------|
71| `MODEL` | Diffusion model weights | CheckpointLoaderSimple (output 0) |
72| `CLIP` | Text encoder | CheckpointLoaderSimple (output 1) |
73| `VAE` | Variational autoencoder | CheckpointLoaderSimple (output 2) |
74| `CONDITIONING` | Encoded text prompt | CLIPTextEncode (output 0) |
75| `LATENT` | Latent space tensor | EmptyLatentImage, KSampler, VAEEncode |
76| `IMAGE` | Pixel image tensor (BHWC) | VAEDecode, LoadImage, SaveImage |
77| `MASK` | Single-channel mask | LoadImage (output 1) |
78| `UPSCALE_MODEL` | Upscaling model | UpscaleModelLoader |
79
80## Standard Pipeline Patterns
81
82### Text-to-Image (txt2img)
83
84```
85CheckpointLoaderSimple → MODEL, CLIP, VAE
86 ├─ CLIP → CLIPTextEncode (positive) → CONDITIONING
87 ├─ CLIP → CLIPTextEncode (negative) → CONDITIONING
88 │
89EmptyLatentImage → LATENT
90 │
91KSampler (model, positive, negative, latent_image) → LATENT
92 │
93VAEDecode (samples, vae) → IMAGE
94 │
95SaveImage (images)
96```
97
98Node IDs typically: 1=Checkpoint, 2=Positive, 3=Negative, 4=EmptyLatent, 5=KSampler, 6=VAEDecode, 7=SaveImage
99
100### Image-to-Image (img2img)
101
102Same as txt2img but replace `EmptyLatentImage` with:
103```
104LoadImage → IMAGE
105VAEEncode (pixels, vae) → LATENT → KSampler.latent_image
106```
107Set `KSampler.denoise` to 0.5–0.8 (lower = closer to input image).
108
109### Upscale
110
111```
112LoadImage → IMAGE
113UpscaleModelLoader → UPSCALE_MODEL
114ImageUpscaleWithModel (upscale_model, image) → IMAGE
115SaveImage (images)
116```
117
118### Inpaint
119
120```
121LoadImage (image) → IMAGE → VAEEncode → LATENT
122LoadImage (mask) → MASK
123SetLatentNoiseMask (samples, mask) → LATENT → KSampler.latent_image
124```
125
126## MCP Tool Usage Guide
127
128### Quick Generation
129
1301. `create_workflow` with template `"txt2img"` and your params
1312. `enqueue_workflow` with the returned JSON — returns `prompt_id` immediately
1323. Poll `get_job_status` with the `prompt_id` until `done` is true
1334. Use `list_output_images` (limit 1) to find the generated image, then `Read` to display it
134
135### Inspect & Modify
136
137- `get_node_info` — query what nodes are available and their schemas
138- `modify_workflow` — patch an existing workflow (set_input, add_node, remove_node, connect, insert_between)
139- `visualize_workflow` — see a workflow as a mermaid diagram
140
141### Reverse Engineering
142
143- `visualize_workflow` — workflow JSON → mermaid diagram
144- `mermaid_to_workflow` — mermaid diagram → workflow JSON (uses `/object_info` for schema resolution)
145
146### Model Management
147
148- `list_local_models` — see what's installed
149- `search_models` — find models on HuggingFace
150- `download_model` — download to ComfyUI's models directory
151
152**Important**: Never ask the user to manually download models. If a required model is missing, proactively search for it and download it yourself:
153
1541. Check `list_local_models` first
1552. If missing, search HuggingFace via `search_models` or CivitAI via their REST API
1563. Use `download_model` to install it directly to the correct subfolder
157
158**CivitAI API** (when `CIVITAI_API_TOKEN` env var is available):
159- Search: `GET https://civitai.com/api/v1/models?query={query}&types=Checkpoint&sort=Most+Downloaded&limit=5`
160- Details: `GET https://civitai.com/api/v1/models/{modelId}`
161- Download: `GET https://civitai.com/api/download/models/{modelVersionId}?token={token}`
162
163CivitAI is preferred for fine-tuned models, community-rated checkpoints, and specialized LoRAs.
164HuggingFace is preferred for official/base models (SDXL, Flux, SD 1.5).
165
166### Custom Nodes
167
168- `search_custom_nodes` — search the ComfyUI Registry
169- `get_node_pack_details` — get details about a specific pack
170- `generate_node_skill` — auto-generate a skill file for a node pack
171
172### Workflow Execution
173
174`enqueue_workflow` submits to ComfyUI's queue and returns `prompt_id` + queue position immediately. It does NOT block.
175
176### Background Progress Monitoring
177
178After enqueuing one or more workflows, use a **background Bash task** to monitor progress silently:
179
180```bash
181# Single job
182Bash(run_in_background: true):
183node "${CLAUDE_PLUGIN_ROOT}/scripts/monitor-progress.mjs" <prompt_id>
184
185# Multiple jobs (batch)
186Bash(run_in_background: true):
187node "${CLAUDE_PLUGIN_ROOT}/scripts/monitor-progress.mjs" <id1> <id2> <id3>
188```
189
190The script connects to ComfyUI's WebSocket and reports:
191- Step-by-step progress (e.g., `KSampler step 12/20 (60%)`)
192- Success with output filenames and timing
193- Errors with node details and messages
194
195**Standard generation pattern:**
1961. `create_workflow` or build workflow JSON + `enqueue_workflow` (repeat for batch)
1972. Start background monitor with all prompt_ids
1983. Continue conversation — results appear when jobs finish
1994. Use `list_output_images` or `Read` to display the generated images
200
201**Do NOT** poll `get_job_status` in a loop. The background monitor replaces polling entirely.
202
203**Fallback**: If the monitor script is unavailable, use `get_job_status` to poll until `done` is true.
204
205### Queue Management
206
207- `get_queue` — shows running/pending job counts and prompt_ids
208- `get_job_status` — check if a specific prompt_id is running, pending, or done
209- `cancel_job` — interrupt a running job (pass optional `prompt_id` to target a specific one)
210- `cancel_queued_job` — remove a specific pending job from the queue by `prompt_id`
211- `clear_queue` — remove all pending jobs (does NOT stop the currently running job)
212
213**When to use queue tools:**
214- To check status: `get_job_status` for a quick boolean check (prefer background monitor for ongoing tracking)
215- To abort: `cancel_job` stops what's running now; `cancel_queued_job` removes a pending one
216- To start fresh: `clear_queue` then optionally `cancel_job`
217
218### Monitoring & Recovery
219
220- `get_system_stats` — GPU, VRAM, Python version, OS details
221- `get_queue` — see running/pending jobs (also listed above under Queue Management)
222
223**When ComfyUI is unresponsive or crashed:**
2241. Try `get_system_stats` — if it fails, ComfyUI is down
2252. Use `restart_comfyui` to restart it (preserves launch args from prior `stop_comfyui`)
2263. If restart fails (no saved process info), use `start_comfyui` or ask the user to start it manually
2274. After ComfyUI is back, re-enqueue any failed/lost workflows
228
229**When a job appears hung (monitor shows `[STALL]`):**
2301. Check `get_system_stats` — look at VRAM usage (OOM causes hangs)
2312. Try `cancel_job` to interrupt the stuck job
2323. If cancel fails, use `restart_comfyui` to force-restart
2334. Use `clear_vram` after restart to free GPU memory before retrying
234
235## KSampler Parameters
236
237| Parameter | Type | Common Values |
238|-----------|------|---------------|
239| `seed` | int | Random (0 to 2^48). Omit to auto-randomize. |
240| `steps` | int | 20 (standard), 4-8 (turbo/lightning models) |
241| `cfg` | float | 7-8 (SD 1.5/SDXL), 1.0 (Flux), 3.5 (turbo) |
242| `sampler_name` | string | `"euler"`, `"euler_ancestral"`, `"dpmpp_2m"`, `"dpmpp_sde"` |
243| `scheduler` | string | `"normal"`, `"karras"`, `"sgm_uniform"` |
244| `denoise` | float | 1.0 (txt2img), 0.5-0.8 (img2img), 0.75-0.9 (inpaint) |
245
246## Mermaid Visualization Conventions
247
248The `visualize_workflow` tool produces mermaid flowcharts with:
249
250- **Subgraphs** grouping nodes by category: `loading`, `conditioning`, `sampling`, `image`, `output`
251- **Edge labels** showing data types: `-->|MODEL|`, `-->|CLIP|`, `-->|LATENT|`, etc.
252- **Node labels** showing class_type and optionally widget values
253- **Direction**: `LR` (left-to-right) by default, `TB` (top-to-bottom) for large workflows
254
255The `mermaid_to_workflow` tool parses mermaid back into workflow JSON, using connection type labels to resolve the correct input/output slots via `/object_info` schemas.
256
257## Common Mistakes to Avoid
258
2591. **Wrong connection format**: Use `["1", 0]` not `[1, 0]` — node IDs are strings
2602. **Web UI format**: Don't pass `{ nodes: [], links: [] }` — use API format
2613. **Missing VAE**: CheckpointLoaderSimple has 3 outputs — MODEL(0), CLIP(1), VAE(2)
2624. **Wrong output index**: Check the node's output list order via `get_node_info`
2635. **Seed handling**: `enqueue_workflow` randomizes seeds by default unless `disable_random_seed: true`