Herramientas para agentes con MCP: diseño de un servidor que el modelo use bien
Qué es el Model Context Protocol, cómo escribir un servidor MCP en Python, cómo diseñar nombres, descripciones y resultados de herramientas, y los riesgos de instalar servidores de terceros.

Envolver cada endpoint de tu API REST en una herramienta MCP es la forma más rápida de tener un servidor MCP y una de las peores formas de tener un agente que funcione. Una API pensada para programadores tiene decenas de endpoints granulares, parámetros técnicos y respuestas enormes en JSON. Un modelo que la usa necesita pocas herramientas, con nombres y descripciones que expliquen cuándo usarlas, y resultados breves. El protocolo resuelve la conexión; el diseño de las herramientas sigue siendo trabajo tuyo.
Qué es MCP
El Model Context Protocol, publicado por Anthropic como estándar abierto a finales de 2024, define cómo una aplicación con un modelo (el cliente) se conecta a servicios externos (los servidores). Un servidor MCP expone principalmente tres cosas: herramientas que el modelo puede invocar, recursos que la aplicación puede leer y prompts predefinidos. La comunicación funciona en local mediante entrada y salida estándar, o en remoto sobre HTTP.
La ventaja práctica: escribes la integración una vez y la usan todos los clientes compatibles con MCP, en lugar de reimplementarla para cada aplicación y cada proveedor de modelos.
Un servidor mínimo en Python
El SDK oficial de Python incluye una clase de servidor que genera el esquema de cada herramienta a partir de las anotaciones de tipo y el docstring. En la versión 2 del SDK se llama MCPServer; en la versión 1 se llamaba FastMCP y se importaba de mcp.server.fastmcp, así que muchos ejemplos que encontrarás usan todavía ese nombre:
from mcp.server.mcpserver import MCPServer
mcp = MCPServer("pedidos")
@mcp.tool()
def buscar_pedido(numero_pedido: str) -> dict:
"""Devuelve el estado, la fecha y el importe de un pedido.
Úsala cuando el usuario mencione un número de pedido (formato P-123456).
Si solo conoces el correo del cliente, usa listar_pedidos_cliente.
"""
pedido = db.obtener_pedido(numero_pedido)
if pedido is None:
return {"error": f"No existe el pedido {numero_pedido}. "
"Comprueba el formato P- seguido de 6 cifras."}
return {"estado": pedido.estado, "fecha": pedido.fecha.isoformat(),
"importe": str(pedido.importe), "moneda": pedido.moneda}
if __name__ == "__main__":
mcp.run()
El docstring se convierte en la descripción que lee el modelo. Por eso explica cuándo usar la herramienta y qué alternativa usar si no aplica, no cómo está implementada.
Diseño de herramientas para modelos
Agrupa por tarea, no por endpoint. Si para saber por qué un pedido no ha llegado hay que consultar el pedido, el envío y la incidencia con tres llamadas, una herramienta diagnosticar_entrega que haga las tres y devuelva lo relevante ahorra pasos, tokens y errores.
Devuelve poco y legible. El modelo no necesita los 60 campos del objeto pedido. Devuelve los que sirven para decidir y responder, con nombres claros. Para listados, pagina y di cuántos resultados hay en total.
Usa identificadores que el modelo pueda manejar. Los UUID largos se copian mal con más frecuencia que los identificadores cortos o los nombres. Si tu sistema usa UUID internamente, considera aceptar también el identificador visible para el usuario.
Errores que enseñan. Un error debe decir qué estuvo mal y cómo corregirlo, como en el ejemplo anterior. «Error 400» no le sirve al modelo para nada.
Nombres distintos entre sí. Si el usuario conecta varios servidores, el modelo verá todas sus herramientas juntas. buscar es ambiguo; buscar_pedido no.
Seguridad: un servidor MCP es código con acceso
Instalar un servidor MCP de un tercero es instalar software que se ejecuta con tus permisos y cuyas descripciones de herramientas entran en el contexto del modelo. Esas descripciones son una vía de inyección de prompts: un servidor malicioso puede incluir instrucciones ocultas en la descripción de una herramienta inofensiva para que el modelo haga otra cosa con otras herramientas. Instala solo servidores de fuentes en las que confíes, revisa su código o su origen, y fija la versión para que una actualización no cambie su comportamiento sin que lo sepas.
En tus propios servidores: usa las credenciales del usuario o tokens con el mínimo alcance necesario, separa las herramientas de lectura de las de escritura, y haz que las acciones destructivas o con efectos externos requieran confirmación en el cliente. Los servidores remotos necesitan autenticación; la especificación de MCP define un mecanismo basado en OAuth para ello.
El contenido que devuelven las herramientas (un correo, una página web, un ticket) también puede contener instrucciones inyectadas. MCP no cambia eso: aplican las mismas defensas que a cualquier agente que lee contenido externo.
Errores frecuentes y limitaciones
Demasiadas herramientas conectadas. Cada servidor añade sus descripciones al contexto de cada llamada. Con varios servidores de decenas de herramientas, el modelo dedica tokens a leerlas y elige peor. Conecta solo los servidores que la tarea necesita.
No probar con el modelo. Una herramienta que funciona en un test unitario puede ser usada mal por el modelo: argumentos con formato equivocado, llamadas en el orden incorrecto. Prueba con tareas reales y revisa las trayectorias; casi siempre se corrigen mejorando la descripción.
Cambiar herramientas sin versionar. Renombrar una herramienta o cambiar sus parámetros rompe prompts y flujos que dependían de ella. Trata la interfaz del servidor como una API pública.
¿MCP sustituye a la llamada a funciones de las APIs de modelos?
No, se apoya en ella. El cliente MCP descubre las herramientas del servidor y se las presenta al modelo mediante la llamada a funciones del proveedor; cuando el modelo pide una, el cliente la ejecuta en el servidor. Si tu aplicación tiene pocas herramientas propias y un solo cliente, definirlas directamente en la API puede ser más simple.
Primer servidor
Elige tres o cuatro tareas que los usuarios piden al agente, crea una herramienta por tarea con descripción de cuándo usarla, resultados breves y errores que expliquen cómo corregir, y pruébala con veinte peticiones reales revisando las trayectorias antes de añadir más herramientas.


