Cómo Crear un Servidor MCP con TypeScript y Python: Guía Práctica

Equipo Technonautas
Equipo Technonautas · Redacción
Imagen del artículo
5 min de lectura Avanzado
Intro
Esta guía muestra cómo construir un servidor MCP (Model Context Protocol) funcional en TypeScript y en Python. Incluye la configuración del entorno, la implementación de una Tool, un Resource y un Prompt, pruebas con MCP Inspector, la conexión a Claude Desktop y una introducción a las extensiones MCP Tasks y MCP Apps. Al final el servidor queda operativo y listo para recibir consultas desde el cliente.

Requisitos previos

Necesario antes de empezar
  • TypeScript
    Node.js 18 o 20 o superior, gestor de paquetes npm/pnpm/bun y familiaridad básica con TypeScript y Zod
  • Python
    Python 3.10 o superior, el gestor uv (o pip) y nociones de async/await y tipado
  • Cliente de prueba
    Claude Desktop instalado localmente o la CLI MCP Inspector (mcp dev)

Configuración del entorno

Configurar el proyecto en TypeScript

Crea el directorio de trabajo e inicializa el proyecto Node.js.

terminal
bash
mkdir mcp-servidor-ts
cd mcp-servidor-ts
npm init -y

Instala el SDK oficial de servidores MCP, las utilidades de Node.js y la librería de validación Zod.

terminal
bash
npm install @modelcontextprotocol/sdk zod
npm install -D typescript @types/node

Configura package.json para soportar módulos ES2022 y el script de compilación.

package.json
json
{
  "name": "mcp-servidor-ts",
  "version": "1.0.0",
  "type": "module",
  "main": "build/index.js",
  "scripts": {
    "build": "tsc"
  }
}

Crea tsconfig.json con la configuración de compilación.

tsconfig.json
json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./build",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"]
}

Configurar el proyecto en Python

Usa uv para inicializar el proyecto y crear el entorno virtual.

terminal
bash
# Inicializar el proyecto e instalar dependencias
uv init mcp-servidor-python
cd mcp-servidor-python
uv venv
source .venv/bin/activate  # En Windows: .venv\Scripts\activate

Agrega el SDK oficial de Python con la CLI integrada.

terminal
bash
uv add "mcp[cli]"

Implementación del servidor

Implementar el servidor en TypeScript

Crea src/index.ts. Este servidor expone una Tool para consultar métricas, un Resource con la política de alertas y un Prompt de diagnóstico guiado.

src/index.ts
typescript
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";

// 1. Inicialización de la instancia del servidor MCP
const server = new McpServer({
  name: "servidor-metricas-ts",
  version: "1.0.0",
});

// 2. Definición de una Tool (Acción con parámetros validados por Zod)
server.registerTool(
  "obtener_rendimiento",
  {
    description: "Obtiene el porcentaje de uso de CPU y memoria de un servidor remoto.",
    inputSchema: z.object({
      servidorId: z.string().describe("Identificador único del servidor (ej. srv-01)"),
    }),
  },
  async ({ servidorId }) => {
    // Registro de logs seguro enviado a stderr
    console.error(`[INFO] Consultando métricas para: ${servidorId}`);

    // Respuesta estructurada requerida por el protocolo
    return {
      content: [
        {
          type: "text",
          text: `Servidor ${servidorId}: Uso de CPU al 42%, Memoria al 68%. Estado: Saludable.`,
        },
      ],
    };
  }
);

// 3. Definición de un Resource (Datos de solo lectura)
server.registerResource(
  "politica_alerta",
  "config://politica-alerta",
  {
    name: "Política de Alertas",
    description: "Límites estipulados para el disparo de alertas de infraestructura.",
    mimeType: "text/plain",
  },
  async (uri) => ({
    contents: [
      {
        uri: uri.href,
        text: "Límite crítico CPU: 90%. Límite crítico Memoria: 85% sostenido por 5 min.",
      },
    ],
  })
);

// 4. Definición de un Prompt (Plantilla de usuario)
server.registerPrompt(
  "diagnosticar_servidor",
  {
    description: "Genera un análisis guiado sobre la salud del servidor.",
    args: {
      servidorId: z.string().describe("ID del servidor a revisar"),
    },
  },
  ({ servidorId }) => ({
    messages: [
      {
        role: "user",
        content: {
          type: "text",
          text: `Por favor analiza las métricas del servidor ${servidorId}, verifica si excede la politica_alerta y recomienda acciones.`,
        },
      },
    ],
  })
);

// 5. Conexión e inicio del transporte STDIO
async function main() {
  const transport = new StdioServerTransport();
  await server.connect(transport);
  console.error("Servidor MCP TypeScript ejecutándose en STDIO");
}

main().catch((error) => {
  console.error("Error fatal en main():", error);
  process.exit(1);
});

Compila el código ejecutando npx tsc; el archivo resultante queda en build/index.js.

terminal
bash
npx tsc

Implementar el servidor en Python

Crea servidor.py con la misma funcionalidad, usando el SDK de Python vía decoradores.

servidor.py
python
import logging
from typing import Any
from mcp.server.fastmcp import FastMCP

# Configuración de logs dirigidos strictly a stderr
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger("servidor-python")

# 1. Inicialización de la instancia del servidor MCP con FastMCP
mcp = FastMCP("servidor-metricas-py")

# 2. Definición de Tool mediante decoradores sintácticos
@mcp.tool()
def obtener_rendimiento(servidor_id: str) -> str:
    """Obtiene el porcentaje de uso de CPU y memoria de un servidor remoto.

    Args:
        servidor_id: Identificador único del servidor (ej. srv-01)
    """
    logger.error(f"[INFO] Consultando servidor Python: {servidor_id}")
    return f"Servidor {servidor_id} (Py): Uso de CPU al 38%, Memoria al 55%. Estado: Óptimo."

