Skip to content
BotServBotServ
MCPMCP-ServerModel Context ProtocolAgentes de IAIA Local

Construir tu propio servidor MCP

Construye tu propio servidor MCP para agentes de IA locales. Protocolo, herramientas, transporte, JSON-RPC y mejores prácticas.

S

schutzgeist

5 min read
Construir tu propio servidor MCP

Construir tu propio servidor MCP

Qué trata este artículo

  • Qué es el Model Context Protocol (MCP).
  • Cómo está estructurado un servidor MCP.
  • Cómo definir herramientas, recursos y prompts.
  • Qué tipos de transporte existen.
  • Un ejemplo sencillo en TypeScript y Python.
  • Buenas prácticas y problemas comunes.

Introducción: Construir tu propio servidor MCP

El Model Context Protocol (MCP) es un estándar abierto para conectar agentes de IA con fuentes de datos externas y herramientas. Un servidor MCP proporciona funcionalidades que un cliente MCP puede invocar. Al construir tu propio servidor MCP, puedes integrar bases de datos específicas de tu empresa, APIs o herramientas locales en flujos de trabajo con IA.

Este artículo muestra cómo crear un servidor MCP sencillo desde cero. Va dirigido a desarrolladores y usuarios que alojan localmente sus sistemas, quienes desean poner sus propias herramientas a disposición de los agentes.

Qué es MCP

MCP define una comunicación estandarizada entre un cliente MCP y un servidor MCP. El cliente es típicamente un agente de IA o una interfaz de chat. El servidor ofrece:

  • Herramientas: Funciones que el agente puede invocar.
  • Recursos: Datos que el agente puede leer.
  • Prompts: Plantillas para tareas específicas.
  • Sampling: Solicitudes inversas del servidor al cliente.

La comunicación ocurre mediante JSON-RPC 2.0.

Conceptos clave

  • Host MCP: Aplicación que contiene un cliente MCP, como Claude Desktop o un framework de agentes.
  • Cliente MCP: Se comunica con uno o más servidores MCP.
  • Servidor MCP: Proporciona herramientas, recursos y prompts.
  • Herramienta: Función ejecutable con nombre, descripción y esquema JSON.
  • Recurso: Fuente de datos direccionable, por ejemplo un archivo o tabla de base de datos.
  • Transporte: Canal de comunicación, usualmente stdio o Server-Sent Events sobre HTTP.
  • JSON-RPC: Protocolo ligero para llamadas a procedimientos remotos.

Tipos de transporte

stdio

El servidor se ejecuta como un subproceso del cliente. La comunicación ocurre a través de entrada y salida estándar. Es particularmente sencillo para herramientas locales.

SSE sobre HTTP

El servidor se ejecuta como un servicio independiente. El cliente se conecta mediante HTTP y recibe mensajes a través de Server-Sent Events. Funciona bien para configuraciones remotas o con múltiples clientes.

Estructura de un servidor MCP

Un servidor MCP debe proporcionar lo siguiente:

  1. Inicialización: Intercambiar versión del protocolo y capacidades.
  2. Capacidades: Comunicar qué herramientas, recursos y prompts están disponibles.
  3. Gestores de herramientas: Ejecutar funciones para cada herramienta.
  4. Gestores de recursos: Devolver recursos bajo demanda.
  5. Manejo de errores: Enviar mensajes de error claros al cliente.

Ejemplo sencillo en Python

Este servidor ofrece una herramienta get_current_time que devuelve la hora actual.

# server.py
import json
import sys
from datetime import datetime


def send_message(msg):
    payload = json.dumps(msg)
    print(payload, flush=True)


