PTENES
MÓDULO 5.4

📘 MCP con TypeScript

Crea un MCP Server usando el SDK oficial en TypeScript: la alternativa para desarrolladores de JavaScript.

6
Temas
35
Minutos
Avanzado
Nivel
Práctico
Tipo
1

📘 SDK de TypeScript vs. Python

MCP cuenta con dos SDK oficiales mantenidos por Anthropic: el @modelcontextprotocol/sdk para TypeScript y el fastmcp para Python. Ambos implementan la misma especificación y producen servers totalmente compatibles entre sí. La elección entre ellos depende de tu stack y tus preferencias personales: el resultado final es idéntico para el client.

💎 Concepto principal

El SDK de TypeScript (@modelcontextprotocol/sdk) es más verboso que Python, pero ofrece tipado fuerte con interfaces y tipos definidos para cada request y response. El SDK de Python (fastmcp) usa decorators y es más conciso, ideal para crear prototipos rápidamente. Ambos se comunican mediante JSON-RPC sobre stdio o SSE y producen servers 100% compatibles con cualquier cliente MCP. La elección depende únicamente de tus preferencias — el protocolo es el mismo.

❌ Evitar
  • •Asumir que un SDK es «mejor» que el otro
  • •Mezclar patrones de Python en el código TS
  • •Ignorar el tipado fuerte de TypeScript
  • •Usar any en lugar de tipos específicos del SDK
✅ Hacer
  • •Elige el SDK de tu stack principal
  • •Aprovechar el tipado fuerte de TS para la validación
  • •Seguir los patrones idiomáticos de cada lenguaje
  • •Probar la compatibilidad con varios clients
📊 Datos e investigación

El ecosistema MCP está dividido entre los dos SDKs: aproximadamente 55% de los servidores de la comunidad están escritos en Python (por su simplicidad) y 45% en TypeScript (por la robustez de tipos). Servers oficiales como filesystem, fetch e memory están escritos en TypeScript. Ambos SDK reciben actualizaciones simultáneas cuando evoluciona la spec.

2

🏗️ Estructura del proyecto TS

Crear un MCP Server en TypeScript sigue el flujo estándar de cualquier proyecto Node.js/TS: inicializar con npm, configurar TypeScript, instalar el SDK y escribir el código en el directorio src/. La estructura es sencilla y familiar para quienes ya trabajan con TypeScript.

💎 Concepto principal

La estructura mínima de un MCP Server TypeScript consiste en: package.json con la dependencia @modelcontextprotocol/sdk, tsconfig.json configurado para ESModules y target ES2020+, y src/index.ts con el código del server. El entry point crea una instancia de Server, registra los handlers y se conecta al transporte stdio con StdioServerTransport.

📋 Configuración del proyecto paso a paso
Paso 1

mkdir meu-mcp-server && cd meu-mcp-server && npm init -y — Crea el directorio del proyecto e inicializa package.json.

Paso 2

npm install @modelcontextprotocol/sdk — Instala el SDK oficial de MCP para TypeScript.

Paso 3

npx tsc --init — Genera tsconfig.json. Configura "module": "ESNext", "target": "ES2020" e "outDir": "./dist".

Paso 4

mkdir src && touch src/index.ts — Crea el archivo principal donde se implementará el servidor.

💡 Consejo práctico

Agrega "type": "module" en tu package.json para usar ESModules de forma nativa. En el tsconfig.json, define "moduleResolution": "node16" para compatibilidad. Agrega también un script "build": "tsc" e "start": "node dist/index.js" en package.json para facilitar el workflow.

3

💻 Implementando tools en TS

En el SDK TypeScript, las tools se registran usando request handlers. A diferencia de Python, donde los decorators simplifican la sintaxis, en TS defines explícitamente el handler para CallToolRequestSchema y declara las entradas mediante JSON Schema. Es más verboso, pero cada tipo es explícito y se valida en tiempo de compilación.

💎 Concepto principal

Para implementar tools en TypeScript, usas server.setRequestHandler(ListToolsRequestSchema, ...) para listar las tools disponibles (que devuelve name, description e inputSchema) y server.setRequestHandler(CallToolRequestSchema, ...) para ejecutarlas. El inputSchema se define como JSON Schema estándar con type, properties y required. Dentro del handler de CallTool, haces un switch en el request.params.name para despachar la lógica correcta.

❌ Evitar
  • •Olvidar incluir la tool en ListToolsHandler
  • •Definir inputSchema incorrecto o incompleto
  • •No manejar los errores dentro del handler
  • •Usar tipos any en los parámetros de la tool
✅ Hacer
  • •Definir interfaces TypeScript para los argumentos
  • •Validar los inputs antes de procesarlos
  • •Devolver isError: true en caso de falla
  • •Documentar cada tool con descripciones claras
💡 Consejo práctico

El patrón en TS es devolver { content: [{ type: "text", text: resultado }] } del handler de CallTool. Para errores, agrega isError: true a la respuesta. Crea una función auxiliar makeTextResponse(text: string) para evitar repeticiones, un patrón común en servers TS bien estructurados.

4

📦 Resources y Prompts en TS

Además de Tools, el SDK TypeScript admite Resources e Prompts usando el mismo patrón de request handlers. Resources exponen datos para que el modelo los lea, mientras que Prompts proporcionan templates reutilizables. La API sigue la misma filosofía: registrar un handler para el schema correspondiente.

