Ahora que nuestro servidor MCP está funcionando, es momento de construir el lado del cliente. El cliente es lo que permite que el código de 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:
- Cliente MCP: una clase personalizada que creamos para facilitar el uso de la sesión
- Sesión del cliente: la conexión real con el servidor (parte del SDK de Python de MCP)

La sesión del cliente requiere una gestión cuidadosa de los recursos: necesitamos limpiar correctamente las conexiones cuando terminamos. Por eso la envolvemos en nuestra propia clase que se encarga de toda la limpieza automáticamente.
Cómo encaja el cliente en nuestra aplicación
¿Recuerdas nuestro diagrama de flujo de la aplicación? El cliente es lo que permite que nuestro código interactúe con el servidor MCP en dos puntos 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
Necesitamos implementar dos funciones esenciales: list_tools() y call_tool().
Función List Tools
Esta función obtiene todas las herramientas disponibles del servidor MCP:
async def list_tools(self) -> list[types.Tool]:
result = await self.session().list_tools()
return result.toolsEs sencillo: accedemos a nuestra sesión (la conexión con el servidor), llamamos al método integrado list_tools() y devolvemos las herramientas a partir del resultado.
Función Call Tool
Esta función ejecuta una herramienta específica en el servidor:
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
El archivo del cliente incluye un arnés de prueba sencillo al final. Haz que llame a uno de tus nuevos métodos e imprima el resultado:
async with MCPClient(
command="uv", args=["run", "mcp_server.py"]
) as client:
result = await client.list_tools()
print(result)Luego ejecuta el archivo directamente para verificar que todo funciona:
uv run mcp_client.pyEsto se conectará a tu servidor MCP e imprimirá las herramientas disponibles. Deberías ver una salida que muestra las definiciones de tus herramientas, incluyendo descripciones y esquemas de entrada.
Uniendo todo
Una vez que las funciones del cliente estén implementadas, puedes probar el flujo completo ejecutando tu aplicación principal:
uv run main.pyIntenta preguntar:
Esto es lo que sucede detrás de escena:
- Tu aplicación usa el cliente para obtener las herramientas disponibles
- Estas herramientas se envían a Claude junto con tu pregunta
- Claude decide usar la herramienta read_doc_contents
- Tu aplicación usa el cliente para ejecutar esa herramienta
- El resultado se devuelve a Claude, quien luego te responde
El cliente actúa como el puente entre la lógica de tu aplicación y la funcionalidad del servidor MCP, facilitando la integración de herramientas potentes en tus flujos de trabajo de IA.