def handle_request(req):
    method = req.get("method")
    id_ = req.get("id")

    if method == "initialize":
        return {
            "jsonrpc": "2.0",
            "id": id_,
            "result": {
                "protocolVersion": "2024-11-05",
                "capabilities": {"tools": {}},
                "serverInfo": {"name": "time-server", "version": "1.0.0"},
            },
        }

    if method == "tools/list":
        return {
            "jsonrpc": "2.0",
            "id": id_,
            "result": {
                "tools": [
                    {
                        "name": "get_current_time",
                        "description": "Devuelve la hora actual.",
                        "inputSchema": {
                            "type": "object",
                            "properties": {},
                        },
                    }
                ]
            },
        }

    if method == "tools/call":
        name = req["params"]["name"]
        if name == "get_current_time":
            now = datetime.now().isoformat()
            return {
                "jsonrpc": "2.0",
                "id": id_,
                "result": {
                    "content": [{"type": "text", "text": f"Hora actual: {now}"}]
                },
            }
        return {"jsonrpc": "2.0", "id": id_, "error": {"code": -32601, "message": "Herramienta no encontrada"}}

    return {"jsonrpc": "2.0", "id": id_, "error": {"code": -32601, "message": "Método no encontrado"}}


def main():
    for line in sys.stdin:
        line = line.strip()
        if not line:
            continue
        req = json.loads(line)
        resp = handle_request(req)
        send_message(resp)


if __name__ == "__main__":
    main()

El servidor lee solicitudes JSON-RPC línea por línea desde stdin y escribe respuestas a stdout.

Configuración en Claude Desktop

Después de construir el archivo del servidor, puedes registrarlo en Claude Desktop. En macOS, la configuración se encuentra en ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "time": {
      "command": "python3",
      "args": ["/ruta/a/server.py"]
    }
  }
}

Después de reiniciar Claude Desktop, la herramienta get_current_time estará disponible.

SDKs de MCP

En lugar de construirlo todo manualmente, puedes aprovechar los SDKs:

  • SDK de Python: mcp en PyPI.
  • SDK de TypeScript: @modelcontextprotocol/sdk en npm.
  • SDK de Java: mcp-java.

Estos SDKs se encargan de versiones de protocolo, transporte y detalles de JSON-RPC.

Buenas prácticas

  • Descripciones claras de herramientas: El modelo de lenguaje decide si usar una herramienta basándose en su descripción.
  • Validación segura de entrada: Cada argumento de herramienta debe ser verificado.
  • Mensajes de error informativos: Devuelve errores significativos para que el agente pueda reaccionar.
  • Sin estado: Las herramientas no deben mantener estado oculto.
  • Permisos: El servidor solo debe realizar acciones para las que está autorizado.
  • Logging: Envía salida a stderr para mantener stdout limpio para JSON-RPC.

Problemas comunes

  • Formato JSON-RPC incorrecto: Faltan campos jsonrpc o id.
  • stdout contaminado: Salida de depuración en stdout en lugar de stderr.
  • Capacidades faltantes: El cliente no sabe qué herramientas están disponibles.
  • Descripciones de herramientas poco claras: El modelo invoca la herramienta incorrecta.
  • Sin validación de entrada: Entradas malformadas causan errores.
  • Mezcla de transportes: No mezcles stdio y HTTP en el mismo servidor.

Enlaces e información adicional

FAQ: Construir tu propio servidor MCP

¿Necesito un framework especial? No. Un servidor MCP puede implementarse en cualquier lenguaje que hable JSON-RPC. Los SDKs facilitan el comienzo.

¿Puede un servidor MCP ofrecer múltiples herramientas? Sí. tools/list devuelve un array con todas las herramientas.

¿Qué tan seguro es un servidor MCP? Se ejecuta localmente y solo realiza lo que está definido en el código. Sin embargo, debes validar cada entrada y restringir permisos.

¿Cuál es la diferencia entre stdio y SSE? stdio es más simple para procesos locales, SSE funciona mejor para configuraciones de red o contenedores.

¿Puedo ejecutar un servidor MCP en Docker? Sí. En ese caso, SSE sobre HTTP o un wrapper que proporcione stdio al cliente son buenas opciones.

Fuentes y lecturas adicionales

Resumen: Construir tu propio servidor MCP

Un servidor MCP propio amplía los agentes de IA con herramientas especializadas y fuentes de datos. El Model Context Protocol se basa en JSON-RPC y soporta transporte stdio e HTTP. Lo importante es proporcionar descripciones claras de herramientas, validar entradas de forma segura, manejar errores adecuadamente y separar stdout de stderr. Una vez comprendas el protocolo, puedes integrar funcionalidades específicas de tu empresa de forma segura en flujos de trabajo locales con agentes.

Volver al blog
Share:

Entradas relacionadas