Skip to main content
Glama

Comfy MCP Server

MCP server for comprehensive ComfyUI workflow automation, management, and image generation.

Overview

This server provides Claude Code (and other MCP clients) with full access to ComfyUI capabilities:

  • System monitoring: Check server health, queue status, and history

  • Workflow execution: Run saved workflows or execute custom workflow dicts

  • Workflow management: Create, modify, save, and validate workflows

  • Node discovery: List available nodes, models, and their parameters

  • Image generation: Simple prompt-based generation or full workflow control

Related MCP server: ComfyUI MCP Server

Key Features

βœ… Schema-Validated Workflows

All generated workflows are validated against the ComfyUI v0.4 workflow schema, ensuring compatibility and correct execution. No more invalid workflow errors.

🎨 Beautiful Visual Layout

Programmatically generated workflows have coherent node positions with proper spacing and alignment. The built-in layout engine produces untangled, professional-looking workflows that are easy to read and modify in the ComfyUI editor.

Technical: Uses graph-based layout algorithms (NetworkX) to automatically position nodes, eliminating the typical spaghetti diagrams from programmatic workflow generation.

Prerequisites

  • uv - Python package manager

  • Running ComfyUI server (local or remote)

  • Workflow files exported from ComfyUI (API format)

Installation

# Run directly with uvx
uvx comfyui-easy-mcp

# Or install globally
uv pip install comfyui-easy-mcp

From Source

git clone https://github.com/IO-AtelierTech/comfyui-mcp.git
cd comfyui-mcp
uv sync

Configuration

Environment Variables

Variable

Required

Default

Description

COMFY_URL

No

http://localhost:8188

ComfyUI server URL

COMFY_URL_EXTERNAL

No

Same as COMFY_URL

External URL for image retrieval

COMFY_WORKFLOWS_DIR

No

-

Directory for API format workflows (execution)

COMFY_WORKFLOWS_UI_DIR

No

-

Directory for UI format workflows (editor)

COMFY_WORKFLOW_JSON_FILE

No

-

Default workflow file for generate_image

PROMPT_NODE_ID

No

-

Default prompt node ID for generate_image

OUTPUT_NODE_ID

No

-

Default output node ID

OUTPUT_MODE

No

file

Output mode: file (Image) or url (string URL)

POLL_TIMEOUT

No

60

Max seconds to wait for workflow (1-300)

POLL_INTERVAL

No

1.0

Seconds between status polls (0.1-10.0)

Example Configuration

export COMFY_URL=http://localhost:8188
export COMFY_WORKFLOWS_DIR=/path/to/workflows-api      # API format for execution
export COMFY_WORKFLOWS_UI_DIR=/path/to/workflows-ui    # UI format for editor
export COMFY_WORKFLOW_JSON_FILE=/path/to/workflows-api/default.json
export PROMPT_NODE_ID=6
export OUTPUT_NODE_ID=9
export OUTPUT_MODE=file

Claude Desktop Config

{
  "mcpServers": {
    "ComfyUI": {
      "command": "uvx",
      "args": ["comfyui-easy-mcp"],
      "env": {
        "COMFY_URL": "http://localhost:8188",
        "COMFY_WORKFLOWS_DIR": "/path/to/workflows-api",
        "COMFY_WORKFLOWS_UI_DIR": "/path/to/workflows-ui",
        "COMFY_WORKFLOW_JSON_FILE": "/path/to/workflows-api/default.json",
        "PROMPT_NODE_ID": "6",
        "OUTPUT_NODE_ID": "9"
      }
    }
  }
}

Or use the pre-configured .mcp.json from comfyui-template.

Available Tools

System Tools

Tool

Description

get_system_stats()

Get ComfyUI server health: version, memory, device info

get_queue_status()

Get current queue: running and pending jobs

get_history(limit=10)

Get recent generation history (1-100 entries)

cancel_current(prompt_id=None)

Interrupt current generation

clear_queue(delete_ids=None)

Clear queue or delete specific items

Discovery Tools

Tool

Description

list_nodes(filter=None)

List available ComfyUI nodes (optional filter)

