現在我們的 MCP 伺服器已經運作正常,接下來是時候建構客戶端了。客戶端是讓我們的應用程式能夠與 MCP 伺服器通訊並存取其功能的部分。
了解客戶端架構
在大多數實際專案中,您通常只會實作 MCP 客戶端或 MCP 伺服器——不會同時實作兩者。我們在這個專案中同時建構兩者,只是為了讓您能看到它們如何協同運作。

MCP 客戶端由兩個主要元件組成:
- MCP Client - 我們建立的自訂類別,用於讓使用 session 更加容易
- Client Session - 與伺服器的實際連線(屬於 MCP Python SDK 的一部分)

當我們使用完 client session 後,需要進行適當的資源清理。這就是為什麼我們將它包裝在自訂的 MCP Client 類別中——以自動處理所有清理工作。
客戶端如何融入我們的應用程式
還記得我們的應用程式流程嗎?我們的 CLI 程式碼需要對 MCP 伺服器執行兩項主要工作:

- 取得可用工具清單以傳送給 Claude
- 當 Claude 請求時執行工具
MCP 客戶端透過簡單的方法呼叫提供這些功能,供我們的應用程式程式碼使用。
實作核心方法
我們需要在客戶端中實作兩個關鍵方法:list_tools() 和 call_tool()。
List Tools 方法
此方法會從伺服器取得所有可用的工具:
async def list_tools(self) -> list[types.Tool]:
result = await self.session().list_tools()
return result.tools這非常直接——我們存取我們的 session(與伺服器的連線),呼叫內建的 list_tools() 函式,然後從結果中回傳工具清單。
Call Tool 方法
此方法會在伺服器上執行特定的工具:
async def call_tool(
self, tool_name: str, tool_input: dict
) -> types.CallToolResult | None:
return await self.session().call_tool(tool_name, tool_input)我們將工具名稱和輸入參數(由 Claude 提供)傳遞給伺服器,並回傳結果。
測試客戶端
為了測試我們的實作,我們可以直接執行客戶端。該檔案包含一個測試工具,可連接到我們的 MCP 伺服器並呼叫我們的方法:
async with MCPClient(
command="uv", args=["run", "mcp_server.py"]
) as client:
result = await client.list_tools()
print(result)當我們執行此測試時,應該會看到印出我們的工具定義,包括我們先前建立的 read_doc_contents 和 edit_document 工具。
整合所有內容
現在我們的客戶端可以列出工具並呼叫它們,我們可以測試完整的流程。當我們執行主應用程式並向 Claude 詢問有關文件的問題時:
- 我們的程式碼使用客戶端取得可用的工具
- 這些工具會連同使用者的問題一起傳送給 Claude
- Claude 決定使用
read_doc_contents工具 - 我們的程式碼使用客戶端執行該工具
- 結果會傳回給 Claude,然後 Claude 會回應使用者
舉例來說,詢問「report.pdf 文件的內容是什麼?」將觸發 Claude 使用我們的文件讀取工具,我們將取得有關我們在伺服器中設定的 20m 冷凝塔文件的資訊。
客戶端充當我們的應用程式邏輯與 MCP 伺服器之間的橋樑,讓我們能夠輕鬆存取伺服器功能,而不必擔心底層連線細節。