Skip to main content

Agent-first CLI for executing ComfyUI workflows on RunPod serverless

Project description

comfy-gen

An agentic CLI for running ComfyUI workflows on RunPod serverless. Designed to be used by AI coding agents (Claude Code, Cursor, Codex, Windsurf, Gemini CLI) as much as by humans. All output is structured JSON. No interactive prompts. Every command has verbose --help so agents can discover capabilities without documentation.

Table of Contents

Use with Your Favorite AI Agent

ComfyGen ships with an agent skill file at SKILL.md in the repo root. Drop it into your agent's skill/tool directory and it can submit workflows, download models, check job status, and manage your RunPod infrastructure — all through natural language.

You: "Submit this workflow with seed 42 and download the output"
Agent: runs comfy-gen submit workflow.json --override 7.seed=42, parses JSON, fetches URL

Works with any agent that can run shell commands and parse JSON. The skill file teaches your agent the full API surface, including workflow analysis, parameter overrides, and error handling.

How It Works

comfy-gen submit workflow.json
  1. Detects local file references in your workflow and uploads them to S3
  2. Submits the workflow to your RunPod serverless endpoint
  3. Polls for completion with real-time progress
  4. Returns a JSON result with output URLs

Workers spin up on demand, execute the workflow, and shut down. You pay only for execution time.

Development & Testing

pip install -e '.[dev]'    # installs pytest + pytest-mock
python3 -m pytest tests/

Tests for the serverless worker (serverless-runtime/) use the dispatch_command fixture in tests/conftest.py, which mirrors the worker's command-dispatch path so routing is exercised end-to-end.

Installation

Requires Python 3.11+.

Recommended: pipx (installs system-wide, no venv needed)

brew install pipx        # macOS — or: apt install pipx / pip install pipx
pipx ensurepath          # adds pipx bin dir to PATH (restart your shell after)
pipx install comfy-gen

Alternative: pip

python -m pip install comfy-gen

Development install

git clone https://github.com/Hearmeman24/ComfyGen.git
cd ComfyGen
python -m pip install -e '.[dev]'

After installation, comfy-gen is available system-wide as a CLI command.

Windows users: Make sure "Add Python to PATH" was checked during Python installation, or comfy-gen won't be found. If you missed it, add Python's Scripts directory to your PATH manually (e.g. C:\Users\<you>\AppData\Local\Programs\Python\Python3xx\Scripts).

Quick Start

# 1. Run the setup wizard (creates RunPod endpoint + configures storage)
comfy-gen init

# 2. Download models to your network volume
comfy-gen download civitai 456789 --dest loras
comfy-gen download url https://huggingface.co/org/repo/resolve/main/model.safetensors --dest checkpoints

# 3. Submit a workflow
comfy-gen submit workflow.json

# 4. Submit with an input image for a LoadImage node
comfy-gen submit workflow.json --input 193=/path/to/photo.jpg

# 5. Override workflow parameters
comfy-gen submit workflow.json --override 7.seed=42 --override 7.denoise=0.8

# 6. Check job status / cancel
comfy-gen status <job-id>
comfy-gen cancel <job-id>

Commands

comfy-gen submit <workflow.json>

Full pipeline: upload inputs, submit to serverless, poll, return output URLs.

comfy-gen submit workflow.json
comfy-gen submit workflow.json --input 193=/path/to/ref.jpg
comfy-gen submit workflow.json --override 7.seed=42
comfy-gen submit workflow.json --timeout 300

Progress (stderr):

Submitting to RunPod serverless endpoint...
Job submitted: abc-123-def
[3s]  IN_QUEUE
[6s]  node_check: Checking custom nodes (10%)
[9s]  inference: (2/8) Step 1/8 (29%)
[12s] inference: (5/8) Step 4/8 (55%)
[15s] upload: Uploading outputs to S3 (92%)
Completed in 27s (+2s queue). 1 image

Result (stdout):

{
  "ok": true,
  "output": {
    "url": "https://bucket.s3.region.amazonaws.com/comfy-gen/outputs/abc123.png",
    "seed": 1027836870258818,
    "resolution": {"width": 828, "height": 1248},
    "model_hashes": {
      "model.safetensors": {"sha256": "240761...", "type": "diffusion_models"},
      "lora.safetensors": {"sha256": "2fdc9d...", "type": "loras", "strength": 0.8}
    }
  },
  "job_id": "abc-123-def",
  "delay_seconds": 2,
  "elapsed_seconds": 27
}

