El principal cuello de botella en arquitecturas de agentes de IA no es la capacidad del modelo, sino la integración con sistemas externos. Cada nueva herramienta—desde una base de datos hasta una API interna—requiere código específico que acopla al agente con la implementación concreta. Model Context Protocol (MCP), propuesto por Anthropic en noviembre de 2024 y actualmente en evolución constante, busca eliminar esa fricción mediante un protocolo abierto que estandariza cómo los agentes descubren y ejecutan herramientas externas. No se trata de un estándar formal ratificado por organismos como IETF o W3C, sino de un proyecto open source (licencia MIT) que ofrece una capa de abstracción práctica y está ganando tracción rápida en el ecosistema de desarrollo de agentes.
El problema de la integración ad-hoc
Antes de MCP, integrar un agente con herramientas externas implicaba escribir código específico por cada servicio. Si tu agente necesitaba consultar PostgreSQL, interactuar con Slack y leer archivos de S3, debías implementar tres adaptadores distintos, manejar autenticaciones particulares y mapear manualmente los esquemas de entrada/salida. Este enfoque genera:
- Acoplamiento excesivo: Cambios en la API de la herramienta obligan a modificar la lógica del agente.
- Duplicación de esfuerzos: Cada equipo reimplementa conectores similares.
- Dificultad para escalar: Añadir una nueva capacidad requiere tocar el código core del agente.
- stdio: Comunicación via streams estándar (ideal para servidores locales).
- SSE (Server-Sent Events): Para servidores remotos sobre HTTP.
MCP aborda esto mediante un modelo cliente-servidor donde las herramientas se exponen como servicios independientes que cualquier agente con capacidad MCP puede consumir, siempre y cuando implemente la capa cliente correspondiente.
Arquitectura y componentes clave
El protocolo define tres elementos fundamentales que operan sobre JSON-RPC 2.0:
1. Servidores MCP
Son procesos independientes que exponen recursos (datos contextuales) y herramientas (funciones ejecutables). Un servidor PostgreSQL, por ejemplo, expone operaciones de consulta sin revelar detalles de conexión al agente.
2. Clientes MCP
Implementaciones integradas en el agente o en el framework que orquesta la ejecución (como LangChain o la SDK de Anthropic). El cliente gestiona el descubrimiento de herramientas, el paso de parámetros y la serialización de resultados.
3. Capa de transporte
Actualmente soporta:
Esta separación permite que un mismo servidor MCP sirva a múltiples agentes, y que un agente consuma múltiples servidores sin código específico por integración.
Implementación práctica: un servidor PostgreSQL
A continuación, un servidor MCP funcional que expone consultas a PostgreSQL. Nota importante: utilizamos asyncpg para mantener la compatibilidad asíncrona con el loop de eventos de MCP, evitando el bloqueo que causaría psycopg2.
# server.py
import asyncpg
import asyncio
from mcp.server import Server
from mcp.types import Tool, TextContent
app = Server("postgres-server")
@app.list_tools()
async def list_tools() -> list[Tool]:
return [
Tool(
name="query_database",
description="Ejecuta consultas SELECT seguras",
inputSchema={
"type": "object",
"properties": {
"sql": {"type": "string", "description": "Consulta SQL"}
},
"required": ["sql"]
}
)
]
@app.call_tool()
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
if name != "query_database":
raise ValueError(f"Herramienta desconocida: {name}")
# Uso correcto de librería asíncrona
conn = await asyncpg.connect(
"postgresql://user:pass@localhost/db",
min_size=1, max_size=10
)
try:
rows = await conn.fetch(arguments["sql"])
result = "n".join([str(dict(row)) for row in rows])
return [TextContent(type="text", text=result)]
finally:
await conn.close()
async def main():
from mcp.server.stdio import stdio_server
async with stdio_server() as (read_stream, write_stream):
await app.run(
read_stream,
write_stream,
app.create_initialization_options()
)
if __name__ == "__main__":
asyncio.run(main())
Para simplificar el desarrollo en Python, existe FastMCP, un SDK de alto nivel sobre la implementación oficial que reduce la verbosidad:
from fastmcp import FastMCP
import asyncpg
mcp = FastMCP("postgres-server")
@mcp.tool()
async def query_database(sql: str) -> str:
"""Ejecuta consultas SELECT seguras"""
conn = await asyncpg.connect("postgresql://user:pass@localhost/db")
try:
rows = await conn.fetch(sql)
return "n".join([str(dict(row)) for row in rows])
finally:
await conn.close()
if __name__ == "__main__":
mcp.run()
Limitaciones y consideraciones actuales (Enero 2025)
Si bien MCP representa un avance significativo, es crucial entender su estado y restricciones:
Conclusión
Model Context Protocol ofrece una ruta concreta para desacoplar agentes de IA de sus herramientas, promoviendo una arquitectura modular donde los desarrolladores pueden añadir capacidades sin modificar el core del sistema. Sin embargo, su adopción requiere una inversión inicial: implementar la capa cliente en tu agente y adaptar tus herramientas al formato de servidor MCP.
Aprendizajes clave:
asyncpg, aiohttp) en servidores MCP para no bloquear el event loop.Llamada a la acción: Identifica una herramienta interna que actualmente integres con código específico en tus agentes. Intenta encapsularla en un servidor MCP durante esta semana. La fricción inicial es real, pero el desacoplamiento posterior justifica el esfuerzo cuando tu stack de herramientas comience a crecer exponencialmente.
Geek de la tecnología, en busca de la mejora y aprendizaje continuo.
Ingeniero en ciencias de la computación, Postgrado en Análisis y predicción de datos