$ desarrollomcp
Volver al blog
Novedades

MCP Apps: Interfaces de Usuario Interactivas para Servidores MCP

Por DesarrolloMCP
|
#mcp #ui #interfaces #mcp-apps #openai #anthropic

Introducción

Una de las solicitudes más frecuentes de la comunidad MCP finalmente se hace realidad: interfaces de usuario interactivas directamente integradas en el protocolo. El 21 de noviembre de 2025, Anthropic anunció la extensión MCP Apps (SEP-1865), desarrollada en colaboración con OpenAI y el proyecto comunitario MCP-UI.

Esta iniciativa permite que los servidores MCP entreguen experiencias visuales ricas más allá del texto plano y los datos estructurados.

El problema actual

Hasta ahora, los servidores MCP se limitaban a intercambiar texto y datos estructurados con los hosts. Por ejemplo, un servidor de visualización de datos debía devolver los datos del gráfico en JSON, dejando que la aplicación cliente interpretara y renderizara la información.

// Antes: El servidor solo podía devolver datos
server.setRequestHandler(CallToolRequestSchema, async (request) => {
  const chartData = await getChartData();

  // Solo JSON, sin visualización
  return {
    content: [{
      type: "text",
      text: JSON.stringify(chartData)
    }]
  };
});

Limitaciones:

  • Cada cliente debía implementar su propia lógica de renderizado
  • Experiencias inconsistentes entre aplicaciones
  • Imposibilidad de crear interfaces interactivas personalizadas

La solución: MCP Apps

MCP Apps introduce un mecanismo estandarizado para que los servidores entreguen interfaces de usuario interactivas directamente a los clientes.

Características principales

1. Recursos predeclarados con URI ui://

Las plantillas de UI se registran utilizando el esquema ui:// y se referencian en los metadatos de las herramientas:

// Declarar recurso UI
const uiResource = {
  uri: "ui://visualization/chart",
  mimeType: "text/html",
  content: `
    <html>
      <body>
        <canvas id="chart"></canvas>
        <script>
          // Lógica de renderizado del gráfico
        </script>
      </body>
    </html>
  `
};

// Referenciar en herramienta
server.registerTool({
  name: "create_chart",
  description: "Crea un gráfico interactivo",
  ui: {
    resourceUri: "ui://visualization/chart"
  }
});

Esto permite que los hosts revisen el contenido antes de ejecutar las herramientas.

2. Transporte sobre protocolo MCP existente

La extensión utiliza el protocolo JSON-RPC existente sobre postMessage, lo que permite a los desarrolladores usar el SDK estándar:

import { App } from "@modelcontextprotocol/ext-apps";

// La App se comunica con el host usando el SDK existente
const app = new App();

app.onMessage((message) => {
  // Manejar mensajes del host
  console.log("Mensaje recibido:", message);
});

// Llamar herramientas del servidor
await app.callTool("get_data", { query: "ventas" });

3. Soporte HTML en iframes sandboxed

La especificación inicial soporta contenido text/html renderizado en iframes con sandbox:

<iframe
  sandbox="allow-scripts"
  src="ui://my-component"
  style="width: 100%; height: 400px;">
</iframe>

Ventajas:

  • Compatibilidad universal con navegadores
  • Modelo de seguridad bien establecido
  • Aislamiento completo del contenido

4. Seguridad multicapa

El diseño prioriza la seguridad en múltiples niveles:

┌─────────────────────────────────────────────┐
│  Capa 1: Sandboxing de iframes              │
│  - Permisos restringidos                    │
│  - Aislamiento de origen                    │
├─────────────────────────────────────────────┤
│  Capa 2: Plantillas predeclaradas           │
│  - Revisables antes de ejecución            │
│  - Sin código dinámico inesperado           │
├─────────────────────────────────────────────┤
│  Capa 3: Mensajes auditables                │
│  - Comunicación vía JSON-RPC                │
│  - Trazabilidad completa                    │
├─────────────────────────────────────────────┤
│  Capa 4: Consentimiento del usuario         │
│  - Aprobación para llamadas a herramientas  │
│  - Control explícito de acciones            │
└─────────────────────────────────────────────┘

Arquitectura técnica

Componentes del SDK

El repositorio ext-apps contiene:

MóduloDescripción
types.tsTipos JSON-RPC para comunicación App-Host
app.tsClase App para que las Apps se comuniquen con su host
app-bridge.tsClase AppBridge para interacciones host-App
message-transport.tsClase PostMessageTransport para mensajes en iframes

Ejemplo de servidor con UI

import { Server } from "@modelcontextprotocol/sdk/server/index.js";

const server = new Server({
  name: "visualization-server",
  version: "1.0.0"
});

// Registrar recurso UI
server.registerResource({
  uri: "ui://dashboard/sales",
  mimeType: "text/html",
  content: await readFile("./dashboard.html", "utf-8")
});

// Herramienta que utiliza el recurso UI
server.registerTool({
  name: "show_sales_dashboard",
  description: "Muestra un dashboard interactivo de ventas",
  inputSchema: {
    type: "object",
    properties: {
      period: { type: "string", enum: ["week", "month", "year"] }
    }
  },
  ui: {
    resourceUri: "ui://dashboard/sales"
  }
});