💎 Concepto principal

Para Resources, usa server.setRequestHandler(ListResourcesRequestSchema, ...) para listar recursos y server.setRequestHandler(ReadResourceRequestSchema, ...) para servir el contenido. Cada recurso tiene una URI única (ej.: file:///config.json) y devuelve contenido como text o blob. Para Prompts, el patrón es idéntico: ListPromptsRequestSchema e GetPromptRequestSchema. La misma arquitectura, diferentes schemas.

📋 Flujo de implementación de Resources
Definir

Registrar el handler de ListResources que devuelve la lista de resources con uri, name y description.

Implementar

Registrar el handler de ReadResource que recibe la URI y devuelve el contenido con el mimeType apropiado.

Probar

Comprobar en MCP Inspector si los resources aparecen y devuelven contenido correctamente.

📊 Datos e investigación

En la práctica, Tools es la funcionalidad más usada (presente en ~95% de los servers), seguidas por Resources (~40%) y Prompts (~15%). Sin embargo, Resources son especialmente valiosos en escenarios enterprise donde el modelo necesita acceder a documentación, configs o datos sin ejecutar acciones. Prompts son ideales para estandarizar interacciones recurrentes con el modelo.

5

⚙️ Build y configuración

A diferencia de Python, donde ejecutas el archivo directamente, en TypeScript es necesario compilar antes de ejecutar. El comando tsc compila TypeScript a JavaScript en el directorio dist/, y después ejecutas con node dist/index.js. La configuración de Claude Desktop apunta al archivo JavaScript compilado.

💎 Concepto principal

El workflow de build es: npm run build (que ejecuta tsc) para compilar y luego node dist/index.js para ejecutar. En Claude Desktop, la configuración queda así: "command": "node", "args": ["/caminho/absoluto/dist/index.js"]. Usa siempre rutas absolutas en el config para evitar problemas. Como alternativa, usa npx ts-node src/index.ts durante el desarrollo para omitir el build.

💡 Consejo práctico

Agrega "build": "tsc" e "watch": "tsc --watch" en los scripts de package.json. Durante el desarrollo, usa npm run watch en una terminal para recompilar automáticamente con cada cambio. Para producción, siempre ejecuta npm run build y prueba con node dist/index.js antes de configurarlo en Claude Desktop.

🚨 Alerta

¡Siempre compila antes de ejecutar! Un error común es editar el archivo .ts y olvidarte de volver a compilar, ejecutando la versión antigua de .js. Si tus cambios no parecen surtir efecto, verifica si ejecutaste tsc antes de reiniciar el server. Consejo: configura un script "dev": "tsc && node dist/index.js" que compila y ejecuta en secuencia.

6

🧪 Probando el servidor TS

Probar un MCP Server TypeScript sigue el mismo flujo que en Python: usa el MCP Inspector para depuración interactiva y el Claude Desktop para una prueba de uso real. El resultado debe ser idéntico al de un server de Python equivalente: si ambos implementan la misma tool, el output para el cliente es el mismo.

💎 Concepto principal

O MCP Inspector (npx @modelcontextprotocol/inspector node dist/index.js) se conecta a tu server y te permite probar cada tool, resource y prompt individualmente. Ves los requests JSON-RPC enviados y las responses recibidas en tiempo real. Para hacer pruebas en producción, configura el server en el Claude Desktop y úsalo en conversaciones reales. Compara el resultado con un servidor Python equivalente para garantizar la compatibilidad.

❌ Evitar
  • •Probar solo en Inspector sin usar Claude Desktop
  • •Ignorar logs de error de stderr
  • •Omitir la validación de casos límite en las entradas
  • •No probar con inputs malformados
✅ Hacer
  • •Probar cada tool individualmente en el Inspector
  • •Validar el comportamiento con Claude Desktop
  • •Comparar el output con el server equivalente en Python
  • •Probar escenarios de error y entradas no válidas
📋 Flujo de pruebas recomendado
1. Compilar

Ejecutar npm run build y verificar que no haya errores de compilación de TypeScript.

2. Inspector

Probar en MCP Inspector: verificar que tools, resources y prompts aparezcan y respondan correctamente.

3. Claude Desktop

Configura Claude Desktop y haz pruebas en conversaciones reales para validar la experiencia de usuario.

4. Comparar

Si tienes un server de Python equivalente, compara los outputs para garantizar un comportamiento idéntico.

📝 Resumen del módulo

  • ✓ El SDK de TypeScript (@modelcontextprotocol/sdk) y el de Python (fastmcp) producen servers 100% compatibles: la elección depende de tus preferencias.
  • ✓ La estructura de un proyecto TS es familiar: package.json, tsconfig.json y src/index.ts, con el SDK instalado mediante npm.
  • ✓ Las tools usan setRequestHandler con CallToolRequestSchema: son más verbosas que en Python, pero tienen tipado explícito.
  • ✓ Los Resources y los Prompts siguen el mismo patrón de request handlers con sus schemas específicos.
  • ✓ Siempre compila con tsc antes de ejecutar: Claude Desktop ejecuta el .js compilado, no el .ts.
  • ✓ Usa MCP Inspector para depurar y Claude Desktop para pruebas reales: el output debe ser idéntico al de Python.

Siguiente Módulo: 5.5 — Explorando servidores de la comunidad