ai-toolkit-trainer
Train custom LoRAs with ostris AI-Toolkit. Covers WAN 2.2/2.1 (people, styles, video motion) and Z-Image (Turbo & Base, low-VRAM image LoRAs). Use when the…
Diagnose and fix video/image color OBJECTIVELY with the get_image (action:"analyze_color") tool (scopes/stats such as black/white points, contrast, saturation, clipping, cast) instead of eyeballing a contact sheet. Covers the "washed out" signature, why reference color-match
$ npx -y skills add artokun/comfyui-mcp --skill color-correction --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/color-correctionContext preview
The summary Claude sees to decide when to auto-load this skill.
Diagnose and fix video/image color OBJECTIVELY with the get_image (action:"analyze_color") tool (scopes/stats such as black/white points, contrast, saturation, clipping, cast) instead of eyeballing a contact sheet. Covers the "washed out" signature, why reference color-match
name: color-correction description: Diagnose and fix video/image color OBJECTIVELY with the get_image (action:"analyze_color") tool (scopes/stats such as black/white points, contrast, saturation, clipping, cast) instead of eyeballing a contact sheet. Covers the "washed out" signature, why reference color-match (mkl/ColorMatch/ColorMatchAdobe) CAN'T add contrast a flat source lacks, the levels/contrast-stretch fix (core AdjustContrast / CurveEditor), the measure→fix→re-measure loop, the side-by-side sandbox pattern, and where to place the fix in a render graph (after decode, before save). Use when a render looks washed out / flat / dull / over-saturated / color-cast, or when deciding between a color-match and a contrast/levels fix. globs: - "**/*.json" - "**/packs/**"
You cannot reliably judge color from a storyboard or contact sheet. "Is it washed out?" flip-flops by eye, especially on AI-gen video. Make color measurable with the `get_image (action:"analyze_color")` MCP tool, read the numbers like a colorist reads scopes, pick the fix the data points to, then re-measure to confirm. The whole skill is this loop:
extract a frame ─► get_image (action:"analyze_color") ─► read black/white points + contrast + saturation
▲ │
│ ▼
re-measure ◄──── apply fix (levels / contrast / match) ◄── diagnose from the numbers> Origin: on a WAN-Animate render we argued for many turns over whether the clip was > "washed out." The instant we measured it, the answer was unambiguous and the *correct* > fix (a contrast stretch, not the color-match nodes we'd been adding) fell straight out.
---
Read-only. Source = `asset_id`, a ComfyUI output ref (`filename`/`subfolder`/`type`), or an image `path` (absolute, or under the output dir). It returns per-image stats, heuristic flags, a one-line verdict, and optionally an overlaid R/G/B/luma histogram PNG.
get_image({ action: "analyze_color", filename: "render_00007_.png" }) # absolute numbers
get_image({ action: "analyze_color", path: "frame.png", reference_path: "src.jpg" }) # + shot-match deltas
get_image({ action: "analyze_color", filename: "x.png", histogram: true }) # + histogram imageFor videos, `get_image (action:"analyze_color")` is image-only (no ffmpeg dep). Extract a frame first with the ComfyUI venv's cv2:
"<comfy-venv>/python" -c "import cv2; c=cv2.VideoCapture(r'IN.mp4'); n=int(c.get(7)); \ c.set(1, n//2); _,f=c.read(); cv2.imwrite(r'frame.png', f)"
Grab the middle frame, or frame 0. For window-drift checks grab a frame from each window.
| Field | Reads like a scope | Healthy-ish | |---|---|---| | `luma.blackPoint` (1st pct) | where shadows bottom out | ~0–16 (lifted if >16) | | `luma.whitePoint` (99th pct) | where highlights top out | ~240–255 (dim if <235) | | `luma.contrast` (std) | overall punch | ~45+ (flat if <45) | | `luma.dynamicRange` | white−black | wide is good | | `saturation.meanSaturation` (HSV S) | vectorscope spread | ~0.25+ (dull if <0.22) | | `channels.{r,g,b}Mean` + `castHint` | RGB parade / white balance | spread <~12 = neutral | | `luma.clippedHighPct/LowPct` | blown / crushed pixels | keep low (<~2%) |
Flags: `washedOut, lowContrast, liftedBlacks, dimHighlights, lowSaturation, colorCast`.
---
Washed out means compressed tonal range, and it has an exact fingerprint:
If you see that, the fix is a levels / contrast stretch, not a color match. In a real case, a WAN-Animate frame measured blackPoint 45 / whitePoint 191 / contrast 43, clearly a range problem; saturation 0.25 was fine.
---
The instinct is to "match the render to the input photo" with a color-match node (`ColorMatchV2` mkl/hm, `ImageColorMatchAdobe+`, easy `imageColorMatch`). Measure the reference first. If the reference is itself flat (e.g. a casual phone selfie with blackPoint 40, contrast 44), matching to it cannot produce punch; you'll match your way to the *same* flat numbers. In the real case, mkl and Adobe matches both left the frame flagged `washedOut` (whitePoint only crept from 191 to ~218).
So:
a known-good graded frame or shot-match across clips*, and the reference is actually good.
It targets full range *regardless* of the reference. This is usually the real fix.
---
`AdjustContrast` (core `comfy_extras.nodes_dataset`, category *image/adjustments*) has one `factor` (1.0 = none, >1 = more). It pivots around mid-gray, so it pushes the white point up and the black point down together. Tune it by measurement, not feel. A real measured sweep on the washout frame:
| factor | blackPoint | whitePoint | contrast | sat | clippedHigh | verdict | |---|---|---|---|---|---|---| | 1.3 | 29 | 239 | 56 | 0.33 | **0%** | ✅ not washed (slightly soft) | | ~1.4 | ~20 | ~247 | ~60 | ~0.38 | ~1–2% | ✅ **sweet spot** | | 1.6 | 7 | 254 | 67 | 0.44 | **7.2%** ⚠️ | punchy but blows highlights |
Pick the factor that lands whitePoint ~248 to 255 with `clippedHighPct` < ~2%. Going too far (1.6 here) blows highlights *and* over-warms, because per-channel contrast drops blue more than red and `castHint` worsens. The sweet spot was ~1.4.
Other levers when contrast alone isn't enough: -
This project is no longer maintained. ComfyUI now ships official agent and MCP tooling — Comfy Agent and Comfy MCP — built and supported by the Comfy-Org team with deeper integration than a community project can match.
Repo: artokun/comfyui-mcp
Train custom LoRAs with ostris AI-Toolkit. Covers WAN 2.2/2.1 (people, styles, video motion) and Z-Image (Turbo & Base, low-VRAM image LoRAs). Use when the…
Anime/illustration text-to-image (ANIMA 1.0, ~2B Cosmos DiT). Use for anime, manga, illustrated characters; accepts Danbooru tags + natural language;…
Train a custom anime LoRA on the ANIMA base model with Citron's local Gradio trainer (kohya sd-scripts), <6GB VRAM, character/style LoRAs; covers setup,…
Discover Civitai models with the BUILT-IN download_model action:"search_civitai" and install/generate them locally. Find a checkpoint/LoRA/embedding on…
Core ComfyUI knowledge covering workflow format, node types, pipeline patterns, and MCP tool usage
Authoring ComfyUI v2 frontend extensions with @comfyorg/extension-api, covering defineNode/defineExtension/defineWidget, shell UI (sidebar tabs, commands,…