Ir al contenido principal
IngenieríaMar 28, 2026

Construye tu primer servidor MCP: guia practica para desarrolladores

OS
Open Soft Team

Engineering Team

Que es el Model Context Protocol (MCP)?

El Model Context Protocol (MCP) es un estandar abierto creado por Anthropic que define como las aplicaciones de AI se comunican con fuentes de datos y herramientas externas. Piensa en MCP como el USB-C para la integracion de AI: asi como USB-C proporciona un unico conector universal para carga, transferencia de datos y salida de pantalla, MCP proporciona un unico protocolo universal para conectar modelos de AI a bases de datos, APIs, sistemas de archivos y cualquier otro servicio. MCP elimina la necesidad de integraciones personalizadas entre cada aplicacion de AI y cada herramienta.

En 2026, MCP se ha convertido en el estandar dominante para la comunicacion AI-herramientas. Gartner predice que el 40 % de las aplicaciones empresariales incluiran agentes de AI para finales de 2026, y MCP es el protocolo que hace esto practico a gran escala. Antes de MCP, conectar un modelo de AI a N herramientas requeria N integraciones personalizadas. Con M aplicaciones de AI y N herramientas, se necesitaban M x N adaptadores de integracion. MCP reduce esto a M + N: cada aplicacion de AI implementa un MCP client, cada herramienta implementa un MCP server.

Arquitectura MCP: Host, Client, Server y Transport

Comprender la arquitectura MCP es esencial antes de escribir codigo. El protocolo define cuatro roles clave:

ComponenteRolEjemplo
HostLa aplicacion de AI con la que interactua el usuario finalClaude Desktop, Cursor, VS Code Copilot
ClientEl manejador del protocolo MCP dentro del hostIntegrado en la aplicacion host
ServerExpone tools, resources y prompts a traves de MCPTu servidor personalizado (lo que vamos a construir)
TransportLa capa de comunicacion entre client y serverstdio, HTTP+SSE, Streamable HTTP

El flujo de comunicacion funciona asi:

  1. El Host arranca e inicializa un MCP Client para cada servidor configurado.
  2. El Client se conecta al Server a traves de un Transport (stdio para local, HTTP para remoto).
  3. El Client envia una solicitud initialize, negociando la version del protocolo y las capacidades.
  4. El Server responde con sus tools, resources y prompts disponibles.
  5. Cuando el modelo de AI necesita datos o acciones externas, el Client llama al metodo del servidor apropiado.
  6. El Server ejecuta la operacion y devuelve los resultados a traves de mensajes JSON-RPC 2.0.

Tools vs Resources vs Prompts

Los MCP servers pueden exponer tres tipos de capacidades:

  • Tools son funciones que el modelo de AI puede llamar. Aceptan entrada estructurada y devuelven salida estructurada. Ejemplo: query_database(sql: string) o send_email(to: string, subject: string, body: string).
  • Resources son datos que el modelo de AI puede leer. Se identifican por URIs y devuelven contenido. Ejemplo: file:///path/to/document.md o postgres://localhost/mydb/users.
  • Prompts son plantillas de prompts reutilizables proporcionadas por el servidor. Ayudan a estandarizar como la AI interactua con el dominio del servidor. Ejemplo: una plantilla summarize_ticket para un Jira MCP server.

Paso a paso: construir un servidor MCP en TypeScript

Construyamos un servidor MCP practico que proporcione una herramienta para consultar una base de datos SQLite. Este es un caso de uso comun: dar a un modelo de AI acceso seguro de solo lectura a los datos de tu aplicacion.

Paso 1: Inicializar el proyecto

mkdir mcp-sqlite-server && cd mcp-sqlite-server
npm init -y
npm install @modelcontextprotocol/sdk better-sqlite3
npm install -D typescript @types/node @types/better-sqlite3
npx tsc --init

Configurar tsconfig.json:

{
  "compilerOptions": {
    "target": "ES2022",
    "module": "Node16",
    "moduleResolution": "Node16",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "esModuleInterop": true,
    "declaration": true
  },
  "include": ["src/**/*"]
}

Paso 2: Implementar el servidor

Crear src/index.ts:

import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import Database from "better-sqlite3";
import { z } from "zod";

const db = new Database(process.env.DB_PATH || "./data.db", {
  readonly: true,
});

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

