Skip to main content
Glama
jhauga
by jhauga

mcp-chat-cards

Un servidor MCP (Model Context Protocol) que renderiza tarjetas HTML interactivas dentro de clientes de chat de escritorio. En lugar de muros de texto, las conversaciones obtienen cajas de pestañas, tablas, gráficos, formularios, videoclips cortos, secciones plegables y esquemas numerados. En hosts que admiten la extensión MCP Apps (SEP-1865), las tarjetas se renderizan en línea en la conversación como iframes en sandbox; otros hosts reciben cada tarjeta como un recurso HTML incrustado autocontenido.

Características

  • Tarjetas de pestañas: ver diferentes contextos de un mismo tema lado a lado (por idioma, por SO, por nivel de habilidad), incluidos ejemplos de código con botones de copiar.

  • Tarjetas de tabla: construir tablas HTML a partir de filas explícitas o texto sin formato delimitado de forma laxa. Los delimitadores se detectan automáticamente, las columnas se equilibran y las celdas de URL se convierten en enlaces.

  • Tarjetas de gráfico: gráficos SVG generados dinámicamente de barras, líneas, circulares y de anillo con leyendas y una tabla de datos plegable para accesibilidad.

  • Tarjetas de formulario: formularios que el usuario rellena para dar contexto y dirección a la conversación. Al enviarlos, los valores se devuelven al chat como la siguiente indicación.

  • Formularios web reflejados: obtener una página real, reconstruir uno de sus formularios como tarjeta y luego enviar el formulario web real con los valores introducidos por el usuario mediante submit_web_form.

  • Tarjetas de vídeo: reproductores de vídeo HTML para clips cortos.

  • Tarjetas de animación: clips animados compuestos por el modelo para cuando no existe una URL de vídeo directa: escenas secuenciales de texto, viñetas escalonadas, diagramas SVG simples que se dibujan a sí mismos y gráficos de una sola serie que se acercan al rango de datos en discusión, todo con controles de reproducción/pausa, repetición y progreso estilo vídeo.

  • Tarjetas de mostrar/ocultar: secciones plegables con controles de mostrar todo/ocultar todo.

  • Tarjetas de lista secuencial: listas ordenadas anidadas numeradas 1., 1.1., 1.1.1. mediante contadores CSS.

  • Tarjetas de documento: renderizar un documento markdown (una guía o tutorial que el modelo escribió) como una tarjeta interactiva con secciones plegables, tablas con estilo y código copiable.

  • Tarjetas de recorrido de código: presentar un proyecto como una pestaña por archivo fuente, en el orden en que se dan los archivos (README y manifiestos se colocan primero), con código etiquetado por idioma y botones de copiar.

  • Ingesta de archivos generados por el modelo: leer archivos de texto locales y descomprimir archivos zip que el modelo produjo anteriormente en la conversación, para que sus propios entregables se conecten directamente a las tarjetas sin volver a escribir nada.

  • División automática en varias partes: documentos y proyectos grandes se empaquetan en partes que cada una se mantiene por debajo de un presupuesto de tamaño de tarjeta, para que los hosts nunca trunquen un resultado sobredimensionado. Cada parte se renderiza como su propia tarjeta y el resultado dice exactamente cómo obtener la siguiente.

  • Obtención de referencias: fetch_reference obtiene una página pública y devuelve datos estructurados (encabezados, texto, tablas, imágenes, enlaces, especificaciones de formularios) listos para alimentar las herramientas de tarjetas.

  • Tutor de tarjetas: las tarjetas educativas pueden marcar términos que muestran información emergente después de mantener el cursor, y definir acciones de menú contextual que envían indicaciones anticipadas por el modelo.

  • Contenido movible: los bloques de tarjetas se pueden reordenar arrastrando, arrastrar fuera de la tarjeta lleva el bloque como HTML, y cada tarjeta tiene un botón "Copiar tarjeta" que copia el HTML independiente para pegarlo en otras respuestas o archivos.

  • Alternancias de encabezado: cada encabezado de tarjeta tiene un botón </> que muestra u oculta el código fuente HTML de la propia tarjeta en un panel de código, y un botón de chevron a su lado que colapsa la tarjeta hasta su fila de encabezado y la expande de nuevo.

  • Tarjetas copiables: el menú contextual de cada tarjeta tiene un elemento integrado "Copiar tarjeta" que copia el HTML independiente, reflejando el botón del encabezado. Para colocarlo visualmente, get_insert_bookmarklet devuelve un bookmarklet que muestra un elemento flotante "Insertar tarjeta" al hacer clic derecho e inyecta la tarjeta copiada en ese lugar (vista previa local de la página; desaparece al recargar).

