Jetzt, da unser MCP-Server funktioniert, ist es Zeit, die Client-Seite zu bauen. Der Client ist das, was es unserem Anwendungscode ermöglicht, mit dem MCP-Server zu kommunizieren und auf dessen Funktionalität zuzugreifen.
Die Client-Architektur verstehen
In den meisten realen Projekten implementierst du entweder einen MCP-Client oder einen MCP-Server - nicht beides. Wir bauen in diesem Projekt beides, nur damit du sehen kannst, wie sie zusammenarbeiten.

Der MCP-Client besteht aus zwei Hauptkomponenten:
- MCP Client - Eine benutzerdefinierte Klasse, die wir erstellen, um die Nutzung der Session zu vereinfachen
- Client Session - Die eigentliche Verbindung zum Server (Teil des MCP Python SDK)

Die Client Session erfordert eine sorgfältige Ressourcenverwaltung - wir müssen Verbindungen ordnungsgemäß bereinigen, wenn wir fertig sind. Deshalb umschließen wir sie mit unserer eigenen Klasse, die die gesamte Bereinigung automatisch übernimmt.
Wie der Client in unsere Anwendung passt
Erinnerst du dich an unser Anwendungsablaufdiagramm? Der Client ist das, was es unserem Code ermöglicht, an zwei entscheidenden Stellen mit dem MCP-Server zu interagieren:

Unser CLI-Code verwendet den Client, um:
- Eine Liste verfügbarer Tools zu erhalten, die an Claude gesendet werden
- Tools auszuführen, wenn Claude sie anfordert
Implementierung der Kernfunktionen des Clients
Wir müssen zwei wesentliche Funktionen implementieren: list_tools() und call_tool().
List Tools Funktion
Diese Funktion ruft alle verfügbaren Tools vom MCP-Server ab:
async def list_tools(self) -> list[types.Tool]:
result = await self.session().list_tools()
return result.toolsEs ist unkompliziert - wir greifen auf unsere Session zu (die Verbindung zum Server), rufen die eingebaute Methode list_tools() auf und geben die Tools aus dem Ergebnis zurück.
Call Tool Funktion
Diese Funktion führt ein bestimmtes Tool auf dem Server aus:
async def call_tool(
self, tool_name: str, tool_input: dict
) -> types.CallToolResult | None:
return await self.session().call_tool(tool_name, tool_input)Wir übergeben den Tool-Namen und die Eingabeparameter (bereitgestellt von Claude) an den Server und geben das Ergebnis zurück.
Testen des Clients
Die Client-Datei enthält unten einen einfachen Test-Harness. Lass ihn eine deiner neuen Methoden aufrufen und das Ergebnis ausgeben:
async with MCPClient(
command="uv", args=["run", "mcp_server.py"]
) as client:
result = await client.list_tools()
print(result)Führe dann die Datei direkt aus, um zu überprüfen, ob alles funktioniert:
uv run mcp_client.pyDies verbindet sich mit deinem MCP-Server und gibt die verfügbaren Tools aus. Du solltest eine Ausgabe sehen, die deine Tool-Definitionen zeigt, einschließlich Beschreibungen und Eingabeschemata.
Alles zusammenfügen
Sobald die Client-Funktionen implementiert sind, kannst du den vollständigen Ablauf testen, indem du deine Hauptanwendung ausführst:
uv run main.pyVersuche zu fragen:
Hier ist, was hinter den Kulissen passiert:
- Deine Anwendung verwendet den Client, um verfügbare Tools zu erhalten
- Diese Tools werden zusammen mit deiner Frage an Claude gesendet
- Claude entscheidet sich, das Tool read_doc_contents zu verwenden
- Deine Anwendung verwendet den Client, um dieses Tool auszuführen
- Das Ergebnis wird an Claude zurückgegeben, der dir dann antwortet
Der Client fungiert als Brücke zwischen deiner Anwendungslogik und der Funktionalität des MCP-Servers und macht es einfach, leistungsstarke Tools in deine KI-Workflows zu integrieren.