get_node_info(node_name)

Get detailed node info: inputs, outputs, parameters

search_nodes(query)

Search nodes by name, type, or category

list_models(folder="checkpoints")

List models in a folder

list_model_folders()

List available model folder types

list_embeddings()

List available embeddings

list_extensions()

List loaded extensions (custom node packs)

refresh_nodes()

Refresh cached node list from ComfyUI

Workflow Management Tools

Tool

Description

list_workflows()

List available workflow files

load_workflow(workflow_name)

Load a workflow from file

save_workflow(workflow, name, format="ui")

Save workflow (format: "api" or "ui")

create_workflow()

Create an empty workflow structure

add_node(workflow, node_id, class_type, inputs)

Add a node to a workflow

remove_node(workflow, node_id)

Remove a node from a workflow

update_node_input(workflow, node_id, input_name, value)

Update a node's input

validate_workflow(workflow)

Validate workflow structure and node types

convert_workflow_to_ui(workflow)

Convert API format to UI/Litegraph format

list_templates()

List available workflow templates

get_workflow_template(template_name)

Get a pre-built workflow template

generate_workflow_name(words=2)

Generate random funny workflow name

Execution Tools

Tool

Description

generate_image(prompt)

Generate image using default workflow (simple interface)

run_workflow(workflow_name, inputs=None, output_node_id=None)

Execute a saved workflow file

execute_workflow(workflow, output_node_id)

Execute an arbitrary workflow dict

submit_workflow(workflow)

Submit workflow without waiting (returns prompt_id)

get_prompt_status(prompt_id)

Get status of a submitted prompt

get_result_image(prompt_id, output_node_id)

Get result image from completed prompt

Workflow Formats

ComfyUI uses two workflow formats. Understanding the difference is critical:

Format

Structure

Use Case

Directory

API

{"node_id": {"class_type": "...", "inputs": {...}}}

MCP execution, automation

workflows-api/

UI

{"nodes": [...], "links": [...], "version": ...}

ComfyUI editor only

workflows-ui/

IMPORTANT:

  • Only API format workflows can be executed via MCP (run_workflow(), execute_workflow())

  • UI format workflows are for loading/editing in the ComfyUI web editor

  • The MCP server will reject UI format workflows with an error if you try to execute them

Format Detection

The server automatically detects format by checking for "nodes" or "version" keys (UI format) vs "class_type" keys (API format).

Creating, Validating, and Saving Workflows

# 1. CREATE: Start with empty workflow or template
wf = create_workflow()
# Or use a template:
wf = get_workflow_template("fal-flux-dev")

# 2. BUILD: Add nodes with explicit connections
wf = add_node(wf, "1", "LoadImage", {"image": "input.jpg"})
wf = add_node(wf, "2", "LumaImageToVideoNode", {
    "prompt": "smooth camera motion",
    "model": "ray-2",
    "first_image": ["1", 0],  # Connect to node "1", output index 0
    "resolution": "1080p",
    "duration": "5s"
})
wf = add_node(wf, "3", "SaveVideo_fal", {
    "videos": ["2", 0],
    "filename_prefix": "output"
})

# 3. VALIDATE: Check structure and node types before saving
validation = validate_workflow(wf)
# Returns: {"valid": true/false, "errors": [...], "warnings": [...]}

# 4. SAVE: Choose format based on purpose
# For MCP execution (API format):
save_workflow(wf, "my-workflow", format="api")  # β†’ workflows-api/my-workflow.json

# For ComfyUI editor (UI format):
save_workflow(wf, "my-workflow", format="ui")   # β†’ workflows-ui/my-workflow.json

Node Connections

Connections use the format ["source_node_id", output_index]:

# Connect node "1" output slot 0 to this input
wf = add_node(wf, "2", "CLIPTextEncode", {
    "text": "my prompt",
    "clip": ["1", 0]  # ← Connection to node "1", first output
})

Discovering Node Parameters

Before adding a node, check its required inputs:

# Find available nodes
nodes = list_nodes(filter="Luma")  # β†’ ["LumaImageToVideoNode", ...]

