Cargando

Ahora que nuestro servidor MCP está funcionando, es momento de construir el lado del cliente. El cliente es lo que permite que nuestra aplicación se comunique con el servidor MCP y acceda a su funcionalidad.

Entendiendo la arquitectura del cliente

En la mayoría de los proyectos del mundo real, implementarás un cliente MCP O un servidor MCP, no ambos. Estamos construyendo ambos en este proyecto solo para que puedas ver cómo funcionan juntos.

El cliente MCP consta de dos componentes principales:

  • MCP Client - Una clase personalizada que creamos para facilitar el uso de la sesión
  • Client Session - La conexión real con el servidor (parte del SDK de Python de MCP)

La sesión del cliente requiere una limpieza adecuada de recursos cuando terminamos de usarla. Por eso la envolvemos en nuestra clase personalizada MCP Client, para manejar toda esa limpieza automáticamente.

Cómo se integra el cliente en nuestra aplicación

¿Recuerdas el flujo de nuestra aplicación? Nuestro código CLI necesita hacer dos cosas principales con el servidor MCP:

  1. Obtener una lista de herramientas disponibles para enviar a Claude
  2. Ejecutar herramientas cuando Claude las solicite

El cliente MCP proporciona estas capacidades a través de simples llamadas a métodos que nuestro código de aplicación puede usar.

Implementando los métodos principales

Necesitamos implementar dos métodos clave en nuestro cliente: list_tools() y call_tool().

Método List Tools

Este método obtiene todas las herramientas disponibles del servidor:

python
async def list_tools(self) -> list[types.Tool]:
    result = await self.session().list_tools()
    return result.tools

Es sencillo: accedemos a nuestra sesión (la conexión con el servidor), llamamos a la función integrada list_tools(), y devolvemos las herramientas del resultado.

Método Call Tool

Este método ejecuta una herramienta específica en el servidor:

python
async def call_tool(
    self, tool_name: str, tool_input: dict
) -> types.CallToolResult | None:
    return await self.session().call_tool(tool_name, tool_input)

Pasamos el nombre de la herramienta y los parámetros de entrada (proporcionados por Claude) al servidor y devolvemos el resultado.

Probando el cliente

Para probar nuestra implementación, podemos ejecutar el cliente directamente. El archivo incluye un arnés de pruebas que se conecta a nuestro servidor MCP y llama a nuestros métodos:

python
async with MCPClient(
    command="uv", args=["run", "mcp_server.py"]
) as client:
    result = await client.list_tools()
    print(result)

Cuando ejecutamos esta prueba, deberíamos ver impresas nuestras definiciones de herramientas, incluyendo las herramientas read_doc_contents y edit_document que creamos anteriormente.

Uniendo todo

Ahora que nuestro cliente puede listar herramientas y llamarlas, podemos probar el flujo completo. Cuando ejecutamos nuestra aplicación principal y le preguntamos a Claude sobre un documento:

  1. Nuestro código usa el cliente para obtener las herramientas disponibles
  2. Estas herramientas se envían a Claude junto con la pregunta del usuario
  3. Claude decide usar la herramienta read_doc_contents
  4. Nuestro código usa el cliente para ejecutar esa herramienta
  5. El resultado se envía de vuelta a Claude, quien luego responde al usuario

Por ejemplo, preguntar "¿Cuál es el contenido del documento report.pdf?" hará que Claude use nuestra herramienta de lectura de documentos, y obtendremos información sobre el documento de la torre de condensación de 20m que configuramos en nuestro servidor.

El cliente actúa como el puente entre la lógica de nuestra aplicación y el servidor MCP, facilitando el acceso a la funcionalidad del servidor sin preocuparse por los detalles de conexión subyacentes.