MCP Client 开发实战指南(Python版)
原文链接
资料
MCP 官方文档
https://modelcontextprotocol.io/introduction
各个 clients 对 MCP 的支持情况
https://modelcontextprotocol.io/clients
MCP Python SDK:MCP Client 和 Server 官方 SDK
https://github.com/modelcontextprotocol/python-sdk
前言
MCP 客户端(MCP Clients):在主机程序内部,与 MCP server 保持 1:1 的连接。比如支持配置 MCP 的客户端,底层都实现了 MCP Client,然后提供界面让用户配置 MCP Server,比如 Cursor、Claude、Cline、Codebuddy、AI 工具等等。

上面的流程图介绍了 MCP 跟 LLM 的完整交互过程,App 为支持调用 MCP Server 的客户端,比如 Cursor、Claude、Codebuddy 等,他们底层其实就是实现一个 MCP Client,有连接 MCP Server 和调用 Tool的能力。
接下来我会开发一个支持连接 MCP Server 的客户端,以及如何将 MCP Server Tools 提供给大模型,让模型调用 Tools,最终实现通过自然语言调用 MCP Server。
MCP Client Demo 开发
一、环境配置
- 开发语言:Python 3.13.2
- 操作系统:MacOS 或 Linux
- Python 项目管理工具:uv
- 框架:langchain
项目初始化
git clone https://github.com/zhengjianhong001/ai_agent_test
cd ai_agent_test
# 创建虚拟环境
uv venv && source .venv/bin/activate
# 安装相关依赖
uv pip install -r requirements.txt
创建 .evn 配置环境变量
# OpenAI 配置,也可以填写deepseek或元宝的
OPENAI_API_KEY=your_openai_api_key_here
OPENAI_MODEL=gpt-4o-mini
OPENAI_API_BASE=https://api.openai.com/v1
二、编写 Client 代码
通过本地的MCP Server Stdio调用
# Create server parameters for stdio connection
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from langchain_mcp_adapters.tools import load_mcp_tools
from langgraph.prebuilt import create_react_agent
from langchain_openai import ChatOpenAI
from langchain_core.messages import HumanMessage, ToolMessage
import asyncio
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
from langchain.agents import AgentExecutor, create_openai_tools_agent
from dotenv import load_dotenv
import os
# 加载环境变量
load_dotenv()
# 把工具列表发送给 LLM,根据 LLM 返回需要调用的工具,然后手动调用工具,并把工具结果发送给模型,模型返回最终结果
base_params = {
"model": os.getenv("OPENAI_MODEL", ""),
"temperature": 0.1,
"streaming": True,
"openai_api_key": os.getenv("OPENAI_API_KEY", ""),
"openai_api_base": os.getenv("OPENAI_API_BASE", ""),
}
model = ChatOpenAI(**base_params)
server_params = StdioServerParameters(
command="uvx",
# Make sure to update to the full absolute path to your math_server.py file
args=["mcp-server-tapd"],
env={
"TAPD_ACCESS_TOKEN": os.getenv("TAPD_ACCESS_TOKEN", ""),
"TAPD_API_BASE_URL": os.getenv("TAPD_API_BASE_URL", ""),
"TAPD_BASE_URL": os.getenv("TAPD_BASE_URL", ""),
"CURRENT_USER_NICK": os.getenv("CURRENT_USER_NICK", ""),
"BOT_URL": os.getenv("BOT_URL", "")
}
)
async def run_agent():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Initialize the connection
await session.initialize()
# Get tools
tools = await load_mcp_tools(session)
# 直接绑定工具到模型
model_with_tools = model.bind_tools(tools)
# 第一轮:调用模型
messages = [HumanMessage(content="获取我参与的项目,只返回项目名称列表,不要返回其他内容")]
result = await model_with_tools.ainvoke(messages)
# 检查是否有工具调用
if result.tool_calls:
print("检测到工具调用,正在执行...")
# 执行工具调用
tool_results = []
for tool_call in result.tool_calls:
tool_name = tool_call['name']
tool_args = tool_call['args']
# 找到对应的工具
for tool in tools:
if tool.name == tool_name:
print(f"执行工具: {tool_name}")
tool_result = await tool.ainvoke(tool_args)
tool_results.append(tool_result)
break
# 第二轮:将工具结果发送给模型
if tool_results:
# 添加工具结果到消息列表
new_messages = messages + [result] + [
ToolMessage(
content=str(tool_results[0]), # 假设只有一个工具调用
tool_call_id=result.tool_calls[0]['id']
)
]
print("将工具结果发送给模型...")
final_result = await model_with_tools.ainvoke(new_messages)
return final_result
return result
# Run the async function
if __name__ == "__main__":
result = asyncio.run(run_agent())
print("AI 最终内容:", result.content)
# print(result)
三、运行服务
python client.py