# Get node details
info = get_node_info("LumaImageToVideoNode")
# Returns:
# {
#   "input": {
#     "required": {
#       "prompt": ["STRING", {...}],
#       "model": [["ray-2", "ray-flash-2"], {...}],
#       "first_image": ["IMAGE"],
#       ...
#     },
#     "optional": {...}
#   },
#   "output": ["VIDEO"],
#   ...
# }

Validation Errors

Common validation issues:

Error

Cause

Fix

Unknown node type

Node class doesn't exist

Use list_nodes() to find correct name

Missing required input

Required input not provided

Check get_node_info() for required inputs

Invalid connection

Source node/output doesn't exist

Verify node IDs and output indices

UI format detected

Trying to execute UI format

Use API format or re-export from ComfyUI

Usage Examples

Simple Image Generation

# Using default workflow configuration
result = generate_image("a cyberpunk city at sunset")

Run a Named Workflow

# Execute saved workflow with custom inputs
result = run_workflow(
    "flux-dev.json",
    inputs={"6": {"text": "a forest landscape"}},
    output_node_id="9"
)

Build and Execute Custom Workflow

# 1. Create empty workflow
wf = create_workflow()

# 2. Add nodes
wf = add_node(wf, "1", "CheckpointLoaderSimple", {
    "ckpt_name": "flux-dev.safetensors"
})
wf = add_node(wf, "2", "CLIPTextEncode", {
    "text": "beautiful sunset over mountains",
    "clip": ["1", 1]  # Connect to checkpoint's CLIP output
})
wf = add_node(wf, "3", "KSampler", {
    "model": ["1", 0],
    "positive": ["2", 0],
    # ... other inputs
})

# 3. Validate before execution
validation = validate_workflow(wf)
if not validation.get("valid"):
    print(f"Errors: {validation.get('errors')}")

# 4. Execute
result = execute_workflow(wf, output_node_id="9")

Async Workflow Submission

# Submit without waiting
submission = submit_workflow(workflow)
prompt_id = submission["prompt_id"]

# Check status later
status = get_prompt_status(prompt_id)

# Get result when ready
if status["completed"]:
    image = get_result_image(prompt_id, "9")

Discover Available Nodes

# List all fal.ai nodes
nodes = list_nodes(filter="fal")

# Get details about a specific node
info = get_node_info("RemoteCheckpointLoader_fal")

Using fal.ai Connector

The ComfyUI-fal-Connector enables cloud GPU inference via fal.ai.

# 1. Verify fal.ai extension is loaded
extensions = list_extensions()
# Should include "ComfyUI-fal-Connector"

# 2. List available fal.ai nodes
fal_nodes = list_nodes(filter="fal")
# Returns: ["RemoteCheckpointLoader_fal", "StringInput_fal", "SaveImage_fal", ...]

# 3. Get node details
info = get_node_info("RemoteCheckpointLoader_fal")
# Shows available checkpoints: flux-dev, flux-schnell, sd3.5-large, etc.

# 4. Build a fal.ai workflow
wf = create_workflow()
wf = add_node(wf, "1", "RemoteCheckpointLoader_fal", {
    "ckpt_name": "flux-dev"
})
wf = add_node(wf, "2", "StringInput_fal", {
    "text": "a futuristic city at sunset, cyberpunk style"
})
wf = add_node(wf, "3", "CLIPTextEncode", {
    "text": ["2", 0],
    "clip": ["1", 1]
})
# ... add sampler, VAE decode, save image nodes

# 5. Execute on fal.ai cloud GPUs
result = execute_workflow(wf, output_node_id="9")

Environment Setup:

export FAL_KEY=your-fal-api-key

Architecture

comfy_mcp_server/
β”œβ”€β”€ __init__.py      # Entry point, FastMCP server
β”œβ”€β”€ api.py           # HTTP helpers, ComfyUI API functions
β”œβ”€β”€ models.py        # Pydantic models for type safety
β”œβ”€β”€ settings.py      # Configuration with pydantic-settings
β”œβ”€β”€ compat.py        # Version compatibility layer
└── tools/           # MCP tool implementations
    β”œβ”€β”€ system.py    # System monitoring tools
    β”œβ”€β”€ discovery.py # Node/model discovery
    β”œβ”€β”€ workflow.py  # Workflow management
    └── execution.py # Workflow execution

