2026-02-11 01:13:16 +08:00
2026-02-06 00:11:12 +08:00
2026-02-06 00:11:12 +08:00
2026-02-06 08:09:33 +08:00
2026-02-06 00:11:12 +08:00
2026-02-06 00:11:12 +08:00

ComfyUI-OpenClaw

OpenClaw /run command example

ComfyUI-OpenClaw is a security-first ComfyUI custom node pack that adds:

  • LLM-assisted nodes (planner/refiner/vision/batch variants)
  • A built-in extension UI (OpenClaw panel)
  • A secure-by-default HTTP API for automation (webhooks, triggers, schedules, approvals, presets)
  • And more exciting features being added continuously

This project is intentionally not a general-purpose “assistant platform” with broad remote execution surfaces. It is designed to make ComfyUI a reliable automation target with an explicit admin boundary and hardened defaults.

Security stance (how this project differs from convenience-first automation packs):

  • Localhost-first defaults; remote access is opt-in
  • Explicit Admin Token boundary for write actions
  • Webhooks are deny-by-default until auth is configured
  • Strict outbound SSRF policy (callbacks + custom LLM base URLs)
  • Secrets are never stored in browser storage (optional server-side key store is local-only convenience)

Latest Updates - Click to expand

Sprint A: closes out with five concrete reliability and security improvements
  • Configuration save/apply now returns explicit apply metadata, so callers can see what was actually applied, what requires restart, and which effective provider/model is active.
  • The Settings update flow adds defensive guards against stale or partial state, reducing accidental overwrites.
  • Provider/model precedence is now deterministic across save, test, and chat paths, and prevents model contamination when switching providers.
  • In localhost convenience mode (no admin token configured), chat requests enforce same-origin CSRF protection: same-origin requests are allowed, cross-origin requests are denied.
  • Model-list fetching now uses a bounded in-memory cache keyed by provider and base URL, with a 5-minute TTL and LRU eviction cap to improve responsiveness and stability.
Sprint B: ships security doctor diagnostics, registry quarantine gates, and constrained transforms defaults
  • Added the Security Doctor surface (GET /openclaw/security/doctor) for operator-focused security posture checks across endpoint exposure, token boundaries, SSRF posture, state-dir permissions, redaction drift, runtime mode, feature flags, and API key posture.
  • Added optional remote pack registry quarantine controls with explicit lifecycle states, SHA256 integrity verification, bounded local persistence, and per-entry audit trail; this path remains disabled by default and fail-closed.
  • Added optional constrained transform execution with trusted-directory + integrity pinning, timeout and output-size caps, and bounded chain execution semantics; transforms remain disabled by default and mapping-only behavior remains intact unless explicitly enabled.
Settings contract, frontend graceful degradation, and provider drift governance
  • Enforced a strict settings write contract with schema-coerced values and explicit unknown-key rejection, reducing save/apply regressions across ComfyUI variants.
  • Hardened frontend behavior to degrade safely when optional routes or runtime capabilities are unavailable, with clearer recovery hints instead of brittle failures.
  • Added provider alias/deprecation governance and normalization coverage to reduce preset drift as upstream model IDs and endpoint shapes evolve.
Mapping v1, job event stream, and operator doctor
  • Added webhook mapping engine v1 with declarative field mapping + type coercion, enabling external payload normalization without custom adapter code paths.
  • Added real-time job event stream support via SSE (/openclaw/events/stream) with bounded buffering and polling fallback (/openclaw/events) for compatibility.
  • Added Operator Doctor diagnostics tooling for runtime/deployment checks (Python/Node environment, state-dir posture, and contract readiness signals).
Security doctor, registry quarantine, and constrained transforms
  • Added Security Doctor diagnostics surface (GET /openclaw/security/doctor) for operator-focused security posture checks and guarded remediation flow.
  • Added optional remote registry quarantine lifecycle controls with integrity verification, bounded local persistence, and explicit trust/audit gates.
  • Added optional constrained transform execution with integrity pinning, timeout/output caps, and bounded chain semantics; default posture remains disabled/fail-closed.

Table of Contents


Installation

  • ComfyUI-Manager: install as a custom node (recommended for most users), then restart ComfyUI.
  • Git (manual):
    • git clone <repo> ComfyUI/custom_nodes/comfyui-openclaw

Alternative install options:

  1. Copy/clone this repository into your ComfyUI custom_nodes folder
  2. Restart ComfyUI.

