ComfyUI custom node - REST endpoints for OpenClaw plugin
Find a file
Rudy 9872e18bd4 feat: /claw/update handles missing .git via archive download
- If .git exists: git fetch + git pull --ff-only (normal flow)
- If no .git: downloads tarball from Forgejo API, extracts, replaces changed files
- Preserves local-only files (__pycache__, .db, etc.)
- Reports which files were updated
2026-03-31 22:54:17 -04:00
__init__.py initial: comfy-claw-helper ComfyUI custom node 2026-03-28 12:24:09 -04:00
db.py initial: comfy-claw-helper ComfyUI custom node 2026-03-28 12:24:09 -04:00
downloader.py initial: comfy-claw-helper ComfyUI custom node 2026-03-28 12:24:09 -04:00
jobs.py initial: comfy-claw-helper ComfyUI custom node 2026-03-28 12:24:09 -04:00
README.md docs: update warmup section for direct loading 2026-03-28 12:38:51 -04:00
routes.py feat: /claw/update handles missing .git via archive download 2026-03-31 22:54:17 -04:00

comfy-claw-helper

ComfyUI custom node that bridges OpenClaw ↔ ComfyUI. No visible nodes — just REST API endpoints.

Endpoints

Method Path Description
GET /claw/status VRAM usage, loaded models, queue depth
GET /claw/models List available models on disk (filterable by ?type=)
GET /claw/config Current runtime configuration
POST /claw/config Apply runtime config (DB path, Civitai API key)
POST /claw/warmup Preload models into VRAM (async job)
GET /claw/warmup/{job_id} Poll warmup job status
POST /claw/download Download models from Civitai/HuggingFace/URL (async job)
GET /claw/download/{job_id} Poll download job status
POST /claw/download/{job_id}/cancel Cancel a running download
GET /claw/downloads List all download jobs
GET /claw/jobs List all jobs (warmup + download)
GET /claw/jobs/{job_id} Poll any job by ID
POST /claw/resolve Resolve a single model by hash, AIR, or civitaiVersionId
POST /claw/resolve/batch Batch resolve multiple models
POST /claw/export Convert workflow JSON → OpenClaw plugin config

Job System

Warmup and download operations run asynchronously. All return a job_id you can poll:

# Start a warmup
curl -X POST http://comfy:8188/claw/warmup \
  -H "Content-Type: application/json" \
  -d '{"checkpoint": "illustrious/model.safetensors", "type": "checkpoint"}'
# → {"job_id": "warmup-abc123", "status": "queued"}

# Poll any job
curl http://comfy:8188/claw/jobs/warmup-abc123
# → {"job_id": "warmup-abc123", "status": "done", ...}

Jobs auto-prune after completion.

Warmup

Loads models directly into VRAM using ComfyUI's internal Python API — no workflow needed.

# Standard checkpoint → loaded + moved to GPU
curl -X POST http://comfy:8188/claw/warmup \
  -d '{"checkpoint": "Illustrious/model.safetensors", "type": "checkpoint"}'

# UNET model (Chroma, Lumina, etc.)
curl -X POST http://comfy:8188/claw/warmup \
  -d '{"checkpoint": "chroma/model.safetensors", "type": "unet"}'

# LoRA → loaded into OS page cache (applied on use)
curl -X POST http://comfy:8188/claw/warmup \
  -d '{"checkpoint": "pony/my_lora.safetensors", "type": "lora"}'

Supported types: checkpoint, unet, lora, vae, clip.

Append ?sync=true to block until loaded. Default is async — returns a job ID immediately. Set "gpu": false to skip moving to VRAM (just read into RAM/page cache).

Model Resolution

Resolve models by AIR URN, SHA256 hash, or Civitai version ID. Returns local path if found, or Civitai download info if not.

# By AIR
curl -X POST http://comfy:8188/claw/resolve \
  -d '{"air": "urn:air:illustrious:checkpoint:civitai:827184@2514310"}'

# By hash
curl -X POST http://comfy:8188/claw/resolve \
  -d '{"hash": "a5f58eb1c336..."}'

# By Civitai version ID
curl -X POST http://comfy:8188/claw/resolve \
  -d '{"civitaiVersionId": 2514310}'

# Batch resolve
curl -X POST http://comfy:8188/claw/resolve/batch \
  -d '{"items": [{"air": "..."}, {"hash": "..."}, ...]}'

Resolution chain: AIR lookup (DB) → Hash lookup (DB) → Version ID lookup (DB) → Civitai API → download info.

Download

# From Civitai
curl -X POST http://comfy:8188/claw/download \
  -d '{"civitai_model_version_id": 12345, "type": "checkpoints", "save_path": "illustrious"}'

# From HuggingFace
curl -X POST http://comfy:8188/claw/download \
  -d '{"huggingface": "stabilityai/sdxl-base-1.0/model.safetensors", "type": "checkpoints"}'

# Direct URL
curl -X POST http://comfy:8188/claw/download \
  -d '{"url": "https://example.com/model.safetensors", "type": "loras", "filename": "my_lora.safetensors"}'

Features: threaded downloads, SHA256 hashing, progress tracking, cancellation, duplicate detection, concurrency limits.

Configuration

Runtime config is sent by the OpenClaw plugin (lazy sync on first image gen):

curl -X POST http://comfy:8188/claw/config \
  -d '{"db_path": "/path/to/models.db", "enable_db": true, "civitai_api_key": "..."}'

DB is opt-in. When enabled, shares the SQLite database with comfyui-comfychair-helper (schema v6, AIR support).

Export

Convert a ComfyUI API-format workflow into OpenClaw plugin config:

curl -X POST http://comfy:8188/claw/export \
  -d '{"workflow": {...}, "name": "my-workflow"}'

Returns workflow_def, model_aliases, lora_aliases, and analysis.

Installation

Symlink or copy into ComfyUI's custom_nodes/ directory:

ln -s /path/to/comfy-claw-helper /path/to/ComfyUI/custom_nodes/comfy-claw-helper

Restart ComfyUI. Routes register automatically via PromptServer.instance.routes.

Architecture

  • Routes register via aiohttp on ComfyUI's PromptServer
  • Warmup loads models directly via comfy.sd (no workflow/prompt queue needed)
  • Downloads run as background threads with asyncio bridges
  • Job system provides unified tracking for all async operations
  • No actual ComfyUI nodes registered (NODE_CLASS_MAPPINGS is empty)
  • Shared SQLite DB with comfychair-helper for model metadata + AIR