dcc-mcp-comfyui 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dcc_mcp_comfyui-0.1.0/.github/workflows/ci.yml +61 -0
- dcc_mcp_comfyui-0.1.0/.github/workflows/release.yml +68 -0
- dcc_mcp_comfyui-0.1.0/.gitignore +21 -0
- dcc_mcp_comfyui-0.1.0/.release-please-manifest.json +3 -0
- dcc_mcp_comfyui-0.1.0/CHANGELOG.md +18 -0
- dcc_mcp_comfyui-0.1.0/PKG-INFO +117 -0
- dcc_mcp_comfyui-0.1.0/README.md +90 -0
- dcc_mcp_comfyui-0.1.0/pyproject.toml +66 -0
- dcc_mcp_comfyui-0.1.0/release-please-config.json +35 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/__init__.py +79 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/__version__.py +6 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/_env.py +75 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/api.py +82 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/bridge.py +397 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/cli.py +72 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/server.py +301 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/SKILL.md +81 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/scripts/_runtime.py +23 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/scripts/get_artifact.py +34 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/scripts/query_job_status.py +27 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/scripts/submit_workflow.py +52 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/scripts/validate_workflow.py +20 -0
- dcc_mcp_comfyui-0.1.0/src/dcc_mcp_comfyui/skills/comfyui-workflow/tools.yaml +174 -0
- dcc_mcp_comfyui-0.1.0/tests/__init__.py +0 -0
- dcc_mcp_comfyui-0.1.0/tests/test_server.py +469 -0
- dcc_mcp_comfyui-0.1.0/uv.lock +483 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
push:
|
|
6
|
+
branches: [main, "release-please--branches--**"]
|
|
7
|
+
pull_request:
|
|
8
|
+
branches: [main]
|
|
9
|
+
|
|
10
|
+
concurrency:
|
|
11
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
12
|
+
cancel-in-progress: true
|
|
13
|
+
|
|
14
|
+
permissions:
|
|
15
|
+
contents: read
|
|
16
|
+
|
|
17
|
+
jobs:
|
|
18
|
+
test:
|
|
19
|
+
name: Test Python ${{ matrix.python }} on ${{ matrix.os }}
|
|
20
|
+
runs-on: ${{ matrix.os }}
|
|
21
|
+
timeout-minutes: 15
|
|
22
|
+
strategy:
|
|
23
|
+
fail-fast: false
|
|
24
|
+
matrix:
|
|
25
|
+
include:
|
|
26
|
+
- {os: ubuntu-latest, python: "3.10"}
|
|
27
|
+
- {os: ubuntu-latest, python: "3.13"}
|
|
28
|
+
- {os: windows-latest, python: "3.12"}
|
|
29
|
+
- {os: macos-latest, python: "3.12"}
|
|
30
|
+
|
|
31
|
+
steps:
|
|
32
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
33
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
34
|
+
with:
|
|
35
|
+
python-version: ${{ matrix.python }}
|
|
36
|
+
- run: python -m pip install --upgrade pip
|
|
37
|
+
- run: python -m pip install "dcc-mcp-core==0.19.91"
|
|
38
|
+
- run: python -m pip install -e ".[dev]"
|
|
39
|
+
- run: python -m pytest
|
|
40
|
+
|
|
41
|
+
lint-and-build:
|
|
42
|
+
runs-on: ubuntu-latest
|
|
43
|
+
timeout-minutes: 15
|
|
44
|
+
steps:
|
|
45
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
46
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
47
|
+
with:
|
|
48
|
+
python-version: "3.12"
|
|
49
|
+
- run: python -m pip install --upgrade pip
|
|
50
|
+
- run: python -m pip install "dcc-mcp-core==0.19.91"
|
|
51
|
+
- run: python -m pip install -e ".[dev]" twine
|
|
52
|
+
- run: python -m ruff check .
|
|
53
|
+
- run: python -m ruff format --check .
|
|
54
|
+
- run: python -m build
|
|
55
|
+
- run: python -m twine check dist/*
|
|
56
|
+
- name: Smoke test the built wheel
|
|
57
|
+
shell: bash
|
|
58
|
+
run: |
|
|
59
|
+
python -m pip install --force-reinstall --no-deps dist/*.whl
|
|
60
|
+
python -c "import importlib.metadata as m, importlib.resources as r, dcc_mcp_comfyui as p; assert p.__version__ == m.version('dcc-mcp-comfyui'); root = r.files('dcc_mcp_comfyui'); assert root.joinpath('skills', 'comfyui-workflow', 'SKILL.md').is_file(); assert root.joinpath('skills', 'comfyui-workflow', 'tools.yaml').is_file(); assert root.joinpath('skills', 'comfyui-workflow', 'scripts', '_runtime.py').is_file()"
|
|
61
|
+
python -c "import importlib.metadata as m, subprocess; expected = m.version('dcc-mcp-comfyui'); actual = subprocess.check_output(['dcc-mcp-comfyui', '--version'], text=True).strip(); assert actual == expected, (actual, expected)"
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
workflow_dispatch:
|
|
7
|
+
inputs:
|
|
8
|
+
tag_name:
|
|
9
|
+
description: Existing tag to rebuild and publish
|
|
10
|
+
required: false
|
|
11
|
+
default: ""
|
|
12
|
+
publish_to_pypi:
|
|
13
|
+
description: Publish a manually rebuilt tag to PyPI
|
|
14
|
+
type: boolean
|
|
15
|
+
required: false
|
|
16
|
+
default: false
|
|
17
|
+
|
|
18
|
+
concurrency:
|
|
19
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
20
|
+
cancel-in-progress: false
|
|
21
|
+
|
|
22
|
+
permissions:
|
|
23
|
+
contents: read
|
|
24
|
+
|
|
25
|
+
jobs:
|
|
26
|
+
release-please:
|
|
27
|
+
runs-on: ubuntu-latest
|
|
28
|
+
timeout-minutes: 10
|
|
29
|
+
if: github.ref == 'refs/heads/main'
|
|
30
|
+
permissions:
|
|
31
|
+
contents: write
|
|
32
|
+
pull-requests: write
|
|
33
|
+
outputs:
|
|
34
|
+
release_created: ${{ steps.release.outputs.release_created }}
|
|
35
|
+
tag_name: ${{ steps.release.outputs.tag_name || inputs.tag_name }}
|
|
36
|
+
steps:
|
|
37
|
+
- uses: googleapis/release-please-action@0dfd8538845b8e92600d271a895a5372865d4062 # v5
|
|
38
|
+
id: release
|
|
39
|
+
with:
|
|
40
|
+
token: ${{ github.token }}
|
|
41
|
+
config-file: release-please-config.json
|
|
42
|
+
manifest-file: .release-please-manifest.json
|
|
43
|
+
|
|
44
|
+
build-and-publish:
|
|
45
|
+
needs: release-please
|
|
46
|
+
if: needs.release-please.outputs.release_created == 'true' || (github.event_name == 'workflow_dispatch' && inputs.tag_name != '' && inputs.publish_to_pypi)
|
|
47
|
+
runs-on: ubuntu-latest
|
|
48
|
+
timeout-minutes: 15
|
|
49
|
+
environment:
|
|
50
|
+
name: pypi
|
|
51
|
+
url: https://pypi.org/p/dcc-mcp-comfyui
|
|
52
|
+
permissions:
|
|
53
|
+
contents: read
|
|
54
|
+
id-token: write
|
|
55
|
+
steps:
|
|
56
|
+
- uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
|
|
57
|
+
with:
|
|
58
|
+
ref: ${{ needs.release-please.outputs.tag_name || inputs.tag_name }}
|
|
59
|
+
- uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # v6
|
|
60
|
+
with:
|
|
61
|
+
python-version: "3.12"
|
|
62
|
+
- run: python -m pip install --upgrade pip build twine
|
|
63
|
+
- run: python -m build
|
|
64
|
+
- run: python -m twine check dist/*
|
|
65
|
+
- uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # release/v1
|
|
66
|
+
with:
|
|
67
|
+
verbose: true
|
|
68
|
+
print-hash: true
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
__pycache__/
|
|
2
|
+
*.py[cod]
|
|
3
|
+
*.egg-info/
|
|
4
|
+
.eggs/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg
|
|
8
|
+
.pytest_cache/
|
|
9
|
+
.ruff_cache/
|
|
10
|
+
.mypy_cache/
|
|
11
|
+
.coverage
|
|
12
|
+
htmlcov/
|
|
13
|
+
.venv/
|
|
14
|
+
venv/
|
|
15
|
+
*.log
|
|
16
|
+
.DS_Store
|
|
17
|
+
Thumbs.db
|
|
18
|
+
|
|
19
|
+
# Local agent runtime context
|
|
20
|
+
.agent_context/
|
|
21
|
+
.multica/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 (2026-08-12)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* initial ComfyUI adapter MVP ([9f9627b](https://github.com/dcc-mcp/dcc-mcp-comfyui/commit/9f9627b1e92272406f2eba788ce850d1e3aafa9d))
|
|
9
|
+
* ship production-ready ComfyUI workflows ([#2](https://github.com/dcc-mcp/dcc-mcp-comfyui/issues/2)) ([ddb03cd](https://github.com/dcc-mcp/dcc-mcp-comfyui/commit/ddb03cd835db1f92b251a80e1d21307525a2e8fa))
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
* accept ComfyUI API-format workflows ([93c8c4d](https://github.com/dcc-mcp/dcc-mcp-comfyui/commit/93c8c4da92b5ea3f3fb940f2f081446b979e59d2))
|
|
15
|
+
|
|
16
|
+
## Changelog
|
|
17
|
+
|
|
18
|
+
All notable changes are generated from Conventional Commits by Release Please.
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: dcc-mcp-comfyui
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: ComfyUI adapter for the DCC Model Context Protocol (MCP) ecosystem — bridges MCP tools to ComfyUI via REST + WebSocket API
|
|
5
|
+
Project-URL: Homepage, https://github.com/dcc-mcp/dcc-mcp-comfyui
|
|
6
|
+
Project-URL: Repository, https://github.com/dcc-mcp/dcc-mcp-comfyui
|
|
7
|
+
Author-email: Long Hao <hal.long@outlook.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
Keywords: ai,comfyui,dcc,llm,mcp,model-context-protocol,stable-diffusion,workflow
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Multimedia :: Graphics
|
|
15
|
+
Requires-Python: >=3.10
|
|
16
|
+
Requires-Dist: dcc-mcp-core<1.0.0,>=0.19.91
|
|
17
|
+
Requires-Dist: httpx>=0.25.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
20
|
+
Requires-Dist: hatchling; extra == 'dev'
|
|
21
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
22
|
+
Requires-Dist: pytest-mock>=3.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: pytest>=7.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: pyyaml>=6.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: ruff>=0.8.0; extra == 'dev'
|
|
26
|
+
Description-Content-Type: text/markdown
|
|
27
|
+
|
|
28
|
+
# dcc-mcp-comfyui
|
|
29
|
+
|
|
30
|
+
<p align="center">
|
|
31
|
+
<picture>
|
|
32
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/dcc-mcp-comfyui-dark.svg">
|
|
33
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/assets/dcc-mcp-comfyui.svg">
|
|
34
|
+
<img src="docs/assets/dcc-mcp-comfyui.svg" alt="DCC-MCP · COMFYUI" width="600">
|
|
35
|
+
</picture>
|
|
36
|
+
</p>
|
|
37
|
+
|
|
38
|
+
Production ComfyUI adapter for the DCC Model Context Protocol (MCP) ecosystem. It gives agents a typed, bounded path from API-format workflow validation to queue execution and artifact delivery through ComfyUI's local REST API.
|
|
39
|
+
|
|
40
|
+

|
|
41
|
+
|
|
42
|
+
_Illustrative workflow generated with OpenAI ImageGen from the retained source in `docs/assets/sources`; it depicts only the implemented validation, queue, polling, and artifact-delivery path._
|
|
43
|
+
|
|
44
|
+
## Capabilities
|
|
45
|
+
|
|
46
|
+
- `validate_workflow` checks API-format structure, graph references, live node classes, and required inputs against the running ComfyUI registry.
|
|
47
|
+
- `submit_workflow` validates before queue submission and can wait for a bounded terminal result.
|
|
48
|
+
- `query_job_status` returns status, node outputs, errors, and normalized artifact metadata.
|
|
49
|
+
- `get_artifact` builds a local download URL for a known output without exposing filesystem paths.
|
|
50
|
+
- Standalone discovery, packaged Skill subprocesses, and six-part DCC-MCP readiness are supported out of the box.
|
|
51
|
+
|
|
52
|
+
The production path was live-validated on ComfyUI 0.31.0 with a three-node `EmptyImage -> ImageInvert -> SaveImage` workflow, including typed CLI validation, execution, status polling, and artifact retrieval.
|
|
53
|
+
|
|
54
|
+
## Quick Start
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
# Install
|
|
58
|
+
pip install dcc-mcp-comfyui
|
|
59
|
+
|
|
60
|
+
# Start ComfyUI locally (in another terminal)
|
|
61
|
+
python main.py --listen 127.0.0.1
|
|
62
|
+
|
|
63
|
+
# Start the MCP server
|
|
64
|
+
dcc-mcp-comfyui --comfyui-base-url http://127.0.0.1:8188
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Environment Variables
|
|
68
|
+
|
|
69
|
+
| Variable | Default | Description |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| `DCC_MCP_COMFYUI_BASE_URL` | `http://127.0.0.1:8188` | ComfyUI server URL |
|
|
72
|
+
| `DCC_MCP_COMFYUI_TIMEOUT` | `120` | Request timeout (seconds) |
|
|
73
|
+
| `DCC_MCP_COMFYUI_PORT` | OS-assigned | MCP instance port |
|
|
74
|
+
| `DCC_MCP_GATEWAY_PORT` | `9765` | Gateway port |
|
|
75
|
+
| `DCC_MCP_COMFYUI_ENABLE_GATEWAY_FAILOVER` | `true` | Gateway failover |
|
|
76
|
+
|
|
77
|
+
## Skills
|
|
78
|
+
|
|
79
|
+
### comfyui-workflow
|
|
80
|
+
|
|
81
|
+
The bundled Skill for ComfyUI workflow management:
|
|
82
|
+
|
|
83
|
+
- `validate_workflow` — Validate workflow JSON structure
|
|
84
|
+
- `submit_workflow` — Submit workflow for execution
|
|
85
|
+
- `query_job_status` — Poll execution status and outputs
|
|
86
|
+
- `get_artifact` — Get download URL for output images
|
|
87
|
+
|
|
88
|
+
## MCP Client Config
|
|
89
|
+
|
|
90
|
+
```json
|
|
91
|
+
{
|
|
92
|
+
"mcpServers": {
|
|
93
|
+
"dcc-mcp-comfyui": {
|
|
94
|
+
"url": "http://127.0.0.1:9765/mcp"
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Build & Test
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
uv pip install -e ".[dev]"
|
|
104
|
+
uv run pytest
|
|
105
|
+
uv run ruff check src/ tests/
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Architecture
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
MCP Client → Gateway (:9765) → ComfyUiMcpServer (OS port)
|
|
112
|
+
└─ Skill scripts → ComfyUIBridge → ComfyUI REST API (:8188)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## License
|
|
116
|
+
|
|
117
|
+
MIT
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# dcc-mcp-comfyui
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<picture>
|
|
5
|
+
<source media="(prefers-color-scheme: dark)" srcset="docs/assets/dcc-mcp-comfyui-dark.svg">
|
|
6
|
+
<source media="(prefers-color-scheme: light)" srcset="docs/assets/dcc-mcp-comfyui.svg">
|
|
7
|
+
<img src="docs/assets/dcc-mcp-comfyui.svg" alt="DCC-MCP · COMFYUI" width="600">
|
|
8
|
+
</picture>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
Production ComfyUI adapter for the DCC Model Context Protocol (MCP) ecosystem. It gives agents a typed, bounded path from API-format workflow validation to queue execution and artifact delivery through ComfyUI's local REST API.
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
_Illustrative workflow generated with OpenAI ImageGen from the retained source in `docs/assets/sources`; it depicts only the implemented validation, queue, polling, and artifact-delivery path._
|
|
16
|
+
|
|
17
|
+
## Capabilities
|
|
18
|
+
|
|
19
|
+
- `validate_workflow` checks API-format structure, graph references, live node classes, and required inputs against the running ComfyUI registry.
|
|
20
|
+
- `submit_workflow` validates before queue submission and can wait for a bounded terminal result.
|
|
21
|
+
- `query_job_status` returns status, node outputs, errors, and normalized artifact metadata.
|
|
22
|
+
- `get_artifact` builds a local download URL for a known output without exposing filesystem paths.
|
|
23
|
+
- Standalone discovery, packaged Skill subprocesses, and six-part DCC-MCP readiness are supported out of the box.
|
|
24
|
+
|
|
25
|
+
The production path was live-validated on ComfyUI 0.31.0 with a three-node `EmptyImage -> ImageInvert -> SaveImage` workflow, including typed CLI validation, execution, status polling, and artifact retrieval.
|
|
26
|
+
|
|
27
|
+
## Quick Start
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Install
|
|
31
|
+
pip install dcc-mcp-comfyui
|
|
32
|
+
|
|
33
|
+
# Start ComfyUI locally (in another terminal)
|
|
34
|
+
python main.py --listen 127.0.0.1
|
|
35
|
+
|
|
36
|
+
# Start the MCP server
|
|
37
|
+
dcc-mcp-comfyui --comfyui-base-url http://127.0.0.1:8188
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Environment Variables
|
|
41
|
+
|
|
42
|
+
| Variable | Default | Description |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| `DCC_MCP_COMFYUI_BASE_URL` | `http://127.0.0.1:8188` | ComfyUI server URL |
|
|
45
|
+
| `DCC_MCP_COMFYUI_TIMEOUT` | `120` | Request timeout (seconds) |
|
|
46
|
+
| `DCC_MCP_COMFYUI_PORT` | OS-assigned | MCP instance port |
|
|
47
|
+
| `DCC_MCP_GATEWAY_PORT` | `9765` | Gateway port |
|
|
48
|
+
| `DCC_MCP_COMFYUI_ENABLE_GATEWAY_FAILOVER` | `true` | Gateway failover |
|
|
49
|
+
|
|
50
|
+
## Skills
|
|
51
|
+
|
|
52
|
+
### comfyui-workflow
|
|
53
|
+
|
|
54
|
+
The bundled Skill for ComfyUI workflow management:
|
|
55
|
+
|
|
56
|
+
- `validate_workflow` — Validate workflow JSON structure
|
|
57
|
+
- `submit_workflow` — Submit workflow for execution
|
|
58
|
+
- `query_job_status` — Poll execution status and outputs
|
|
59
|
+
- `get_artifact` — Get download URL for output images
|
|
60
|
+
|
|
61
|
+
## MCP Client Config
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"dcc-mcp-comfyui": {
|
|
67
|
+
"url": "http://127.0.0.1:9765/mcp"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Build & Test
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
uv pip install -e ".[dev]"
|
|
77
|
+
uv run pytest
|
|
78
|
+
uv run ruff check src/ tests/
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## Architecture
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
MCP Client → Gateway (:9765) → ComfyUiMcpServer (OS port)
|
|
85
|
+
└─ Skill scripts → ComfyUIBridge → ComfyUI REST API (:8188)
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## License
|
|
89
|
+
|
|
90
|
+
MIT
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dcc-mcp-comfyui"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "ComfyUI adapter for the DCC Model Context Protocol (MCP) ecosystem — bridges MCP tools to ComfyUI via REST + WebSocket API"
|
|
9
|
+
authors = [{ name = "Long Hao", email = "hal.long@outlook.com" }]
|
|
10
|
+
readme = "README.md"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
requires-python = ">=3.10"
|
|
13
|
+
keywords = ["comfyui", "stable-diffusion", "mcp", "dcc", "ai", "llm", "model-context-protocol", "workflow"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Topic :: Multimedia :: Graphics",
|
|
20
|
+
]
|
|
21
|
+
|
|
22
|
+
dependencies = [
|
|
23
|
+
"dcc-mcp-core>=0.19.91,<1.0.0",
|
|
24
|
+
"httpx>=0.25.0",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.optional-dependencies]
|
|
28
|
+
dev = [
|
|
29
|
+
"pytest>=7.0",
|
|
30
|
+
"pytest-mock>=3.0",
|
|
31
|
+
"pytest-asyncio>=0.23",
|
|
32
|
+
"ruff>=0.8.0",
|
|
33
|
+
"hatchling",
|
|
34
|
+
"build>=1.0",
|
|
35
|
+
"pyyaml>=6.0",
|
|
36
|
+
]
|
|
37
|
+
|
|
38
|
+
[project.urls]
|
|
39
|
+
Homepage = "https://github.com/dcc-mcp/dcc-mcp-comfyui"
|
|
40
|
+
Repository = "https://github.com/dcc-mcp/dcc-mcp-comfyui"
|
|
41
|
+
|
|
42
|
+
[project.scripts]
|
|
43
|
+
dcc-mcp-comfyui = "dcc_mcp_comfyui.cli:main"
|
|
44
|
+
|
|
45
|
+
[project.entry-points."dcc_mcp.adapters"]
|
|
46
|
+
comfyui = "dcc_mcp_comfyui:ComfyUiMcpServer"
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["src/dcc_mcp_comfyui"]
|
|
50
|
+
|
|
51
|
+
[tool.hatch.build.targets.sdist]
|
|
52
|
+
exclude = ["docs/**/*.png", "docs/**/*.svg", "docs/**/*.webp"]
|
|
53
|
+
|
|
54
|
+
[tool.pytest.ini_options]
|
|
55
|
+
testpaths = ["tests"]
|
|
56
|
+
python_files = ["test_*.py"]
|
|
57
|
+
addopts = "-v --tb=short"
|
|
58
|
+
asyncio_mode = "auto"
|
|
59
|
+
|
|
60
|
+
[tool.ruff]
|
|
61
|
+
line-length = 120
|
|
62
|
+
target-version = "py310"
|
|
63
|
+
|
|
64
|
+
[tool.ruff.lint]
|
|
65
|
+
select = ["E", "F", "I", "W"]
|
|
66
|
+
ignore = ["E501"]
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
3
|
+
"release-type": "python",
|
|
4
|
+
"include-v-in-tag": true,
|
|
5
|
+
"packages": {
|
|
6
|
+
".": {
|
|
7
|
+
"package-name": "dcc-mcp-comfyui",
|
|
8
|
+
"include-component-in-tag": false,
|
|
9
|
+
"release-type": "python",
|
|
10
|
+
"changelog-path": "CHANGELOG.md",
|
|
11
|
+
"bump-minor-pre-major": true,
|
|
12
|
+
"bump-patch-for-minor-pre-major": true,
|
|
13
|
+
"extra-files": [
|
|
14
|
+
{
|
|
15
|
+
"type": "toml",
|
|
16
|
+
"path": "pyproject.toml",
|
|
17
|
+
"jsonpath": "$.project.version"
|
|
18
|
+
},
|
|
19
|
+
"src/dcc_mcp_comfyui/skills/comfyui-workflow/SKILL.md"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"changelog-sections": [
|
|
24
|
+
{"type": "feat", "section": "Features", "hidden": false},
|
|
25
|
+
{"type": "fix", "section": "Bug Fixes", "hidden": false},
|
|
26
|
+
{"type": "perf", "section": "Performance Improvements", "hidden": false},
|
|
27
|
+
{"type": "refactor", "section": "Code Refactoring", "hidden": false},
|
|
28
|
+
{"type": "docs", "section": "Documentation", "hidden": false},
|
|
29
|
+
{"type": "style", "section": "Styles", "hidden": true},
|
|
30
|
+
{"type": "chore", "section": "Miscellaneous Chores", "hidden": true},
|
|
31
|
+
{"type": "test", "section": "Tests", "hidden": true},
|
|
32
|
+
{"type": "ci", "section": "Continuous Integration", "hidden": true},
|
|
33
|
+
{"type": "build", "section": "Build System", "hidden": true}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"""ComfyUI adapter for DCC MCP Core.
|
|
2
|
+
|
|
3
|
+
Provides MCP server bridging AI agents to ComfyUI workflow execution
|
|
4
|
+
via ComfyUI's REST + WebSocket API.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from dcc_mcp_comfyui.__version__ import __version__
|
|
8
|
+
from dcc_mcp_comfyui._env import (
|
|
9
|
+
DEFAULT_COMFYUI_BASE_URL,
|
|
10
|
+
DEFAULT_COMFYUI_TIMEOUT,
|
|
11
|
+
ENV_COMFYUI_BASE_URL,
|
|
12
|
+
ENV_COMFYUI_TIMEOUT,
|
|
13
|
+
ENV_ENABLE_GATEWAY_FAILOVER,
|
|
14
|
+
ENV_GATEWAY_PORT,
|
|
15
|
+
ENV_PORT,
|
|
16
|
+
resolve_comfyui_base_url,
|
|
17
|
+
resolve_comfyui_timeout,
|
|
18
|
+
resolve_enable_gateway_failover,
|
|
19
|
+
resolve_minimal_mode_enabled,
|
|
20
|
+
)
|
|
21
|
+
from dcc_mcp_comfyui.api import (
|
|
22
|
+
ComfyUINotAvailableError,
|
|
23
|
+
cf_error,
|
|
24
|
+
cf_from_exception,
|
|
25
|
+
cf_success,
|
|
26
|
+
get_bridge,
|
|
27
|
+
is_comfyui_available,
|
|
28
|
+
set_bridge,
|
|
29
|
+
with_comfyui,
|
|
30
|
+
)
|
|
31
|
+
from dcc_mcp_comfyui.bridge import (
|
|
32
|
+
ComfyUIBridge,
|
|
33
|
+
ComfyUIWorkflowError,
|
|
34
|
+
)
|
|
35
|
+
from dcc_mcp_comfyui.bridge import (
|
|
36
|
+
ComfyUINotAvailableError as BridgeNotAvailableError,
|
|
37
|
+
)
|
|
38
|
+
from dcc_mcp_comfyui.server import (
|
|
39
|
+
DEFAULT_PORT,
|
|
40
|
+
SERVER_NAME,
|
|
41
|
+
ComfyUiMcpServer,
|
|
42
|
+
ComfyUiServerOptions,
|
|
43
|
+
get_server,
|
|
44
|
+
start_server,
|
|
45
|
+
stop_server,
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
__all__ = [
|
|
49
|
+
"__version__",
|
|
50
|
+
"BridgeNotAvailableError",
|
|
51
|
+
"cf_error",
|
|
52
|
+
"cf_from_exception",
|
|
53
|
+
"cf_success",
|
|
54
|
+
"ComfyUIBridge",
|
|
55
|
+
"ComfyUINotAvailableError",
|
|
56
|
+
"ComfyUiMcpServer",
|
|
57
|
+
"ComfyUiServerOptions",
|
|
58
|
+
"ComfyUIWorkflowError",
|
|
59
|
+
"DEFAULT_COMFYUI_BASE_URL",
|
|
60
|
+
"DEFAULT_COMFYUI_TIMEOUT",
|
|
61
|
+
"DEFAULT_PORT",
|
|
62
|
+
"ENV_COMFYUI_BASE_URL",
|
|
63
|
+
"ENV_COMFYUI_TIMEOUT",
|
|
64
|
+
"ENV_ENABLE_GATEWAY_FAILOVER",
|
|
65
|
+
"ENV_GATEWAY_PORT",
|
|
66
|
+
"ENV_PORT",
|
|
67
|
+
"get_bridge",
|
|
68
|
+
"get_server",
|
|
69
|
+
"is_comfyui_available",
|
|
70
|
+
"resolve_comfyui_base_url",
|
|
71
|
+
"resolve_comfyui_timeout",
|
|
72
|
+
"resolve_enable_gateway_failover",
|
|
73
|
+
"resolve_minimal_mode_enabled",
|
|
74
|
+
"SERVER_NAME",
|
|
75
|
+
"set_bridge",
|
|
76
|
+
"start_server",
|
|
77
|
+
"stop_server",
|
|
78
|
+
"with_comfyui",
|
|
79
|
+
]
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Environment variable helpers for dcc-mcp-comfyui."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import logging
|
|
6
|
+
import os
|
|
7
|
+
from typing import Optional
|
|
8
|
+
|
|
9
|
+
logger = logging.getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
ENV_PORT = "DCC_MCP_COMFYUI_PORT"
|
|
12
|
+
ENV_GATEWAY_PORT = "DCC_MCP_GATEWAY_PORT"
|
|
13
|
+
ENV_COMFYUI_BASE_URL = "DCC_MCP_COMFYUI_BASE_URL"
|
|
14
|
+
ENV_COMFYUI_TIMEOUT = "DCC_MCP_COMFYUI_TIMEOUT"
|
|
15
|
+
ENV_ENABLE_GATEWAY_FAILOVER = "DCC_MCP_COMFYUI_ENABLE_GATEWAY_FAILOVER"
|
|
16
|
+
|
|
17
|
+
DEFAULT_COMFYUI_BASE_URL = "http://127.0.0.1:8188"
|
|
18
|
+
DEFAULT_COMFYUI_TIMEOUT = 120.0
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def _env_truthy(name: str) -> bool:
|
|
22
|
+
return os.environ.get(name, "").strip().lower() in ("1", "true", "yes", "on")
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def resolve_comfyui_base_url(value: Optional[str] = None) -> str:
|
|
26
|
+
"""Return the ComfyUI server base URL from arg, env, or default."""
|
|
27
|
+
if value:
|
|
28
|
+
return value.rstrip("/")
|
|
29
|
+
raw = os.environ.get(ENV_COMFYUI_BASE_URL, "").strip()
|
|
30
|
+
if raw:
|
|
31
|
+
return raw.rstrip("/")
|
|
32
|
+
return DEFAULT_COMFYUI_BASE_URL
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def resolve_comfyui_timeout(value: Optional[float] = None) -> float:
|
|
36
|
+
"""Return the ComfyUI request timeout from arg, env, or default."""
|
|
37
|
+
if value is not None:
|
|
38
|
+
return float(value)
|
|
39
|
+
raw = os.environ.get(ENV_COMFYUI_TIMEOUT, "").strip()
|
|
40
|
+
if raw:
|
|
41
|
+
try:
|
|
42
|
+
return float(raw)
|
|
43
|
+
except ValueError:
|
|
44
|
+
logger.warning("Invalid %s=%r; using default %.1f", ENV_COMFYUI_TIMEOUT, raw, DEFAULT_COMFYUI_TIMEOUT)
|
|
45
|
+
return DEFAULT_COMFYUI_TIMEOUT
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def resolve_enable_gateway_failover(value: Optional[bool]) -> bool:
|
|
49
|
+
if value is not None:
|
|
50
|
+
return value
|
|
51
|
+
raw = os.environ.get(ENV_ENABLE_GATEWAY_FAILOVER, "").strip()
|
|
52
|
+
if raw:
|
|
53
|
+
return _env_truthy(ENV_ENABLE_GATEWAY_FAILOVER)
|
|
54
|
+
return True
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def resolve_minimal_mode_enabled() -> bool:
|
|
58
|
+
raw = os.environ.get("DCC_MCP_MINIMAL", "1").strip().lower()
|
|
59
|
+
return raw not in ("0", "false", "no", "off")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def get_extra_skill_paths() -> list[str]:
|
|
63
|
+
"""Read ``DCC_MCP_COMFYUI_SKILL_PATHS`` and ``DCC_MCP_SKILL_PATHS``."""
|
|
64
|
+
sep = ";" if os.sep == "\\" else ":"
|
|
65
|
+
paths: list[str] = []
|
|
66
|
+
|
|
67
|
+
for env_var in ("DCC_MCP_COMFYUI_SKILL_PATHS", "DCC_MCP_SKILL_PATHS"):
|
|
68
|
+
raw = os.environ.get(env_var, "")
|
|
69
|
+
if raw:
|
|
70
|
+
for part in raw.split(sep):
|
|
71
|
+
part = part.strip()
|
|
72
|
+
if part:
|
|
73
|
+
paths.append(part)
|
|
74
|
+
|
|
75
|
+
return paths
|