Features:

  • Auto-detects LoadImage nodes referencing local files and uploads them to S3
  • --input NODE_ID=FILE_PATH for explicit file mapping (videos, etc.) — repeatable
  • --override NODE_ID.PARAM=VALUE for parameter overrides — repeatable, auto-coerces numbers
  • Real-time progress with stage, step count, and percentage
  • Output metadata stripped (no embedded workflow data in images)
  • Returns model hashes (SHA256), types, and LoRA strengths

comfy-gen status <job-id>

Check the status of a submitted job.

{"job_id": "abc-123", "status": "completed", "ok": true, "output": {"url": "..."}, "elapsed_seconds": 27, "delay_seconds": 2}

comfy-gen cancel <job-id>

Cancel a running or queued job.

comfy-gen download <civitai|url> <target>

Download models to your RunPod network volume via a serverless job. Files land directly on the mounted volume at /runpod-volume/ComfyUI/models/<dest>/.

# Download a LoRA from CivitAI (use model VERSION ID, not model ID)
comfy-gen download civitai 456789 --dest loras

# Download a checkpoint from HuggingFace
comfy-gen download url https://huggingface.co/Comfy-Org/flux1-dev/resolve/main/flux1-dev-fp8.safetensors --dest checkpoints

# Download with a custom filename
comfy-gen download url https://example.com/model.safetensors --dest diffusion_models --filename my_model.safetensors

# Batch download from a JSON file
comfy-gen download --batch models.json

Supported --dest values: checkpoints, loras, vae, clip, diffusion_models, text_encoders, controlnet, upscale_models

Batch file format:

[
  {"source": "civitai", "version_id": "456789", "dest": "loras"},
  {"source": "url", "url": "https://huggingface.co/.../model.safetensors", "dest": "checkpoints"}
]

Result:

{
  "ok": true,
  "files": [
    {"filename": "model.safetensors", "dest": "loras", "path": "/runpod-volume/ComfyUI/models/loras/model.safetensors", "size_mb": 228.5}
  ],
  "job_id": "abc-123-def",
  "elapsed_seconds": 45
}

comfy-gen list [model_type]

List model files installed on the RunPod network volume. Submits a lightweight job to a worker which scans the filesystem.

comfy-gen list loras              # List LoRAs (default)
comfy-gen list checkpoints        # List checkpoints
comfy-gen list diffusion_models   # List diffusion models

Result:

{
  "ok": true,
  "model_type": "loras",
  "files": [
    {"filename": "my_lora.safetensors", "path": "/runpod-volume/ComfyUI/models/loras/my_lora.safetensors", "size_mb": 228.5}
  ],
  "search_paths": ["/ComfyUI/models/loras", "/runpod-volume/ComfyUI/models/loras"],
  "job_id": "abc-123-def"
}

Getting Models onto Your Volume

There are two ways to populate your RunPod network volume with models:

Option 1: comfy-gen download (individual models)

Download specific models from CivitAI or HuggingFace directly to your volume. Best for adding individual LoRAs, checkpoints, or other files on demand. See the download command above.

Option 2: Pre-populated RunPod Templates (full model sets)

For common workflows, deploy a HearmemanAI RunPod template that comes pre-configured to download entire model sets to your network volume on first boot.

For example, to get all models needed for Wan 2.2 + Wan Animate video generation:

  1. Deploy the Wan template as a GPU pod attached to your network volume
  2. Set these environment variables on the pod:
    • download_wan22=true
    • download_wan_animate=true
  3. Wait for the pod to fully deploy — all Wan 2.2 and Wan Animate models will be downloaded to the volume
  4. Stop and delete the pod — the models persist on your network volume
  5. Your serverless endpoint (which mounts the same volume) can now run Wan workflows

This is the fastest way to get started with a specific workflow type. You only need to deploy the template once per model set.


comfy-gen config

Manage persistent configuration stored at ~/.comfy-gen/config.json.

comfy-gen config                                     # Show all config
comfy-gen config --set runpod_api_key=rpa_abc123     # Set a value
comfy-gen config --get endpoint_id                   # Get a single value

Configuration

Config is read from multiple sources with this priority order:

config.json > .env file > environment variables > defaults

Key Description Env Var Default
runpod_api_key RunPod API key RUNPOD_API_KEY
endpoint_id RunPod serverless endpoint ID RUNPOD_ENDPOINT_ID
aws_access_key_id S3 access key AWS_ACCESS_KEY_ID
aws_secret_access_key S3 secret key AWS_SECRET_ACCESS_KEY
s3_bucket S3 bucket name S3_BUCKET
s3_region S3 region S3_REGION eu-west-2
s3_endpoint_url Custom S3 endpoint (for R2/B2/MinIO) S3_ENDPOINT_URL
civitai_token CivitAI API token for model downloads CIVITAI_TOKEN
timeout_seconds Max wait for completion COMFY_GEN_TIMEOUT 600
poll_interval_seconds Status poll interval COMFY_GEN_POLL_INTERVAL 3

You can also put these in a .env file in your project directory.

Storage

ComfyGen requires S3-compatible storage for transferring input files (images, videos) to workers and receiving output files. The setup wizard (comfy-gen init) configures storage and verifies it works before creating your endpoint.

Service Config
AWS S3 Set aws_access_key_id, aws_secret_access_key, s3_bucket, s3_region
Cloudflare R2 Same as above + s3_endpoint_url=https://<account-id>.r2.cloudflarestorage.com, s3_region=auto
Backblaze B2 Same as above + s3_endpoint_url=https://s3.<region>.backblazeb2.com
MinIO Same as above + s3_endpoint_url=http://your-minio:9000
DigitalOcean Spaces Same as above + s3_endpoint_url=https://<region>.digitaloceanspaces.com

Uploads are content-addressed (MD5 hash key) — identical files are never re-uploaded.

Workflow Format

Workflows must be in ComfyUI API format — the node-ID-keyed JSON with class_type and inputs fields. Export from ComfyUI via Save (API Format) or enable Dev Mode first.

{
  "7": {
    "inputs": {"seed": 42, "steps": 20, "cfg": 7.0, "model": ["10", 0]},
    "class_type": "KSampler"
  },
  "10": {
    "inputs": {"ckpt_name": "model.safetensors"},
    "class_type": "CheckpointLoaderSimple"
  }
}

Output Format

All commands output JSON to stdout. Human-readable progress goes to stderr. This makes comfy-gen composable with jq, shell scripts, and AI agents.

# Extract just the output URL
comfy-gen submit workflow.json 2>/dev/null | jq -r '.output.url'

# Save output URL to a variable
URL=$(comfy-gen submit workflow.json 2>/dev/null | jq -r '.output.url')

Success exits with code 0:

{"ok": true, "output": {"url": "...", "seed": 42, "resolution": {"width": 1024, "height": 1024}}, "job_id": "...", "elapsed_seconds": 30}

Error exits with code 1:

{"status": "error", "error": "No RunPod API key configured. Set via: comfy-gen config --set runpod_api_key=rpa_..."}

Prerequisites

You need:

  1. A RunPod accountcomfy-gen init creates the serverless endpoint for you
  2. S3-compatible storage — AWS S3, Cloudflare R2, Backblaze B2, or any S3-compatible service (see Storage)
  3. Python 3.11+

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

comfy_gen-0.2.0.tar.gz (78.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

comfy_gen-0.2.0-py3-none-any.whl (53.7 kB view details)

Uploaded Python 3

File details

Details for the file comfy_gen-0.2.0.tar.gz.

File metadata

  • Download URL: comfy_gen-0.2.0.tar.gz
  • Upload date:
  • Size: 78.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for comfy_gen-0.2.0.tar.gz
Algorithm Hash digest
SHA256 91f886a4604f8785df5d6d0dc6cb63114094a0fcc52a5d7463570701c85bbf82
MD5 d55a6c24fd0caad30188b20c7df6134d
BLAKE2b-256 3d9bb45b7d0f613db939f9bd1a34eaec75adb6d69bde8e25581bcd0e2295370b

See more details on using hashes here.

Provenance

The following attestation bundles were made for comfy_gen-0.2.0.tar.gz:

Publisher: publish-pypi.yml on Hearmeman24/ComfyGen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file comfy_gen-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: comfy_gen-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 53.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for comfy_gen-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 686c9f6b440efe890fec5a5a65be0d82ef4878eb8a7f035c1d9f6fd98bcba874
MD5 45c3c3cad7f673723e0c8a2f7c6b0067
BLAKE2b-256 4d817336b50b9ed1cf179a22a849e3b63d11e36f6595ca683ab1752555f673a5

See more details on using hashes here.

Provenance

The following attestation bundles were made for comfy_gen-0.2.0-py3-none-any.whl:

Publisher: publish-pypi.yml on Hearmeman24/ComfyGen

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page