> 技术文档 > 【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client


什么是mcp

MCP 是一个开放协议,它为应用程序向 LLM 提供上下文的方式进行了标准化。你可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供了标准化的方式一样,MCP 为 AI 模型连接各种数据源和工具提供了标准化的接口。

MCP 核心采用客户端-服务器架构,主机应用可以连接多个服务器:
【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

  • MCP Hosts: 如 Claude Desktop、IDE 或 AI 工具,希望通过 MCP 访问数据的程序
  • MCP Clients: 维护与服务器一对一连接的协议客户端
  • MCP Servers: 轻量级程序,通过标准的 Model Context Protocol 提供特定能力
  • 本地数据源: MCP 服务器可安全访问的计算机文件、数据库和服务
  • 远程服务: MCP 服务器可连接的互联网上的外部系统(如通过 APIs)

初始化环境

Python 需要是 3.11+ 版本

安装uv

mcp默认使用uv作为第三方库管理工具,如果还没有安装,执行如下命令安装即可

pip install uv

执行命令 uv version 查看是否成功安装

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

使用 uv 创建项目

uv init mcp-server-democd mcp-server-demo

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

执行 uv add \"mcp[cli]\" 添加mcp依赖到项目中

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

创建 MCP server

编写server端代码

from pathlib import Pathfrom mcp.server import FastMCPmcp = FastMCP(name=\"demo1\", log_level=\'ERROR\')# 添加一个工具@mcp.tool()def list_file(path: str): \"\"\" 列出指定目录的所有文件和子目录 参数: path: 根目录 返回: 文件列表 \"\"\" try: path = Path(path) if not path.exists(): print(f\"错误:目录 \'{path}\' 不存在\") return [] contents = [] for item in path.iterdir(): contents.append({ \'name\': item.name, \'type\': \'file\' if item.is_file() else \'directory\', \'size\': item.stat().st_size if item.is_file() else 0, \'modified\': item.stat().st_mtime }) return contents except PermissionError: print(f\"错误:没有权限访问目录 \'{path}\'\") return []if __name__ == \'__main__\': mcp.run(transport=\'stdio\')

创建 MCP client

编写client代码

import asynciofrom dotenv import load_dotenvfrom mcp import StdioServerParameters, ClientSession, stdio_clientload_dotenv() # 从.env加载环境变量# Client 会使用这里的配置来启动本地MCP Serverserver_params = StdioServerParameters( command=\'python\', args=[\"./server_demo.py\"], env=None)async def main(): async with stdio_client(server_params) as (read, write): async with ClientSession( read, write, sampling_callback=None ) as session: await session.initialize() print(\'\\n 正在调用工具...\') result = await session.call_tool(\"list_file\", {\"path\": \"D:/pic\"}) print(result.content)asyncio.run(main())

测试使用

1、直接运行client_demo.py代码

正在调用工具...[TextContent(type=\'text\', text=\'{\"name\": \"01.jpg\", \"type\": \"file\", \"size\": 192323, \"modified\": 1697902736.3849685}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"05.jpg\", \"type\": \"file\", \"size\": 379369, \"modified\": 1697819759.6860936}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"22.jpg\", \"type\": \"file\", \"size\": 249651, \"modified\": 1698055119.5418005}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"cheetah.jpg\", \"type\": \"file\", \"size\": 20552, \"modified\": 1717745181.0207932}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"dog\", \"type\": \"directory\", \"size\": 0, \"modified\": 1718097770.096676}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"dog.jpg\", \"type\": \"file\", \"size\": 44733, \"modified\": 1711027923.611414}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"dog.png\", \"type\": \"file\", \"size\": 351610, \"modified\": 1711027861.5564046}\', annotations=None), TextContent(type=\'text\', text=\'{\"name\": \"\\\\u5b81\\\\u6ce2\\\\u56db\\\\u660e\\\\u5c71\", \"type\": \"directory\", \"size\": 0, \"modified\": 1696489530.0600708}\', annotations=None)]

2、启动 mcp server 在浏览器端使用

uv run mcp dev server_demo.py

出现如下日志,代表正常启动

Starting MCP inspector...⚙️ Proxy server listening on port 6277🔍 MCP Inspector is up and running at http://127.0.0.1:6274 🚀

浏览器中打开 http://127.0.0.1:6274,可以看见如下页面:

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

然后点击 “Connect” 按钮,点击“Tools - List Tools”,可以看见后台MCP Server提供的服务,在右边输入参数后,点击“Run Tool”可以看见正常调用的后端接口

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

3、在VS code插件“Cline”中使用

打开插件 Cline ,点击顶部的 “MCP Servers” 按钮,

打开配置文件 “cline_mcp_settings.json”,输入如下配置,出现绿灯代表配置成功

{ \"mcpServers\": { \"myMcpDemo1\": { \"disabled\": false, \"timeout\": 60, \"command\": \"cmd\", \"args\": [ \"/c\", \"python\", \"C:/workspace/py/mcp-demo/demo2/server_demo.py\" ], \"env\": {}, \"transportType\": \"stdio\" } }}

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

注意:如果出现错误“Processing request of type server.py:534 ListToolsRequest 534 ListResourcesRequest ListResourceTemplatesRequest”,则需要调整日志输出级别 log_level=\'ERROR\'

mcp = FastMCP(name=\"demo1\", log_level=\'ERROR\')

接下来就可以在对话框中直接对话使用了,列入我输入“列出目录 C:\\workspace\\py 的所有文件和子目录”,效果如下:

【Ai】MCP实战:手写 client 和 server [Python版本]_python mcp client

参考

  • https://mcpservers.org/
  • https://docs.anthropic.com/en/home
  • https://modelcontextprotocol.io/introduction
  • https://mcp-docs.cn/introduction
  • https://github.com/modelcontextprotocol/python-sdk