Crear un conector MCP remoto
Construye un servidor MCP sin estado y Streamable-HTTP (TypeScript, @modelcontextprotocol/sdk) que funciona como un conector personalizado de claude.ai, opcionalmente con tarjetas visuales en línea (MCP Apps), y lo despliega en Vercel. Probado en un proyecto real con más de 30 herramientas.
Las plantillas están en templates/ junto a este archivo. Las notas más detalladas están en references/; léelas solo cuando el paso las requiera:
references/mcp-apps-cards.md— tarjetas en línea: recursoui://, protocolo postMessage, CSP, listas clicablesreferences/deploy-vercel.md— configuración de Vercel, despliegue, re-añadir el conector en claude.aireferences/gotchas.md— trampas que cuestan tiempo real (léelo antes de depurar)
Flujo de trabajo
- Aclarar (pregunta solo lo que no puedas inferir): qué datos/API, solo lectura o escritura, necesita autenticación o no, quiere tarjetas o solo texto. Por defecto: datos públicos, solo lectura, sin autenticación, texto + tarjetas.
- Sondear cada API upstream antes de escribir código.
curla cada endpoint: estado, forma de la respuesta, formatos de fecha, límites de tasa, tiempos de espera, redirecciones (un301significa que la URL cambió, ej.api.frankfurter.dev, no.app). Los endpoints públicos SPARQL/búsqueda pueden ser lentos: mide el tiempo, mantén las consultas simples, filtra en el código. - Estructurar desde
templates/(copiapackage.json,tsconfig.json,vercel.json,api/,src/,scripts/), renombramy-connector,npm install. - Escribir herramientas en
src/server.ts(unaregisterToolcada una). Reglas a continuación. - Añadir cada herramienta a
scripts/test-client.ts. El ejecutor falla en herramientas no probadas, salida vacía eisError. - Verificar localmente:
npm run typecheck, iniciaPORT=<puerto nuevo> npm run dev, confirma que el log diga "listening" (noEADDRINUSE), luegonpm test -- http://localhost:<puerto>/mcp. Objetivo:Untested tools: none. Problems: 0. - Documentar: tabla de herramientas en el README (una fila por herramienta), CONTRIBUTING, LICENSE.
- Commit, push, desplegar solo con la autorización del usuario (ver
references/deploy-vercel.md), luego ejecuta la prueba contra la URL en producción. - Decir al usuario que elimine y vuelva a añadir el conector en claude.ai (almacena en caché la lista de herramientas) y proporciona entre 3 y 5 prompts de prueba cortos.
Reglas de diseño de herramientas
- Pocas herramientas, que realmente funcionen. Los nombres son verbos en
snake_case:search_x,get_x,list_x. - Esquema Zod con límites en cada entrada (
min/max,default); describe cada campo con un ejemplo. - La descripción dice qué devuelve y cuándo usarla, en una o dos frases. El modelo la lee para elegir la herramienta.
- Anotaciones:
readOnlyHint: true, idempotentHint: true, destructiveHint: false, másopenWorldHint: truepara APIs externas. - Envolver cada manejador en
safe(...): los fallos upstream se convierten en resultadosisErrorcon un mensaje legible, nunca un bloqueo. - Nombrar la fuente de datos en cada resultado. Indicar cuando los datos son editados por la comunidad o provisionales.
- Nunca bloquearse por campos faltantes; recurrir a "desconocido".
- Tolerancia a errores tipográficos: si no hay coincidencia, devuelve sugerencias "quizás quisiste decir" en lugar de un resultado vacío.
- Cachear llamadas upstream (la plantilla
getJson/getTexttiene TTL, deduplicación de solicitudes en vuelo, caché corta de fallos, tiempo de espera). Usa TTL cortos (minutos) para datos en vivo, horas para datos estáticos. Sé amable con las APIs gratuitas. - Devolver tanto texto (para el modelo) como
structuredContent(para la tarjeta) mediante un helper comocard(text, data). - Sin secretos en el repositorio. Si se requiere una clave, léela de
process.envy documéntala. - Filtrar trabajo pesado en el código, no en la consulta upstream, cuando el upstream sea lento.
Servidor sin estado (compatible con Vercel)
Se crea un nuevo McpServer y transporte por cada solicitud (src/handler.ts); sin sesiones, sin memoria entre solicitudes. El único estado es la caché en memoria, que es de mejor esfuerzo. CORS y un límite de tamaño del cuerpo están en el manejador. api/mcp.ts exporta { fetch } y maxDuration: 30; vercel.json reescribe /mcp a /api/mcp.
Tarjetas (MCP Apps), versión corta
Registra un recurso HTML ui://… (mimeType: text/html;profile=mcp-app), luego asigna a cada herramienta _meta: { ui: { resourceUri }, "ui/resourceUri": resourceUri } y devuelve structuredContent con un campo kind. El HTML es un archivo autocontenido que renderiza según kind. Ver references/mcp-apps-cards.md y templates/src/view.ts.
Salida para el usuario
Sé conciso. Informa: qué se construyó (lista de herramientas), resultado de la prueba, URL y los pasos exactos para refrescar el conector. Expresa las limitaciones con honestidad (rutas de UI no verificadas, upstreams lentos, datos comunitarios).