Ir al contenido

Lab: Tu Primer Servidor MCP

Es hora de construir. Crearemos un Servidor MCP robusto usando TypeScript que permitirá a la IA leer y filtrar archivos de logs locales.

  1. Crea una carpeta para el proyecto

    Crea una carpeta nueva en tu escritorio o espacio de trabajo llamada mcp-logs-server.

  2. Inicializa el proyecto e instala dependencias

    Usaremos el SDK oficial de MCP, zod para validación y tsx para ejecutar TypeScript directamente sin complicaciones.

    Ventana de terminal
    npm init -y
    npm install @modelcontextprotocol/sdk zod
    npm install -D typescript @types/node tsx
  3. Configura TypeScript

    Crea el archivo tsconfig.json con esta configuración básica:

    tsconfig.json
    {
    "compilerOptions": {
    "target": "ES2022",
    "module": "NodeNext",
    "moduleResolution": "NodeNext",
    "verbatimModuleSyntax": false,
    "esModuleInterop": true,
    "skipLibCheck": true,
    "strict": true,
    "outDir": "./dist"
    },
    "include": ["src/**/*", "index.ts"]
    }
  4. Crea los archivos base

    Vamos a crear los siguientes archivos vacíos para tener la estructura lista. Puedes hacerlo desde tu editor o terminal:

    • index.ts (Donde irá nuestro código)
    • system.log (Donde irán los datos de prueba)

    En Mac/Linux:

    Ventana de terminal
    touch index.ts system.log

    En Windows (PowerShell):

    Ventana de terminal
    New-Item index.ts, system.log
  5. Estructura final

    Tu proyecto debe verse así:

    • Directoriomcp-logs-server
      • node_modules
      • index.ts (Nuestro servidor)
      • system.log (Datos de prueba)
      • package.json
      • tsconfig.json (Configuración de TypeScript)

Primero, llenemos el archivo de logs con información falsa para que la IA tenga algo que leer. Copia esto dentro de system.log:

system.log
[2024-03-10 08:00:01] INFO: Servicio de pagos iniciado correctamente.
[2024-03-10 08:15:22] WARN: Tiempo de respuesta alto en endpoint /api/users (450ms).
[2024-03-10 09:30:00] ERROR: Fallo de conexión con la base de datos (Timeout).
[2024-03-10 09:30:05] ERROR: No se pudo reintentar la transacción ID #9928.
[2024-03-10 10:00:00] INFO: Tarea programada 'backup_diario' completada.
[2024-03-10 11:45:00] ERROR: Excepción no controlada en módulo de autenticación.

Ahora, la magia. Abre index.ts y escribe el siguiente código. Hemos comentado cada parte para que entiendas qué hace el protocolo.

index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
import { readFile } from "fs/promises";
import path from "path";
// 1. Crear la instancia del servidor
const server = new McpServer({
name: "LogsInspector",
version: "1.0.0",
});
// 2. Definir la Herramienta (Tool)
// Esta es la función que la IA "verá" y podrá ejecutar.
server.tool(
"analyze_logs", // Nombre de la herramienta
{ severity: z.enum(["INFO", "WARN", "ERROR"]) }, // Esquema de entrada (Zod)
async ({ severity }) => {
try {
// Lógica interna: Leer el archivo real
const logPath = path.join(process.cwd(), "system.log");
const data = await readFile(logPath, "utf-8");
// Filtrar líneas según lo que pidió la IA
const logs = data.split("\n").filter(line => line.includes(severity));
if (logs.length === 0) {
return {
content: [{ type: "text", text: "No se encontraron logs con esa severidad." }]
};
}
return {
content: [{ type: "text", text: logs.join("\n") }],
};
} catch (error) {
const errorMessage = error instanceof Error ? error.message : "Error desconocido";
return {
content: [{ type: "text", text: `Error leyendo logs: ${errorMessage}` }],
isError: true
};
}
}
);
// 3. Conectar al transporte (STDIO)
// MCP usa la entrada/salida estándar (consola) para comunicarse con el Host.
async function main() {
const transport = new StdioServerTransport();
await server.connect(transport);
}
main().catch(console.error);
  1. Definimos una Tool: Le dijimos a la IA: “Tengo una capacidad llamada analyze_logs que requiere un parámetro severity (INFO, WARN o ERROR)”.
  2. Tipado Seguro: Al usar TypeScript y Zod, nos aseguramos de que el servidor sea robusto ante datos incorrectos.
  3. Transporte Stdio: Esta es la clave. El servidor no abre un puerto HTTP. Escucha por la consola (stdin/stdout).
    • Esto hace que sea seguro (solo la app que lanza el proceso puede hablar con él).
    • Y rápido (comunicación directa entre procesos).

A diferencia de un servidor web, si ejecutas esto manualmente se quedará “colgado” esperando inputs.

Ventana de terminal
npx tsx index.ts

(No verás nada en la consola, ¡eso es buena señal! Significa que está escuchando en modo silencioso).

Presiona Ctrl + C para detenerlo. En el siguiente paso, conectaremos este script a VS Code para verlo en acción real.