Model Context Protocol (MCP): Estandarización de herramientas para agentes de IA en 2025

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.
  • 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:

  • stdio: Comunicación via streams estándar (ideal para servidores locales).
  • SSE (Server-Sent Events): Para servidores remotos sobre HTTP.
  • 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:

  • No es plug-and-play universal: Para que un agente consuma un servidor MCP, debe implementar explícitamente un cliente MCP. No funciona automáticamente con agentes existentes que no tengan esta capa.
  • Especificación en evolución: La versión actual (2024-11-05) cambia rápidamente. Lo que funciona hoy puede requerir ajustes menores en meses venideros.
  • Gestión de estado: El protocolo es stateless por diseño. Si necesitas sesiones persistentes o gestión compleja de estado entre llamadas, deberás implementarla a nivel de aplicación.
  • Seguridad: El servidor MCP tiene acceso directo a tus sistemas. Debes implementar validación de inputs, rate limiting y autenticación en la capa de transporte, ya que el protocolo base no prescribe mecanismos de seguridad específicos.

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:

  • MCP reduce la duplicación de código de integración, pero introduce una dependencia arquitectónica (el cliente MCP).
  • Usa siempre librerías asíncronas compatibles (asyncpg, aiohttp) en servidores MCP para no bloquear el event loop.
  • Evalúa FastMCP si buscas prototipar rápidamente en Python, pero migra a la SDK oficial si necesitas control granular del protocolo.
  • 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.

    LinkedIn
    Share
    Instagram
    WhatsApp