RunComfy MCP
MCP-сервер для платформы RunComfy: Serverless API (ComfyUI), Model API и Trainer API. Управляйте развёртываниями, запускайте размещённые модели, обучайте LoRA и получайте результаты с помощью AI-ассистентов, таких как Claude, Cursor и Windsurf.
Endpoint: https://mcp.runcomfy.com/mcp
Документация: docs.runcomfy.com/mcp
Возможности
31 инструмент, которые в точности повторяют документацию RunComfy и охватывают три продукта, а также баланс аккаунта.
Serverless API (ComfyUI) — собственные рабочие процессы на выделенных endpoint
Документация: docs.runcomfy.com/serverless
| Категория | Инструменты |
|---|---|
| Управление развёртываниями | list_deployments, get_deployment, create_deployment, update_deployment, delete_deployment |
| Инференс | submit_request, get_request_status, get_request_result, cancel_request |
| Расширенные возможности | call_instance_proxy |
Model API — размещённые модели из каталога, доступные по запросу
Документация: docs.runcomfy.com/model-apis
| Категория | Инструменты |
|---|---|
| Каталог | list_models, get_model, list_model_categories |
| Инференс | run_model, get_model_request_status, get_model_request_result, cancel_model_request |
Развёртывание не требуется, оплата взимается за каждый запрос. Инструмент list_models позволяет искать модели в каталоге по ключевому слову или возможностям (category=image-to-video). Инструмент get_model возвращает схему входных данных модели: типы и значения по умолчанию свойств, допустимые значения и диапазоны. С помощью run_model можно запустить модель. Таким образом, ассистент может перейти от запроса «создай видео» к корректному запросу, не выходя за пределы инструментов и не подбирая параметры наугад.
В записях также указаны description, base_price_usd за price_unit и model_url — ссылка на страницу модели.
model_id — это идентификатор со страницы модели на runcomfy.com/models, включая косые черты. Например: blackforestlabs/flux-1-kontext/pro/edit. Для файловых входных данных требуются общедоступные URL с HTTPS.
Trainer API — наборы данных и обучение LoRA с помощью AI Toolkit
Документация: docs.runcomfy.com/trainer-apis
| Категория | Инструменты |
|---|---|
| Наборы данных | create_dataset, list_datasets, get_dataset_status, delete_dataset |
| Загрузка файлов в наборы данных | upload_dataset_file_from_url, upload_dataset_text_file, get_dataset_upload_urls |
| Задачи обучения | submit_training_job, get_training_job_status, get_training_job_result, cancel_training_job, resume_training_job, edit_training_job |
Типичный процесс: создать набор данных → загрузить медиафайлы и соответствующие подписи в формате .txt →
дождаться статуса READY → отправить задачу с конфигурацией AI Toolkit в формате YAML → отслеживать её статус
→ получить контрольные точки из результата.
Сервер работает удалённо и не может читать локальные файлы. Загрузите доступные по HTTP медиафайлы с помощью upload_dataset_file_from_url, добавьте подписи непосредственно в запросе через upload_dataset_text_file, а для локальных файлов или файлов размером более 150 MB используйте get_dataset_upload_urls и самостоятельно отправьте данные методом PUT на подписанный URL.
Аккаунт
| Категория | Инструменты |
|---|---|
| Баланс | get_balance |
Все три продукта используют общий кошелёк. Инструмент get_balance показывает остаток средств в полях balance_usd — для удобного просмотра — и balance_microdollars — для проверки точных пороговых значений в миллионных долях доллара. Данные поступают с api.runcomfy.net, а не из отдельных источников для каждого продукта, поскольку баланс общий.
Взаимодействие между продуктами
Обученную LoRA можно запускать без развёртывания: передайте model_id базовой модели в run_model, а LoRA укажите как входные данные, например:
{"lora": {"path": "my_first_lora_3000.safetensors"}} — можно использовать имя из раздела LoRA Assets или общедоступный URL, например URL контрольной точки из get_training_job_result. Чтобы создать выделенный endpoint с выбранным оборудованием, разверните модель и воспользуйтесь инструментами Serverless API.
Быстрая настройка
Для аутентификации в каждом клиенте используется API-токен RunComfy со страницы Профиль. Передать его можно двумя способами:
-
Заголовок с API-токеном — подходит для любого клиента Streamable HTTP. Самый простой вариант и единственный доступный для клиентов без браузерного потока OAuth.
-
OAuth через браузер — токен не нужно хранить в конфигурационном файле. Поддерживается Claude.ai, Cursor и локальными клиентами, которые регистрируют loopback callback, например Claude Code.
Claude Code
Заголовок с токеном — достаточно выполнить одну команду:
claude mcp add --transport http runcomfy https://mcp.runcomfy.com/mcp --header "Authorization: Bearer YOUR_RUNCOMFY_TOKEN"
Или используйте OAuth через браузер: не указывайте заголовок, затем выполните /mcp в Claude Code и выберите
Authenticate:
claude mcp add --transport http runcomfy https://mcp.runcomfy.com/mcp
--transport http — транспорт Streamable HTTP. Значение streamable-http Claude Code не принимает; одиночный дефис в параметрах -transport и -header также недопустим. В обоих случаях команда завершится ошибкой, даже не обратившись к серверу.
Проверьте подключение командой claude mcp list: в списке должно появиться runcomfy: connected.
Claude.ai
Добавьте https://mcp.runcomfy.com/mcp в разделе **Settings → Connectors → Add custom
connector**, затем выберите Connect. Claude обнаружит конечные точки OAuth 2.1 RunComfy, откроет страницу подтверждения RunComfy и запросит один из API-токенов, указанных в вашем профиле RunComfy. RunComfy проверяет токен и сохраняет его в зашифрованном виде в разрешении MCP; Claude его не получает.
Cursor
Файл .cursor/mcp.json:
{
"mcpServers": {
"runcomfy": {
"url": "https://mcp.runcomfy.com/mcp",
"headers": { "Authorization": "Bearer YOUR_RUNCOMFY_TOKEN" }
}
}
}
VS Code (Copilot)
Файл .vscode/mcp.json:
{
"servers": {
"runcomfy": {
"type": "http",
"url": "https://mcp.runcomfy.com/mcp",
"headers": { "Authorization": "Bearer YOUR_RUNCOMFY_TOKEN" }
}
}
}
Windsurf
Settings → MCP:
{
"mcpServers": {
"runcomfy": {
"serverUrl": "https://mcp.runcomfy.com/mcp",
"headers": { "Authorization": "Bearer YOUR_RUNCOMFY_TOKEN" }
}
}
}
Другие клиенты
-
URL:
https://mcp.runcomfy.com/mcp -
Транспорт: Streamable HTTP
-
Аутентификация:
Authorization: Bearerв каждом запросе или OAuth 2.1 с loopback redirect URI либо точным callback, поддерживаемым клиентом
Устранение неполадок
| Симптом | Причина |
|---|---|
401 с сообщением RunComfy rejected this API token | Токен неверен, истёк или был скопирован не полностью. Создайте новый на странице Профиль — в теле ответа указано, как устранить проблему. |
401 без error_description | До сервера не дошёл заголовок Authorization. Убедитесь, что значение заголовка заключено в кавычки как один аргумент: --header "Authorization: Bearer ...". |
invalid_client_metadata при OAuth | Клиент зарегистрировал callback, который не входит в список разрешённых loopback-адресов и точных адресов клиента. Используйте поддерживаемый callback или заголовок с токеном. |
invalid_target при OAuth | Указанный URL должен точно совпадать с https://mcp.runcomfy.com/mcp — без завершающего слеша. Согласно RFC 8707, токен привязывается именно к этому ресурсу. |
503 с заголовком Retry-After | Не удалось связаться с API RunComfy для проверки токена. Повторите запрос. |
429 | С одного IP-адреса поступает более 600 запросов в минуту с аутентификацией по токену. |
Чтобы отозвать доступ, создайте новый токен в профиле RunComfy. Это сделает недействительными заголовок с токеном и все разрешения OAuth, созданные на его основе: каждый запрос MCP повторно проверяет токен в RunComfy.
Архитектура
MCP Client ──RunComfy API token──┐
│ Cloudflare Worker (/mcp)
MCP Client ──MCP OAuth token─────┤ validates the credential, resolves
│ it to one user's RunComfy token
▼
Cloudflare Container
(Python FastMCP app)
│ request-scoped RunComfy credential
┌───────────────┼───────────────┐
▼ ▼ ▼
api.runcomfy.net model-api. trainer-api.
(Serverless) runcomfy.net runcomfy.net
(Model) (Trainer)
Один токен RunComfy используется для аутентификации во всех трёх продуктах, поэтому разрешение учётных данных выполняется одинаково для всех инструментов.
Оба типа учётных данных преобразуются в один и тот же заголовок идентификации, заданный для запроса, ещё до обращения к контейнеру. Они различаются по формату: OAuth access tokens всегда имеют вид userId:grantId:secret, а токен RunComfy API никогда не содержит двоеточий.
-
Cloudflare Worker (
src/index.ts) — сервер авторизации OAuth 2.1 и граница защищённого ресурса. Отсутствующие, недействительные, просроченные учётные данные и учётные данные с неверной аудиторией отклоняются до инициализации MCP или обнаружения инструментов. -
Прямой токен API (
src/index.ts) — токен RunComfy Profile, переданный в заголовкеAuthorization: Bearer, повторно проверяется черезapi.runcomfy.netпри каждом запросе, ограничивается по частоте использования для каждого IP-адреса источника и никогда не пересылается без изменений. -
Согласие OAuth (
src/oauth-bridge.ts) — проверяет существующий токен RunComfy Profile, сохраняет его только в зашифрованных данных OAuth grant и выдаёт отдельный MCP access token, привязанный к аудитории. Динамическая регистрация клиентов принимает callback-адреса loopback (Claude Code и другие локальные клиенты), точный список разрешённых callback-адресов хостируемых клиентов и точный legacy app callback для Cursor. Cursor регистрирует вместеcursor://anysphere.cursor-mcp/oauth/callback,https://www.cursor.com/agents/mcp/oauth/callbackиhttp://localhost:8787/callback; должны приниматься все три адреса, даже если в качестве активного redirect используется localhost. Произвольные пользовательские протоколы и варианты callback-адресов по-прежнему отклоняются; S256 PKCE обязателен. -
Контейнер Python (
server.py) — приложение FastMCP с 31 инструментом для API Serverless, Model и Trainer. У него нет общих учётных данных оператора; при отсутствии токена RunComfy текущего пользователя, привязанного к запросу и переданного аутентифицированным пограничным компонентом, запрос завершается отказом. -
Cloudflare Container запускается автоматически при первом запросе и переходит в режим ожидания после 10 минут бездействия.
Структура проекта
.github/workflows/deploy.yml CI: typecheck, test, deploy to Cloudflare
src/index.ts Cloudflare Worker entrypoint
src/oauth-bridge.ts OAuth consent and RunComfy token validation
server.py MCP tool definitions (31 tools)
runcomfy_client.py RunComfy API clients (serverless, model, trainer)
container_app.py ASGI middleware (request IDs, token forwarding)
container_entrypoint.py Uvicorn startup
container_runtime.py Env validation, structured logging
wrangler.jsonc Cloudflare Worker + Container config
Dockerfile Container image
.env.example Local dev config
Локальная разработка
# Python 3.11+
python3.11 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
python -m container_entrypoint
Локальные адреса:
-
http://127.0.0.1:8000/healthz -
http://127.0.0.1:8000/mcp
В локальном endpoint Python намеренно не предусмотрены общие резервные учётные данные.
Защищённые вызовы инструментов должны проходить через аутентифицированную границу Worker.
Развёртывание
При отправке изменений в main развёртывание запускается автоматически через .github/workflows/deploy.yml:
сначала должны успешно пройти проверка типов, тесты Worker и тесты контейнера, после чего
wrangler deploy --containers-rollout immediate развёртывает Worker и контейнер
Python одновременно. Для pull request выполняются те же проверки, но без
развёртывания. Запустить workflow вручную также можно на вкладке Actions.
Необходим один секрет репозитория:
| Секрет | Назначение |
|---|---|
CLOUDFLARE_API_TOKEN | Токен с разрешением Edit Cloudflare Workers для аккаунта, указанного в wrangler.jsonc |
CLOUDFLARE_ACCOUNT_ID | Необязательный параметр. account_id уже указан в wrangler.jsonc; задайте это значение только для развёртывания в другом аккаунте. |
Чтобы выполнить развёртывание вручную (требуется платный план Cloudflare Workers с включённой поддержкой Containers):
npm install
npm run check
npm test
npx wrangler deploy --containers-rollout immediate
MCP endpoint будет доступен по адресу https://mcp.runcomfy.com/mcp (пользовательский домен настроен в wrangler.jsonc).
Переменные среды и bindings
Общий секрет с ключом RunComfy API намеренно не используется. Состояние OAuth хранится
в binding OAUTH_KV, а каждый запрос к вышестоящему сервису связан с пользователем,
который авторизовал OAuth grant.
Переменные Worker (в wrangler.jsonc)
| Имя | Значение по умолчанию | Описание |
|---|---|---|
CONTAINER_INSTANCE_NAME | runcomfy-unified | Имя экземпляра Durable Object |
CONTAINER_STARTUP_TIMEOUT_MS | 15000 | Максимальное время ожидания запуска контейнера |
CONTAINER_PORT_READY_TIMEOUT_MS | 30000 | Максимальное время ожидания готовности порта |
MCP_MAX_BODY_BYTES | 1048576 | Максимальный размер тела запроса |
OPENAI_APPS_CHALLENGE | Текущий токен для отправки | Общедоступный токен проверки домена OpenAI, который без изменений возвращается по адресу GET /.well-known/openai-apps-challenge; если значение не задано или пустое, возвращается 404. Перед заменой существующего токена убедитесь, что вы подтвердили право собственности на него. |
MCP_DIRECT_TOKEN_RATE_LIMITER | 600 / 60s | Лимит запросов /mcp с аутентификацией по токену API для каждого IP-адреса |
RUNCOMFY_SERVERLESS_BASE_URL | https://api.runcomfy.net | Базовый URL Serverless API |
RUNCOMFY_MODEL_API_BASE_URL | https://model-api.runcomfy.net | Базовый URL Model API |
RUNCOMFY_TRAINER_API_BASE_URL | https://trainer-api.runcomfy.net | Базовый URL Trainer API |
Локальная разработка на Python (файл .env)
| Имя | Обязательно | Описание |
|---|---|---|
RUNCOMFY_SERVERLESS_BASE_URL | Нет | Переопределяет базовый URL Serverless (по умолчанию: https://api.runcomfy.net) |
RUNCOMFY_MODEL_API_BASE_URL | Нет | Переопределяет базовый URL Model API (по умолчанию: https://model-api.runcomfy.net) |
RUNCOMFY_TRAINER_API_BASE_URL | Нет | Переопределяет базовый URL Trainer API (по умолчанию: https://trainer-api.runcomfy.net) |
RUNCOMFY_MCP_MOUNT_PREFIX | Нет | Префикс пути для монтирования MCP (по умолчанию: пустой) |