If the UI loads but endpoints return 404, ComfyUI likely did not load the Python part of the pack (see “Troubleshooting”).

Quick Start (Minimal)

Sprint A Reliability Highlights

Sprint A closes the M1 release gate with stronger config behavior and safer local convenience mode:

  • R53: config save/apply semantics are explicit in PUT /openclaw/config responses
  • R54: frontend guards for stale/partial settings states reduce accidental overwrite risk
  • R57: provider/model precedence is deterministic and stable across save/test/chat paths
  • S27: /openclaw/llm/chat enforces same-origin checks in localhost convenience mode
  • R60: /openclaw/llm/models uses bounded in-memory caching (TTL + max entries)

1) Configure an LLM key (for Planner/Refiner/vision helpers)

Set at least one of:

  • OPENCLAW_LLM_API_KEY (generic)
  • Provider-specific keys from the provider catalog (preferred; see services/providers/catalog.py)

Provider/model configuration can be set via env or /openclaw/config (admin boundary; localhost-only convenience if no Admin Token configured).

Notes:

  • Recommended: set API keys via environment variables.
  • Optional: for single-user localhost setups, you can store a provider API key from the Settings tab (“UI Key Store (Advanced)”).
    • This writes to the server-side secret store ({STATE_DIR}/secrets.json).
    • Environment variables always take priority over stored keys.

2) Configure webhook auth (required for /webhook*)

Webhooks are deny-by-default unless auth is configured:

  • OPENCLAW_WEBHOOK_AUTH_MODE=bearer and OPENCLAW_WEBHOOK_BEARER_TOKEN=...
  • or OPENCLAW_WEBHOOK_AUTH_MODE=hmac and OPENCLAW_WEBHOOK_HMAC_SECRET=...
  • or OPENCLAW_WEBHOOK_AUTH_MODE=bearer_or_hmac to accept either
  • optional replay protection: OPENCLAW_WEBHOOK_REQUIRE_REPLAY_PROTECTION=1

Admin/write actions (save config, /llm/test, key store) are protected by the Admin Token:

  • If OPENCLAW_ADMIN_TOKEN (or legacy MOLTBOT_ADMIN_TOKEN) is set, clients must send it via X-OpenClaw-Admin-Token.
  • If no admin token is configured, admin actions are allowed on localhost only (convenience mode). Do not use this mode on shared/public deployments.

Remote admin actions are denied by default. If you understand the risk and need remote administration, opt in explicitly:

  • OPENCLAW_ALLOW_REMOTE_ADMIN=1

Windows env var tips (PowerShell / CMD / portable .bat / Desktop)

  • PowerShell (current session only):
    • $env:OPENCLAW_LLM_API_KEY="<YOUR_API_KEY>"
    • $env:OPENCLAW_ADMIN_TOKEN="<YOUR_ADMIN_TOKEN>"
  • PowerShell (persistent; takes effect in new shells):
    • setx OPENCLAW_LLM_API_KEY "<YOUR_API_KEY>"
    • setx OPENCLAW_ADMIN_TOKEN "<YOUR_ADMIN_TOKEN>"
  • CMD (current session only): set OPENCLAW_LLM_API_KEY=<YOUR_API_KEY>
  • Portable .bat launchers: add set OPENCLAW_LLM_API_KEY=... / set OPENCLAW_ADMIN_TOKEN=... before launching ComfyUI.
  • ComfyUI Desktop: if env vars are not passed through reliably, prefer the Settings UI key store for localhost-only convenience, or set system-wide env vars.

Nodes

Nodes are exported as Moltbot* class names for compatibility, but appear as openclaw:* display names in ComfyUI:

  • openclaw: Prompt Planner
  • openclaw: Prompt Refiner
  • openclaw: Image to Prompt
  • openclaw: Batch Variants

See web/docs/ for node usage notes.

Extension UI

OpenClaw /sidebar ui example

