Guía9 min

MCP con Python: conecta APIs y bases de datos a tu agente

TL;DR

Cómo construir un servidor MCP en Python con el SDK oficial de FastMCP: exponer una herramienta que consulta una API externa y otra que lee una base de datos SQLite en modo solo lectura, conectarlo a Claude Code, y las reglas de seguridad, límites y verificación antes de darle herramientas reales a tu agente.

Anthropic
Diagrama de un servidor MCP en Python conectando un agente a una API y a una base de datos

Por qué importa

Esta nota se enfoca en la decisión práctica para builders: qué cambia, qué riesgo agrega y cómo aplicarlo sin romper operación.

El Model Context Protocol (MCP) estandariza cómo un agente usa herramientas externas, y el SDK oficial de Python lo vuelve ridículamente simple: con unas líneas de FastMCP conviertes una función cualquiera en una herramienta que tu agente puede invocar. El caso más útil para empezar: un servidor que consulta una API externa y lee una base de datos local. Así tu agente deja de inventar datos y empieza a responder con información real, con permisos controlados por ti.

Qué necesitas

pip install "mcp[cli]" httpx

El paquete mcp incluye FastMCP, la clase que define el servidor y sus herramientas. La documentación oficial del Python SDK recomienda este camino para la mayoría de servidores: definir herramientas como funciones decoradas y dejar que el SDK maneje el transporte y los tipos.

Paso 1: una herramienta que consulta una API

El primer caso típico: exponer datos de una API externa para que el agente los consulte sin que tú tengas que pegar respuestas en el prompt.

from mcp.server.fastmcp import FastMCP
import httpx

mcp = FastMCP("mi-servidor")

@mcp.tool()
def estado_servicio(servicio: str) -> str:
    """Consulta el estado de un servicio externo por su nombre."""
    url = f"https://api.ejemplo.com/status/{servicio}"
    with httpx.Client(timeout=10) as client:
        resp = client.get(url)
        resp.raise_for_status()
        return f"{servicio}: {resp.json()['estado']}"

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

La firma de la función define el schema de la herramienta: los nombres de parámetros y sus tipos son lo que el modelo ve para decidir cómo llamarla. La docstring es el prompt de la herramienta: cuanto más clara, mejor decide el agente.

Paso 2: una herramienta que lee tu base de datos

El segundo caso: datos propios. Con SQLite no necesitas servidor de base de datos ni credenciales; solo el archivo.

import sqlite3

@mcp.tool()
def ventas_por_dia(fecha: str) -> list[dict]:
    """Devuelve las ventas registradas de una fecha (formato YYYY-MM-DD)."""
    conn = sqlite3.connect("file:datos.db?mode=ro", uri=True)
    try:
        rows = conn.execute(
            "SELECT producto, monto FROM ventas WHERE fecha = ?",
            (fecha,),
        ).fetchall()
        return [{"producto": r[0], "monto": r[1]} for r in rows]
    finally:
        conn.close()

Detalle que no es menor: la conexión usa mode=ro (solo lectura) y consultas parametrizadas. El agente genera el argumento fecha; tu código controla que nunca haya escritura ni inyección SQL. Esa separación —el modelo propone, tu código valida— es la base de cualquier integración segura.

Arquitectura del servidor MCP en Python: agente, protocolo, herramientas de API y base de datos

Paso 3: conectar el servidor a Claude Code

Guarda el archivo como servidor.py y conéctalo por stdio (proceso local):

claude mcp add mi-servidor -- python servidor.py
claude mcp list

Con claude mcp list verificas que el servidor está registrado y en qué transporte. Al reiniciar la sesión, el agente puede llamar estado_servicio y ventas_por_dia como si fueran funciones nativas. Para servidores remotos, el transporte HTTP (Streamable HTTP) es la opción; para desarrollo local, stdio es más simple y no expone nada en la red.

Seguridad y límites

Conectar un servidor MCP es darle a tu agente una mano dentro de tu sistema. Antes de agregar herramientas:

  1. Mínimo privilegio: base de datos en solo lectura, API key con los scopes más reducidos posibles.
  2. Valida todo en el servidor: el modelo genera argumentos; tu código decide qué es aceptable.
  3. Nada de credenciales en el prompt: la API key vive en variables de entorno del proceso, no en la conversación.
  4. Revisa qué expones: si el servidor trae una herramienta de escritura que no necesitas, no la agregues.
  5. Mide el costo: cada llamada a herramienta consume tokens; una sesión con MCP activo cuesta más que una conversación simple.

Verificación antes de usarlo en producción

  1. claude mcp list muestra el servidor con estado correcto.
  2. Llamaste cada herramienta al menos una vez y la respuesta es correcta.
  3. Probaste un argumento inválido (fecha mal formada, servicio inexistente) y el error es claro.
  4. Confirmaste que la base de datos está en modo solo lectura (intenta una escritura desde la herramienta y verifica que falla).
  5. Revisaste que ninguna credencial aparezca en los logs de la sesión.

Verificación de un servidor MCP: lista de servidores, prueba de herramientas y permisos de solo lectura

Más allá de las herramientas: recursos y prompts

Las herramientas no son la única capacidad de un servidor MCP. El protocolo también define recursos —datos que el host puede leer bajo demanda, como un archivo de configuración o el esquema de la base— y prompts —plantillas de interacción que el servidor ofrece. Un patrón útil: exponer el esquema de tus tablas como recurso, para que el agente pueda consultarlo antes de pedir datos y formule mejores preguntas:

from mcp.server.fastmcp import FastMCP, Resource

@Resource("esquema://ventas")
def esquema_ventas() -> str:
    """Devuelve las columnas de la tabla ventas."""
    return "ventas(fecha TEXT, producto TEXT, monto REAL)"

Empieza con herramientas y agrega recursos cuando el agente necesite contexto repetido: menos tokens, respuestas más precisas y un solo lugar donde mantener el esquema actualizado.

Errores comunes al montar el servidor

  • claude mcp list no muestra el servidor: revisa que la ruta al script y el intérprete de Python sean correctos; prueba el servidor directo con python servidor.py antes de conectarlo.
  • La herramienta devuelve errores de tipos: el SDK valida los argumentos contra la firma de la función; si el modelo envía algo raro, revisa que los tipos y docstrings sean explícitos.
  • El servidor remoto no autentica: los transportes HTTP requieren autenticación explícita; para desarrollo local, stdio evita todo el problema de red.
  • Credenciales filtradas en logs: nunca imprimas la API key; usa variables de entorno y revisa que los mensajes de error no incluyan encabezados.
  • El modelo no descubre la herramienta: revisa que la docstring describa cuándo y cómo usarla; los modelos eligen herramientas por su firma y descripción, no por magia.

Cuándo no usar MCP

MCP brilla cuando la herramienta se reutiliza entre agentes y hosts. Para un solo endpoint privado, un function call directo en tu código es más simple, más barato y más fácil de auditar. Y si tu base de datos maneja datos sensibles, la recomendación es auditar quién mantiene el servidor y a dónde envía datos antes de conectarlo.

Para entender el protocolo completo —herramientas, recursos y transportes— lee MCP explicado: cómo conectar herramientas a tu agente, y antes de exponer datos sensibles, revisa seguridad en MCP: permisos y tool poisoning. Si quieres ver el patrón de datos aplicado a PostgreSQL y RAG, el hub de construcción de agentes te lleva al resto, y el curso gratuito de instalación te deja el primer agente corriendo.