comfyui-mcp
MCP server exposing a local (or LAN) ComfyUI instance's HTTP API as tools, so an LLM client can queue generations, inspect the queue/history, upload reference images, browse installed models/nodes, and pull back generated images.
README
comfyui-mcp
MCP server exposing a local (or LAN) ComfyUI instance's HTTP API as tools, so an
LLM client (Claude Desktop, Claude Code, etc.) can queue generations, inspect the
queue/history, upload reference images, browse installed models/nodes, and pull
back generated images -- without hand-rolling curl calls every time.
Built with Python + FastMCP, stdio transport (local subprocess, talks to ComfyUI
over HTTP on 127.0.0.1:8188 by default).
Requirements
- Python 3.10+
- A running ComfyUI instance reachable over HTTP (default assumes the same machine, default port)
Install
cd comfyui-mcp # this directory
python -m venv .venv
.venv\Scripts\activate # Windows
# source .venv/bin/activate # macOS/Linux
pip install -r requirements.txt
Configure
Environment variables (optional -- sane defaults for a local install):
| Variable | Default | Purpose |
|---|---|---|
COMFYUI_BASE_URL |
http://127.0.0.1:8188 |
Where ComfyUI's API is reachable |
COMFYUI_HTTP_TIMEOUT |
30 |
Per-request HTTP timeout in seconds (not the job-wait timeout, which is a per-tool-call parameter) |
COMFYUI_MOUNT_DIR |
E:\Claude\Projects\Krea2\comfy_out |
Where comfyui_save_output writes renders — a folder the client/sandbox can see |
COMFYUI_LORA_DIR |
(unset) | LoRA .safetensors directory, for comfyui_get_lora_metadata (ComfyUI's API exposes LoRA names but not their path) |
COMFYUI_MODELS_DIR |
(unset) | Parent models/ dir; COMFYUI_LORA_DIR falls back to <this>/loras |
The last three power the filesystem-backed tools. They assume the MCP server process runs on the same (Windows) host as ComfyUI, which is the intended setup.
Copy .env.example to .env and edit if your ComfyUI runs on a different
host/port, or just set the variables in your MCP client config (see below).
Register with an MCP client
Claude Code:
claude mcp add comfyui -- python /absolute/path/to/comfyui-mcp/comfyui_mcp/server.py
Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"comfyui": {
"command": "python",
"args": ["/absolute/path/to/comfyui-mcp/comfyui_mcp/server.py"],
"env": {
"COMFYUI_BASE_URL": "http://127.0.0.1:8188"
}
}
}
}
Use the venv's Python interpreter path (.venv/Scripts/python.exe on Windows,
.venv/bin/python on macOS/Linux) if you don't want to rely on a global install.
Tools
| Tool | Purpose |
|---|---|
comfyui_generate_image |
High-level text-to-image: builds a standard txt2img graph and submits it (checkpoint, prompts, size, sampler, steps, cfg, seed, etc.) |
comfyui_queue_prompt |
Submit any raw API-format node graph (img2img, ControlNet, LoRA, custom nodes -- anything exported from ComfyUI's "Save (API Format)") |
comfyui_get_queue |
List running/pending jobs |
comfyui_manage_queue |
Clear pending queue, or remove specific pending jobs |
comfyui_get_history |
Get a finished job's result, or list recent history |
comfyui_manage_history |
Clear history, or remove specific entries |
comfyui_interrupt |
Stop the currently running job |
comfyui_free_memory |
Unload models / free VRAM |
comfyui_upload_image |
Upload a reference image (for img2img, ControlNet, etc.) |
comfyui_upload_mask |
Upload an inpainting mask tied to a reference image |
comfyui_view_image |
Fetch actual image bytes for a filename (the only tool that returns image content); optional max_dim returns a downscaled thumbnail |
comfyui_save_output |
Copy a finished render out of ComfyUI into COMFYUI_MOUNT_DIR so the client/sandbox can reach, present, or edit it |
comfyui_get_lora_metadata |
Read a LoRA's trigger words / base model / training resolution from its safetensors header (no model load) |
comfyui_list_templates |
List server-side workflow templates and the slots each accepts |
comfyui_run_template |
Run a named template, filling in only its slots (no hand-retyped graphs) |
comfyui_get_progress |
Live progress/ETA (node, step, percent) for a running job, via ComfyUI's websocket |
comfyui_get_node_info |
Browse/inspect node types and their input/output schemas |
comfyui_list_models |
List model folder types, or filenames within one (checkpoints, loras, vae, ...) |
comfyui_list_embeddings |
List installed textual-inversion embeddings |
comfyui_get_system_stats |
Python/ComfyUI version + per-device VRAM/RAM |
Design notes
- Endpoint shapes were verified against ComfyUI's actual
server.py(fetched fromcomfyanonymous/ComfyUImaster), not assumed, since the API has no formal versioned spec. - Images are references, not inline bytes, by default.
comfyui_generate_imageandcomfyui_get_historyreturn{filename, subfolder, type}for each output image; callcomfyui_view_imageto actually fetch and view one. This keeps responses small when a batch produces several images, most of which the agent won't need to inspect. - Large ComfyUI payloads are summarized by default.
/object_info(all node schemas) and/queue//history(which embed full node graphs) can be tens to hundreds of KB.comfyui_get_queue,comfyui_get_history, andcomfyui_get_node_infodefault to condensed output with asummary=false/ explicitnode_classescape hatch for full detail. wait+ polling for completion; websocket for progress. Job completion is detected by polling/history/{prompt_id}(it only populates once a job finishes) up to a per-calltimeout— this maps cleanly onto a synchronous tool call, andwait=falsereturns immediately with aprompt_idto check later viacomfyui_get_history. Live progress (node/step/percent) can't be polled from/history, so a single background subscription to ComfyUI's/wswebsocket caches the latest progress perprompt_id, surfaced bycomfyui_get_progress. The websocket is best-effort: if it can't connect (orwebsocketsisn't installed), progress reports"unknown"and nothing else breaks.- The filesystem bridge (
comfyui_save_output,comfyui_get_lora_metadata). These are the only tools that touch the host filesystem. ComfyUI's output/ dir isn't visible to the client's sandbox, and its API exposes LoRA names but not their on-disk paths — so both tools read/write local paths directly. Every access is confined to a configured root (COMFYUI_MOUNT_DIR/COMFYUI_LORA_DIR) and validated against directory traversal.comfyui_save_outputfetches bytes through the existing/viewendpoint rather than reading ComfyUI's output dir directly, so it works without knowing where ComfyUI stores files. - Server-side workflow templates.
comfyui_run_templaterenders a stored API graph (comfyui_mcp/templates/*.json) by substituting typed slots —"{{seed}}"as a whole value keeps its int/bool/null type;"{{x}}"inside a longer string is spliced as text. A graph that references an undeclared slot is rejected before submission, rather than shipping a literal{{typo}}. Add your own canonical graphs (Krea2 base, film-grain tail, caption stack) as new files in that directory. - No response_format (json/markdown) toggle. Every tool returns plain JSON. For a single-user local tool this is simpler and more predictable than maintaining two output shapes per tool; revisit if this ever needs to serve a chat-facing UI that benefits from markdown.
- Newer
/api/jobsendpoint intentionally not used. ComfyUI's current master branch has a richer job-status API (/api/jobs/{id}with explicit pending/in_progress/completed/failed status), but it's very recent and may not exist on older ComfyUI installs./history+/queueare long-standing and work everywhere, so they're used for polling instead. Worth revisiting if you're always running latest ComfyUI.
Testing
Run the unit tests:
.venv\Scripts\python.exe -m pytest tests/ -q
They cover the pure logic in the newer tools without needing a live ComfyUI:
the safetensors metadata reader, template loading + slot substitution (including
type preservation and undeclared-slot rejection), path-traversal safety, the
http→ws URL derivation, the progress tracker's websocket-message handling,
the prompt/slots JSON-string coercion, and image downscaling. All 20 tools
also register cleanly with FastMCP.
Exercise the filesystem/networked tools against a real ComfyUI instance
before relying on them — checkpoint/sampler/scheduler names are install-specific
(use comfyui_list_models and comfyui_get_node_info(node_class="KSampler")),
and comfyui_save_output / comfyui_get_lora_metadata depend on the
COMFYUI_MOUNT_DIR / COMFYUI_LORA_DIR paths being correct for your machine.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.