源码:
https://github.com/zhengjianhong001/ai_agent_test/tree/main/mcp
MCP Client 开发实战指南(Python版)的更多相关文章
- 推荐一本书:清华出版的《Modbus软件开发实战指南》
前言: 最近在研究Modbus开发,如果只是简单的了解了一些modbus基础知识,但是不够系统和全面. 其实,modbus虽然比较简单,但是如果不注意有很多坑,特别是寄存器的位数,大小端处理,浮点数, ...
- HTML5 Canvas游戏开发实战 PDF扫描版
HTML5 Canvas游戏开发实战主要讲解使用HTML5 Canvas来开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读 ...
- HTML5移动Web开发实战 PDF扫描版
<HTML5移动Web开发实战>提供了应对这一挑战的解决方案.通过阅读本书,你将了解如何有效地利用最新的HTML5的那些针对移动网站的功能,横跨多个移动平台.全书共分10章,从移动Web. ...
- 【书籍连载】《STM32 HAL 库开发实战指南—基于F7》-第一章
从今天起,每天开始连载一章<STM32 HAL 库开发实战指南—基于F7>.欢迎各位阅读.点评.学习. 第1章 如何使用本书 1.1 本书的参考资料 本书参考资料为:<STM32 ...
- 《Django企业开发实战 高效Python Web框架指南》胡阳
链接:https://pan.baidu.com/s/1NmN_IT5RvevCMt9bZCW1-g提取码:2ki9
- (六)Spark-Eclipse开发环境WordCount-Java&Python版Spark
Spark-Eclipse开发环境WordCount 视频教程: 1.优酷 2.YouTube 安装eclipse 解压eclipse-jee-mars-2-win32-x86_64.zip Java ...
- 【深入浅出Seata原理及实战】「入门基础专题」探索Seata服务的AT模式下的分布式开发实战指南(2)
承接上文 上一篇文章说到了Seata 为用户提供了 AT.TCC.SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案.那么接下来我们将要针对于AT模式下进行分布式事务开发的原理进行介绍以及 ...
- 【Python开发实战】Python环境的配置
1. 安装Pythonsudo aptitude -y install python-dev 安装Distribute:支撑模块构建与导入的包sudo chmod -R 0775 /usr/local ...
- Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 1
在开发Modbus程序的过程中,也可以发现经常需要使用诸如Modbus Poll和Modbus Slave等辅助调试工具, 用于验证MODBUS通讯消息是否正确.但是,Modbus Poll和Modb ...
- Modbus软件开发实战指南 之 开发自己的Modbus Poll工具 - 2
接上一篇文章的内容. 看了前面需求提到的复杂的命令行解析功能,很多人立马开始发怵,其实大可不必. 我们都知道,Linux下的程序往往都提供了复杂的命令行参数处理机制,因为这是与 其他程序或用户进行交互 ...
随机推荐
- 🚀 开源提示词优化神器来了!一键优化Function Calling和MCP提示词,让你的AI应用性能飞跃
还在为Function Calling调用不准确而头疼?MCP提示词写得不够规范?今天给大家推荐一个开源的提示词优化平台,专门解决这些痛点! 背景:为什么需要专业的提示词优化? 在AI应用开发中,我们 ...
- 动手学深度学习v2——第六章predict_ch6
在QA环节,有位同学问了第六章的predict函数在哪,书中没有给出,使用predict_ch3稍作更改可得. def predict_ch6(net, test_iter, device, n=6) ...
- Linux系统根分区满载清理
问题说明 这里我们在使用centos7.6系统时,遇到根分区满载的问题.进入根分区后,查找了所有的目录,并没有查到大的文件.这里怀疑是文件删除未释放导致.由于系统根分区满载,执行lsof |grep ...
- 直播预约丨《袋鼠云大数据实操指南》No.4:数据服务API实战解读,助力企业数字化跃迁
近年来,新质生产力.数据要素及数据资产入表等新兴概念犹如一股强劲的浪潮,持续冲击并革新着企业数字化转型的观念视野,昭示着一个以数据为核心驱动力的新时代正稳步启幕. 面对这些引领经济转型的新兴概念,为了 ...
- 第1周作业题-numpy构建基本函数
numpy构建基本函数 1. Jupyter Notebook ① 编写代码后,通过按 "SHIFT" + "ENTER" 或单击笔记本上部栏中的 " ...
- NOI2024破防记/rain
NOI 2024 预警:在本篇游记中,你将看到包括但不限于 诶我好高兴,诶我破防了,诶我好高兴,诶我破防了,诶我好高兴,诶我破防了,诶我好高兴,诶我破防了,诶我好高兴,诶我破防了,诶我好高兴,诶我破防 ...
- 真正的生产力来了!Docker迁移部署两步搞定!
前言 最近遇到了需要部署一套比较复杂的应用场景,刚好这套应用我在其他服务器部署过,为了节省折腾的时间,我打算直接把服务器上已有的搬过去. PS:没想到这个过程比从头开始来耗费时间 好在是把一键迁移的脚 ...
- vue入门(二)基于前面的基础的一个小Demo
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 4G网关8305LN远程监控西门子触摸屏SMART 700IE ZLAN8305LN应用
1.概述 ZLAN8305LN是一款专门为工业环境设计的RS485设备数据采集器/物联网网关,他通过4G的方式传输,结合卓岚特有的P2P技术,无需构建公网服务器也可以同样随时随地采集设备的数据,本次案 ...
- JS兼容性复制剪切板
前言 有时候,navigator.clipboard对象可能会不存在. 因为我们要做一套降级处理! 封装 copy.js function fallbackCopyText(text) { const ...