Cargando

Implementando un cliente

Lección 5310 min

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

Antes de sumergirnos en el código, aclaremos un punto importante sobre los proyectos MCP. Normalmente, implementarías 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 que trabajan juntos:

  • 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 MCP Python SDK)

La sesión del cliente maneja la comunicación de bajo nivel, pero requiere una limpieza cuidadosa de recursos cuando tu programa se cierra. Por eso la envolvemos en nuestra propia clase: para gestionar esa limpieza automáticamente.

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

¿Recuerdas nuestro diagrama de flujo de la aplicación? El cliente juega un papel crucial en dos momentos clave:

Nuestro código CLI usa el cliente para:

  • Obtener una lista de herramientas disponibles para enviar a Claude
  • Ejecutar herramientas cuando Claude las solicita

Implementando las funciones principales del cliente

Implementemos las dos funciones esenciales: list_tools y call_tool.

Para list_tools, necesitamos conectarnos a nuestra sesión y solicitar las herramientas disponibles:

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

Para call_tool, pasamos el nombre de la herramienta y los parámetros de entrada al 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)

¡Eso es todo! La sesión maneja todos los detalles complejos de comunicación por nosotros.

Probando el cliente

El archivo del cliente incluye un arnés de prueba simple en la parte inferior. Puedes ejecutarlo directamente para verificar que todo funciona:

bash
uv run mcp_client.py

Esto se conectará a tu servidor MCP e imprimirá las herramientas disponibles. Deberías ver una salida que muestra las definiciones de tus herramientas, incluyendo nombres, descripciones y esquemas de entrada.

Diferencias importantes en el esquema

Aquí hay algo que debes saber: las definiciones de herramientas MCP no coinciden exactamente con lo que Claude espera. La especificación MCP tiene su propio formato para los esquemas de herramientas, que es ligeramente diferente de lo que requiere Bedrock.

No te preocupes: ya hay código en el proyecto que maneja esta conversión automáticamente. La función to_bedrock_tools en core/bedrock.py traduce las definiciones de herramientas MCP al formato que Claude entiende.

Probando con Claude

Ahora que tanto el servidor como el cliente están funcionando, puedes probar el flujo completo. Intenta ejecutar tu aplicación principal y pedirle a Claude que lea un documento:

bash
uv run main.py

Luego pregunta: "¿Cuál es el contenido del documento report.pdf?"

Claude hará lo siguiente:

  1. Recibirá la lista de herramientas disponibles de tu cliente
  2. Decidirá usar la herramienta read_doc_contents
  3. Tu cliente ejecutará esa herramienta en el servidor MCP
  4. Claude recibirá el contenido del documento y responderá

El cliente actúa como el puente entre el código de tu aplicación y el servidor MCP, facilitando la exposición de la funcionalidad del servidor a Claude y a otras partes de tu sistema.