# Directory Structure
```
├── .dockerignore
├── .gitignore
├── .python-version
├── Dockerfile
├── Dockerfile.sse
├── LICENSE
├── pyproject.toml
├── README.md
├── requirements.txt
├── resources
│ └── run_workflow_from_file_demo.png
├── src
│ ├── .env
│ ├── client
│ │ ├── __init__.py
│ │ └── comfyui.py
│ ├── server.py
│ └── test_comfyui.py
├── uv.lock
└── workflows
└── text_to_image.json
```
# Files
--------------------------------------------------------------------------------
/.python-version:
--------------------------------------------------------------------------------
```
1 | 3.12
2 |
```
--------------------------------------------------------------------------------
/.dockerignore:
--------------------------------------------------------------------------------
```
1 | test.py
2 | test
3 |
4 | # Git
5 | .git
6 | .gitignore
7 | .github
8 |
9 | # Python
10 | __pycache__/
11 | *.py[cod]
12 | *$py.class
13 | *.so
14 | .Python
15 | env/
16 | build/
17 | develop-eggs/
18 | dist/
19 | downloads/
20 | eggs/
21 | .eggs/
22 | lib/
23 | lib64/
24 | parts/
25 | sdist/
26 | var/
27 | wheels/
28 | *.egg-info/
29 | .installed.cfg
30 | *.egg
31 |
32 | # Virtual Environment
33 | venv/
34 | ENV/
35 | .env
36 | .venv
37 |
38 | # IDE
39 | .idea/
40 | .vscode/
41 | *.swp
42 | *.swo
43 | .DS_Store
44 |
45 | # Docker
46 | Dockerfile
47 | docker-compose.yml
48 | .docker/
49 |
50 | # Logs
51 | *.log
52 | logs/
53 |
54 | # Test
55 | test/
56 | tests/
57 | .coverage
58 | .pytest_cache/
59 | htmlcov/
60 |
61 | # Documentation
62 | docs/
63 | *.md
64 |
```
--------------------------------------------------------------------------------
/src/.env:
--------------------------------------------------------------------------------
```
1 | # if true, the server will return the url of the generated image
2 | # if false, the server will return the image bytes
3 | RETURN_URL=true
4 |
5 | # ComfyUI parameters
6 | # When using Docker, it's recommended to set the host as 'host.docker.internal'
7 | # But, if you don't set up a separate volume, downloading images with the download_image tool will be difficult
8 | # COMFYUI_HOST=host.docker.internal
9 | COMFYUI_HOST=localhost
10 | COMFYUI_PORT=8188
11 | # If you use authentication setting, you can set the authentication type and value
12 | # COMFYUI_AUTHENTICATION="Bearer <token>"
13 | # COMFYUI_AUTHENTICATION="Basic <b64_encoded_credentials>"
14 |
15 | # The directory of the workflow files
16 | WORKFLOW_DIR=workflows
17 |
18 | # MCP Transport
19 | # sse or stdio
20 | MCP_TRANSPORT=stdio
21 |
```
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
```
1 | test
2 |
3 | # Byte-compiled / optimized / DLL files
4 | __pycache__/
5 | *.py[cod]
6 | *$py.class
7 |
8 | # C extensions
9 | *.so
10 |
11 | # Distribution / packaging
12 | .Python
13 | build/
14 | develop-eggs/
15 | dist/
16 | downloads/
17 | eggs/
18 | .eggs/
19 | lib/
20 | lib64/
21 | parts/
22 | sdist/
23 | var/
24 | wheels/
25 | share/python-wheels/
26 | *.egg-info/
27 | .installed.cfg
28 | *.egg
29 | MANIFEST
30 |
31 | # PyInstaller
32 | # Usually these files are written by a python script from a template
33 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
34 | *.manifest
35 | *.spec
36 |
37 | # Installer logs
38 | pip-log.txt
39 | pip-delete-this-directory.txt
40 |
41 | # Unit test / coverage reports
42 | htmlcov/
43 | .tox/
44 | .nox/
45 | .coverage
46 | .coverage.*
47 | .cache
48 | nosetests.xml
49 | coverage.xml
50 | *.cover
51 | *.py,cover
52 | .hypothesis/
53 | .pytest_cache/
54 | cover/
55 |
56 | # Translations
57 | *.mo
58 | *.pot
59 |
60 | # Django stuff:
61 | *.log
62 | local_settings.py
63 | db.sqlite3
64 | db.sqlite3-journal
65 |
66 | # Flask stuff:
67 | instance/
68 | .webassets-cache
69 |
70 | # Scrapy stuff:
71 | .scrapy
72 |
73 | # Sphinx documentation
74 | docs/_build/
75 |
76 | # PyBuilder
77 | .pybuilder/
78 | target/
79 |
80 | # Jupyter Notebook
81 | .ipynb_checkpoints
82 |
83 | # IPython
84 | profile_default/
85 | ipython_config.py
86 |
87 | # pyenv
88 | # For a library or package, you might want to ignore these files since the code is
89 | # intended to run in multiple environments; otherwise, check them in:
90 | # .python-version
91 |
92 | # pipenv
93 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
94 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
95 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
96 | # install all needed dependencies.
97 | #Pipfile.lock
98 |
99 | # UV
100 | # Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
101 | # This is especially recommended for binary packages to ensure reproducibility, and is more
102 | # commonly ignored for libraries.
103 | #uv.lock
104 |
105 | # poetry
106 | # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
107 | # This is especially recommended for binary packages to ensure reproducibility, and is more
108 | # commonly ignored for libraries.
109 | # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
110 | #poetry.lock
111 |
112 | # pdm
113 | # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
114 | #pdm.lock
115 | # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
116 | # in version control.
117 | # https://pdm.fming.dev/latest/usage/project/#working-with-version-control
118 | .pdm.toml
119 | .pdm-python
120 | .pdm-build/
121 |
122 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
123 | __pypackages__/
124 |
125 | # Celery stuff
126 | celerybeat-schedule
127 | celerybeat.pid
128 |
129 | # SageMath parsed files
130 | *.sage.py
131 |
132 | # Environments
133 | # .env
134 | .venv
135 | env/
136 | venv/
137 | ENV/
138 | env.bak/
139 | venv.bak/
140 |
141 | # Spyder project settings
142 | .spyderproject
143 | .spyproject
144 |
145 | # Rope project settings
146 | .ropeproject
147 |
148 | # mkdocs documentation
149 | /site
150 |
151 | # mypy
152 | .mypy_cache/
153 | .dmypy.json
154 | dmypy.json
155 |
156 | # Pyre type checker
157 | .pyre/
158 |
159 | # pytype static type analyzer
160 | .pytype/
161 |
162 | # Cython debug symbols
163 | cython_debug/
164 |
165 | # PyCharm
166 | # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
167 | # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
168 | # and can be added to the global gitignore or merged into this file. For a more nuclear
169 | # option (not recommended) you can uncomment the following to ignore the entire idea folder.
170 | #.idea/
171 |
172 | # Ruff stuff:
173 | .ruff_cache/
174 |
175 | # PyPI configuration file
176 | .pypirc
177 |
```
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
```markdown
1 | # ComfyUI MCP Server
2 |
3 | ## 1. Overview
4 |
5 | - A server implementation for integrating ComfyUI with MCP.
6 | - ⚠️ IMPORTANT: This server requires a running ComfyUI server.
7 | - You must either host your own ComfyUI server,
8 | - or have access to an existing ComfyUI server address.
9 |
10 | <a href="https://glama.ai/mcp/servers/@Overseer66/comfyui-mcp-server">
11 | <img width="380" height="200" src="https://glama.ai/mcp/servers/@Overseer66/comfyui-mcp-server/badge" alt="ComfyUI Server MCP server" />
12 | </a>
13 |
14 | ---
15 |
16 | ## 2. Debugging
17 |
18 | ### 2.1 ComfyUI Debugging
19 |
20 | ```bash
21 | python src/test_comfyui.py
22 | ```
23 |
24 | ### 2.2 MCP Debugging
25 |
26 | ```bash
27 | mcp dev src/server.py
28 | ```
29 |
30 | ---
31 |
32 | ## 3. Installation and Configuration
33 |
34 | ### 3.1 ComfyUI Configuration
35 |
36 | - Edit `src/.env` to set ComfyUI host and port:
37 |
38 | ```env
39 | COMFYUI_HOST=localhost
40 | COMFYUI_PORT=8188
41 | ```
42 |
43 | ### 3.2 Adding Custom Workflows
44 |
45 | - To add new tools, place your workflow JSON files in the `workflows` directory and declare them as new tools in the system.
46 |
47 | ---
48 |
49 | ## 4. Built-in Tools
50 |
51 | - **text_to_image**
52 |
53 | - Returns only the URL of the generated image.
54 | - To get the actual image:
55 | - Use the `download_image` tool, or
56 | - Access the URL directly in your browser.
57 |
58 | - **download_image**
59 |
60 | - Downloads images generated by other tools (like `text_to_image`) using the image URL.
61 |
62 | - **run_workflow_with_file**
63 |
64 | - Run a workflow by providing the path to a workflow JSON file.
65 |
66 | ```
67 | # You should ask to agent like this.
68 | Run comfyui workflow with text_to_image.json
69 | ```
70 |
71 | - example image of CursorAI
72 | 
73 |
74 | - **run_workflow_with_json**
75 |
76 | - Run a workflow by providing the workflow JSON data directly.
77 |
78 | ```
79 | # You should ask to agent like this.
80 | Run comfyui workflow with this
81 | {
82 | "3": {
83 | "inputs": {
84 | "seed": 156680208700286,
85 | "steps": 20,
86 | ... (workflow JSON example)
87 | }
88 | ```
89 |
90 | ---
91 |
92 | ## 5. How to Run
93 |
94 | ### 5.1 Using UV (Recommended)
95 |
96 | - Example `mcp.json`:
97 |
98 | ```json
99 | {
100 | "mcpServers": {
101 | "comfyui": {
102 | "command": "uv",
103 | "args": [
104 | "--directory",
105 | "PATH/MCP/comfyui",
106 | "run",
107 | "--with",
108 | "mcp",
109 | "--with",
110 | "websocket-client",
111 | "--with",
112 | "python-dotenv",
113 | "mcp",
114 | "run",
115 | "src/server.py:mcp"
116 | ]
117 | }
118 | }
119 | }
120 | ```
121 |
122 | ### 5.2 Using Docker
123 |
124 | - Downloading images to a local folder with `download_image` may be difficult since the Docker container does not share the host filesystem.
125 | - When using Docker, consider:
126 | 1. Set `RETURN_URL=false` in `.env` to receive image data as bytes.
127 | 2. Set `COMFYUI_HOST` in `.env` to the appropriate address (e.g., `host.docker.internal` or your server's IP).
128 | 3. Note: Large image payloads may exceed response limits when using binary data.
129 |
130 | #### 5.2.1 Build Docker Image
131 |
132 | ```bash
133 | # First build image
134 | docker image build -t mcp/comfyui .
135 | ```
136 |
137 | ```json
138 | {
139 | "mcpServers": {
140 | "comfyui": {
141 | "command": "docker",
142 | "args": [
143 | "run",
144 | "-i",
145 | "--rm",
146 | "-p",
147 | "3001:3000",
148 | "mcp/comfyui"
149 | ]
150 | }
151 | }
152 | }
153 | ```
154 |
155 | #### 5.2.2 Using Existing Images
156 |
157 | Also you can use prebuilt image.
158 |
159 | ```json
160 | {
161 | "mcpServers": {
162 | "comfyui": {
163 | "command": "docker",
164 | "args": [
165 | "run",
166 | "-i",
167 | "--rm",
168 | "-p",
169 | "3001:3000",
170 | "overseer66/mcp-comfyui"
171 | ]
172 | }
173 | }
174 | }
175 | ```
176 |
177 | #### 5.2.3 Using SSE Transport
178 |
179 | 1. Run the SSE server with Docker:
180 |
181 | ```bash
182 | docker run -i --rm -p 8001:8000 overseer66/mcp-comfyui-sse
183 | ```
184 |
185 | 2. Configure `mcp.json` (change localhost to your IP or domain if needed):
186 |
187 | ```json
188 | {
189 | "mcpServers": {
190 | "comfyui": {
191 | "url": "http://localhost:8001/sse"
192 | }
193 | }
194 | }
195 | ```
196 |
197 | > NOTE: When adding new workflows as tools, you need to rebuild and redeploy the Docker images to make them available.
198 |
199 | ---
```
--------------------------------------------------------------------------------
/src/client/__init__.py:
--------------------------------------------------------------------------------
```python
1 |
```
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
```
1 | mcp[cli]
2 | websocket-client
3 | python-dotenv
4 |
5 |
```
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
```toml
1 | [project]
2 | name = "comfyui-mcp-server"
3 | version = "0.1.0"
4 | description = "Add your description here"
5 | readme = "README.md"
6 | requires-python = ">=3.12"
7 | dependencies = [
8 | "mcp[cli]>=1.6.0",
9 | "python-dotenv>=1.1.0",
10 | "websocket-client>=1.8.0",
11 | ]
12 |
```
--------------------------------------------------------------------------------
/Dockerfile:
--------------------------------------------------------------------------------
```dockerfile
1 | FROM python:3.12-slim
2 |
3 | WORKDIR /app
4 |
5 | RUN apt-get update && apt-get install -y curl
6 |
7 | COPY . .
8 |
9 | RUN curl -LsSf https://astral.sh/uv/install.sh | sh
10 |
11 | ENV PATH="/root/.local/bin:${PATH}"
12 |
13 | RUN uv venv .venv && uv pip install -r pyproject.toml
14 |
15 | EXPOSE 3000
16 |
17 | ENTRYPOINT ["uv", "run", "--with", "mcp", "mcp", "run", "src/server.py:mcp"]
18 |
```
--------------------------------------------------------------------------------
/workflows/text_to_image.json:
--------------------------------------------------------------------------------
```json
1 | {
2 | "3": {
3 | "inputs": {
4 | "seed": 156680208700286,
5 | "steps": 20,
6 | "cfg": 8,
7 | "sampler_name": "euler",
8 | "scheduler": "normal",
9 | "denoise": 1,
10 | "model": [
11 | "4",
12 | 0
13 | ],
14 | "positive": [
15 | "6",
16 | 0
17 | ],
18 | "negative": [
19 | "7",
20 | 0
21 | ],
22 | "latent_image": [
23 | "5",
24 | 0
25 | ]
26 | },
27 | "class_type": "KSampler",
28 | "_meta": {
29 | "title": "KSampler"
30 | }
31 | },
32 | "4": {
33 | "inputs": {
34 | "ckpt_name": "v1-5-pruned-emaonly-fp16.safetensors"
35 | },
36 | "class_type": "CheckpointLoaderSimple",
37 | "_meta": {
38 | "title": "Load Checkpoint"
39 | }
40 | },
41 | "5": {
42 | "inputs": {
43 | "width": 512,
44 | "height": 512,
45 | "batch_size": 1
46 | },
47 | "class_type": "EmptyLatentImage",
48 | "_meta": {
49 | "title": "Empty Latent Image"
50 | }
51 | },
52 | "6": {
53 | "inputs": {
54 | "text": "beautiful scenery nature glass bottle landscape, , purple galaxy bottle,",
55 | "clip": [
56 | "4",
57 | 1
58 | ]
59 | },
60 | "class_type": "CLIPTextEncode",
61 | "_meta": {
62 | "title": "CLIP Text Encode (Prompt)"
63 | }
64 | },
65 | "7": {
66 | "inputs": {
67 | "text": "text, watermark",
68 | "clip": [
69 | "4",
70 | 1
71 | ]
72 | },
73 | "class_type": "CLIPTextEncode",
74 | "_meta": {
75 | "title": "CLIP Text Encode (Prompt)"
76 | }
77 | },
78 | "8": {
79 | "inputs": {
80 | "samples": [
81 | "3",
82 | 0
83 | ],
84 | "vae": [
85 | "4",
86 | 2
87 | ]
88 | },
89 | "class_type": "VAEDecode",
90 | "_meta": {
91 | "title": "VAE Decode"
92 | }
93 | },
94 | "9": {
95 | "inputs": {
96 | "filename_prefix": "ComfyUI",
97 | "images": [
98 | "8",
99 | 0
100 | ]
101 | },
102 | "class_type": "SaveImage",
103 | "_meta": {
104 | "title": "Save Image"
105 | }
106 | }
107 | }
```
--------------------------------------------------------------------------------
/src/server.py:
--------------------------------------------------------------------------------
```python
1 | import os
2 | import json
3 | import urllib.request
4 | import urllib.parse
5 | from typing import Any
6 | from client.comfyui import ComfyUI
7 | from mcp.server.fastmcp import FastMCP
8 | from dotenv import load_dotenv
9 |
10 | load_dotenv()
11 |
12 | mcp = FastMCP("comfyui")
13 |
14 | @mcp.tool()
15 | async def text_to_image(prompt: str, seed: int, steps: int, cfg: float, denoise: float) -> Any:
16 | """Generate an image from a prompt.
17 |
18 | Args:
19 | prompt: The prompt to generate the image from.
20 | seed: The seed to use for the image generation.
21 | steps: The number of steps to use for the image generation.
22 | cfg: The CFG scale to use for the image generation.
23 | denoise: The denoise strength to use for the image generation.
24 | """
25 | auth = os.environ.get("COMFYUI_AUTHENTICATION")
26 | comfy = ComfyUI(
27 | url=f'http://{os.environ.get("COMFYUI_HOST", "localhost")}:{os.environ.get("COMFYUI_PORT", 8188)}',
28 | authentication=auth
29 | )
30 | images = await comfy.process_workflow("text_to_image", {"prompt": prompt, "seed": seed, "steps": steps, "cfg": cfg, "denoise": denoise}, return_url=os.environ.get("RETURN_URL", "true").lower() == "true")
31 | return images
32 |
33 | @mcp.tool()
34 | async def download_image(url: str, save_path: str) -> Any:
35 | """Download an image from a URL and save it to a file.
36 |
37 | Args:
38 | url: The URL of the image to download.
39 | save_path: The absolute path to save the image to. Must be an absolute path, otherwise the image will be saved relative to the server location.
40 | """
41 | urllib.request.urlretrieve(url, save_path)
42 | return {"success": True}
43 |
44 | @mcp.tool()
45 | async def run_workflow_from_file(file_path: str) -> Any:
46 | """Run a workflow from a file.
47 |
48 | Args:
49 | file_path: The absolute path to the file to run.
50 | """
51 | with open(file_path, "r", encoding="utf-8") as f:
52 | workflow = json.load(f)
53 |
54 | auth = os.environ.get("COMFYUI_AUTHENTICATION")
55 | comfy = ComfyUI(
56 | url=f'http://{os.environ.get("COMFYUI_HOST", "localhost")}:{os.environ.get("COMFYUI_PORT", 8188)}',
57 | authentication=auth
58 | )
59 | images = await comfy.process_workflow(workflow, {}, return_url=os.environ.get("RETURN_URL", "true").lower() == "true")
60 | return images
61 |
62 | @mcp.tool()
63 | async def run_workflow_from_json(json_data: dict) -> Any:
64 | """Run a workflow from a JSON data.
65 |
66 | Args:
67 | json_data: The JSON data to run.
68 | """
69 | workflow = json_data
70 |
71 | auth = os.environ.get("COMFYUI_AUTHENTICATION")
72 | comfy = ComfyUI(
73 | url=f'http://{os.environ.get("COMFYUI_HOST", "localhost")}:{os.environ.get("COMFYUI_PORT", 8188)}',
74 | authentication=auth
75 | )
76 | images = await comfy.process_workflow(workflow, {}, return_url=os.environ.get("RETURN_URL", "true").lower() == "true")
77 | return images
78 |
79 | if __name__ == "__main__":
80 | mcp.run(transport=os.environ.get("MCP_TRANSPORT", "stdio"))
81 |
```
--------------------------------------------------------------------------------
/src/client/comfyui.py:
--------------------------------------------------------------------------------
```python
1 | import os
2 | import websocket
3 | import json
4 | import uuid
5 | import urllib.parse
6 | import urllib.request
7 | from typing import Dict, Any
8 |
9 | class ComfyUI:
10 | def __init__(self, url: str, authentication: str = None):
11 | self.url = url
12 | self.authentication = authentication
13 | self.client_id = str(uuid.uuid4())
14 | self.headers = {
15 | "Content-Type": "application/json"
16 | }
17 | if authentication:
18 | self.headers["Authorization"] = authentication
19 |
20 | def get_image(self, filename, subfolder, folder_type):
21 | data = {"filename": filename, "subfolder": subfolder, "type": folder_type}
22 | url_values = urllib.parse.urlencode(data)
23 | url = f"{self.url}/view?{url_values}"
24 | req = urllib.request.Request(url, headers=self.headers)
25 | with urllib.request.urlopen(req) as response:
26 | return response.read()
27 |
28 | def get_history(self, prompt_id):
29 | url = f"{self.url}/history/{prompt_id}"
30 | req = urllib.request.Request(url, headers=self.headers)
31 | with urllib.request.urlopen(req) as response:
32 | return json.loads(response.read())
33 |
34 | def queue_prompt(self, prompt):
35 | p = {"prompt": prompt, "client_id": self.client_id}
36 | data = json.dumps(p).encode("utf-8")
37 | req = urllib.request.Request(
38 | f"{self.url}/prompt",
39 | headers=self.headers,
40 | data=data
41 | )
42 | return json.loads(urllib.request.urlopen(req).read())
43 |
44 | async def process_workflow(self, workflow: Any, params: Dict[str, Any], return_url: bool = False):
45 | if isinstance(workflow, str):
46 | workflow_path = os.path.join(os.environ.get("WORKFLOW_DIR", "workflows"), f"{workflow}.json")
47 | if not os.path.exists(workflow_path):
48 | raise Exception(f"Workflow {workflow} not found")
49 | with open(workflow_path, "r", encoding='utf-8') as f:
50 | prompt = json.load(f)
51 | else:
52 | prompt = workflow
53 |
54 | self.update_workflow_params(prompt, params)
55 |
56 | ws = websocket.WebSocket()
57 | ws_url = f"ws://{os.environ.get("COMFYUI_HOST", "localhost")}:{os.environ.get("COMFYUI_PORT", 8188)}/ws?clientId={self.client_id}"
58 |
59 | if self.authentication:
60 | ws.connect(ws_url, header=[f"Authorization: {self.authentication}"])
61 | else:
62 | ws.connect(ws_url)
63 |
64 | try:
65 | images = self.get_images(ws, prompt, return_url)
66 | return images
67 | finally:
68 | ws.close()
69 |
70 | def get_images(self, ws, prompt, return_url):
71 | prompt_id = self.queue_prompt(prompt)["prompt_id"]
72 | output_images = {}
73 |
74 | while True:
75 | out = ws.recv()
76 | if isinstance(out, str):
77 | message = json.loads(out)
78 | if message["type"] == "executing":
79 | data = message["data"]
80 | if data["node"] is None and data["prompt_id"] == prompt_id:
81 | break
82 | else:
83 | continue
84 |
85 | history = self.get_history(prompt_id)[prompt_id]
86 | for node_id in history["outputs"]:
87 | node_output = history["outputs"][node_id]
88 | if "images" in node_output:
89 | if return_url:
90 | output_images[node_id] = []
91 | for image in node_output["images"]:
92 | data = {"filename": image["filename"], "subfolder": image["subfolder"], "type": image["type"]}
93 | url_values = urllib.parse.urlencode(data)
94 | url = f"{self.url}/view?{url_values}"
95 | output_images[node_id].append(url)
96 | else:
97 | output_images[node_id] = [
98 | self.get_image(image["filename"], image["subfolder"], image["type"])
99 | for image in node_output["images"]
100 | ]
101 |
102 | return output_images
103 |
104 | def update_workflow_params(self, prompt, params):
105 | if not params:
106 | return
107 |
108 | for node in prompt.values():
109 | if node["class_type"] == "CLIPTextEncode" and "text" in params:
110 | if isinstance(node["inputs"]["text"], str):
111 | node["inputs"]["text"] = params["text"]
112 | elif node["class_type"] == "KSampler":
113 | if "seed" in params:
114 | node["inputs"]["seed"] = params["seed"]
115 | if "steps" in params:
116 | node["inputs"]["steps"] = params["steps"]
117 | if "cfg" in params:
118 | node["inputs"]["cfg"] = params["cfg"]
119 | if "denoise" in params:
120 | node["inputs"]["denoise"] = params["denoise"]
121 |
122 | elif node["class_type"] == "LoadImage" and "image" in params:
123 | node["inputs"]["image"] = params["image"]
124 |
```