En pocas palabras
Framework Python para crear servidores y clientes MCP con una API de alto nivel.
Qué problema resuelve
Código repetitivo para publicar herramientas, recursos y contratos del protocolo.
Cuándo utilizarlo
Integración de agentes con servicios. Ejemplo: exponer un cálculo de dominio como herramienta.
De la idea a la práctica
Funcionamiento, ejemplos y decisiones para pasar al siguiente nivel.
En el Radar compartido: Trial (valoración de la edición aportada).
Cómo funciona
Deriva esquemas de funciones Python y ofrece primitivas para capacidades MCP. Permite concentrarse en lógica de negocio y gestionar transporte y ciclo de vida con el framework.
Ejemplo de uso
Ejemplo ilustrativo de una herramienta sin efectos externos:
from fastmcp import FastMCP
app = FastMCP("Cálculos")
@app.tool
def subtotal(unidades: int, precio: float) -> float:
"""Calcula un subtotal de ejemplo."""
return unidades * precio
if __name__ == "__main__":
app.run()
Para importes reales, usar una representación monetaria precisa y validar rangos.
Primitivas: herramientas, recursos y prompts
from typing import Annotated
from pydantic import Field
from fastmcp import FastMCP, Context
mcp = FastMCP("cartera")
@mcp.tool
async def saldo_credito(
credito_id: Annotated[str, Field(pattern=r"^CR-\d{6}$", description="Identificador del crédito")],
ctx: Context,
) -> dict:
"""Devuelve saldo, próxima cuota y días de mora de un crédito."""
await ctx.info(f"Consultando {credito_id}")
return await api_cartera.saldo(credito_id)
@mcp.resource("politica://credito/{producto}")
def politica(producto: str) -> str:
"""Texto vigente de la política de crédito para un producto."""
return repositorio_politicas.leer(producto)
@mcp.prompt
def explicar_mora(credito_id: str) -> str:
"""Plantilla para explicar al cliente el estado de mora."""
return f"Explica con lenguaje sencillo el estado del crédito {credito_id} y las opciones de pago."
Los tipos y Field se convierten en el JSON Schema que ve el modelo, y FastMCP valida los argumentos antes de llamar a la función. El Context da acceso a logging, progreso, sampling (pedir una generación al cliente) y elicitation (pedir datos al usuario).
Transportes y despliegue
if __name__ == "__main__":
mcp.run() # stdio para clientes locales
# mcp.run(transport="http", host="0.0.0.0", port=8000) # Streamable HTTP remoto
Un servidor HTTP puede desplegarse como cualquier servicio web (por ejemplo en Cloud Run) e integrarse en una aplicación ASGI existente.
Autenticación
Para servidores remotos, FastMCP incluye verificación de tokens JWT y proveedores OAuth (Google, GitHub, Azure, WorkOS, Auth0 y otros) que implementan el flujo de autorización de la especificación MCP. Usa la identidad del usuario para aplicar permisos en cada herramienta, no una credencial técnica con acceso total.
Cliente y pruebas en memoria
import pytest
from fastmcp import Client
from servidor import mcp
@pytest.mark.asyncio
async def test_saldo_valida_formato():
async with Client(mcp) as cliente: # sin red: transporte en memoria
herramientas = await cliente.list_tools()
assert "saldo_credito" in [h.name for h in herramientas]
with pytest.raises(Exception):
await cliente.call_tool("saldo_credito", {"credito_id": "invalido"})
Composición y generación
| Función | Uso |
|---|---|
mcp.mount("pagos", otro_mcp) |
Combinar varios servidores en uno, con prefijo |
| Proxy | Exponer un servidor remoto como local, o cambiar de transporte |
FastMCP.from_openapi(...) |
Generar herramientas a partir de una especificación OpenAPI |
Generar desde OpenAPI es rápido, pero las APIs REST rara vez están diseñadas para un modelo: suele ser mejor exponer pocas herramientas de alto nivel, con descripciones claras, que cien endpoints. Ver Model Context Protocol para los riesgos de seguridad.
Criterios de implementación
Fijar versiones compatibles de cliente y servidor. Probar esquemas, errores y autorizaciones, y evitar exponer acceso arbitrario a SQL o comandos.
Continúa en las fuentes
Documentación oficial para verificar detalles y explorar más.