comfyui-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@comfyui-mcp-serverUse the txt2img workflow to generate a photo of a sunset over mountains."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
comfyui-mcp-server
An MCP server that turns curated ComfyUI workflows into tools. Every workflow
you drop into a directory becomes a typed MCP tool (txt2img(prompt, seed, …))
and a REST endpoint, executed against ComfyUI's HTTP API.
MCP client ──/mcp──┐
├─ comfyui-mcp-server ──HTTP──> ComfyUI (or llama-swap /upstream/comfyui)
REST client ─/api──┘ │
workflows/*.json + *.yamlStreamable HTTP, stateless by default, so replicas need no sticky sessions
Workflows as tools with JSON-schema parameters, defaults, ranges and enums
Results inline: generated images come back as MCP image content plus download URLs
Image inputs as base64/data URI, a previous job's output, or (opt-in) a URL
Hot reload: edited workflow files and remounted ConfigMaps are picked up live
Bearer auth, probes that never touch ComfyUI, OCI image and Helm chart
Why not the official comfy-mcp?
Comfy-Org/comfy-mcp is a stdio
server that runs comfy-cli commands as subprocesses to control the ComfyUI
installed on the same machine: launching it, installing nodes and
downloading models. Behind a stdio→HTTP bridge in a cluster, most of those
tools would act on the container instead of your ComfyUI. Its run_workflow
also takes a file path rather than exposing workflows as tools. This server
does the opposite: it doesn't manage ComfyUI at all, and serves a fixed,
reviewed set of workflows to many clients.
Workflows
A workflow is a graph exported from ComfyUI with Export (API), plus optional metadata that names the inputs a caller may set:
workflows/
txt2img.json # the API-format graph
txt2img.yaml # description, parameters, outputstitle: Text to image
description: Generate an image from a text prompt.
parameters:
prompt:
type: string # string | integer | number | boolean | image
required: true
description: What the image should show
target: Positive Prompt.text # "<node id or node title>.<input>"
width:
type: integer
minimum: 64
maximum: 2048
target: Empty Latent Image.width # default is read from the graph
seed:
type: integer
randomize: true # a fresh random value when omitted
target: [KSampler.seed] # one parameter may set several inputs
outputs: [Save Image] # only return these nodes' files (default: all)Targets resolve by node id (
"6.text") or by node title ("Positive Prompt.text"). Titles survive re-exports, so set meaningful titles in the ComfyUI editor.Everything is checked at load time. A typo in a target, a UI-format export or a target wired to another node disables that one workflow and is reported under
load_errorsin/api/workflowsand/readyz.The graph may be inlined in the YAML under
workflow:instead of a separate.json, which is handy in Helm values.Omitted optional parameters keep the value stored in the graph.
A
.jsonwithout a.yamlis still served. It has no parameters, butrun_workflowcan set any input throughoverrides({"6.text": "a cat"}).
image parameters upload the file into ComfyUI's input directory and accept:
Value | Meaning |
| inline image |
| reuse a previous job's output (chain workflows) |
| a file already in ComfyUI's input directory |
| fetched by the server, only with |
The image ships two examples, txt2img and
img2img, built on the stock SD 1.5 graph.
Related MCP server: ComfyUI-MCP-Server-Python
MCP tools
Tool | |
| one per workflow; waits for the result and returns images + URLs |
| names, descriptions and parameter schemas |
| run by name, with |
| status and outputs of a job, waiting by default |
| drop a queued job or interrupt a running one |
| what ComfyUI is running and has queued |
| arbitrary API-format graph, only with |
A tool call waits up to JOB_TIMEOUT and sends progress notifications while
the job is queued or running. If the job is still going after that, the call
returns its job_id with status pending or running, and get_job picks it
up again.
claude mcp add --transport http comfyui https://comfyui-mcp.example.com/mcp \
--header "Authorization: Bearer $API_TOKEN"REST API
Method | Path | |
|
| list workflows (+ |
|
| one workflow's schema; |
|
| body: parameters, or |
|
| job status and outputs; |
|
| cancel |
|
| ComfyUI queue |
|
| download an output file |
|
| probes (unauthenticated, never call ComfyUI) |
curl -s -X POST https://comfyui-mcp.example.com/api/workflows/txt2img/run \
-H "Authorization: Bearer $API_TOKEN" -H 'Content-Type: application/json' \
-d '{"prompt": "a lighthouse at dawn", "steps": 25}'200 completed or failed (see status), 202 still running, 422 invalid
parameters, 4xx/502 rejected by or unable to reach ComfyUI.
Configuration
Variable | Default | |
|
| ComfyUI base URL; a path prefix is fine |
| sent as | |
|
| seconds per ComfyUI request (cold starts behind llama-swap) |
|
|
|
|
| seconds a call waits for a job before returning its id; keep it below your MCP clients' tool timeout |
|
| seconds between status polls |
| require | |
| external base URL used for output links | |
|
| return images inline in MCP results |
|
| total inline image budget per result |
|
| let image parameters be fetched from URLs |
|
| expose |
|
| stateless streamable HTTP |
| comma-separated | |
|
|
ComfyUI itself has no authentication, and anything that can reach this server
can run workflows on your GPU. Set API_TOKEN whenever the service is exposed.
With llama-swap-comfyui
Point COMFYUI_URL at llama-swap's proxy path, e.g.
http://llama-swap:8080/upstream/comfyui. The first tool call loads ComfyUI,
which evicts the resident LLM. Probes never call ComfyUI, so they don't
trigger swaps. If llama-swap swaps ComfyUI out while a job runs, the job is
reported as failed ("job disappeared") and doesn't hang until the timeout.
Deployment
Container
docker run --rm -p 8000:8000 \
-e COMFYUI_URL=http://host.docker.internal:8188 \
-e API_TOKEN=change-me \
-v ./my-workflows:/workflows:ro -e WORKFLOWS_DIR=/app/workflows:/workflows \
ghcr.io/hauke-cloud/comfyui-mcp-server:latestHelm
helm install comfyui-mcp oci://ghcr.io/hauke-cloud/charts/comfyui-mcp-server \
--set config.comfyuiUrl=http://llama-swap.ai.svc:8080/upstream/comfyui \
--set auth.apiToken=change-me \
--set-file 'workflows.files.sdxl\.json=./sdxl.json' \
--set-file 'workflows.files.sdxl\.yaml=./sdxl.yaml'Workflows come from the image (workflows.includeBundled), a ConfigMap
rendered from workflows.files or named by workflows.existingConfigMap, and
any workflows.extraDirs you mount. See
values.yaml.
The chart can expose the service through an ingress or, for clusters that
run a Gateway API implementation, through httpRoute. Either route's request
timeout must outlast config.jobTimeout, which the HTTPRoute defaults already
do. With Envoy Gateway, envoyGateway.securityPolicy and
envoyGateway.backendTrafficPolicy attach policies to that route. For
example, validate Keycloak JWTs and rate-limit at the gateway:
httpRoute:
enabled: true
parentRefs:
- name: hauke-cloud
namespace: envoy-gateway
hostnames: [comfyui-mcp.example.com]
envoyGateway:
securityPolicy:
enabled: true
spec:
jwt:
providers:
- name: keycloak
issuer: https://id.hauke.cloud/realms/cloud
remoteJWKS:
uri: https://id.hauke.cloud/realms/cloud/protocol/openid-connect/certs
backendTrafficPolicy:
enabled: true
spec:
rateLimit:
type: Local
local:
rules:
- limit: {requests: 30, unit: Minute}CI/CD
.github/workflows/ci.yml lints and renders the
chart, then runs
inpacken-un-af-dor-mit.
That action runs ruff and pytest, builds a multi-arch image to
ghcr.io/hauke-cloud/comfyui-mcp-server and pushes the chart to
oci://ghcr.io/hauke-cloud/charts.
push to
main: imagelatest,main,0.0.0-dev-<sha>and chart0.0.0-dev-<sha>tag
v1.2.3: image and chart1.2.3, plus a GitHub releasepull request: lint, test and build without pushing
Development
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt -e .
pytest && ruff check . && ruff format --check .
COMFYUI_URL=http://127.0.0.1:8188 WORKFLOWS_DIR=./workflows comfyui-mcp-serverThe tests run against an in-process fake of ComfyUI's HTTP API, so they need neither a GPU nor ComfyUI.
Licence
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Remote MCP for RunComfy: ComfyUI deployments, hosted models, LoRA training. 31 tools.
Create, browse, remix, collaborate on, and run durable AI workflow nodes from MCP hosts.
Build, validate, deploy — HTTP APIs, cron jobs, webhooks and MCP tools — from your AI client.
Multi-model AI image and video generator. 14 models behind one OAuth-secured MCP endpoint.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceDynamically loads ComfyUI workflows as MCP tools, enabling AI assistants to generate images, videos, and audio by executing workflows across categories like text-to-image, image-to-video, and text-to-audio with automatic parameter mapping and progress monitoring.35,030 npm3MIT
- AlicenseNot gradedqualityDmaintenanceConverts ComfyUI workflows into MCP tools for AI agents to generate images, videos, and other multimedia content.6MIT
- AlicenseNot gradedqualityDmaintenanceExposes ComfyUI workflows as callable MCP tools, enabling LLMs to run image generation workflows via API.59 PyPIMIT
- AlicenseBqualityBmaintenanceMCP server that dynamically exposes each enabled ComfyUI workflow as a tool with JSON Schema, supports job submission with wait and idempotency, file uploads, and resource metadata, with both stdio and authenticated Streamable HTTP transports.35MIT