MCP Apps vs salida simple de tools: cuándo una integración de IA necesita UI
Una elección práctica entre una respuesta MCP de texto o estructurada y una MCP App interactiva: criterios de valor, arquitectura, seguridad, fallback, pruebas y rollout.
Contenido del artículo
- 01Respuesta corta: usa UI para interactuar, no para decorar
- 02Cómo una MCP App complementa el contrato normal del tool
- 03Matriz de decisión: lectura, exploración, entrada y ejecución
- 04El sandbox reduce riesgo, pero no crea confianza
- 05Diseña fallback y portabilidad antes del primer render
- 06Las pruebas deben cubrir protocolo, accesibilidad y consecuencias
- 07Rollout: una porción de interacción y una salida explícita
Respuesta corta: usa UI para interactuar, no para decorar
Mantén una salida simple del tool cuando el resultado pueda leerse, citarse o pasarse al siguiente paso de forma fiable como texto compacto o datos tipados. Elige una MCP App cuando el usuario necesite explorar datos multidimensionales, gestionar el estado de un formulario, revisar rich media o trabajar con muchos objetos en secuencia. La extensión oficial permite que un tool declare un recurso de UI interactivo que un host compatible renderiza dentro de la conversación.
Una MCP App no hace que el tool sea más preciso ni le concede autoridad adicional. Es una capa separada de presentación e interacción sobre las capacidades del servidor. Si una tabla de diez filas y una recomendación clara ya resuelven la intención, un iframe, un bundle JavaScript, un protocolo de eventos y una nueva superficie de seguridad solo aumentan el coste. Empieza por analizar la tarea: ¿qué acción no puede completar la persona de forma cómoda o segura con una respuesta normal?
- Respuesta corta, citation o handoff legible por máquina → salida simple del tool.
- Filtros, drill-down, canvas, controles multimedia o review de varios pasos → candidato para una MCP App.
- Acción con consecuencias → policy del servidor y confirmación explícita independientemente de la UI.
- El host no soporta la extensión → fallback útil en texto o estructura.
- No hay beneficio de interacción verificable → no añadas una capa de app.
Cómo una MCP App complementa el contrato normal del tool
En el patrón básico, la definición del tool contiene `_meta.ui.resourceUri`, que apunta a un recurso `ui://`. El host obtiene el recurso HTML, normalmente lo renderiza en un iframe aislado y entrega el resultado del tool a la vista. La UI y el host se comunican mediante JSON-RPC sobre `postMessage`: la app puede recibir resultados, pedir al host que invoque un tool permitido del servidor o actualizar el contexto del modelo. El tool y su schema siguen siendo el contrato canónico de ejecución.
Separa tres tipos de estado. El estado de dominio autoritativo vive en el sistema de registro; el resultado del tool es un snapshot versionado o un handle; el estado efímero de la vista contiene la pestaña seleccionada, un filtro o un campo incompleto. No escondas el único identificador de una operación solo en el estado del navegador. Tras refresh, rerender o fallback, el usuario debe poder restaurar el contexto mediante un resource ID explícito y una versión verificada por el servidor.
Matriz de decisión: lectura, exploración, entrada y ejecución
Para leer un hecho, una lista de conclusiones o un conjunto pequeño de records, la salida simple se conserva mejor en el transcript, es más fácil de revisar por el modelo y funciona en más clients. Para explorar un cohort heatmap, un mapa, una línea temporal o una tabla grande, una UI con ordenación y filtros locales puede reducir llamadas repetidas al modelo. La app debe enviar al modelo solo decisiones significativas del usuario, no cada hover o scroll.
Para unos pocos parámetros que faltan suele bastar la elicitation nativa del host o el siguiente turno conversacional. Una MCP App se justifica con campos interdependientes, live preview o review de varios pasos. Para writes, la UI prepara una propuesta de acción exacta, pero el servidor vuelve a comprobar identity, tenant, versión del objeto, scope y approval. Un botón llamado Approve no demuestra autorización y un campo oculto de role no es un claim de confianza.
- Un resultado y hasta cinco campos simples → empieza con texto, structured content o formulario nativo.
- Dataset grande con exploración local → app con snapshot acotado y provenance.
- Configuración dependiente con preview → app, pero repite la validación en el servidor.
- Pago, publish, delete o cambio en producción → proposal, policy gate, idempotency y reconciliation.
- Distintas capacidades del client → progressive enhancement, no dos lógicas de negocio.
El sandbox reduce riesgo, pero no crea confianza
El modelo oficial aísla la app del DOM padre, las cookies y el local storage del host, y conduce la comunicación por un canal controlado. La metadata del recurso puede declarar origins de Content Security Policy y permisos solicitados. El host decide qué capacidades concede. Por ello, la app debe trabajar con allowlists mínimas de connect, resource y permissions; microphone, camera, clipboard o navegación externa no deben pedirse por si acaso.
Trata el recurso HTML o JavaScript, el resultado del tool y los datos de otros tools como inputs no confiables separados. El host valida resource URI, negociación de la extensión, origin del mensaje, allowlist de métodos, tamaño del payload y correlation ID. El servidor nunca confía en un botón deshabilitado ni en validación del client. Los secrets y bearer tokens no pasan al contexto del modelo ni al bundle de la vista; la app invoca el tool del servidor a través del host y el límite de credenciales queda fuera del iframe.
Diseña fallback y portabilidad antes del primer render
MCP Apps es una extensión opt-in y su soporte depende del host y de la versión. Un tool debe devolver un resultado semántico útil incluso cuando la UI no se renderiza: un resumen breve para la persona, `structuredContent` para el client o modelo e identificadores estables para la siguiente llamada. No devuelvas únicamente una instrucción para abrir el widget, porque una negociación fallida de la extensión o un error de render se convertirían en pérdida de funcionalidad.
Progressive enhancement significa una única operación de negocio del lado servidor con varias rutas de presentación. La app no debe obtener un endpoint privilegiado oculto que no exista en el flujo normal del client. Si la interacción rica no es portable por naturaleza, define un fallback mínimo: resumen read-only, artifact descargable o enlace seguro a un producto independiente. Analytics debe distinguir resultados de app, fallback y host no compatible sin tratar el render como una acción de negocio completada.
Las pruebas deben cubrir protocolo, accesibilidad y consecuencias
La suite de contrato verifica metadata del tool, recurso `ui://`, perfil MIME, inicialización, entrega del resultado, validación de mensajes y degradación correcta sin la extensión. Las pruebas de browser cubren sandbox, rechazo por CSP, bundle lento, refresh, eventos duplicados, snapshot stale, estado offline y dos vistas simultáneas. Las pruebas de seguridad intentan invocar un tool no declarado, sustituir un object ID, introducir un origin externo y repetir una petición con consecuencias.
La calidad de interacción se comprueba con navegación solo por teclado, orden del foco, labels, anuncio de errores, contraste de color, zoom y viewport estrecho. Un eval del modelo verifica por separado que el assistant elige el tool correcto, explica la app y usa solo selecciones relevantes del usuario. Las señales de producto importantes son task completion, correction rate, tiempo hasta un outcome verificado y éxito del fallback; el número de clicks o renders por sí solo no demuestra valor.
Rollout: una porción de interacción y una salida explícita
Elige un escenario intensivo en lectura donde la UI tenga una ventaja evidente, por ejemplo explorar gastos con filtros y drill-down. Registra el baseline del flujo de salida simple, implementa la app como progressive enhancement y reproduce ambos sobre los mismos snapshots. Limita el canary a tenants de prueba y tools read-only; abre writes solo después de pruebas negativas, revisión de accesibilidad, evidencia de policy y reconciliación idempotente.
Un feature flag debe poder desactivar el recurso de la app sin desactivar el tool base. El rollback detiene nuevos renders, restaura la respuesta simple, invalida la versión problemática del asset y reconcilia operaciones incompletas. El audit vincula server, tool, versión del recurso, capacidad del host, sesión de vista, acción del usuario, policy verdict y outcome autoritativo sin registrar campos sensibles del formulario. Elimina la app si tras el rollout no mejora el outcome definido o crea una carga operativa inaceptable.
Ejemplos prácticos
Explorador de gastos sin approval autónomo
El tool devuelve un snapshot acotado de gastos, currency, generatedAt, referencias de fuente y un resumen estructurado. Un host compatible renderiza una MCP App con filtros, chart y drill-down; el fallback muestra las principales anomalies e IDs. Cuando el usuario selecciona records para review, la app envía una propuesta tipada. Un tool separado del servidor vuelve a leer los records actuales, verifica tenant y versión y crea una review queue, pero no aprueba pagos.
FAQ
¿Una MCP App reemplaza una aplicación web?
No siempre. Es útil para interacción acotada dentro del contexto conversacional. Un producto completo con navegación propia, ciclo de vida de cuenta y workflows complejos puede seguir siendo una web app separada.
¿Se puede usar una MCP App sin fallback de texto?
Eso reduce la portabilidad y convierte un fallo de render en fallo funcional. Devuelve un resultado semántico útil e identificadores estables incluso para hosts sin la extensión.
¿Un iframe aislado es seguro por defecto?
El sandbox es un límite importante, pero el host sigue validando origins, mensajes, capacidades y payloads, mientras el servidor reaplica autorización y policy de dominio.
¿Cuándo usar elicitation en vez de una MCP App?
Para unos pocos campos ausentes o una confirmación simple suele bastar la interacción nativa. Una app encaja mejor con rich preview, campos dependientes, navegación y review repetido de varios elementos.