Extensions/comfy-portal-endpoint
ComfyUI Extension

comfy-portal-endpoint

This is a ComfyUI extension that provides additional API endpoints functionality, primarily designed to support Comfy Portal - a modern iOS client application for ComfyUI.

By ShunL12324·Created 2 years ago·Updated a day ago· 36
ShunL12324/comfy-portal-endpoint
Nodes
On cloudLocal install
Stars36
Updateda day ago
Readme

ComfyUI Portal Endpoint

Version License: MIT ComfyUI

REST API extension for ComfyUI that handles workflow management and UI → API format conversion. Built for Comfy Portal.

Conversion runs in a headless Chromium browser (via Playwright) that loads the real ComfyUI frontend — ensuring full compatibility with all node types including custom nodes.

Installation

cd ComfyUI/custom_nodes
git clone https://github.com/ShunL12324/comfy-portal-endpoint

Or search comfy-portal-endpoint in ComfyUI Manager.

Restart ComfyUI — the extension auto-installs all dependencies (Playwright, Chromium, system libs on Linux) on first startup.

API

All endpoints are under ComfyUI's HTTP server. Prefix with /api when using the default proxy.

| Endpoint | Method | Description | |----------|--------|-------------| | /cpe/health | GET | Browser status | | /cpe/workflow/list | GET | List workflow files | | /cpe/workflow/get?filename= | GET | Read a workflow file | | /cpe/workflow/save | POST | Save a workflow file | | /cpe/workflow/convert | POST | Convert UI format → API format | | /cpe/workflow/get-and-convert?filename= | GET | Read + convert in one call (recommended) |

GET /cpe/health

Returns headless browser status: not_installed | not_initialized | initializing | ready | error

{ "status": "success", "browser": { "status": "ready" } }

GET /cpe/workflow/list

Lists all .json files in user/default/workflows/.

{
  "status": "success",
  "workflows": [
    { "filename": "my_workflow.json", "size": 4096, "modified": 1706000000.0 }
  ]
}

GET /cpe/workflow/get

| Param | Required | Description | |-------|----------|-------------| | filename | Yes | Path relative to workflows directory |

{ "status": "success", "filename": "my_workflow.json", "workflow": "<raw JSON string>" }

POST /cpe/workflow/save

| Field | Required | Description | |-------|----------|-------------| | workflow | Yes | Workflow JSON as string | | name | No | Filename (auto-generated if omitted) |

POST /cpe/workflow/convert

Post the workflow JSON object directly as the request body.

| Status | Meaning | |--------|---------| | 200 | Success | | 400 | Invalid body | | 503 | Browser unavailable |

{
  "status": "success",
  "data": {
    "workflow": {
      "1": {
        "inputs": { "ckpt_name": "model.safetensors" },
        "class_type": "CheckpointLoaderSimple",
        "_meta": { "title": "Load Checkpoint" }
      }
    }
  }
}

First request ~5–15s (cold start). Subsequent ~1–2s.

GET /cpe/workflow/get-and-convert

Same as /cpe/workflow/convert but reads the file server-side. Takes filename query param. Response includes an additional filename field.

How It Works

Client → HTTP → ComfyUI PromptServer
                    ↓
              comfy-portal-endpoint
                    ↓
              Headless Chromium (page pool)
              ┌──────────┐ ┌──────────┐
              │ Page 1   │ │ Page 2   │
              │ ComfyUI  │ │ ComfyUI  │
              │ Frontend │ │ Frontend │
              └──────────┘ └──────────┘

Each conversion request acquires a page from the pool, reloads it for clean state, runs graphToPrompt() via page.evaluate(), and returns the page to the pool. Default pool size is 2 for concurrent requests.

First request takes ~5–15s (browser cold start). Subsequent requests ~1–2s.

Troubleshooting

| Issue | Fix | |-------|-----| | 503 on convert | pip install playwright && python -m playwright install chromium | | Linux: missing .so libs | sudo python -m playwright install-deps | | Docker: browser won't launch | Add RUN playwright install-deps chromium to Dockerfile | | error in /cpe/health | Auto-recovers on next request. Check logs for details |

Known Limitations

  • Not compatible with ComfyUI-Login or any extension that blocks/intercepts the ComfyUI frontend from loading. The headless browser needs full access to the frontend to perform workflow conversion. This is expected behavior and we have no plans to address it.

Changelog

v1.2.1

  • Use ComfyUI native app.loadGraphData + app.graphToPrompt for workflow conversion so subgraph workflows expand correctly (fixes class_type: null / UNKNOWN_NODE in Comfy Portal)
  • Keep legacy __cpe_graphToPrompt fallback for older ComfyUI frontends
  • Wait for the native API specifically before converting. The previous readiness check accepted either the native API or the legacy helper, and the legacy helper is available ~8s earlier — so the native path above never actually ran, and virtual nodes (Note, Reroute) were emitted instead of dropped. Falling back to the legacy helper now logs a warning instead of happening silently
  • Stop reloading the page before every conversion. The frontend persists the open workflow and restores it asynchronously on load, which raced loadGraphData and could finish after it — so a conversion returned the previous workflow's graph, and every workflow converted to whatever was converted before it. Reloading is now only done on the retry path
  • Reject a converted graph containing nodes that aren't in the requested workflow. That failure returned wrong data rather than an error, which no caller could detect

v1.2.0

  • Page pool for concurrent conversions (default 2 pages)
  • Auto-install system deps on Linux (playwright install-deps)
  • Auto-install pip via get-pip.py fallback
  • Robust process cleanup via driver PID
  • Auto-replace broken pages in pool
  • Fixed duplicate log output

v1.1.0

  • Replaced WebSocket architecture with Playwright headless browser
  • Works on headless servers, Docker, cloud VMs
  • Auto-installs Playwright + Chromium on first startup
  • Added /cpe/health endpoint and auto-recovery

v1.0.2

  • Fixed array widget values, updated for ComfyUI frontend v1.9.10+
  • Improved group node handling and virtual node support

License

MIT © 2025 Shun.L