Convierte cualquier API REST en un MCP con FastMCP

Convierte cualquier API REST en un MCP con FastMCP

API MCP Python Automatización 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

HerramientaVersión probadaUso
Python3.9+Lenguaje principal
uv0.1.43Gestión de entornos / dependencias
GitCualquieraControl de versiones
Railway CLIOpcionalDespliegue

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

  1. Crea un nuevo proyecto desde tu repositorio.
  2. En Settings → Variables copia los pares HOST=0.0.0.0 y PORT=8000.
  3. En Deployments → Start Command escribe:
    uv run python main.py
  4. 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


¡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.