Related MCP server: mcp-interactive-ui-server

Cuándo el modelo debe llamar a este servidor

El servidor se anuncia para conversaciones sobre investigación, educación, habilidades profesionales, habilidades de aficionados en general (carpintería, artes y similares), temas profesionales, historia y noticias, además de temas relacionados, siempre que una tarjeta comunique mejor que el texto.

Instalación

git clone https://github.com/jhauga/mcp-chat-cards.git
cd mcp-chat-cards
npm install
npm run build

Requiere Node.js 18.17 o superior.

Uso con Claude Desktop

Añade el servidor a claude_desktop_config.json (Configuración > Desarrollador > Editar configuración), ajustando la ruta a donde clonaste el repositorio:

{
  "mcpServers": {
    "chat-cards": {
      "command": "node",
      "args": ["C:/path/to/mcp-chat-cards/dist/index.js"]
    }
  }
}

Reinicia el cliente de escritorio después de guardar. El mismo comando stdio funciona en cualquier host MCP; para hosts que admiten recursos de interfaz de usuario MCP, las tarjetas se renderizan como iframes en sandbox.

Herramientas

Herramienta

Propósito

create_tab_card

Vistas con pestañas de un tema (texto, HTML o código por pestaña)

create_table_card

Tabla HTML a partir de filas o texto sin formato con detección de delimitadores

create_chart_card

Gráfico SVG de barras, líneas, circular o de anillo con tabla de datos

create_form_card

Formulario cuyo envío se convierte en la siguiente indicación de conversación

create_video_card

Reproductor de vídeo HTML para un clip corto (URL de archivo directa, data:video/* o blob:; las páginas de plataformas de streaming se rechazan)

create_reveal_card

Secciones plegables de mostrar/ocultar (texto, HTML o código por sección)

create_list_card

Esquema secuencial anidado (1., 1.1., 1.1.1.)

create_markdown_card

Renderizar un documento markdown (contenido o ruta de archivo) como una tarjeta

create_code_tour_card

Renderizar un proyecto (ruta zip o archivos explícitos) como pestañas de archivo

read_local_file

Leer un archivo de texto local para revisión o construcción de tarjetas

unpack_archive

Listar un zip local y devolver el contenido de sus archivos de texto

fetch_reference

Obtener una página pública y devolver datos extraídos estructurados

mirror_web_form

Reconstruir un formulario de sitio web como tarjeta interactiva

submit_web_form

Enviar valores confirmados por el usuario al formulario web real

Ejemplo: create_table_card

{
  "title": "JavaScript array methods",
  "headers": ["Method", "Purpose"],
  "rows": [
    ["map", "Transform each item"],
    ["filter", "Keep matching items"],
    ["reduce", "Fold items into one value"]
  ]
}

Salida: un resumen de texto más un recurso incrustado (ui://mcp-chat-cards/<id>, text/html) que contiene el documento completo de la tarjeta.

Ejemplo: create_form_card

{
  "title": "Study preferences",
  "promptTemplate": "Teach {{topic}} with {{style}} examples.",
  "fields": [
    { "name": "topic", "label": "Topic", "required": true },
    { "name": "style", "type": "select", "options": ["practical", "theoretical"] }
  ]
}

Cuando el usuario envía la tarjeta, la plantilla rellenada se publica en el host como la siguiente indicación. Si el host no consume el mensaje, la tarjeta revela el texto de la indicación con un botón de copiar como respaldo.

Ejemplo: plug-n-play con archivos que el modelo genera

Supongamos que antes en la conversación el modelo construyó un pequeño proyecto y entregó project.zip más un tutorial GUIDE.md. En lugar de que el usuario los descomprima y lea manualmente, el modelo los convierte en tarjetas interactivas en dos llamadas:

{ "path": "C:/Users/jane/Downloads/GUIDE.md" }

enviado a create_markdown_card renderiza toda la guía como una tarjeta: el primer H1 se convierte en el título, cada sección H2 se pliega en un bloque mostrar/ocultar, las tablas reciben estilo de tarjeta y cada bloque de código delimitado obtiene un botón de copiar.

{
  "title": "Project source tour",
  "archivePath": "C:/Users/jane/Downloads/project.zip",
  "intro": "Read the guide card first, then follow these files in order."
}

enviado a create_code_tour_card descomprime el archivo en memoria y renderiza una pestaña por archivo de texto, ordenado README, manifiesto y luego fuente, cada uno etiquetado por idioma con un botón de copiar. Los files explícitos mantienen el orden que el llamador les da (README y manifiestos se colocan al frente), por lo que un orden de enseñanza deliberado (modelo de datos, luego errores, luego el punto de entrada) se renderiza como está escrito en lugar de alfabéticamente. Las cachés de compilación (target/, node_modules/) y las entradas binarias se omiten automáticamente. Usa unpack_archive o read_local_file primero cuando el modelo necesite inspeccionar el contenido antes de decidir qué tarjetas construir.

Cuando un documento o proyecto excede el presupuesto de tamaño de tarjeta (por defecto alrededor de 32,000 caracteres de marcado de tarjeta, ajustable mediante MCP_CHAT_CARDS_CARD_BUDGET), la herramienta lo divide en límites naturales (secciones H2 para documentos, archivos completos para recorridos) y devuelve la parte 1 con una instrucción como "llama a create_code_tour_card de nuevo con part: 2". El modelo repite la llamada hasta que cada parte se haya renderizado como su propia tarjeta, y los archivos individuales sobredimensionados se truncan con un aviso visible.

El presupuesto se mide contra lo que cuesta un archivo después de renderizar, no su longitud en disco: el código fuente se escapa a HTML en el panel de pestañas, donde un solo < se convierte en cuatro caracteres, por lo que un puñado de archivos densos en marcado puede costar mucho más de lo que sugiere su tamaño bruto. Cada resultado final se mide luego una vez más contra el límite del host (alrededor de 40,000 caracteres de resultado serializado, ajustable mediante MCP_CHAT_CARDS_RESULT_LIMIT). Una tarjeta que sigue siendo demasiado grande y no puede dividirse sola (una tabla con miles de filas, por ejemplo) devuelve un error accionable que nombra el exceso en lugar de un resultado sobredimensionado que el host se negaría silenciosamente a renderizar.

Ejemplo: formulario web reflejado

  1. mirror_web_form con { "url": "https://example.com/newsletter" } renderiza el formulario de suscripción de la página como una tarjeta.

  2. El usuario lo rellena y lo envía; la tarjeta devuelve una carga útil estructurada al chat.

  3. El modelo revisa los valores con el usuario y luego llama a submit_web_form con la carga útil para enviar el formulario real e informa el resultado HTTP.

Cómo se renderizan las tarjetas

El servidor admite dos rutas de entrega, negociadas automáticamente por el host:

En línea en la conversación (MCP Apps, SEP-1865). El servidor predeclara un recurso de plantilla de interfaz de usuario en ui://mcp-chat-cards/card.html con tipo MIME text/html;profile=mcp-app, y cada herramienta de tarjetas enlaza a él mediante _meta.ui.resourceUri y declara un esquema de salida (los hosts eliminan structuredContent de las herramientas sin esquema, dejando a la tarjeta nada que pintar). Los hosts que admiten la extensión Apps (incluidas las compilaciones recientes de Claude Desktop) renderizan la plantilla en línea en el chat como un iframe en sandbox, completan el protocolo de enlace ui/initialize y entregan el resultado de la herramienta a él. La plantilla es defensiva sobre las partes que fallan silenciosamente: anuncia ui/notifications/initialized tanto en un tiempo de espera como en la respuesta del protocolo de enlace (el host retiene el resultado de la herramienta hasta que ve el anuncio), localiza la carga útil de la tarjeta mediante búsqueda profunda en lugar de un anidamiento fijo, informa ui/notifications/size-changed después de cada pintado y al cambiar el tamaño para que el iframe tome su altura real, y adopta el tema del host (incluida una paleta oscura completa). Las interacciones de la tarjeta viajan de vuelta a través de JSON-RPC postMessage: los envíos de formularios y las acciones de contexto se convierten en solicitudes ui/message (la siguiente indicación de conversación), los enlaces pasan por ui/open-link y la telemetría utiliza notificaciones de registro.

Respaldo de documento independiente. Para los clientes que no declararon la extensión Apps, cada resultado incluye un enlace a ui://mcp-chat-cards/html/<card-id>. Al leer ese recurso se devuelve la misma tarjeta como un documento HTML autónomo (CSS y JS en línea, política de seguridad de contenido restrictiva, sin scripts externos). Los hosts sin soporte de Apps pero con renderizado de estilo MCP-UI muestran ese documento en un panel aislado; allí la tarjeta envía mensajes de estilo MCP-UI (prompt, notify, link).

El documento deliberadamente no se incluye en línea en el resultado de la herramienta. Su tema y tiempo de ejecución son idénticos byte a byte en cada tarjeta, por lo que incluirlo repetía unos 16 KB de código repetitivo por llamada: saturaba el contexto del llamador y era la razón principal por la que una tarjeta por lo demás normal podía superar el límite de resultado de un host y no renderizar nada. Establece MCP_CHAT_CARDS_EMBED_HTML=1 para restaurar la copia en línea en un host que no puede seguir un enlace de recurso. El servidor mantiene las últimas 24 tarjetas renderizadas disponibles para lectura.

Forma de resultado consistente

Cada herramienta de tarjeta devuelve las mismas tres cosas, sea cual sea el tipo de tarjeta:

Parte

Contenido

content[0]

Resumen de texto de la tarjeta, significativo por sí mismo

content[1]

Enlace de recurso al HTML independiente (omitido para hosts Apps)

structuredContent

{ "card": { "articleHtml": "…", "config": { "id", "kind", … } } }

Superficie de renderizado

Las tarjetas se renderizan en línea en la barra lateral de la aplicación de escritorio de Claude. Otras superficies (móvil y web) reciben el resumen de texto y la carga útil estructurada, pero no pintan la tarjeta, por lo que cada resumen está escrito para ser autónomo y se instruye a las herramientas para que también indiquen la conclusión de una tarjeta en la conversación.

Los campos de texto son texto plano

Cada campo de texto que acepta una herramienta (títulos, etiquetas, valores de celda, consejos de tutor) es texto plano y es escapado por el servidor exactamente una vez. Los llamadores no deben pre-escapar: pasa Predict, Spot & Fix, no Predict, Spot &amp; Fix.

La entrada nunca se decodifica primero, en ningún campo. Un llamador que sí pase &amp; obtiene una tarjeta que muestra los seis caracteres &amp;, porque eso es lo que una guía que documenta HTML, escapado o plantillas quiere mostrar a su lector. La regla es la misma en todas partes, por lo que la misma cadena se renderiza de manera idéntica en una celda de tabla, una pestaña, una tabla de markdown y una muestra de código.

El HTML sin procesar solo se respeta en campos llamados html (secciones de create_tab_card y create_reveal_card), donde se sanitiza: se eliminan scripts, manejadores de eventos, marcos, formularios y URL peligrosas, mientras se conserva el formato como <b> y <i>. En cualquier otro lugar, incluido el HTML escrito dentro de un documento create_markdown_card, las etiquetas se renderizan como texto literal, así que usa sintaxis de markdown para el formato allí. El HTML de nivel de bloque escapado se envuelve en el párrafo que implica la estructura de markdown en lugar de dejarse caer entre hermanos como texto suelto, y los comentarios HTML se eliminan en lugar de mostrarse, ya que una directiva <!-- markdownlint-disable --> no es prosa.

Dónde se resuelven las rutas

create_markdown_card(path), create_code_tour_card(archivePath), read_local_file y unpack_archive resuelven todas las rutas en el sistema de archivos de la máquina que ejecuta este servidor. Cuando el servidor se alcanza a través de un puente remoto, ese no es el sandbox del llamador: un archivo que el modelo generó en su propio lado no existe aquí. Pasa el contenido en línea (markdown, files) en ese caso. Una ruta del sistema operativo incorrecto, por ejemplo /home/demo-user/project.zip enviada a un servidor que se ejecuta en Windows, se rechaza con un error que indica el desajuste en lugar de resolverse en una unidad donde nunca existió; lo mismo ocurre con rutas de Windows enviadas a un servidor POSIX y con rutas ~/ sin expandir. Establece MCP_CHAT_CARDS_FS_ROOT para confinar las lecturas locales a un directorio.

Notas y límites de interactividad

  • Arrastrar y soltar reordena bloques dentro de una tarjeta. Arrastrar un bloque fuera de la tarjeta lleva su HTML en los datos de arrastre; soltarlo en otra respuesta requiere soporte del host, que los clientes de chat de escritorio generalmente aún no exponen.

  • "Copiar tarjeta" copia el documento HTML independiente para que una tarjeta pueda reproducirse en otra respuesta, un archivo o una pestaña del navegador.

  • Los consejos de tutor aparecen después de pasar el cursor sobre un término marcado durante aproximadamente 1,2 segundos; la tarjeta también notifica al host para que el modelo pueda hacer un seguimiento mientras el usuario explora. Cada término se marca una vez por tarjeta (el término más largo gana cuando dos se superponen), los duplicados en la lista de términos se ignoran y el marcado nunca ocurre dentro de muestras de código, consejos nativos o el consejo de otro término. La coincidencia distingue entre mayúsculas y minúsculas, por lo que un consejo escrito para PATH no se adjunta a una path del sistema de archivos; establece caseInsensitive: true en un término para que coincida con cualquier mayúscula. Pasa tutorTermsInCode: true a create_code_tour_card para incluir el código.

  • Cada resultado de tarjeta lleva structuredContent.parts como { current, total, hasMore }, de modo que una verificación de completitud funciona en cada tipo de tarjeta. Mientras hasMore sea verdadero, se ha retenido contenido y el llamador vuelve a llamar a la misma herramienta con part: current + 1. Solo create_markdown_card y create_code_tour_card pueden dividirse; cualquier otra tarjeta siempre informa { current: 1, total: 1, hasMore: false }. El título renderizado conserva su sufijo legible (parte 1 de 2) para el lector.

  • El umbral de división se mide en caracteres renderizados, no en la entrada que escribe un llamador. El escapado expande la fuente de manera impredecible: <, >, & y las comillas se convierten cada uno en cuatro a seis caracteres, por lo que una carga útil que parece muy por debajo del presupuesto puede superarlo y una que parece más grande puede no hacerlo. Lee parts.hasMore en lugar de predecir a partir del tamaño de la entrada. Un documento de markdown sin encabezados H2 no tiene límite de división y siempre se renderiza como una sola parte.

  • Las acciones de menú contextual con clic derecho son definidas por el modelo por tarjeta; {{selection}} en un mensaje de acción se reemplaza con el texto seleccionado por el usuario.

Seguridad

  • Las herramientas de archivos locales (read_local_file, unpack_archive y las entradas de ruta/archivo de las tarjetas de documento y recorrido de código) leen solo texto, limitan tamaños, rechazan binarios y limitan la extracción de archivos (recuento de entradas, por archivo y bytes totales). Establece MCP_CHAT_CARDS_FS_ROOT para confinar todas las lecturas locales a un directorio.

  • Las solicitudes salientes se limitan a URL http(s) que resuelven a direcciones públicas. Localhost, RFC 1918, enlace local, CGNAT y rangos IPv6 equivalentes están bloqueados, los redireccionamientos se revalidan, los cuerpos tienen un límite de tamaño y las solicitudes tienen tiempo de espera. Establece MCP_CHAT_CARDS_ALLOW_PRIVATE=1 solo si necesitas intencionalmente búsquedas de intranet.

  • Todo el texto proporcionado por el modelo y el usuario se escapa en HTML; el HTML de terceros obtenido se sanitiza (se eliminan scripts, manejadores de eventos, marcos, formularios y URL peligrosas).

  • Las tarjetas incluyen una CSP restrictiva y no cargan scripts, hojas de estilo ni fuentes externas.

  • submit_web_form solo debe llamarse con valores que el usuario ingresó en una tarjeta de formulario reflejada o confirmó explícitamente.

Depuración de tarjetas en Claude Desktop

Si una tarjeta se monta pero permanece vacía, la falla suele ser silenciosa, por lo que la plantilla registra todo en la consola:

  1. Habilita el modo desarrollador en Claude Desktop (Configuración, Desarrollador) y luego abre las herramientas de desarrollador del webview para la conversación.

  2. Filtra la consola por [mcp-chat-cards]. Cada mensaje JSON-RPC que la tarjeta envía y recibe se registra con su dirección (tx/rx), por lo que una respuesta de protocolo de enlace faltante o un resultado de herramienta no entregado es visible de inmediato.

  3. Ejecuta window.__mccDebug() en esa consola para obtener una instantánea: versión de la plantilla, si se anunció initialized, si se pintó una tarjeta, el HTML de la tarjeta renderizada y los últimos 50 mensajes de protocolo. Pega su salida al informar un problema de renderizado.

Puertos complementarios

La carpeta extension/ contiene puertos complementarios de las herramientas de tarjeta para otros hosts. Ambos son autónomos: no importan de src/ ni dist/, y el servidor MCP no se ve afectado por ellos.

  • extension/github/: una extensión de canvas de GitHub Copilot llamada chat-cards. El agente impulsa los mismos tipos de tarjeta (pestañas, tablas, gráficos, formularios, mostrar/ocultar, listas secuenciales, documentos de markdown, video) a través de acciones de canvas, y los envíos de formularios vuelven a la conversación como mensajes. Su README cubre la lista de acciones, las diferencias con las herramientas MCP y cómo la carpeta se asigna al diseño de contribución de awesome-copilot.

  • extension/claude/: una plantilla de artefacto de Claude: una página HTML autónoma cuyo bloque de especificación de tarjeta Claude completa y publica como artefacto. Los formularios y las acciones de clic derecho producen mensajes que el usuario copia de vuelta a la conversación.

Desarrollo

npm run build      # compile TypeScript to dist/
npm test           # run the vitest suite (unit + in-memory MCP integration)
npm run coverage   # run tests with V8 coverage
npm run dev        # compile in watch mode

Licencia

MIT. Consulta LICENSE.

A
license - permissive license
A
quality
A
maintenance

Maintenance

Maintainers
Response time
3dRelease cycle
6Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Renders 45+ interactive chart types, dashboards, and KPI widgets directly inside AI conversations. Supports drill-down, live API polling, 20 themes, and one-click export to PNG, PowerPoint, and A4 documents.
    40
    250
    44
    Functional Source , Version 1.1, MIT Future
  • A
    license
    A
    quality
    D
    maintenance
    Enables AI agents to render interactive user interfaces such as forms, dashboards, charts, tables, and wizards directly in MCP-compatible clients. Supports structured data collection and richer interactions beyond text responses.
    6
    MIT

View all related MCP servers

Related MCP Connectors

  • Renders interactive Chart.js charts and dashboards inline in AI conversations.

  • Generate images, GIFs, and PDFs from HTML, URLs, or templates — from your AI agent.

  • Create diagrams in chat, rendered as live interactive draw.io diagrams. 10,000+ searchable shapes.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jhauga/mcp-chat-cards'

If you have feedback or need assistance with the MCP directory API, please join our Discord server