Development

# Install dev dependencies
uv sync --all-extras

# Run linting
uv run ruff check src/

# Run tests (requires running ComfyUI)
uv run pytest tests/

# Format code
uv run ruff format src/

ComfyUI API Coverage

Target: ComfyUI 0.3.x - 0.4.x

API Endpoint

Method

Description

Status

/prompt

POST

Submit workflow for execution

βœ… Implemented

/queue

GET

View running/pending jobs

βœ… Implemented

/queue

POST

Clear queue / delete items

βœ… Implemented

/history

GET

View generation history

βœ… Implemented

/history/{id}

GET

Get specific job result

βœ… Implemented

/history

POST

Delete history entries

⚠️ Partial

/interrupt

POST

Stop current generation

βœ… Implemented

/object_info

GET

List all available nodes

βœ… Implemented

/object_info/{node}

GET

Get node parameters/inputs

βœ… Implemented

/models

GET

List model folders

βœ… Implemented

/models/{folder}

GET

List models in folder

βœ… Implemented

/system_stats

GET

Server health/resources

βœ… Implemented

/view

GET

Retrieve generated images

βœ… Implemented

/embeddings

GET

List available embeddings

βœ… Implemented

/extensions

GET

List loaded extensions

βœ… Implemented

/upload/image

POST

Upload image for workflows

❌ Not implemented

/upload/mask

POST

Upload mask for inpainting

❌ Not implemented

/free

POST

Free VRAM/memory

❌ Not implemented

