Chargement

Implémenter un client

Leçon 547 min

Maintenant que notre serveur MCP fonctionne, il est temps de construire le côté client. Le client est ce qui permet à notre application de communiquer avec le serveur MCP et d'accéder à ses fonctionnalités.

Comprendre l'architecture du client

Avant de plonger dans le code, clarifions un point important concernant les projets MCP. Normalement, vous implémenteriez soit un client MCP, soit un serveur MCP - pas les deux. Nous construisons les deux dans ce projet simplement pour que vous puissiez voir comment ils fonctionnent ensemble.

Diagramme de notre serveur contenant le client MCP, qui se connecte dans les deux sens à un serveur MCP séparé.

Le client MCP se compose de deux composants principaux :

  • Client MCP - Une classe personnalisée que nous créons pour faciliter l'utilisation de la session
  • Session client - La connexion réelle au serveur (fait partie du SDK Python MCP)

Diagramme de mcp_client.py contenant le client MCP et la session client, qui se connecte à un serveur MCP séparé.

La session client nécessite un nettoyage des ressources une fois que nous en avons terminé avec elle, c'est pourquoi nous l'encapsulons dans notre classe personnalisée. Cela gère automatiquement la gestion des connexions et le nettoyage.

Comment le client s'intègre dans notre application

Vous vous souvenez du flux de notre application ? Notre code CLI doit interagir avec Claude de deux manières clés :

Diagramme de séquence du flux d'application, mettant en évidence où notre code CLI utilise le client pour lister les outils et pour appeler un outil.

Le client permet ces deux interactions en exposant les fonctionnalités du serveur à notre base de code.

Implémenter les fonctions client principales

Nous devons implémenter deux fonctions essentielles : list_tools et call_tool.

Fonction List Tools

Cette fonction récupère tous les outils disponibles depuis le serveur :

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

C'est simple - nous accédons à notre session (la connexion au serveur MCP), appelons la fonction intégrée list_tools, et renvoyons les outils à partir du résultat.

Fonction Call Tool

Cette fonction exécute un outil spécifique sur le serveur :

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)

Nous transmettons le nom de l'outil et les paramètres d'entrée (fournis par Claude) au serveur et renvoyons le résultat.

Tester le client

Pour vérifier que notre implémentation fonctionne, nous pouvons la tester directement. Le fichier client inclut un harnais de test qui se connecte au serveur MCP et exécute des commandes contre celui-ci. Faites-lui appeler list_tools() et afficher le résultat :

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

L'exécution de uv run mcp_client.py devrait renvoyer une liste des outils disponibles avec leurs descriptions et schémas d'entrée. Vous devriez voir des outils comme read_doc_contents et edit_document que nous avons définis dans notre serveur.

Test de bout en bout

Maintenant que le client et le serveur fonctionnent tous les deux, nous pouvons tester le flux complet. L'exécution de notre application principale et la question posée à Claude « Quel est le contenu du document report.pdf ? » devrait :

  1. Envoyer la liste des outils disponibles à Claude
  2. Claude décide d'utiliser l'outil read_doc_contents
  3. Notre client appelle l'outil sur le serveur
  4. Le serveur renvoie le contenu du document
  5. Claude répond avec l'information

Le client agit comme le pont entre le code de votre application et le serveur MCP, facilitant l'accès aux fonctionnalités du serveur sans avoir à gérer directement les détails de connexion de bas niveau.