번들은 ComfyUI 사용자 디렉터리 아래
<user>/comfyui-mcp-panel/apps/<app-id>/에 있습니다 — 의도적으로 워크플로우
디렉터리가 아닙니다. 숨겨진 앱이 워크플로우 브라우저에 나타나지 않게.
저장과 실행 구현은 하나입니다 — 패널 팩의 HTTP 라우트
(
/comfyui_mcp_panel/apps/*). 데스크톱 패널, 모바일 앱 탭, 그리고
apps_* MCP 도구는 모두 그 클라이언트이므로, 어디서 실행하든 앱은
똑같이 동작합니다.요구 사항
앱은 MCP 서버만이 아니라 패널 팩 (comfyui-mcp-panel)이
제공합니다. ComfyUI의 팩이 이 기능보다 오래되면, apps의
action:"list"가 *“the panel pack on this ComfyUI predates the Apps
feature”*라는 명시적 메시지로 실패합니다 — 팩을 업데이트하고 ComfyUI를 재시작하세요.
워크플로우를 앱으로 변환하기
패널에서 앱 툴바 버튼(Civitai 옆)이 앱 그리드를 엽니다. 열린 워크플로우를 변환하면 세 가지를 합니다:- 워크플로우가 이미 가지고 있으면 ComfyUI APP-모드 설정을 가져오고,
없으면 입력과 출력을 휴리스틱으로 고릅니다 (프롬프트 위젯, 시드,
샘플러 설정. 출력은
SaveImage계열 노드). 가져온 APP-모드 입력은 어떤 노드 타입이든 존중되므로, 커스텀 노드 엔드포인트가 변환을 견딥니다. - 의존성을 스캔합니다 — 그래프가 필요로 하는 모델과 커스텀 노드 팩을
manifest.deps로. - API 형식으로 프롬프트를 스냅샷합니다. 변환 시점의 위젯 값이
각 입력의 폼
default가 됩니다.
appMode.inputs의 각 입력은 nodeId, widget, label, 그리고
text, number, combo, toggle, image, 또는 model의 kind를
가집니다. 콤보는 choices도 가집니다. 실행 폼이 데스크톱과 모바일에서
렌더링하는 것이 그것입니다.
워크플로우 숨기기
hideWorkflow는 번들에서 workflow.json을 완전히 빼므로, 그래프가
앱을 실행하거나 설치하는 사람에게 건네지지 않습니다.
앱 실행하기
실행은 폼 값을 저장된 스냅샷에 패치하고 결과를 대기열에 넣습니다. 패치 키는"<nodeId>.<widget>"입니다 — 예를 들어 {"6.text": "a cat", "3.seed": 42}. 키는 첫 점만으로 갈라지므로, 점 자체를 담은
위젯 이름(LoRA 스택, lora_1.model)은 그대로 남습니다.
패치는 엄격합니다: 스냅샷에 없는 노드나 입력을 가리키는 키는
조용한 건너뛰기가 아니라 무조건 오류입니다. 빗나감은 매니페스트가
스냅샷에서 어긋났다는 뜻이고, 오래된 값으로 실행하는 것보다 크게
실패하는 편이 낫습니다. 생략한 입력은 변환 시점 기본값을 유지합니다.
실행은 prompt_id를 반환합니다. 상태를 폴링하세요 (pending → running →
done, ComfyUI가 들어 본 적 없으면 unknown) 그리고 각 출력 노드 아래
묶인 출력을.
RunPod 파드에서 실행하기
패널의 RunPod에서 실행 경로는 같은 패치 엔진을 dry 모드로 재사용합니다: 패널이 로컬에서 대기열에 넣지 않고 패치된 프롬프트를 요청하고, 고정된 의존성을 파드에 밀어 넣은 뒤, 그 대신 거기서 프롬프트를 대기열에 넣습니다.게시와 Explore
패널의 Explore 탭은 공개 레지스트리입니다 (D1 + R2를 뒷배로 하는 Cloudflare Worker). 트렌딩 / 새로움 / 별이 많은 목록과 검색이 있습니다. 트렌딩은 7일stars * 3 + runs입니다. 게시는 번들 — 매니페스트, 프롬프트,
숨기지 않았다면 워크플로우, 썸네일 — 을 sha256 키 크리에이터 신원 아래
업로드합니다.
Explore에서 설치하면 먼저 의존성 동의 대화상자가 보입니다: 앱의
deps는 보고될 뿐, 조용히 설치되지 않습니다. 카드를 탭했다고 해서
장비에 모델이나 커스텀 노드 팩이 설치되지 않습니다.
pricing_json과 hosted_only는 매니페스트 스키마에 있고 그대로
통과하지만, 아무것도 읽지 않습니다. 설계 전용 수익화 단계를 위한
자리를 예약합니다 — 오늘 유료 앱 동작은 없습니다.apps MCP 도구
액션 다섯 개의 도구 하나, 모두 패널의 Apps API 위 얇은 프록시입니다.
캔버스 없는 표면입니다: 모바일 앱과 직접 구동되는 에이전트가 쓰는 것.
오케스트레이터의 call_tool 화이트리스트에 있습니다 — list/get/run_status는
읽기 전용이고, run은 enqueue_workflow와 같은 위험 자세를 가집니다
(사용자가 명시적으로 탭한 작업을 대기열에 넣음).
매개변수
action만 스키마 필수 매개변수입니다 — 각 액션이 다른
부분집합을 필요로 하므로, 나머지는 스키마에서 선택 사항이고 존재는
핸들러가 강제하며, 빠진 필드 이름을 말합니다.
prompt_id 형태 제약은 두 번 강제됩니다 — 스키마 경계에서,
그리고 다시 핸들러 안에서 — id가 URL 경로에 보간되기 때문입니다.
순회 형태의 “프롬프트 id”가 스키마를 우회한 호출자라도 URL
빌더에 닿아서는 안 됩니다.
생성된 도구별 스키마 레퍼런스는
앱 도구를 참고하세요.
레지스트리에서 가져오기
action:"import"는 서버 측에서 레지스트리 번들을 가져와 로컬
앱으로 만듭니다. 레지스트리 id가 로컬 id가 되므로, 이미 가진
앱을 다시 가져오면 복제하는 대신 id 충돌을 보고합니다. 썸네일은
별도 레지스트리 엔드포인트에 있으며 따로 가져와 전달되므로,
설치된 앱이 카드 아트를 유지합니다.
의존성은 설치되지 않습니다. 도구가 매니페스트의 deps를 반환하므로
호출자가 보고하고 사용자가 의도적으로 설치하게 합니다.
제한과 유효성 검사
실제로 부딪힐 수 있는 것:
눈에 띄는 유효성 검사:
- 앱 id는 uuid여야 합니다. 그 외는 경로가 만들어지기 전에 거부되며, 해석된 번들 경로는 앱 루트 아래 포함인지 다시 검사됩니다.
- 프롬프트는 API 형식이어야 합니다 — 숫자 노드 id 키, 각 노드는
{class_type, inputs}객체. UI 형식 그래프는 거부됩니다. hideWorkflow가 설정되지 않는 한 UI 워크플로우가 필요합니다.- 이미 있는 앱을 만드는 것은 덮어쓰기가 아니라 충돌입니다.
- 부분 매니페스트 업데이트는 정말로 부분입니다. 앱을 게시하거나 숨기면
자기 필드만 보내고 이름, 설명, 또는
appMode를 지우지 않습니다. - 알 수 없는 매니페스트 키는 버려집니다. 예약된 통과 필드는 제외. 그래서 오래된 장비는 이해하지 못하는 필드에서 실패하는 대신 무시합니다.
COMFYUI_MCP_APPS_DIR로 재정의할 수 있습니다 (주로 테스트용).
기본값은 ComfyUI 자체 사용자 디렉터리에서 파생되므로, 포터블
설치에서도 살아남습니다.
휴대폰에서
모바일 앱은 실제 앱 탭을 제공합니다 — 미리보기가 아닙니다. 두 절반이 있습니다:- 내 앱 — 장비에 설치된 앱, 브리지를 통해
action:"list"로 나열. 하나를 탭하면 생성된 실행 폼이 열리고,action:"run"으로 대기열에 넣고, 출력이 렌더될 때까지 2초마다action:"run_status"를 폴링합니다 (30분으로 묶임). - Explore — 공개 레지스트리, 휴대폰에서 직접 HTTPS로 칩니다
(브리지 홉 없음, 그래서 페어링 전에도 둘러보기가 동작). 설치는
반대 방향입니다: 장비가
action:"import"로 번들을 스스로 가져옵니다.