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.

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.

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:
- Mínimo privilegio: base de datos en solo lectura, API key con los scopes más reducidos posibles.
- Valida todo en el servidor: el modelo genera argumentos; tu código decide qué es aceptable.
- Nada de credenciales en el prompt: la API key vive en variables de entorno del proceso, no en la conversación.
- Revisa qué expones: si el servidor trae una herramienta de escritura que no necesitas, no la agregues.
- 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
claude mcp listmuestra el servidor con estado correcto.- Llamaste cada herramienta al menos una vez y la respuesta es correcta.
- Probaste un argumento inválido (fecha mal formada, servicio inexistente) y el error es claro.
- Confirmaste que la base de datos está en modo solo lectura (intenta una escritura desde la herramienta y verifica que falla).
- Revisaste que ninguna credencial aparezca en los logs de la sesión.

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 listno muestra el servidor: revisa que la ruta al script y el intérprete de Python sean correctos; prueba el servidor directo conpython servidor.pyantes 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.
Artículos relacionados
Sigue explorando MCP y otras lecturas para builders.

MCP explicado: cómo conectar herramientas a tu agente sin reinventar la rueda

Atlassian Rovo MCP v2 reduce más de 50% el contexto expuesto con discover y execute

Smartsheet enseña cómo operar un MCP remoto: gateway, ráfagas y tokens bajo control
