4 de marzo de 2026

Model Context Protocol Server. Conectando tu empresa con agentes de IA

Un primer acercamiento para construir un servidor MCP en Nodejs para integrarlo con Claude Code CLI u otros Agentes de IA que soporten el protocolo MCP

Raúl Pimentel
Raúl Pimentel
[email protected]
Model Context Protocol Server.  Conectando tu empresa con agentes de IA

¿Qué es el Model Context Protocol?

El Model Context Protocol (MCP) es un estándar abierto creado por Anthropic que define una forma estandarizada para que las aplicaciones de IA se conecten con sistemas externos: bases de datos, APIs, archivos locales, herramientas y servicios de terceros.

La analogía oficial es crear un conector universal (como si fuera un conector USB-C) para cualquier modelo de lenguaje pueda conectarse a otra fuente de datos o herramienta, sin la necesidad de integraciones ad-hoc por cada caso.

Model Context Protocol

Sin MCP, cada herramienta de IA necesita su propia integración personalizada. Con MCP, basta con construir el servidor una vez y cualquier cliente compatible (Claude Desktop, Claude CLI, VS Code, Cursor…) puede usarlo de inmediato.


¿Cómo funciona?

MCP sigue una arquitectura cliente-servidor con tres participantes:

  • MCP Host: La aplicación de IA (ej. Claude CLI, Claude Desktop). Actúa como orquestador.
  • MCP Client: Un componente dentro del host que mantiene la conexión con un servidor específico.
  • MCP Server: El programa que tú escribes. Expone datos y herramientas al modelo.

El protocolo se divide en dos capas:

Capa de Datos (Data Layer)

Define la comunicación mediante JSON-RPC 2.0. Incluye:

  • Lifecycle management: negociación de capacidades al conectar (handshake inicial).
  • Primitivas del servidor: los bloques de construcción que un servidor puede exponer.

Las tres primitivas principales son:

PrimitivaDescripciónEjemplo
ToolsFunciones ejecutables que el modelo puede invocarConsultar materias, calcular, buscar en DB
ResourcesFuentes de datos estáticas o semi-estáticasEsquema de base de datos, archivos
PromptsPlantillas reutilizables para estructurar interaccionesSystem prompts

Capa de Transporte (Transport Layer)

Define el canal de comunicación. MCP soporta dos mecanismos:

  • Stdio transport: Usa stdin/stdout para comunicación entre procesos locales. Sin overhead de red, ideal para herramientas de escritorio y CLI.
  • Streamable HTTP transport: Usa HTTP POST con Server-Sent Events opcionales. Soporta autenticación OAuth, bearer tokens y API keys. Ideal para servidores remotos.

Ejemplo: MCP Escolar

Para explorar MCP en la práctica, construí un servidor en Next.js que simula la integración con un sistema universitario estudiantil. Permitiendo que un estudiante a través de un Asistente de IA pueda realizar preguntas (prompts de consulta) sobre sus materias, horarios, exámenes, tareas, procesos de inscripción, etc .

Stack tecnológico

  • @modelcontextprotocol/sdk: SDK oficial de Anthropic para Node.js.
  • Zod: Validación de esquemas de entrada para cada tool.
  • Next.js: Expone un route o endpoint para el WebStandardStreamableHTTPServerTransport .
  • Transporte: WebStandardStreamableHTTPServerTransport — servidor HTTP como medio de transporte que utiliza comunicación por stream.

Configuración del proyecto inicial

  1. Se creó un proyecto nuevo Next.js de acuerdo a la documentación en Next.js
  2. Se creo una estructura de proyecto, page y nested route para nuestro servidor mcp.

Estructura del Proyecto

  1. Se creó un servidor WebStandardStreamableHTTPServerTransport, se registraron sus herramientas y se definió datos de muestra con persistencia en memoria.

Datos dummy


const CURRENT_STUDENT = {
  nombre: "Carlos Mendoza López",
  matricula: "20230145",
  carrera: "Ingeniería en Sistemas Computacionales",
  semestre: 4,
};