Ejemplo de App con React

import { useApp } from "@modelcontextprotocol/ext-apps/react";

function SalesDashboard() {
  const { callTool, onDataUpdate } = useApp();
  const [data, setData] = useState(null);

  useEffect(() => {
    // Escuchar actualizaciones de datos
    onDataUpdate((newData) => {
      setData(newData);
    });
  }, []);

  const handleRefresh = async () => {
    const result = await callTool("fetch_sales_data", {
      period: "month"
    });
    setData(result);
  };

  return (
    <div className="dashboard">
      <button onClick={handleRefresh}>Actualizar</button>
      {data && <Chart data={data} />}
    </div>
  );
}

Compatibilidad hacia atrás

La extensión MCP Apps es completamente opcional. Los servidores deben proporcionar alternativas de solo texto para todas las herramientas habilitadas con UI:

server.registerTool({
  name: "visualize_data",
  description: "Visualiza datos como gráfico o tabla de texto",
  ui: {
    resourceUri: "ui://chart",
    // Fallback para clientes sin soporte UI
    fallbackEnabled: true
  },
  handler: async (args) => {
    const data = await fetchData(args);

    // Si el cliente no soporta UI, devolver texto
    return {
      content: [{
        type: "text",
        text: formatAsTable(data)
      }]
    };
  }
});

Colaboradores y adopción

Colaboración histórica

Esta extensión representa una colaboración sin precedentes entre:

  • Anthropic: Creadores del protocolo MCP
  • OpenAI: Con su Apps SDK
  • MCP-UI: Proyecto comunitario pionero

Empresas adoptando patrones UI

Varias empresas ya utilizan patrones similares basados en MCP-UI:

  • Postman: Interfaces de prueba de APIs
  • Shopify: Dashboards de e-commerce
  • Hugging Face: Visualización de modelos
  • Goose: Componentes interactivos
  • ElevenLabs: Interfaces de audio

MCP-UI: El proyecto comunitario

MCP-UI fue el proyecto que demostró la viabilidad de interfaces en MCP. Sus conceptos clave ahora forman parte de la especificación oficial:

UIResource

interface UIResource {
  uri: string;           // Identificador único
  mimeType: string;      // Tipo de contenido
  text?: string;         // Contenido textual
  blob?: Uint8Array;     // Contenido binario
}

Tipos de contenido soportados

Tipo MIMEDescripción
text/htmlHTML renderizado en iframe
text/uri-listLista de URIs
application/vnd.mcp-ui.remote-domRemote DOM de Shopify

SDKs disponibles

# TypeScript (servidor)
npm install @mcp-ui/server

# TypeScript (cliente)
npm install @mcp-ui/client

# Python
pip install mcp-ui-server

# Ruby
gem install mcp_ui_server

Instalación y uso

Instalar el SDK

# Actualmente disponible vía Git
npm install git+https://github.com/modelcontextprotocol/ext-apps.git

Estructura de proyecto

mi-servidor-mcp/
├── src/
│   ├── server.ts        # Servidor MCP
│   └── ui/
│       ├── dashboard.html
│       └── components/
│           └── chart.tsx
├── package.json
└── mcp.json

Próximos pasos

El equipo de MCP invita a la comunidad a:

1. Revisar la especificación

# Clonar el repositorio
git clone https://github.com/modelcontextprotocol/modelcontextprotocol

# Ver el PR SEP-1865
gh pr view 1865

2. Participar en discusiones

  • GitHub Issues: Reportar problemas y sugerencias
  • Discord: Canal #ui-wg en MCP Contributors

3. Probar implementaciones

# Clonar ext-apps
git clone https://github.com/modelcontextprotocol/ext-apps

# Instalar dependencias
npm install

# Ejecutar ejemplos
npm run example:react
npm run example:vanilla

Casos de uso

Visualización de datos

// Gráficos interactivos en lugar de tablas de texto
const chartUI = createBarChart({
  data: salesData,
  interactive: true,
  onBarClick: (item) => callTool("get_details", { id: item.id })
});

Formularios complejos

// Formularios con validación en tiempo real
const formUI = createForm({
  fields: schema,
  onSubmit: (data) => callTool("process_form", data),
  validation: "realtime"
});

Dashboards en tiempo real

// Métricas actualizándose automáticamente
const dashboardUI = createDashboard({
  widgets: ["sales", "users", "performance"],
  refreshInterval: 5000,
  onWidgetClick: (widget) => callTool("drill_down", { widget })
});

Conclusión

MCP Apps marca un hito importante en la evolución del protocolo MCP:

  • Experiencias visuales ricas directamente desde servidores MCP
  • Colaboración industria-comunidad entre Anthropic, OpenAI y MCP-UI
  • Seguridad primero con múltiples capas de protección
  • Compatibilidad manteniendo soporte para clientes existentes

Esta extensión posiciona a MCP como un protocolo verdaderamente completo para la integración de IA con datos y servicios externos.


Post anterior: Automatización con MCP Prompts

Recursos: