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_referenceobtiene 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_bookmarkletdevuelve 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 buildRequiere 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 |
| Vistas con pestañas de un tema (texto, HTML o código por pestaña) |
| Tabla HTML a partir de filas o texto sin formato con detección de delimitadores |
| Gráfico SVG de barras, líneas, circular o de anillo con tabla de datos |
| Formulario cuyo envío se convierte en la siguiente indicación de conversación |
| Reproductor de vídeo HTML para un clip corto (URL de archivo directa, |
| Secciones plegables de mostrar/ocultar (texto, HTML o código por sección) |
| Esquema secuencial anidado (1., 1.1., 1.1.1.) |
| Renderizar un documento markdown (contenido o ruta de archivo) como una tarjeta |
| Renderizar un proyecto (ruta zip o archivos explícitos) como pestañas de archivo |
| Leer un archivo de texto local para revisión o construcción de tarjetas |
| Listar un zip local y devolver el contenido de sus archivos de texto |
| Obtener una página pública y devolver datos extraídos estructurados |
| Reconstruir un formulario de sitio web como tarjeta interactiva |
| 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
mirror_web_formcon{ "url": "https://example.com/newsletter" }renderiza el formulario de suscripción de la página como una tarjeta.El usuario lo rellena y lo envía; la tarjeta devuelve una carga útil estructurada al chat.
El modelo revisa los valores con el usuario y luego llama a
submit_web_formcon 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 |
| Resumen de texto de la tarjeta, significativo por sí mismo |
| Enlace de recurso al HTML independiente (omitido para hosts Apps) |
|
|
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 & Fix.
La entrada nunca se decodifica primero, en ningún campo. Un llamador que sí pase &
obtiene una tarjeta que muestra los seis caracteres &, 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
PATHno se adjunta a unapathdel sistema de archivos; establececaseInsensitive: trueen un término para que coincida con cualquier mayúscula. PasatutorTermsInCode: trueacreate_code_tour_cardpara incluir el código.Cada resultado de tarjeta lleva
structuredContent.partscomo{ current, total, hasMore }, de modo que una verificación de completitud funciona en cada tipo de tarjeta. MientrashasMoresea verdadero, se ha retenido contenido y el llamador vuelve a llamar a la misma herramienta conpart: current + 1. Solocreate_markdown_cardycreate_code_tour_cardpueden 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. Leeparts.hasMoreen 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_archivey 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). EstableceMCP_CHAT_CARDS_FS_ROOTpara 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=1solo 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_formsolo 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:
Habilita el modo desarrollador en Claude Desktop (Configuración, Desarrollador) y luego abre las herramientas de desarrollador del webview para la conversación.
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.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 modeLicencia
MIT. Consulta LICENSE.
Maintenance
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
- AlicenseAqualityBmaintenanceRenders 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.4025044Functional Source , Version 1.1, MIT Future
- AlicenseAqualityDmaintenanceEnables 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.6MIT
- AlicenseNot gradedqualityBmaintenanceEnables booking flights and hotels, creating investment portfolios, and managing kanban boards directly within a chat interface using generative UI components.13Apache 2.0
- AlicenseAqualityBmaintenanceHand a human a rich interactive UI by URL from any MCP client and get structured data back: forms, approvals, surveys, pickers, editable lists. Round-trip human-in-the-loop for agents.201MIT
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.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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