server.tool(
  "query",
  "Ejecutar una consulta SQL de solo lectura en la base de datos SQLite",
  {
    sql: z.string().describe("La consulta SQL SELECT a ejecutar"),
  },
  async ({ sql }) => {
    const normalized = sql.trim().toUpperCase();
    if (!normalized.startsWith("SELECT")) {
      return {
        content: [{ type: "text", text: "Error: solo se permiten consultas SELECT." }],
        isError: true,
      };
    }
    try {
      const rows = db.prepare(sql).all();
      return {
        content: [{ type: "text", text: JSON.stringify(rows, null, 2) }],
      };
    } catch (error) {
      return {
        content: [{ type: "text", text: `Error de consulta: ${(error as Error).message}` }],
        isError: true,
      };
    }
  }
);

server.tool(
  "list_tables",
  "Listar todas las tablas de la base de datos con sus esquemas",
  {},
  async () => {
    const tables = db
      .prepare(
        `SELECT name, sql FROM sqlite_master
         WHERE type='table' AND name NOT LIKE 'sqlite_%'
         ORDER BY name`
      )
      .all();
    return {
      content: [{ type: "text", text: JSON.stringify(tables, null, 2) }],
    };
  }
);

Paso 3: Compilar y probar localmente

npx tsc
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"test","version":"1.0"}}}' | node dist/index.js

Deberas ver una respuesta JSON-RPC con las capacidades del servidor.

Paso 4: Construir el mismo servidor en Python

Para desarrolladores Python, aqui esta la implementacion equivalente usando el SDK oficial de Python para MCP:

import sqlite3
import json
from mcp.server.fastmcp import FastMCP

mcp = FastMCP("sqlite-query")
DB_PATH = "data.db"

@mcp.tool()
def query(sql: str) -> str:
    """Ejecutar una consulta SQL de solo lectura en la base de datos SQLite."""
    normalized = sql.strip().upper()
    if not normalized.startswith("SELECT"):
        raise ValueError("Solo se permiten consultas SELECT.")
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    try:
        cursor = conn.execute(sql)
        rows = [dict(row) for row in cursor.fetchall()]
        return json.dumps(rows, indent=2, default=str)
    finally:
        conn.close()

@mcp.tool()
def list_tables() -> str:
    """Listar todas las tablas de la base de datos con sus esquemas."""
    conn = sqlite3.connect(DB_PATH)
    conn.row_factory = sqlite3.Row
    try:
        cursor = conn.execute(
            "SELECT name, sql FROM sqlite_master "
            "WHERE type='table' AND name NOT LIKE 'sqlite_%'"
        )
        tables = [dict(row) for row in cursor.fetchall()]
        return json.dumps(tables, indent=2)
    finally:
        conn.close()

if __name__ == "__main__":
    mcp.run(transport="stdio")

Conexion a Claude Desktop

Claude Desktop soporta servidores MCP de forma nativa. Para conectar tu servidor, edita el archivo de configuracion de Claude Desktop:

macOS: ~/Library/Application Support/Claude/claude_desktop_config.json Windows: %APPDATA%\Claude\claude_desktop_config.json

{
  "mcpServers": {
    "sqlite-query": {
      "command": "node",
      "args": ["/absolute/path/to/dist/index.js"],
      "env": {
        "DB_PATH": "/absolute/path/to/your/data.db"
      }
    }
  }
}

Reinicia Claude Desktop. Veras un icono de martillo en la interfaz de chat indicando las herramientas MCP disponibles. Ahora puedes hacer preguntas a Claude como “Que tablas hay en la base de datos?” o “Muestra los 10 principales usuarios por fecha de registro” y Claude usara tu servidor MCP para consultar la base de datos directamente.

Conexion a Cursor

Cursor tambien soporta servidores MCP. Agrega la configuracion a .cursor/mcp.json en la raiz de tu proyecto:

{
  "mcpServers": {
    "sqlite-query": {
      "command": "node",
      "args": ["./dist/index.js"],
      "env": {
        "DB_PATH": "./data.db"
      }
    }
  }
}

Despues de guardar, reinicia Cursor. Las herramientas MCP aparecen en el panel del asistente de AI y pueden invocarse durante las sesiones de generacion de codigo y depuracion.

Pruebas y depuracion de tu servidor MCP

Uso del MCP Inspector

El MCP Inspector es la herramienta oficial de depuracion. Proporciona una interfaz web para interactuar con tu servidor:

npx @modelcontextprotocol/inspector node dist/index.js

