
Convierte cualquier API REST en un MCP con FastMCP
Qué es un MCP
Un Model Context Protocol dicta cómo un servicio ordena y gestiona el contexto de sus datos. Con él puedes:
- Uniformar las respuestas de varias APIs.
- Ofrecer una única puerta de entrada a distintos servicios.
- Mantener el código con menos esfuerzo y añadir nuevas rutas sin dolores de cabeza.
Ventajas de usar FastMCP
- Reduce la complejidad a la hora de integrar APIs.
- Mantiene la coherencia en el manejo de datos.
- Da control total sobre las transformaciones.
- Permite sumar servicios nuevos en minutos.
Requisitos previos
Herramienta | Versión probada | Uso |
---|---|---|
Python | 3.9+ | Lenguaje principal |
uv | 0.1.43 | Gestión de entornos / dependencias |
Git | Cualquiera | Control de versiones |
Railway CLI | Opcional | Despliegue |
Nota: uv funciona de forma muy parecida a npm. Si vienes de JavaScript te sentirás como en casa.
Preparación del proyecto
# 1. Crear carpeta y entorno
uv init dragonball-mcp-server
cd dragonball-mcp-server
# 2. Inicializar repositorio Git
git init
# 3. Añadir dependencias
uv add fastmcp httpx python-dotenv
Crea un archivo .gitignore
en la raíz con el contenido habitual para proyectos Python (cachés, entornos virtuales, ficheros temporales, etc.).
Variables de entorno
Añade un archivo .env
con lo mínimo para el desarrollo local:
HOST=127.0.0.1
PORT=8000
DEBUG=true
Definir el cliente HTTP
La Dragon Ball API expone sus rutas bajo https://dragonball-api.com/api
. El certificado SSL no cubre el subdominio www
, así que no lo incluyas.
import httpx
client = httpx.AsyncClient(base_url="https://dragonball-api.com/api")
Obtener la especificación OpenAPI
La forma rápida es descargarla en tiempo de arranque:
import requests, yaml
spec_url = "https://dragonball-api.com/api-docs/openapi.yaml"
openapi_spec = yaml.safe_load(requests.get(spec_url, timeout=10).text)
Para evitar una petición extra en cada inicio, puedes copiarla una vez a un módulo dragonball_spec.py
. Hay un ejemplo listo en este gist:
https://gist.github.com/ivanlhz/f0d7fce62c2975c394a5fbb48521ab8a
Crear el servidor MCP
Ahora que tienes la especificación OpenAPI y el cliente HTTP listos, solo necesitas unos pocos pasos para levantar tu propio servidor MCP. El siguiente código crea una instancia de FastMCP usando la especificación de la API y el cliente, y expone el servidor en la ruta /mcp
.
FastMCP.from_openapi(...)
genera automáticamente los endpoints MCP a partir de tu OpenAPI y cliente.- El bloque
if __name__ == "__main__":
permite arrancar el servidor usando variables de entorno para el host y el puerto. - El método
mcp.run(...)
inicia el servidor y lo deja listo para recibir conexiones MCP. - El parámetro
transport="streamable-http"
indica que el servidor usará HTTP como protocolo de comunicación, permitiendo que cualquier cliente compatible pueda interactuar con el MCP desde la web o desde otras aplicaciones.
from fastmcp import FastMCP
from dragonball_spec import openapi_spec # o la descarga anterior
mcp = FastMCP.from_openapi(
openapi_spec=openapi_spec,
client=client,
name="DragonBallAPI MCP Server"
)
if __name__ == "__main__":
import os
host = os.getenv("HOST", "127.0.0.1")
port = int(os.getenv("PORT", 8000))
print(f"Iniciando MCP en {host}:{port}")
mcp.run(
transport="streamable-http",
host=host,
port=port,
path="/mcp"
)
Cliente de prueba
Para comprobar que tu servidor MCP funciona correctamente, puedes usar este sencillo script de prueba. El cliente se conecta al servidor, obtiene la lista de herramientas generadas a partir de tu OpenAPI y las muestra por pantalla. Así puedes verificar que todo está bien configurado antes de integrar con otras aplicaciones.
Guarda lo siguiente como mcp_client.py
y ejecútalo en otra terminal cuando el servidor esté en marcha.
import asyncio, os
from fastmcp import Client
from dotenv import load_dotenv
load_dotenv()
async def main():
host = os.getenv("HOST", "127.0.0.1")
port = int(os.getenv("PORT", 8000))
async with Client(f"http://{host}:{port}/mcp") as client:
tools = await client.list_tools()
print("Herramientas generadas:")
for t in tools:
print("-", t.name)
print("\nEjecutando 'get_character_by_id' con id=1...")
result = await client.call_tool("get_character_by_id", {"id": 1})
print("Respuesta:\n", result[0].text)
if __name__ == "__main__":
asyncio.run(main())
Solución al error SSL
Si encuentras un traceback parecido a:
certificate verify failed: Hostname mismatch, certificate is not valid for 'www.dragonball-api.com'
significa que estás apuntando a https://www.dragonball-api.com
. Usa la URL sin www
o, en última instancia, añade verify=False
al cliente solo para pruebas locales:
client = httpx.AsyncClient(base_url="https://dragonball-api.com/api", verify=False) # ← no en producción
Despliegue en Railway
- Crea un nuevo proyecto desde tu repositorio.
- En Settings → Variables copia los pares
HOST=0.0.0.0
yPORT=8000
. - En Deployments → Start Command escribe:
uv run python main.py
- Pulsa Deploy y espera a que aparezca la URL pública. Ahí encontrarás tu MCP accesible en
/mcp
.
Apéndice
Scripts útiles en pyproject.toml
[tool.uv.scripts]
serve = "python main.py"
client = "python mcp_client.py"
Ahora basta con:
uv run serve # arranca el servidor
uv run client # lanza el cliente de prueba
Configuración en Claude Desktop (MCP)
Si quieres conectar tu API desplegada en Railway desde Claude Desktop usando el protocolo MCP, añade lo siguiente a la configuración de MCP:
Nota: ¡Recuerda reemplazar la URL por la de tu propio despliegue de Railway!
"dragonball-api": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"https://<tu-url-de-railway>/mcp/",
"--allow-http",
"--debug"
]
}
Por ejemplo, si tu URL pública de Railway es:
https://dragonballapi-mcp-server-production.up.railway.app/mcp/
la configuración quedaría así:
"dragonball-api": {
"command": "npx",
"args": [
"-y",
"mcp-remote@latest",
"https://dragonballapi-mcp-server-production.up.railway.app/mcp/",
"--allow-http",
"--debug"
]
}
Esto permite que Claude Desktop reconozca y utilice tu conector MCP de forma remota, facilitando la integración y pruebas.
Recursos
- Documentación completa de la API: https://web.dragonball-api.com/documentation
- Repositorio de FastMCP: https://github.com/MaxAPain/fastmcp
- Proyecto ejemplo terminado: https://github.com/ivanlhz/dragonballapi-mcp-server
¡Listo! En menos de 100 líneas has conseguido que un modelo de lenguaje consulte la base de datos de Dragon Ball sin escribir wrappers manuales.