现在我们的MCP服务器已经可以正常工作了,是时候构建客户端了。客户端是让我们的应用程序代码能够与MCP服务器通信并访问其功能的部分。
理解客户端架构
在大多数实际项目中,您要么实现MCP客户端,要么实现MCP服务器——而不是两者都实现。我们在这个项目中两者都构建,只是为了让您看看它们是如何协同工作的。

MCP客户端由两个主要组件组成:
- MCP Client - 我们创建的一个自定义类,用于让使用会话更加方便
- Client Session - 与服务器的实际连接(属于MCP Python SDK的一部分)

客户端会话需要仔细的资源管理——我们需要在完成后正确清理连接。这就是为什么我们将其封装在自己的类中,以自动处理所有清理工作。
客户端如何融入我们的应用程序
还记得我们的应用程序流程图吗?客户端使我们的代码能够在两个关键点与MCP服务器进行交互:

我们的CLI代码使用客户端来:
- 获取要发送给Claude的可用工具列表
- 在Claude请求时执行工具
实现核心客户端函数
我们需要实现两个基本函数:list_tools() 和 call_tool()。
List Tools 函数
此函数从MCP服务器获取所有可用工具:
python
async def list_tools(self) -> list[types.Tool]:
result = await self.session().list_tools()
return result.tools这很简单——我们访问我们的会话(与服务器的连接),调用内置的 list_tools() 方法,并从结果中返回工具。
Call Tool 函数
此函数在服务器上执行特定的工具:
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)我们将工具名称和输入参数(由Claude提供)传递给服务器,并返回结果。
测试客户端
客户端文件底部包含一个简单的测试工具。让它调用您的一个新方法并打印结果:
python
async with MCPClient(
command="uv", args=["run", "mcp_server.py"]
) as client:
result = await client.list_tools()
print(result)然后直接运行该文件以验证一切正常:
uv run mcp_client.py这将连接到您的MCP服务器并打印出可用的工具。您应该会看到显示您的工具定义的输出,包括描述和输入模式。
整合所有内容
一旦实现了客户端函数,您就可以通过运行主应用程序来测试完整的流程:
uv run main.py尝试询问:
report.pdf文档的内容是什么?
以下是幕后发生的事情:
- 您的应用程序使用客户端获取可用工具
- 这些工具与您的问题一起发送给Claude
- Claude决定使用read_doc_contents工具
- 您的应用程序使用客户端执行该工具
- 结果返回给Claude,然后Claude向您做出回应
客户端充当您的应用程序逻辑与MCP服务器功能之间的桥梁,使将强大的工具集成到您的AI工作流程中变得轻松简单。