Esto abre una interfaz de navegador en http://localhost:5173 donde puedes:

  • Ver todos los tools, resources y prompts registrados
  • Llamar a tools con entradas personalizadas e inspeccionar las respuestas
  • Monitorear el flujo de mensajes JSON-RPC en tiempo real
  • Probar el manejo de errores enviando solicitudes malformadas

Problemas comunes de depuracion

ProblemaCausaSolucion
El servidor no aparece en Claude DesktopRuta de configuracion o error de sintaxis JSONValidar JSON, verificar rutas absolutas
Error “Tool not found”Los tools no estan registrados antes de conectarRegistrar tools antes de llamar a server.connect()
Timeout en llamadas a toolsOperacion de larga duracion sin progresoAgregar notificaciones de progreso via server.sendProgress()
La salida stderr corrompe el protocoloconsole.log escribe en stdout (transporte stdio)Usar console.error() para logging con stdio
Desconexion despues de inactividadTimeout del transporteImplementar heartbeat o usar transporte HTTP

Mejores practicas para produccion

  1. Validacion de entradas: Siempre valida y sanea las entradas de los tools. Usa esquemas Zod (TypeScript) o modelos Pydantic (Python) para verificacion de tipos estricta.

  2. Solo lectura por defecto: Comienza con acceso de solo lectura. Solo agrega capacidades de escritura cuando sea realmente necesario, y siempre solicita confirmacion para operaciones destructivas.

  3. Manejo de errores: Devuelve mensajes de error estructurados con isError: true. Nunca expongas stack traces internos o cadenas de conexion a la base de datos.

  4. Registro: Registra todas las llamadas a tools con marca de tiempo, entradas y duracion de ejecucion. Usa stderr para logging (no stdout) con el transporte stdio.

  5. Limitacion de velocidad: Implementa limites de velocidad por tool para evitar que bucles de AI no controlados sobrecarguen tus servicios backend.

  6. Timeout: Establece timeouts de ejecucion en todos los handlers de tools. Los modelos de AI pueden llamar a tools que disparen consultas costosas — protege tu infraestructura.

  7. Separacion de entornos: Usa variables de entorno para toda la configuracion. Nunca codifiques en duro URLs de bases de datos, claves API o rutas de archivos.

  8. Versionado: Usa versionado semantico para tu servidor MCP. El handshake initialize incluye negociacion de versiones — los cambios incompatibles requieren un bump de version mayor.

FAQ

P: Cual es la diferencia entre MCP y function calling? R: El function calling (usado por OpenAI, Anthropic y otros) define tools en linea en cada solicitud API. MCP externaliza las definiciones de tools a servidores independientes que pueden ser descubiertos y usados por hosts compatibles con MCP. El function calling es por solicitud; MCP es un protocolo persistente con sesiones stateful.

P: Puedo usar MCP con modelos que no sean Claude? R: Si. MCP es un protocolo abierto. OpenAI, Google DeepMind y Microsoft han adoptado soporte MCP en sus plataformas desde principios de 2026. Cualquier aplicacion de AI que implemente un MCP client puede conectarse a cualquier MCP server.

P: MCP es solo para herramientas locales? R: No. Aunque el transporte stdio esta disenado para servidores locales, los transportes HTTP+SSE y Streamable HTTP soportan servidores MCP remotos. Puedes desplegar un servidor MCP como servicio en la nube accesible a traves de la red.

P: Como maneja MCP la autenticacion? R: El protocolo soporta OAuth 2.0 para servidores remotos. Los servidores stdio locales heredan el contexto de seguridad del proceso host. Para despliegues empresariales, un MCP gateway puede centralizar la autenticacion y autorizacion.

P: Que lenguajes se pueden usar para construir un servidor MCP? R: Los SDKs oficiales estan disponibles para TypeScript, Python, Java, Kotlin, C# y Swift. Los SDKs de la comunidad incluyen Rust, Go, Ruby y PHP. El protocolo es agnostico en cuanto al lenguaje — cualquier lenguaje que pueda leer/escribir JSON-RPC a traves de stdio o HTTP puede implementar un servidor MCP.

P: Como actualizar un servidor MCP sin reiniciar el host? R: MCP soporta notificaciones de cambio de capacidades. Cuando los tools de tu servidor cambian, el servidor puede enviar un mensaje notifications/tools/list_changed, que indica al client que vuelva a obtener la lista de tools. Para servidores stdio, el host normalmente necesita reiniciarse. Los servidores HTTP pueden actualizarse sin reiniciar el host.

Etiquetas