The frontend lives in web/ and is served by ComfyUI as an extension panel. It uses the backend routes below (preferring /api/openclaw/*).

API Overview

Base paths

Routes are registered to support both:

  • New prefix: /openclaw/*
  • Legacy prefix: /moltbot/*

And both:

  • Direct: /openclaw/...
  • ComfyUI API shim: /api/openclaw/...

Use /api/... from browsers and extension JS.

Observability (read-only)

  • GET /openclaw/health — pack status, key presence, and basic metrics
  • GET /openclaw/logs/tail?n=50 — log tail (supports trace_id / prompt_id filters)
  • GET /openclaw/trace/{prompt_id} — trace timeline (redacted)
  • GET /openclaw/capabilities — feature/capability probe for frontend compatibility
  • GET /openclaw/jobs — currently a stub (returns an empty list)

Access control:

  • loopback is allowed
  • remote access requires OPENCLAW_OBSERVABILITY_TOKEN via X-OpenClaw-Obs-Token

LLM config (non-secret)

  • GET /openclaw/config — effective config + sources + provider catalog (observability-protected)
  • PUT /openclaw/config — update non-secret config (admin boundary)
  • POST /openclaw/llm/test — test connectivity (admin boundary)
  • POST /openclaw/llm/chat — connector chat completion path (admin boundary)
  • GET /openclaw/llm/models — fetch model list for selected provider/base URL

Notes:

  • Queue submission uses OPENCLAW_COMFYUI_URL (default http://127.0.0.1:8188).
  • PUT /openclaw/config now returns apply metadata so callers can reason about what actually took effect:
    • apply.ok, apply.requires_restart, apply.applied_keys
    • apply.effective_provider, apply.effective_model
  • Provider/model precedence is strict:
    • explicit request values > persisted config > provider defaults
    • model is revalidated against provider when provider changes (prevents cross-provider contamination)
  • POST /openclaw/llm/chat in localhost convenience mode (no admin token configured):
    • allows same-origin loopback requests
    • denies cross-origin requests with CSRF error
  • /openclaw/llm/models cache behavior:
    • key: (provider, base_url)
    • TTL: 5 minutes
    • capacity: 16 entries (LRU eviction)
  • Custom base_url is protected by SSRF policy:
    • built-in provider hosts are allowlisted by default
    • allow additional exact hosts via OPENCLAW_LLM_ALLOWED_HOSTS=host1,host2
    • or opt in to any public host via OPENCLAW_ALLOW_ANY_PUBLIC_LLM_HOST=1
    • OPENCLAW_ALLOW_INSECURE_BASE_URL=1 disables SSRF blocking (not recommended)

Webhooks

  • POST /openclaw/webhook — authenticate + validate schema and return normalized payload (no queue submission)
  • POST /openclaw/webhook/validate — dry-run render (no queue submission; includes render budgets + warnings)
  • POST /openclaw/webhook/submit — full pipeline: auth → normalize → idempotency → render → submit to queue

Payload Mapping (F40):

  • Submit arbitrary payloads (GitHub, Discord, etc.) by adding X-Webhook-Mapping-Profile: github_push (or discord_message).
  • The internal engine maps fields to the canonical schema before validation.

Job Events (R71):

  • GET /openclaw/events/stream — SSE endpoint for real-time job lifecycle events (queued, running, completed, failed).
  • GET /openclaw/events — JSON polling fallback.
  • Supports Last-Event-ID header to resume streams without data loss.

Request schema (minimal):

{
  "version": 1,
  "template_id": "portrait_v1",
  "profile_id": "SDXL-v1",
  "inputs": { "requirements": "..." },
  "job_id": "optional",
  "trace_id": "optional",
  "callback": { "url": "https://example.com/callback" }
}

Auth headers:

  • Bearer: Authorization: Bearer <token>
  • HMAC: X-OpenClaw-Signature: sha256=<hex> (legacy header: X-Moltbot-Signature)
    • optional replay protection: X-OpenClaw-Timestamp and X-OpenClaw-Nonce (legacy X-Moltbot-*)

Callback allowlist:

  • OPENCLAW_CALLBACK_ALLOW_HOSTS=example.com,api.example.com
  • OPENCLAW_CALLBACK_TIMEOUT_SEC=10
  • OPENCLAW_CALLBACK_MAX_RETRIES=3

Triggers + approvals (admin)

  • POST /openclaw/triggers/fire — fire a template with optional approval gate
  • GET /openclaw/approvals
  • GET /openclaw/approvals/{approval_id}
  • POST /openclaw/approvals/{approval_id}/approve — can auto-execute
  • POST /openclaw/approvals/{approval_id}/reject

Admin boundary:

  • OPENCLAW_ADMIN_TOKEN via X-OpenClaw-Admin-Token
  • strict localhost auth is enabled by default (OPENCLAW_STRICT_LOCALHOST_AUTH=1)

Schedules (admin)

  • GET/POST /openclaw/schedules
  • GET/PUT/DELETE /openclaw/schedules/{schedule_id}
  • POST /openclaw/schedules/{schedule_id}/toggle
  • POST /openclaw/schedules/{schedule_id}/run
  • GET /openclaw/schedules/{schedule_id}/runs
  • GET /openclaw/runs

Presets (admin)

  • GET /openclaw/presets and GET /openclaw/presets/{preset_id}:
    • public-read is allowed only when OPENCLAW_PRESETS_PUBLIC_READ=1 and OPENCLAW_STRICT_LOCALHOST_AUTH=0
    • otherwise requires admin token
  • POST/PUT/DELETE /openclaw/presets* always require admin token

Packs (admin)

  • GET /openclaw/packs
  • POST /openclaw/packs/import (multipart upload)
  • GET /openclaw/packs/export/{name}/{version}
  • DELETE /openclaw/packs/{name}/{version}

Packs are versioned zip bundles (templates/presets/profiles) with an integrity manifest (file hashes). Import/export is designed to be reproducible and hardened against common archive attacks (path traversal, zip bombs).

Operational notes:

  • Packs are local-only by default (no auto-download).
  • Packs management requires the Admin Token boundary (or localhost-only convenience mode).
  • UI: OpenClaw panel → Packs tab.
  • Verification: python -m unittest tests.test_packs_integrity -v

Bridge (sidecar; optional)

Sidecar bridge routes are registered under /openclaw/bridge/* and /moltbot/bridge/*.

Enablement and auth (device token model):

  • OPENCLAW_BRIDGE_ENABLED=1
  • OPENCLAW_BRIDGE_DEVICE_TOKEN=...
  • optional allowlist: OPENCLAW_BRIDGE_ALLOWED_DEVICE_IDS=dev1,dev2

Callback delivery allowlist (sidecar HTTP adapter):

  • OPENCLAW_BRIDGE_CALLBACK_HOST_ALLOWLIST=example.com

Templates

Templates live in data/templates/.

  • Any data/templates/<template_id>.json file is runnable (template ID = filename stem).
  • data/templates/manifest.json is optional metadata (e.g. defaults).
  • Rendering performs strict placeholder substitution:
    • Only exact string values matching {{key}} are replaced
    • Partial substitutions (e.g. "foo {{bar}}") are intentionally not supported

For the full step-by-step guide (where to put exported workflow JSON, how to author manifest.json, how to verify /openclaw/templates, and how to use /run), see tests/TEST_SOP.md.

Basic /run usage (chat)

Free-text prompt mode (no key=value needed):

/run z 画面中央是一位年轻女性… seed=-1

The connector will map the free text into a prompt field using:

  • allowed_inputs if a single key is declared in manifest.json, or
  • fallback order: positive_promptprompttextpositivecaption.

Key=value mode (explicit mapping):

/run z positive_prompt="a cat" seed=-1

Important:

  • Ensure your workflow uses the same placeholder (e.g., "text": "{{positive_prompt}}").
  • seed=-1 gives random seeds; a fixed seed reproduces outputs.

Execution Budgets

Queue submissions are protected by concurrency caps and render size budgets (services/execution_budgets.py).

Environment variables:

  • OPENCLAW_MAX_INFLIGHT_SUBMITS_TOTAL (default: 2)
  • OPENCLAW_MAX_INFLIGHT_SUBMITS_WEBHOOK (default: 1)
  • OPENCLAW_MAX_INFLIGHT_SUBMITS_TRIGGER (default: 1)
  • OPENCLAW_MAX_INFLIGHT_SUBMITS_SCHEDULER (default: 1)
  • OPENCLAW_MAX_INFLIGHT_SUBMITS_BRIDGE (default: 1)
  • OPENCLAW_MAX_RENDERED_WORKFLOW_BYTES (default: 524288)

If budgets are exceeded, callers should expect 429 (concurrency) or 413 (oversized render).

LLM Failover

Failover is integrated into services/llm_client.py and controlled via runtime config:

  • OPENCLAW_FALLBACK_MODELS (CSV)
  • OPENCLAW_FALLBACK_PROVIDERS (CSV)
  • OPENCLAW_MAX_FAILOVER_CANDIDATES (int, 15)

State Directory & Logs

By default, state is stored in a platform user-data directory:

  • Windows: %LOCALAPPDATA%\\comfyui-openclaw\\
  • macOS: ~/Library/Application Support/comfyui-openclaw/
  • Linux: ~/.local/share/comfyui-openclaw/

Override:

  • OPENCLAW_STATE_DIR=/path/to/state

Logs:

  • openclaw.log (legacy moltbot.log is still supported)

Troubleshooting

UI shows “Backend Not Loaded” / endpoints return 404

This means ComfyUI did not load the Python part of the pack or route registration failed.

Steps:

  1. Check ComfyUI startup logs for import errors while loading the custom node pack (search for openclaw, Route registration failed, ModuleNotFoundError).

  2. Confirm the pack folder is directly under custom_nodes/ and contains __init__.py.

  3. Run the smoke import check inside the same Python environment ComfyUI uses:

    python scripts/openclaw_smoke_import.py
    # or
    python scripts/openclaw_smoke_import.py --verbose
    
  4. Manually verify the endpoints used by the Settings tab:

    • GET /api/openclaw/health
    • GET /api/openclaw/config
    • GET /api/openclaw/logs/tail?n=50

Notes:

  • If your pack folder name is not comfyui-openclaw, the smoke script may need OPENCLAW_PACK_IMPORT_NAME=your-folder-name.
  • If imports fail with a services.* module error, check for name collisions with other custom nodes and prefer package-relative imports.

Operator Doctor (R72)

Run the built-in diagnostic tool to verify environment readiness (libraries, permissions, contract files):

python scripts/operator_doctor.py
# Or check JSON output:
python scripts/operator_doctor.py --json

Webhooks return 403 auth_not_configured

Set webhook auth env vars (see “Quick Start”) and restart ComfyUI.

Admin Token: server-side vs UI

OPENCLAW_ADMIN_TOKEN is a server-side environment variable. The Settings UI can use an Admin Token for authenticated requests, but cannot set or persist the server token.

Full setup steps: see tests/TEST_SOP.md.

Tests

Run unit tests from the repo root:

python3 -m unittest discover -s tests -p "test_*.py"

Updating

  • Git install: git pull inside custom_nodes/comfyui-openclaw/, then restart ComfyUI.
  • ComfyUI-Manager install: update from Manager UI, then restart ComfyUI.

🎮 Remote Control (Connector)

OpenClaw includes a standalone Connector process that allows you to control your local instance securely via Telegram, Discord, LINE, or WhatsApp.

  • Status & Queue: Check job progress remotely.
  • Run Jobs: Submit templates via chat commands.
  • Approvals: Approve/Reject paused workflows from your phone.
  • Secure: Outbound-only for Telegram/Discord. LINE/WhatsApp require inbound HTTPS (webhook).

👉 See Setup Guide (docs/connector.md)

Security

Read SECURITY.md before exposing any endpoint beyond localhost. The project is designed to be secure-by-default (deny-by-default auth, SSRF protections, redaction, bounded outputs), but unsafe deployment can still create risk.


Disclaimer (Security & Liability)

This project is provided “asis” without warranty of any kind. You are solely responsible for:

  • API keys / Admin tokens: creation, storage, rotation, and revocation
  • Runtime configuration: environment variables, config files, UI settings
  • Network exposure: tunnels, reverse proxies, public endpoints
  • Data handling: logs, prompts, outputs, and any content generated or transmitted

Key Handling Guidance (all environments)

  • Prefer environment variables for API keys and admin tokens.
  • UI key storage (if enabled) is for local, singleuser setups only.
  • Never commit secrets or embed them in versioned files.
  • Rotate tokens regularly and after any suspected exposure.

Common Deployment Contexts (you must secure each)

  • Local / singleuser: treat keys as secrets; avoid longterm browser storage.
  • LAN / shared machines: require admin tokens, restrict IPs, disable unsafe endpoints.
  • Public / tunneled / reverseproxy: enforce strict allowlists, HTTPS, leastprivilege access.
  • Desktop / portable / scripts: ensure secrets are not logged or persisted by launchers.

No Liability

The maintainers and contributors accept no responsibility for:

  • Unauthorized access or misuse of your instance
  • Loss of data, keys, or generated content
  • Any direct or indirect damages resulting from use of this software

By using this project, you acknowledge and accept these terms.

Languages
Python 84.2%
JavaScript 13.6%
CSS 0.9%
Shell 0.6%
HTML 0.4%
Other 0.3%