Банды живут в пользовательском каталоге ComfyUI по пути
<user>/comfyui-mcp-panel/apps/<app-id>/ — нарочно не в каталоге
воркфлоу, чтобы скрытое приложение никогда не всплывало в браузере воркфлоу.
Хранение и запуск реализованы один раз — HTTP-маршруты пакета панели
(
/comfyui_mcp_panel/apps/*). Панель рабочего стола, вкладка «Приложения»
на телефоне и MCP-инструменты apps_* — все клиенты этого, поэтому
приложение ведёт себя одинаково, откуда бы вы его ни запустили.Требования
Приложения обслуживает пакет панели (comfyui-mcp-panel), а не один
MCP-сервер. Если пакет на вашем ComfyUI старше этой возможности, apps с
action:"list" падает с явным сообщением “the panel pack on this ComfyUI predates the Apps
feature” — обновите пакет и перезапустите ComfyUI.
Конвертация воркфлоу в приложение
В панели кнопка «Приложения» на панели инструментов (рядом с Civitai) открывает сетку приложений. Конвертация открытого воркфлоу делает три вещи:- Импортирует конфиг режима APP ComfyUI, если воркфлоу его уже несёт, и
иначе выбирает входы и выходы эвристически (виджеты промпта, сиды,
настройки сэмплера; узлы класса
SaveImageкак выходы). Импортированные входы режима APP соблюдаются на любом типе узла, поэтому эндпоинты кастомных узлов переживают конвертацию. - Сканирует зависимости — модели и пакеты кастомных узлов, которые нужны
графу — в
manifest.deps. - Снимает снимок промпта в API-формате. Значения виджетов на момент
конвертации становятся
defaultформы каждого входа.
appMode.inputs несёт nodeId, widget, label и kind
text, number, combo, toggle, image или model; combo ещё несут
choices. Именно из этого рисуется форма запуска — на рабочем столе и на
телефоне.
Скрытие воркфлоу
hideWorkflow полностью выкидывает workflow.json из бандла, так что граф
не отдаётся тому, кто запускает или ставит приложение.
Запуск приложения
Запуск патчит значения формы в сохранённый снимок и ставит результат в очередь. Ключи патча —"<nodeId>.<widget>" — например {"6.text": "a cat", "3.seed": 42}. Ключ режется только по первой точке, поэтому имена
виджетов, которые сами содержат точки (стеки LoRA, lora_1.model), остаются
целыми.
Патчинг строгий: ключ, указывающий на узел или вход, которого нет в
снимке, — жёсткая ошибка, а не тихий пропуск. Промах значит, что манифест
разошёлся со снимком, и громкий отказ лучше, чем запуск с устаревшими
значениями. Входы, которые вы опускаете, сохраняют значения по умолчанию
времени конвертации.
Запуск возвращает prompt_id; опрашивайте его на статус (pending →
running → done, или unknown, если ComfyUI о нём никогда не слышал) и
на выходы, сгруппированные под каждым выходным узлом.
Запуск на поде RunPod
Путь панели «Запустить на RunPod» переиспользует тот же движок патча в режиме dry: панель просит пропатченный промпт без постановки в очередь локально, пушит закреплённые зависимости на под и ставит промпт в очередь там.Публикация и Обзор
Вкладка панели «Обзор» — публичный реестр (Cloudflare Worker на D1 + R2) со списками популярного / нового / по звёздам и поиском. Популярность — 7-дневныеstars * 3 + runs. Публикация загружает бандл — манифест, промпт,
воркфлоу если не скрыт, миниатюру — под идентификатором автора с ключом
sha256.
Установка из «Обзора» сначала показывает диалог согласия на зависимости:
deps приложения сообщаются, никогда не ставятся молча. Ничто не ставит
модель или пакет кастомных узлов на вашу установку только потому, что вы
нажали карточку.
pricing_json и hosted_only существуют в схеме манифеста и проходят
без изменений, но никто их не читает. Они резервируют место под фазу
монетизации только в дизайне — платного поведения приложений сегодня нет.MCP-инструмент apps
Один инструмент с пятью действиями, все тонкие прокси над Apps API панели.
Это поверхность без холста: то, чем пользуются мобильное приложение и
напрямую управляемый агент. Он в белом списке call_tool оркестратора —
list/get/run_status только для чтения, а run несёт ту же позу риска,
что и enqueue_workflow (ставит в очередь задание, которое пользователь явно
нажал).
Параметры
action — единственный обязательный по схеме параметр: каждому действию
нужен разный поднабор, поэтому остальные в схеме необязательны, а их наличие
проверяет обработчик, который называет поле, которого не хватает.
Ограничение формы
prompt_id применяется дважды — на границе схемы и
ещё раз внутри обработчика — потому что id интерполируется в путь URL.
«Prompt id» в форме traversal никогда не должен дойти до сборщика URL, даже
если вызывающий обходит схему.
Сгенерированный справочник схемы по инструменту — в
инструментах приложений.
Импорт из реестра
action:"import" забирает бандл реестра на стороне сервера и создаёт его как
локальное приложение. Id реестра становится локальным id, поэтому
повторный импорт приложения, которое у вас уже есть, сообщает конфликт id, а
не дублирует его. Миниатюра живёт на отдельном эндпоинте реестра и
забирается и пересылается отдельно, поэтому установленное приложение
сохраняет картинку карточки.
Зависимости не ставятся. Инструмент возвращает deps манифеста, чтобы
вызывающий мог их сообщить и дать пользователю поставить их намеренно.
Лимиты и валидация
То, во что можно реально упереться:
Валидация, которую вы заметите:
- Id приложений должны быть uuid. Всё остальное отклоняется, прежде чем строится путь, и разрешённый путь бандла повторно проверяется на вложенность под корень приложений.
- Промпт должен быть в API-формате — числовые ключи node-id, каждый узел
объект
{class_type, inputs}. Графы в UI-формате отклоняются. - UI-воркфлоу обязателен, если не задан
hideWorkflow. - Создание приложения, которое уже существует — конфликт, а не перезапись.
- Частичные обновления манифеста действительно частичные. Публикация или
скрытие приложения отправляет только свои поля и не затрёт ваше имя,
описание или
appMode. - Неизвестные ключи манифеста отбрасываются, кроме зарезервированных полей pass-through, поэтому более старая установка игнорирует поля, которых не понимает, вместо того чтобы падать.
COMFYUI_MCP_APPS_DIR (в первую
очередь для тестов); по умолчанию он выводится из собственного
пользовательского каталога ComfyUI, поэтому переживает портативные установки.
На телефоне
Мобильное приложение поставляет настоящую вкладку «Приложения» — не превью. У неё две половины:- Мои приложения — приложения, установленные на вашей установке,
перечисленные через мост через
action:"list". Нажатие открывает сгенерированную форму запуска, ставит в очередь черезaction:"run"и опрашиваетaction:"run_status"каждые 2 с (ограничено 30 минутами), пока не отрисуются выходы. - Обзор — публичный реестр, запрос напрямую по HTTPS с телефона
(без прыжка через мост, поэтому обзор работает до сопряжения). Установка
идёт в другую сторону: установка сама забирает бандл через
action:"import".
См. также
- Инструменты приложений — сгенерированный справочник схемы по инструменту
- Боковая панель — где приложения конвертируют, публикуют и смотрят
- Мобильное приложение — вкладка «Приложения» в контексте
- Поды RunPod — под, на который целится путь «Запустить на RunPod»
- Дорожная карта