> ## Documentation Index
> Fetch the complete documentation index at: https://comfyui-mcp.artokun.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Приложения (микроприложения)

> Превратите воркфлоу в приложение в один клик: манифест, открытая форма запуска и снимок API-промпта, в который на каждый запуск патчатся значения. Конвертируйте в панели, запускайте из панели, с телефона или агентом и публикуйте в публичный реестр.

**Приложение** — это воркфлоу, упакованный для запусков в один клик **без
холста**. Это каталог на вашей установке, в котором лежат четыре вещи:

| Файл            | Что это                                                                         |
| --------------- | ------------------------------------------------------------------------------- |
| `manifest.json` | имя, описание, `appMode {inputs, outputs}`, `deps`, `hideWorkflow`, `published` |
| `prompt.json`   | **снимок** промпта в API-формате — значения патчатся сюда на каждый запуск      |
| `workflow.json` | UI-граф litegraph — **отсутствует**, когда задан `hideWorkflow`                 |
| `thumbnail.png` | необязательная картинка карточки                                                |

Банды живут в пользовательском каталоге ComfyUI по пути
`<user>/comfyui-mcp-panel/apps/<app-id>/` — нарочно **не** в каталоге
воркфлоу, чтобы скрытое приложение никогда не всплывало в браузере воркфлоу.

```
workflow ⇄ convert (panel) ⇄ app bundle on disk ⇄ run form ⇄ patch snapshot ⇄ ComfyUI queue
                                    ⇅
                        publish / install ⇄ public registry
```

Причина, почему приложения существуют как свой слой: холст — неправильный
интерфейс, чтобы *запускать* воркфлоу, которому вы уже доверяете. Форма с
пятью подписанными полями — правильный, и это единственный интерфейс, которым
телефон или агент вообще могут управлять.

<Note>
  Хранение и запуск реализованы **один раз** — HTTP-маршруты пакета панели
  (`/comfyui_mcp_panel/apps/*`). Панель рабочего стола, вкладка «Приложения»
  на телефоне и MCP-инструменты `apps_*` — все клиенты этого, поэтому
  приложение ведёт себя одинаково, откуда бы вы его ни запустили.
</Note>

## Требования

Приложения обслуживает **пакет панели** (`comfyui-mcp-panel`), а не один
MCP-сервер. Если пакет на вашем ComfyUI старше этой возможности, `apps` с
`action:"list"` падает с явным сообщением *"the panel pack on this ComfyUI predates the Apps
feature"* — обновите пакет и перезапустите ComfyUI.

## Конвертация воркфлоу в приложение

В панели кнопка **«Приложения»** на панели инструментов (рядом с Civitai)
открывает сетку приложений. Конвертация открытого воркфлоу делает три вещи:

1. **Импортирует конфиг режима APP ComfyUI**, если воркфлоу его уже несёт, и
   иначе выбирает входы и выходы **эвристически** (виджеты промпта, сиды,
   настройки сэмплера; узлы класса `SaveImage` как выходы). Импортированные
   входы режима APP соблюдаются на **любом** типе узла, поэтому эндпоинты
   кастомных узлов переживают конвертацию.
2. **Сканирует зависимости** — модели и пакеты кастомных узлов, которые нужны
   графу — в `manifest.deps`.
3. **Снимает снимок промпта** в API-формате. Значения виджетов на момент
   конвертации становятся `default` формы каждого входа.

Каждый вход в `appMode.inputs` несёт `nodeId`, `widget`, `label` и `kind`
`text`, `number`, `combo`, `toggle`, `image` или `model`; combo ещё несут
`choices`. Именно из этого рисуется форма запуска — на рабочем столе и на
телефоне.

### Скрытие воркфлоу

`hideWorkflow` полностью выкидывает `workflow.json` из бандла, так что граф
не отдаётся тому, кто запускает или ставит приложение.

<Warning>
  **`hideWorkflow` — это обфускация, никогда не безопасность.** API-промпт
  по-прежнему виден любому, кто запустит приложение через собственный
  `/history` ComfyUI, а модели и кастомные узлы, которые приложение ставит,
  выдают зависимости графа. Считайте это «не засоряй мой браузер воркфлоу»,
  а не защитой графа, который нельзя светить.