# 3. Definición de Resource (Lectura de contexto estático)
@mcp.resource("config://politica-alerta")
def obtener_politica() -> str:
    """Devuelve las políticas de alerta predeterminadas del sistema."""
    return "Regla Py: Notificar si el uso de disco supera el 95%."

# 4. Definición de Prompt reutilizable
@mcp.prompt("reporte_rapido")
def plantilla_reporte(servidor_id: str) -> str:
    """Plantilla para solicitar un informe ejecutivo rápido."""
    return f"Genera un resumen ejecutivo de un párrafo sobre el estado actual de {servidor_id}."

# 5. Punto de entrada para ejecución en transporte STDIO
if __name__ == "__main__":
    mcp.run(transport="stdio")

Extensiones: MCP Tasks y MCP Apps

La especificación publicada el 2026-07-28 añade dos extensiones opcionales sobre el núcleo del protocolo: MCP Tasks, para operaciones asíncronas de larga duración, y MCP Apps, para interfaces interactivas incrustadas en la ventana de chat.

Extensiones de la especificación
  • MCP Tasks (SEP-2663)
    Convierte una llamada larga en un objeto task con un taskId duradero y estado inicial working; el cliente sondea con tasks/get hasta completed, failed o cancelled, y usa tasks/update si entra en input_required
  • MCP Apps (SEP-1865)
    Vincula una herramienta a una interfaz mediante _meta.ui.resourceUri (esquema ui://); el host la renderiza en un iframe aislado, sin acceso a cookies, almacenamiento local ni al DOM del host

Pruebas y despliegue en Claude Desktop

Probar con MCP Inspector

Ejecuta el inspector apuntando al script de Python o al build de TypeScript.

terminal
bash
# Para el servidor Python
uv run mcp dev servidor.py

# Para el servidor TypeScript
npx @modelcontextprotocol/inspector node build/index.js

El inspector abre una interfaz web local donde se puede ejecutar la herramienta obtener_rendimiento y revisar la respuesta JSON, sin escrituras accidentales en stdout.

Configurar Claude Desktop

Edita el archivo de configuración global claude_desktop_config.json. Las rutas predeterminadas son:

Ruta del archivo de configuración
  • macOS
    ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows
    %APPDATA%\Claude\claude_desktop_config.json

Agrega la clave mcpServers con ambos servidores y sus rutas absolutas.

claude_desktop_config.json
json
{
  "mcpServers": {
    "metricas-ts": {
      "command": "node",
      "args": [
        "/RUTA/ABSOLUTA/A/mcp-servidor-ts/build/index.js"
      ]
    },
    "metricas-python": {
      "command": "uv",
      "args": [
        "--directory",
        "/RUTA/ABSOLUTA/A/mcp-servidor-python",
        "run",
        "servidor.py"
      ]
    }
  }
}

Nota: en Windows, escapa las barras invertidas de las rutas con doble barra (C:\\Ruta\\Al\\Proyecto).

Verificar el funcionamiento

Checklist de verificación

01

Cerrar Claude Desktop

Cierra completamente la aplicación desde la barra de estado o la bandeja del sistema.

02

Reabrir la aplicación

Inicia Claude Desktop nuevamente.

03

Revisar las herramientas

Abre el icono de herramientas del chat y confirma que aparecen obtener_rendimiento de ambos servidores.

04

Hacer una consulta de prueba

Realiza una consulta como "¿Cuál es el estado de rendimiento del servidor srv-01?".

Preguntas que podrían surgir durante el proceso de implementación:

¿Por qué no aparece el servidor en Claude Desktop?

Revisa la sintaxis de claude_desktop_config.json con un validador JSON y confirma que las rutas registradas sean absolutas.

¿Qué hacer si la llamada a la herramienta falla sin mostrar error?

Consulta los logs en ~/Library/Logs/Claude/mcp-server-<nombre>.log (macOS) o %APPDATA%\Claude\logs\ (Windows/Linux) para ver la salida enviada a stderr.

Seguridad en producción

Medidas defensivas mínimas

01

Sanear las entradas

Valida de forma estricta los argumentos de las herramientas para prevenir inyección de comandos en el transporte STDIO.

02

Aislar los procesos

Ejecuta los servidores MCP en contenedores con permisos de sistema de archivos limitados, bajo el principio de mínimo privilegio.

03

Asegurar el transporte remoto

Exige OAuth 2.1/OIDC y validación del emisor (RFC 9207) al migrar a Streamable HTTP.

Próximos pasos

Con el servidor corriendo en local, el siguiente paso natural es conectar herramientas reales a bases de datos SQL, Supabase o APIs de CRM, aprovechar MCP Tasks para procesos pesados y diseñar paneles con MCP Apps dentro del flujo de conversación.

Como práctica adicional, despliega un servidor en Streamable HTTP con Express o Fastify en TypeScript, o con FastMCP en Python, e integra autenticación centralizada para servicios empresariales.

Sobre el Autor
Equipo Technonautas

Equipo Technonautas

Redacción

Nuestro equipo editorial en Technonautas investiga y analiza el sector tecnológico —inteligencia artificial, desarrollo de software, fintech, ciberseguridad y más— para ofrecer contenido actualizado a nuestra audiencia.

¿Te gustó este artículo? ¡Compártelo y suscríbete!

Comentarios

Un espacio para debatir ideas

  • Sé respetuoso y mantén un tono cordial con los demás lectores.
  • No se tolera el spam, publicidad no solicitada ni insultos.

Sé el primero en comentar