const MATERIAS = [
  {
    id: "ISC401",
    nombre: "Estructuras de Datos",
    creditos: 5,
    maestro: "Dr. Alejandro Ríos",
    correo: "[email protected]",
  },
  {
    id: "ISC402",
    nombre: "Cálculo Integral",
    creditos: 5,
    maestro: "Mtra. Sofía Vargas",
    correo: "[email protected]",
  },
  {
    id: "ISC403",
    nombre: "Programación Orientada a Objetos",
    creditos: 4,
    maestro: "Ing. Marco Pérez",
    correo: "[email protected]",
  },
  {
    id: "ISC404",
    nombre: "Redes de Computadoras",
    creditos: 4,
    maestro: "Dr. Luis Herrera",
    correo: "[email protected]",
  },
  {
    id: "ISC405",
    nombre: "Inglés IV",
    creditos: 3,
    maestro: "Mtra. Ana Torres",
    correo: "[email protected]",
  },
];

const HORARIOS = [
  {
    materia: "Estructuras de Datos",
    dias: ["Lunes", "Miércoles"],
    horario: "07:00 - 08:30",
    aula: "B-201",
  },
  {
    materia: "Cálculo Integral",
    dias: ["Martes", "Jueves"],
    horario: "08:30 - 10:00",
    aula: "A-105",
  },
  {
    materia: "Programación Orientada a Objetos",
    dias: ["Lunes", "Miércoles", "Viernes"],
    horario: "10:00 - 11:00",
    aula: "Lab-3",
  },
  {
    materia: "Redes de Computadoras",
    dias: ["Martes", "Jueves"],
    horario: "11:00 - 12:30",
    aula: "B-310",
  },
  {
    materia: "Inglés IV",
    dias: ["Viernes"],
    horario: "12:00 - 14:00",
    aula: "A-201",
  },
];

const EXAMENES_PARCIALES = [
  {
    materia: "Estructuras de Datos",
    parcial: 1,
    fecha: "2026-03-20",
    hora: "07:00",
    aula: "B-201",
  },
  {
    materia: "Cálculo Integral",
    parcial: 1,
    fecha: "2026-03-22",
    hora: "08:30",
    aula: "A-105",
  },
  {
    materia: "Programación Orientada a Objetos",
    parcial: 1,
    fecha: "2026-03-25",
    hora: "10:00",
    aula: "Lab-3",
  },
  {
    materia: "Redes de Computadoras",
    parcial: 1,
    fecha: "2026-03-27",
    hora: "11:00",
    aula: "B-310",
  },
  {
    materia: "Inglés IV",
    parcial: 1,
    fecha: "2026-03-28",
    hora: "12:00",
    aula: "A-201",
  },
  {
    materia: "Estructuras de Datos",
    parcial: 2,
    fecha: "2026-05-08",
    hora: "07:00",
    aula: "B-201",
  },
  {
    materia: "Cálculo Integral",
    parcial: 2,
    fecha: "2026-05-10",
    hora: "08:30",
    aula: "A-105",
  },
  {
    materia: "Programación Orientada a Objetos",
    parcial: 2,
    fecha: "2026-05-12",
    hora: "10:00",
    aula: "Lab-3",
  },
  {
    materia: "Redes de Computadoras",
    parcial: 2,
    fecha: "2026-05-14",
    hora: "11:00",
    aula: "B-310",
  },
  {
    materia: "Inglés IV",
    parcial: 2,
    fecha: "2026-05-15",
    hora: "12:00",
    aula: "A-201",
  },
];

const EXAMENES_FINALES = [
  {
    materia: "Estructuras de Datos",
    fecha: "2026-06-22",
    hora: "07:00",
    aula: "B-201",
  },
  {
    materia: "Cálculo Integral",
    fecha: "2026-06-24",
    hora: "08:30",
    aula: "A-105",
  },
  {
    materia: "Programación Orientada a Objetos",
    fecha: "2026-06-26",
    hora: "10:00",
    aula: "Lab-3",
  },
  {
    materia: "Redes de Computadoras",
    fecha: "2026-06-29",
    hora: "11:00",
    aula: "B-310",
  },
  { materia: "Inglés IV", fecha: "2026-07-01", hora: "12:00", aula: "A-201" },
];

