Skip to main content
Glama
README.md
# comfy-agent-mcp

Local MCP server and CLI that drive [ComfyUI](https://github.com/comfyanonymous/ComfyUI) with **Qwen Image 2.1** so Cursor (or any MCP client) can generate and edit images on your machine.

## Features

- **`generate_image`** — text-to-image with aspect ratio, megapixels, or exact `width`/`height` (64–2048)
- **`edit_image`** — edit an existing PNG/JPEG with an instruction (e.g. “remove Chinese text, keep the rest”)
- **`get_result`** — wait for queued jobs and return image paths, so slow machines never hit the MCP client timeout
- Seed reuse as a decimal string for reproducible runs
- Same capabilities available from the Python CLI (`comfy_cli.py`)

## Requirements

- [Node.js](https://nodejs.org/) 18+
- Python 3.10+ with `requests` (`py -m pip install requests`)
- [ComfyUI](https://github.com/comfyanonymous/ComfyUI) (Desktop or portable) recent enough for **Qwen Image 2.1**, listening at `http://127.0.0.1:8188`
- The three model files listed below, with **exactly those filenames**, in the ComfyUI model folders

You do **not** need to open or reconfigure a workflow in the ComfyUI UI to use this MCP. The repo ships `workflow.json` with the model names already filled in. The MCP posts that graph to the ComfyUI API. If the files sit in the right folders under those names, ComfyUI loads them automatically.

(The Desktop UI step of picking models in dropdowns is only needed when you *build* a workflow by hand. After that export, clones of this repo skip that step.)

## ComfyUI models

Download from [Comfy-Org/Qwen-Image-2.1](https://huggingface.co/Comfy-Org/Qwen-Image-2.1) and place them as follows (standard ComfyUI layout; Desktop often uses a shared `models` folder next to the install):

| File | Folder |
|------|--------|
| [`qwen_image_2.1_int8_convrot.safetensors`](https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/diffusion_models/qwen_image_2.1_int8_convrot.safetensors) (~7.3 GB) | `models/diffusion_models/` |
| [`qwen3vl_8b_int8_convrot.safetensors`](https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/text_encoders/qwen3vl_8b_int8_convrot.safetensors) (~9.4 GB) | `models/text_encoders/` |
| [`qwen_image_2.1_vae_bf16.safetensors`](https://huggingface.co/Comfy-Org/Qwen-Image-2.1/resolve/main/vae/qwen_image_2.1_vae_bf16.safetensors) (~676 MB) | `models/vae/` |

Those filenames must match `workflow.json`. If you rename a file, either rename it back or edit `workflow.json` to match.

`ResolutionSelector`, `SaveImageAdvanced`, and `TextEncodeQwenImage21` come with recent ComfyUI builds — no extra custom-node pack is required for this workflow.

### Quick check in the UI (optional)

1. Start ComfyUI Desktop / ComfyUI.
2. Open a Qwen Image 2.1 text-to-image template (or load any graph that uses those loaders).
3. Confirm the three dropdowns list the files above. If a dropdown is empty, the file is missing or in the wrong folder — fix that before using the MCP.

You still do not need to keep that graph open while the MCP runs.

## Setup

```bash
git clone https://github.com/jothbc/comfy-agent-mcp.git
cd comfy-agent-mcp
npm install
py -m pip install requests
```

1. Install the models (section above).
2. Start ComfyUI and wait until `http://127.0.0.1:8188` responds.
3. Point Cursor (or another MCP client) at `server.mjs`, or run `npm start` for a manual stdio server.

### Cursor MCP config

```json
{
  "mcpServers": {
    "comfyui-local": {
      "command": "node",
      "args": ["E:/path/to/comfy-agent-mcp/server.mjs"]
    }
  }
}
```

On Windows the CLI is invoked with `py`. Ensure the Python launcher is on your `PATH`.

### If generation fails

- ComfyUI not running → connection error from the CLI.
- Missing model / wrong filename → ComfyUI rejects the prompt (check the ComfyUI console).
- Older ComfyUI without Qwen Image 2.1 nodes → unknown `class_type` errors; update ComfyUI.

## MCP tools

Generation is asynchronous. `generate_image` and `edit_image` queue the job in ComfyUI and return right away with `prompt_ids` and seeds. The agent then calls `get_result`, which waits up to 50 seconds per call and is called again until every job is done. This keeps each call under the MCP client request timeout (60 seconds by default), however long your GPU takes.

### `generate_image`

| Parameter | Description |
|-----------|-------------|
| `prompt` | Image description |
| `count` | 1–4 images (default 1) |
| `aspect_ratio` | `1:1`, `16:9`, or `9:16` (used if size not set) |
| `megapixels` | ~0.05–4 (used if size not set) |
| `width` / `height` | Exact pixels 64–2048 (both required; rounded to multiples of 8) |
| `seed` | Decimal string from a previous result |

Size tips: icons ~256–512, UI ~1024, cinematic up to 2048.

### `edit_image`

| Parameter | Description |
|-----------|-------------|
| `image_path` | Path to the source PNG/JPEG |
| `prompt` | Edit instruction |
| `count` | 1–4 variations |
| `seed` | Optional decimal string |
| `negative_prompt` | Optional (e.g. text, watermarks) |

Editing uses the source as a Qwen reference. Reusing a generation seed alone does **not** edit a picture — use `edit_image`.

### `get_result`

| Parameter | Description |
|-----------|-------------|
| `prompt_ids` | Ids returned by `generate_image` or `edit_image` |
| `wait_seconds` | Max wait per call, 0–50 (default 45) |

Each result reports `completed` (with image paths), `running`, `queued`, `error`, or `not_found`. When `done` is `false`, call it again with the same ids.

## CLI

```bash
# Generate
py comfy_cli.py --prompt "cyberpunk city at night" --aspect-ratio "16:9 (Widescreen)" --megapixels 1

# Exact size
py comfy_cli.py --prompt "app icon, flat" --width 256 --height 256

# Edit
py comfy_cli.py --image ./output/photo.png --prompt "Remove all overlaid text" --negative "text, letters"

# Machine-readable output
py comfy_cli.py --prompt "..." --json

# Queue without waiting, then fetch later
py comfy_cli.py --prompt "..." --no-wait --json
py comfy_cli.py --result <prompt_id> --wait-seconds 50 --json
```

Without `--no-wait`, the CLI waits for the image with no time limit.

Images are written to `output/` by default (gitignored).

## Project layout

| File | Role |
|------|------|
| `server.mjs` | MCP server (stdio) |
| `comfy_cli.py` | ComfyUI HTTP client / CLI |
| `workflow.json` | Qwen Image 2.1 workflow graph |

## License

MIT — see [LICENSE](LICENSE).