</Warning>

## Запуск приложения

Запуск патчит значения формы в сохранённый снимок и ставит результат в
очередь. Ключи патча — `"<nodeId>.<widget>"` — например `{"6.text": "a cat",
"3.seed": 42}`. Ключ режется только по **первой** точке, поэтому имена
виджетов, которые сами содержат точки (стеки LoRA, `lora_1.model`), остаются
целыми.

Патчинг **строгий**: ключ, указывающий на узел или вход, которого нет в
снимке, — жёсткая ошибка, а не тихий пропуск. Промах значит, что манифест
разошёлся со снимком, и громкий отказ лучше, чем запуск с устаревшими
значениями. Входы, которые вы опускаете, сохраняют значения по умолчанию
времени конвертации.

Запуск возвращает `prompt_id`; опрашивайте его на статус (`pending` →
`running` → `done`, или `unknown`, если ComfyUI о нём никогда не слышал) и
на выходы, сгруппированные под каждым выходным узлом.

### Запуск на поде RunPod

Путь панели **«Запустить на RunPod»** переиспользует тот же движок патча в
режиме **dry**: панель просит пропатченный промпт *без* постановки в очередь
локально, пушит закреплённые зависимости на под и ставит промпт в очередь
там.

<Warning>
  Приложения с **входом изображения** отказываются запускаться на поде.
  Загрузки приземляются на **локальный** ComfyUI, до которого под не
  достучится — поэтому панель честно отказывается, вместо того чтобы ставить
  в очередь запуск, который упадёт на отсутствующем файле.
</Warning>

## Публикация и Обзор

Вкладка панели **«Обзор»** — публичный реестр (Cloudflare Worker на D1 + R2)
со списками популярного / нового / по звёздам и поиском. Популярность —
7-дневные `stars * 3 + runs`. Публикация загружает бандл — манифест, промпт,
воркфлоу если не скрыт, миниатюру — под идентификатором автора с ключом
sha256.

Установка из «Обзора» сначала показывает **диалог согласия на зависимости**:
`deps` приложения *сообщаются*, никогда не ставятся молча. Ничто не ставит
модель или пакет кастомных узлов на вашу установку только потому, что вы
нажали карточку.

<Note>
  `pricing_json` и `hosted_only` существуют в схеме манифеста и проходят
  без изменений, но никто их не читает. Они резервируют место под фазу
  монетизации только в дизайне — платного поведения приложений сегодня нет.
</Note>

## MCP-инструмент `apps`

Один инструмент с пятью действиями, все тонкие прокси над Apps API панели.
Это поверхность **без холста**: то, чем пользуются мобильное приложение и
напрямую управляемый агент. Он в белом списке `call_tool` оркестратора —
`list`/`get`/`run_status` только для чтения, а `run` несёт ту же позу риска,
что и `enqueue_workflow` (ставит в очередь задание, которое пользователь явно
нажал).

| Действие              | Эффект                                                                                                                                                                                            |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `action:"list"`       | Перечислить каждое приложение, зарегистрированное на этом ComfyUI — каждая запись это полный манифест плюс `has_workflow` / `has_prompt` / `has_thumbnail`. Других параметров нет. Только чтение. |
| `action:"get"`        | Манифест + факты бандла одного приложения по id. `appMode.inputs` — это форма запуска. Только чтение.                                                                                             |
| `action:"run"`        | Пропатчить `values` в снимок и поставить в очередь. Возвращает `prompt_id`.                                                                                                                       |
| `action:"run_status"` | Опросить один запуск по `prompt_id`: `status` плюс выходы запуска (ссылки на файлы изображений/видео по выходному узлу, текстовые выходы). Только чтение.                                         |
| `action:"import"`     | Установить приложение из публичного реестра на этот ComfyUI.                                                                                                                                      |

### Параметры

`action` — единственный обязательный по схеме параметр: каждому действию
нужен разный поднабор, поэтому остальные в схеме необязательны, а их наличие
проверяет обработчик, который называет поле, которого не хватает.