/api/userdata/*

*

User data management

❌ Not implemented

Implementation Notes

  • Partial: History deletion is not fully exposed as a tool

  • Not implemented: Image/mask upload, memory management, and user data APIs are planned for future releases

Compatibility

  • MCP Server Version: 0.2.0

  • Minimum ComfyUI: 0.3.0

  • Maximum Tested ComfyUI: 0.4.x

  • Python: 3.10+

The server includes a compatibility layer that handles API differences between ComfyUI versions and provides graceful degradation.

License

MIT License - see LICENSE file.

Credits

Originally forked from @lalanikarim/comfyui-mcp.

Available Tools

31 tools
add_nodeA

Add a node to a workflow.

    Args:
        workflow: Existing workflow dict
        node_id: Unique identifier for this node
        node_type: Node class name (use list_nodes() to find)
        inputs: Input values. For connections use ["source_node_id", output_index].

    Examples:
        # Simple value input
        add_node(wf, "1", "StringInput_fal", {"text": "a cat"})

        # Connection to another node
        add_node(wf, "2", "CLIPTextEncode", {
            "text": "prompt",
            "clip": ["1", 0]  # Connect to node "1" output 0
        })

    Returns the modified workflow dict.
    

Inputs: workflow (required), node_id (required), node_type (required), inputs (required).

cancel_currentB

Interrupt current generation.

    Args:
        prompt_id: Optional specific prompt ID to cancel.
                  If not provided, cancels all running jobs.

    Use this to stop a long-running generation.
    

Inputs: prompt_id.

clear_queueB

Clear the queue or delete specific items.

    Args:
        delete_ids: Optional list of prompt IDs to delete.
                   If not provided, clears entire queue.

    Use this to remove pending jobs from the queue.
    

Inputs: delete_ids.

convert_workflow_to_uiA

Convert an API format workflow to UI/Litegraph format.

    Args:
        workflow: Workflow in API format (flat dict with class_type/inputs)

    Returns:
        Workflow in UI format compatible with ComfyUI editor.
        This format includes node positions, visual links, and metadata
        required for the workflow to be displayed and edited in the UI.

    The conversion:
    - Assigns integer IDs to nodes
    - Places nodes in a grid layout
    - Creates visual links from input connections
    - Sets appropriate node sizes based on type
    

Inputs: workflow (required).

create_workflowA

Create an empty workflow structure.

    Returns an empty dict that you can populate with add_node().
    

Inputs: no named parameters.

execute_workflowB

Execute an arbitrary workflow dict.

    Args:
        workflow: Workflow dict in ComfyUI API format
        output_node_id: Node ID that outputs the final image

    Returns the generated image or error message.
    Use this for programmatically built workflows.
    

Inputs: workflow (required), output_node_id (required).

generate_imageA

Generate an image using the default workflow.

    This is a simplified interface for quick image generation.
    Requires COMFY_WORKFLOW_JSON_FILE, PROMPT_NODE_ID, and OUTPUT_NODE_ID
    to be configured.

    For more control, use run_workflow() or execute_workflow().

    Args:
        prompt: Text description of the image to generate
    

Inputs: prompt (required).

generate_workflow_nameA

Generate a random funny workflow name.

    Args:
        words: Number of words in the name (2-4, default: 2)

    Returns a slug like 'cosmic-penguin' or 'mighty-purple-narwhal'.
    Use this when saving new workflows for creative naming.
    

Inputs: words.

get_historyB

Get recent generation history.

    Args:
        limit: Maximum number of history entries (1-100, default: 10)

    Returns history entries with outputs and status for each job.
    Use this to see past generations and their results.
    

Inputs: limit.

get_node_infoA

Get detailed info about a node.

    Args:
        node_name: Node class name (e.g., 'RemoteCheckpointLoader_fal')

    Returns node information including:
    - input: Required and optional inputs with types
    - output: Output types
    - category: Node category
    - description: What the node does

    Use this to understand how to configure a node in a workflow.
    

Inputs: node_name (required).

get_prompt_statusB

Get the status of a submitted prompt.

    Args:
        prompt_id: The prompt ID from submit_workflow()

    Returns status information including completion state.
    

Inputs: prompt_id (required).

get_queue_statusA

Get current queue: running and pending jobs.

    Returns:
    - queue_running: List of currently executing workflows
    - queue_pending: List of queued workflows waiting to run
    - running_count: Number of running jobs
    - pending_count: Number of pending jobs

    Use this to check if workflows are executing or queued.
    

Inputs: no named parameters.

get_result_imageA

Get the result image from a completed prompt.

    Args:
        prompt_id: The prompt ID from submit_workflow()
        output_node_id: Node ID that produced the image

    Returns the image if available, or error message.
    

Inputs: prompt_id (required), output_node_id (required).

get_system_statsA

Get ComfyUI server health: version, memory, device info.

    Returns system information including:
    - ComfyUI and PyTorch versions
    - RAM usage
    - Device info (CPU/GPU)

    Use this to verify ComfyUI is running and check resource usage.
    

Inputs: no named parameters.

get_workflow_templateB

Get a pre-built workflow template.

    Args:
        template_name: One of:
            - 'empty': Empty workflow
            - 'fal-flux-dev': Flux Dev via fal.ai (higher quality)
            - 'fal-flux-schnell': Flux Schnell via fal.ai (faster)

    Returns a workflow dict that can be modified and executed.
    

Inputs: template_name (required).

list_embeddingsB

List available text embeddings.

Returns list of embedding names that can be used in prompts.

Inputs: no named parameters.

list_extensionsA

List loaded ComfyUI extensions.

Returns list of installed extension names (custom node packs). Use this to verify which custom nodes are available (e.g., fal.ai connector).

Inputs: no named parameters.

list_model_foldersA

List available model folder types.

    Returns a list of valid folder names for list_models().
    

Inputs: no named parameters.

list_modelsA

List available models in a folder.

    Args:
        folder: Model folder name. Options:
            - checkpoints: Full model checkpoints
            - loras: LoRA fine-tuning files
            - vae: VAE decoders
            - embeddings: Text embeddings
            - controlnet: ControlNet models
            - upscale_models: Upscaling models
            - clip_vision: CLIP vision encoders

    Returns list of model filenames in the folder.
    

Inputs: folder.

list_nodesA

List available ComfyUI nodes.

    Args:
        filter: Optional string to match node names (case-insensitive)
        category: Optional category filter (exact match)

    Returns a sorted list of node class names.
    Use this to discover available nodes for workflow building.
    

Inputs: filter, category.

list_templatesB

List available workflow templates.

    Returns list of template names for get_workflow_template().
    

Inputs: no named parameters.

list_workflowsA

List available workflow files.

    Returns list of workflow JSON files in the configured workflows directory.
    Use run_workflow() to execute a saved workflow.
    

Inputs: no named parameters.

load_workflowC

Load a workflow file for inspection or modification.

    Args:
        workflow_name: Workflow filename (e.g., 'my-workflow.json')

    Returns the workflow dict that can be modified and executed.
    

Inputs: workflow_name (required).

refresh_nodesA

Refresh the node cache.

    Call this after installing new custom nodes to see them in list_nodes().
    

Inputs: no named parameters.

remove_nodeA

Remove a node from a workflow.

    Args:
        workflow: Workflow dict to modify
        node_id: ID of node to remove

    Warning: This doesn't update connections from other nodes.
    

Inputs: workflow (required), node_id (required).

run_workflowC

Execute a saved workflow file.

    Args:
        workflow_name: Workflow filename (e.g., 'flux-dev.json')
        inputs: Optional input overrides, e.g., {"6": {"text": "new prompt"}}
        output_node_id: Node ID to get output from (uses default if not set)

    Returns the generated image or error message.
    

Inputs: workflow_name (required), inputs, output_node_id.

save_workflowA

Save a workflow to the workflows directory.

    Args:
        workflow: Workflow dict to save (in API format)
        name: Filename (with or without .json extension).
              If not provided, generates a random funny name like 'cosmic-penguin'.
        format: Output format:
            - 'api': Raw API format for execution (flat dict)
            - 'ui': Litegraph format for ComfyUI editor (default)

    Returns path to saved file or error message.
    

Inputs: workflow (required), name, format.

search_nodesC

Search for nodes by name, category, or description.

    Args:
        query: Search string (searches name, category, description)

    Returns matching nodes sorted by relevance.
    

Inputs: query (required).

submit_workflowA

Submit a workflow without waiting for completion.

    Args:
        workflow: Workflow dict to execute

    Returns the prompt_id for tracking.
    Use get_history() or get_prompt_status() to check completion.
    

Inputs: workflow (required).

update_node_inputC

Update a specific input on a node.

    Args:
        workflow: Workflow dict to modify
        node_id: Node ID to update
        input_name: Name of the input to update
        value: New value (use JSON string for lists/dicts)

    Returns the modified workflow dict.
    

Inputs: workflow (required), node_id (required), input_name (required), value (required).

validate_workflowC

Validate a workflow structure.

    Args:
        workflow: Workflow dict to validate

    Returns validation result with any issues found.
    

Inputs: workflow (required).

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.6/5.0

    Scored across 31 tools

    Disambiguation4/5

    Most tools have distinct purposes, but there is some overlap between execute_workflow, run_workflow, and generate_image that could cause confusion. For example, generate_image is described as a simplified interface, but its relationship to the other execution tools isn't entirely clear from the descriptions alone. However, the majority of tools target specific operations like workflow management, node handling, and system monitoring.

    Naming Consistency5/5

    Tool names follow a consistent verb_noun pattern throughout, such as add_node, cancel_current, clear_queue, and get_history. There are no deviations in naming conventions, making it easy to predict what each tool does based on its name. This consistency enhances usability for agents.

    Tool Count3/5

    With 31 tools, the count is borderline high for a single server, potentially overwhelming for agents. While ComfyUI is a complex system with many operations, some tools like generate_workflow_name and get_system_stats might be considered non-essential, contributing to a slightly bloated interface. A more focused set could improve coherence.

    Completeness5/5

    The tool surface comprehensively covers the ComfyUI domain, including workflow creation, modification, execution, monitoring, and system management. It supports full CRUD-like operations for workflows and nodes, provides templates and history, and handles edge cases like validation and conversion. No obvious gaps are present for the stated purpose.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers