MCP Apps vs обычный tool output: когда AI-интеграции нужен UI
Практический выбор между обычным текстовым или structured MCP-ответом и интерактивным MCP App: критерии ценности, архитектура, безопасность, fallback, тестирование и rollout.
Содержание статьи
- 01Короткий ответ: UI нужен для взаимодействия, а не для украшения
- 02Как MCP App дополняет обычный tool contract
- 03Матрица выбора: чтение, исследование, ввод и выполнение
- 04Sandbox снижает риск, но не создает доверие
- 05Fallback и переносимость проектируют до первого render
- 06Тесты должны охватывать протокол, доступность и последствия
- 07Rollout: один interaction slice и явный путь назад
Короткий ответ: UI нужен для взаимодействия, а не для украшения
Оставляйте обычный tool output, когда результат можно надежно прочитать, процитировать или передать следующему шагу как компактный текст либо типизированные данные. Выбирайте MCP App, когда пользователю нужно исследовать многомерные данные, управлять состоянием формы, просматривать rich media или последовательно работать со множеством объектов. Официальное расширение позволяет tool объявить интерактивный UI resource, который совместимый host показывает внутри диалога.
MCP App не делает tool точнее и не дает ему дополнительных полномочий. Это отдельный слой представления и взаимодействия поверх серверных capabilities. Если таблица из десяти строк и четкая рекомендация уже закрывают задачу, iframe, JavaScript bundle, event protocol и новая security surface лишь увеличат стоимость. Начинайте с анализа задачи: какое действие человек не может удобно или безопасно завершить через обычный ответ?
- Короткий ответ, citation или машиночитаемый handoff → обычный tool result.
- Фильтры, drill-down, canvas, media controls или многошаговый review → кандидат на MCP App.
- Действие с последствиями → server-side policy и явное подтверждение независимо от UI.
- Host не поддерживает extension → полезный текстовый или structured fallback.
- Нет измеримой пользы от взаимодействия → не добавляйте app layer.
Как MCP App дополняет обычный tool contract
В базовом паттерне definition инструмента содержит `_meta.ui.resourceUri`, который указывает на `ui://` resource. Host получает HTML resource, обычно рендерит его в sandboxed iframe и передает tool result во view. UI и host общаются через JSON-RPC поверх `postMessage`: app может получать результаты, просить host вызвать разрешенный server tool или обновить model context. Сам tool и его schema остаются каноническим execution contract.
Разделяйте три типа состояния. Authoritative domain state живет в системе-владельце; tool result является versioned snapshot или handle; ephemeral view state содержит выбранную вкладку, фильтр или незавершенное поле. Не прячьте единственный идентификатор операции только в browser state. После refresh, повторного render или перехода на fallback пользователь должен восстановить контекст через явный resource ID и проверенную сервером версию.
Матрица выбора: чтение, исследование, ввод и выполнение
Для одного факта, списка выводов или небольшого набора records plain output лучше сохраняется в transcript, проще проверяется моделью и работает в большем числе clients. Для исследования cohort heatmap, карты, временной шкалы или большой таблицы UI с локальными sort/filter может сократить повторные model calls. App должна отправлять модели только значимые решения пользователя, а не каждый hover или scroll event.
Для нескольких недостающих параметров обычно достаточно host-native elicitation или следующего conversational turn. MCP App оправдан для взаимозависимых полей, live preview или многоэтапного review. Для writes UI готовит exact-action proposal, но сервер повторно проверяет identity, tenant, object version, scope и approval. Кнопка Approve не доказывает authorization, а скрытое поле role не является trusted claim.
- Один результат и до пяти простых полей → сначала text, structured content или native form.
- Большой dataset с локальным exploration → app с bounded snapshot и provenance.
- Зависимая конфигурация с preview → app, но validation повторяется на server.
- Платеж, publish, delete или production change → proposal, policy gate, idempotency и reconciliation.
- Разные client capabilities → progressive enhancement, а не две бизнес-логики.
Sandbox снижает риск, но не создает доверие
Официальная модель изолирует app от parent DOM, cookies и local storage host и проводит коммуникацию через контролируемый channel. Resource metadata может объявлять Content Security Policy origins и запрашиваемые permissions. Host решает, какие capabilities предоставить. Поэтому app должна работать с минимальными connect, resource и permission allowlists; microphone, camera, clipboard или external navigation не следует запрашивать про запас.
Рассматривайте HTML или JavaScript resource, tool result и данные других tools как отдельные недоверенные inputs. Host проверяет resource URI, extension negotiation, message origin, method allowlist, payload size и correlation ID. Server никогда не полагается на disabled button или client-side validation. Secrets и bearer tokens не передаются в model context или view bundle; app вызывает server tool через host, а credential boundary остается вне iframe.
Fallback и переносимость проектируют до первого render
MCP Apps — opt-in extension, поддержка которого зависит от host и версии. Tool должен возвращать полезный semantic result даже когда UI не рендерится: краткий content summary для человека, `structuredContent` для client или model и стабильные identifiers для следующего call. Не возвращайте только инструкцию открыть widget, иначе сбой extension negotiation или render превратится в потерю функции.
Progressive enhancement означает одну server-side business operation и несколько presentation paths. App не должна получать скрытый privileged endpoint, которого нет в обычном client flow. Если rich interaction принципиально непереносим, определите минимальный fallback: read-only summary, downloadable artifact или безопасную ссылку на standalone product. Analytics отдельно отмечает app, fallback и unsupported-host outcomes, не считая render завершенной бизнес-операцией.
Тесты должны охватывать протокол, доступность и последствия
Contract suite проверяет tool metadata, `ui://` resource, MIME profile, initialization, delivery tool result, validation сообщений и корректную деградацию без extension. Browser tests покрывают sandbox, CSP denial, slow bundle, refresh, duplicate event, stale snapshot, offline state и два одновременных views. Security tests пытаются вызвать необъявленный tool, подменить object ID, навязать внешний origin и повторить consequential request.
Качество взаимодействия проверяют keyboard-only navigation, focus order, labels, announcement ошибок, color contrast, zoom и narrow viewport. Model eval отдельно оценивает, правильно ли assistant выбирает tool, объясняет app и использует только релевантные user selections. Главные product signals — task completion, correction rate, время до проверенного outcome и fallback success; число clicks или renders само по себе не доказывает пользу.
Rollout: один interaction slice и явный путь назад
Выберите один read-heavy сценарий с очевидным преимуществом UI, например исследование расходов с фильтрами и drill-down. Зафиксируйте baseline plain-output flow, реализуйте app как progressive enhancement и проведите replay на одинаковых snapshots. Ограничьте canary тестовыми tenants и read-only tools; открывайте writes только после negative tests, accessibility review, policy evidence и idempotent reconciliation.
Feature flag должен отдельно отключать app resource, не отключая базовый tool. Rollback прекращает новые renders, возвращает plain response, инвалидирует проблемную asset version и сверяет незавершенные operations. Audit связывает server, tool, resource version, host capability, view session, user action, policy verdict и authoritative outcome без записи sensitive form fields. После rollout удаляйте app, если она не улучшает заданный outcome или создает неприемлемую operator burden.
Практические примеры
Expense explorer без автономного approval
Tool возвращает bounded expense snapshot, currency, generatedAt, source references и structured summary. Совместимый host показывает MCP App с фильтрами, chart и drill-down; fallback отображает основные anomalies и IDs. Когда пользователь выбирает records для review, app отправляет typed proposal. Отдельный server tool повторно читает актуальные records, проверяет tenant и version и создает review queue, но не approve payment.
FAQ
Заменяет ли MCP App web application?
Не всегда. Она полезна для bounded interaction в контексте диалога. Полный продукт со своей навигацией, account lifecycle и сложными workflows может оставаться отдельным web app.
Можно ли использовать MCP App без text fallback?
Это снижает portability и превращает render failure в функциональный отказ. Возвращайте полезный semantic result и стабильные identifiers даже для host без extension.
Безопасен ли sandboxed iframe по умолчанию?
Sandbox — важная граница, но host все равно проверяет origins, messages, capabilities и payloads, а server повторно применяет authorization и domain policy.
Когда использовать elicitation вместо MCP App?
Для нескольких недостающих полей или простого confirmation обычно достаточно native interaction. App лучше подходит для rich preview, зависимых полей, navigation и повторяющегося multi-item review.
Связанные материалы
Источники
- MCP Apps overview — Model Context Protocolофициальный
- MCP Apps specification 2026-01-26первичный
- MCP Apps API overviewофициальный
- MCP Extensions support matrixофициальный