| Действие     | Параметр       | Тип                           | Заметки                                                      |
| ------------ | -------------- | ----------------------------- | ------------------------------------------------------------ |
| `get`        | `app_id`       | `string` (uuid), обязательный | из `action:"list"`                                           |
| `run`        | `app_id`       | `string` (uuid), обязательный |                                                              |
|              | `values`       | `object`, необязательный      | ключи `"<nodeId>.<widget>"`; неизвестные ключи громко падают |
| `run_status` | `app_id`       | `string` (uuid), обязательный |                                                              |
|              | `prompt_id`    | `string`, обязательный        | должен совпадать с `^[0-9a-zA-Z-]{1,64}$`                    |
| `import`     | `registry_url` | `string` (URL), обязательный  | должен быть реестром по умолчанию или разрешённым origin     |
|              | `app_id`       | `string` (uuid), обязательный | uuid приложения в **реестре**                                |
|              | `slug`         | `string`, необязательный      | записывается в локальные метаданные                          |
|              | `version`      | `integer`, необязательный     | записывается в локальные метаданные                          |

Ограничение формы `prompt_id` применяется **дважды** — на границе схемы и
ещё раз внутри обработчика — потому что id интерполируется в путь URL.
«Prompt id» в форме traversal никогда не должен дойти до сборщика URL, даже
если вызывающий обходит схему.

Сгенерированный справочник схемы по инструменту — в
[инструментах приложений](/docs/docs/tools/apps).

### Импорт из реестра

`action:"import"` забирает бандл реестра на стороне сервера и создаёт его как
локальное приложение. **Id реестра становится локальным id**, поэтому
повторный импорт приложения, которое у вас уже есть, сообщает конфликт id, а
не дублирует его. Миниатюра живёт на отдельном эндпоинте реестра и
забирается и пересылается отдельно, поэтому установленное приложение
сохраняет картинку карточки.

Зависимости **не** ставятся. Инструмент возвращает `deps` манифеста, чтобы
вызывающий мог их сообщить и дать пользователю поставить их намеренно.

<Warning>
  `registry_url` — это белый список, а не свободный URL. Запрос происходит
  **на сервере**, поэтому произвольный URL был бы примитивом SSRF — адреса
  loopback или LAN либо публичный URL, редиректящий в один из них. Принимается
  только публичный реестр по умолчанию, пока оператор не разрешит
  дополнительные origin через `COMFYUI_MCP_REGISTRY_URLS` (через запятую,
  задумано для dev/staging). Редиректы отклоняются сразу, а не следуются.
</Warning>

## Лимиты и валидация

То, во что можно реально упереться:

| Лимит               | Значение      | Где                                                                                                           |
| ------------------- | ------------- | ------------------------------------------------------------------------------------------------------------- |
| Бандл / prompt JSON | 16 МБ         | просторнее обычного графа, потому что промпт может нести изображения в base64                                 |
| Миниатюра           | 5 МБ          | декодируется и проверяется **до** любой записи, чтобы плохая миниатюра не оставила наполовину созданный бандл |
| Имя приложения      | 120 символов  | обрезается                                                                                                    |
| Описание            | 4000 символов | обрезается                                                                                                    |
| `choices` combo     | 200 записей   | обрезается                                                                                                    |
| Запрос реестра      | 16 МБ, 30 с   | проверяется и заявленный `content-length`, **и** фактические байты                                            |

Валидация, которую вы заметите:

* **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"`.

Это самая ясная вещь, которую телефон умеет, а чат нет — запустить настоящий
воркфлоу, с настоящими входами, без холста нигде в поле зрения.

## См. также

* [Инструменты приложений](/docs/docs/tools/apps) — сгенерированный справочник схемы по инструменту
* [Боковая панель](/docs/docs/ru/panel) — где приложения конвертируют, публикуют и смотрят
* [Мобильное приложение](/docs/docs/ru/mobile) — вкладка «Приложения» в контексте
* [Поды RunPod](/docs/docs/tools/runpod) — под, на который целится путь «Запустить на RunPod»
* [Дорожная карта](/docs/docs/ru/roadmap)