const TAREAS = [
  {
    materia: "Estructuras de Datos",
    tarea: "Implementar árbol AVL en C++",
    fechaEntrega: "2026-03-10",
    entregado: false,
  },
  {
    materia: "Cálculo Integral",
    tarea: "Ejercicios 4.1 al 4.5 del libro",
    fechaEntrega: "2026-03-12",
    entregado: false,
  },
  {
    materia: "Programación Orientada a Objetos",
    tarea: "Diagrama UML del proyecto final",
    fechaEntrega: "2026-03-15",
    entregado: false,
  },
  {
    materia: "Redes de Computadoras",
    tarea: "Reporte de práctica de subredes",
    fechaEntrega: "2026-03-18",
    entregado: true,
  },
  {
    materia: "Inglés IV",
    tarea: "Ensayo 'My future career' (500 words)",
    fechaEntrega: "2026-03-20",
    entregado: false,
  },
  {
    materia: "Estructuras de Datos",
    tarea: "Investigación sobre grafos",
    fechaEntrega: "2026-04-05",
    entregado: false,
  },
];

const DIAS_INHABILES = [
  { fecha: "2026-03-16", motivo: "Asueto por período de exámenes" },
  { fecha: "2026-04-02", motivo: "Jueves Santo" },
  { fecha: "2026-04-03", motivo: "Viernes Santo" },
  { fecha: "2026-05-01", motivo: "Día del Trabajo" },
  { fecha: "2026-05-05", motivo: "Batalla de Puebla" },
  { fecha: "2026-06-15", motivo: "Inicio de semana de preparación a finales" },
];

const INSCRIPCION = {
  periodoInscripcion: { inicio: "2026-07-06", fin: "2026-07-17" },
  monto: 4850.0,
  moneda: "MXN",
  requisitos: [
    "No tener adeudos en biblioteca",
    "No tener adeudos financieros con la institución",
    "Credencial de estudiante vigente",
    "Comprobante de pago de inscripción",
    "Kardex actualizado con promedio mínimo de 7.0",
    "Llenar formulario de reinscripción en línea (portal estudiantil)",
  ],
  bancos: ["BBVA", "Santander", "Banamex"],
  referenciaPago: "REINSC-" + STUDENT.matricula,
};

Estructura del servidor

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
import { z } from "zod";

const server = new McpServer({
  name: "simple-mcp-server",
  version: "1.0.0",
});

Cada herramienta se registra con un nombre, descripción, esquema de entrada (Zod) y su handler, ejemplo:

server.registerTool(
  "get_materias",
  {
    description: "Retorna la lista de materias inscritas en el semestre actual",
    inputSchema: z.object({}),
  },
  async () => ({
    content: [{ type: "text", text: JSON.stringify(MATERIAS, null, 2) }],
  })
);

Tools disponibles

Se registraron 10 herramientas o tools en el servidor:

ToolDescripción
get_student_infoNombre, matrícula, carrera y semestre del usuario o alumno que está autenticado para usar el mcp. Para fines de este ejemplo no se ha implementado ningún esquema de seguridad.
get_materiasLista de materias especificando información del maestro y correo electrónico
get_horariosHorario semanal por materia y aula
get_examenes_parcialesFechas de parciales (filtrable por parcial 1 o 2)
get_examenes_finalesFechas de exámenes finales
get_tareas_pendientesTareas sin entregar
get_maestro_infoInformación del Maestro o Docente
get_dias_inhabilesDías festivos y vacaciones del semestre
get_inscripcion_infoFechas, montos y requisitos de reinscripción

Versionamiento y Seguridad

Versionamiento

El SDK de MCP implementa negociación de versión de protocolo en el handshake inicial. Al conectarse, cliente y servidor intercambian el campo protocolVersion (ej. "2025-06-18"). Si las versiones no son compatibles, la conexión se termina. Esto garantiza backward compatibility a medida que el protocolo evoluciona.

A nivel de servidor, esta información se declara la versión en la inicialización:

const server = new McpServer({
  name: "simple-mcp-server",
  version: "1.0.0", // versión de tu aplicación
});

Seguridad (por implementar)

El servidor actual usa WebStandardStreamableHTTPServerTransport, por lo que es accesible de forma remota. Por lo que para una integración con datos reales hay varias capas de seguridad a considerar:

Autenticación:

  • Con Streamable HTTP: implementar OAuth 2.0, bearer tokens o API keys en headers HTTP.

Autorización:

  • Validar en cada tool que el usuario tiene permiso para acceder al recurso solicitado.
  • Para datos escolares reales: verificar sesión/JWT antes de consultar la base de datos.

Validación de inputs:

  • Ya implementado con Zod en cada tool — rechaza inputs malformados antes de procesarlos.

Nota: Cuando se crean servidores MCP que se consumirán desde una aplicación web, es obligatorio configurar CORS en el servidor MCP.  MCP server no tiene funciones de autenticación/autorización nativas, por lo que depender de políticas CORS, TLS y OAuth es crucial para proteger los datos.


Cómo integrarlo con Claude CLI

1. Prepara el servidor

Asegúrate de que el servidor se esté ejecutando. En mi caso el servidor se encuentra escuchando en http://localhost:3000:

Servidor

2. Registra el servidor en Claude CLI

Agrega el servidor usando el siguiente comando de Claude CLI:

claude mcp add control-escolar --transport http http://localhost:3000/api/mcp

3. Verifica la conexión

claude mcp list

O usando el manejador de MCP servers desde el cliente de Claude Code:

MCP Servers


Ejemplo de consulta real

Una vez integrado, puedes tener conversaciones como esta directamente en tu terminal con claude:

Usuario:

dame mi lista de materias para este semestre

Claude (invoca get_materias internamente):

IDMateriaCréditosMaestro
ISC401Estructuras de Datos5Dr. Alejandro Ríos
ISC402Cálculo Integral5Mtra. Sofía Vargas
ISC403Programación Orientada a Objetos4Ing. Marco Pérez
ISC404Redes de Computadoras4Dr. Luis Herrera
ISC405Inglés IV3Mtra. Ana Torres

Usuario:

escribe un correo para el maestro de Inglés IV diciendo que no podré asistir al examen del segundo parcial

Claude (invoca get_examenes_parciales con parcial: 2 y get_maestro_info con "Inglés IV"):

Estimada Mtra. Ana Torres: Por medio del presente correo me dirijo a usted para informarle que no me será posible asistir al examen del segundo parcial de Inglés IV, programado para el 15 de mayo de 2026 a las 12:00 hrs. en el aula A-201

Claude encadenó dos herramientas de forma autónoma para construir una respuesta contextual completa — sin que el usuario tuviera que especificar fechas ni datos del maestro.

Usuario:

Dime las tareas que tengo pendientes por entregar y planifica una calendarización de actividades para realizar cada actividad y entregarla a tiempo.

Claude (invoca get_student_info, get_dias_inhabiles y get_tareas_pendientes):

Agents AI


Conclusión

MCP es una apuesta seria por estandarizar la forma en que los modelos de lenguaje interactúan con el mundo. Lo que antes requería integraciones personalizadas por cada aplicación, ahora se resuelve con un protocolo común y un SDK bien diseñado.

Con menos de 300 líneas de TypeScript, este servidor transforma a Claude en un asistente que conoce tu horario, sabe cuándo son tus exámenes y puede redactar correos con contexto real. La diferencia entre un chatbot genérico y un asistente verdaderamente útil está exactamente aquí: en el contexto.

El siguiente paso natural es conectar el servidor a una base de datos real, agregar autenticación con OAuth y establecer los mecanismos de seguridad adecuados.

El código fuente está disponible en el repositorio del proyecto [mcp-example](https://github.com/rulopimentel/mcp-example).