当前位置: 首页 > article >正文

MCP客户端Client开发流程

1. uv工具入门使用指南

1.1 uv入门介绍

MCP开发要求借助uv进行虚拟环境创建和依赖管理。 uv 是一个Python 依赖管理工具,类似于pip 和 conda ,但它更快、更高效,并且可以更好地管理 Python 虚拟环境和依赖项。它的核心目标是 替代 pip venv pip-tools ,提供更好的性能和更低的管理开销。

uv 的特点

  1. 速度更快:相比 pip uv 采用 Rust 编写,性能更优。
  2. 支持 PEP 582:无需 virtualenv ,可以直接使用 __pypackages__ 进行管理。
  3. 兼容 pip :支持 requirements.txt pyproject.toml 依赖管理。
  4. 替代 venv :提供 uv venv 进行虚拟环境管理,比 venv 更轻量。
  5. 跨平台:支持 WindowsmacOS Linux

1.2 uv安装流程

方法 1:使用 pip 安装(适用于已安装 pip 的系统)

pip install uv

方法 2:使用 curl 直接安装

如果你的系统没有 pip ,可以直接运行:

curl -LsSf https://astral.sh/uv/install.sh | sh

这会自动下载 uv 并安装到 /usr/local/bin

1.3 uv的基本用法介绍

安装 uv 后,你可以像 pip 一样使用它,但它的语法更简洁,速度也更快。注意,以下为使用语法

示例,不用实际运行。

  • 安装 Python 依赖
uv pip install requests

pip install requests 类似,但更快。

  • 创建虚拟环境
uv venv myenv

等效于 python -m venv myenv ,但更高效。

  • 激活虚拟环境
source myenv/bin/activate     # Linux/macOS
myenv\Scripts\activate          # Windows
  • 安装 requirements.txt
uv pip install -r requirements.txt
  • 直接运行 Python 项目
如果项目中包含 pyproject.toml ,你可以直接运行:

uv run python script.py

这等效于:

pip install -r requirements.txt
python script.py

uv 速度更快,管理更高效。

为什么 MCP 更推荐使用 uv 进行环境管理?
MCP 依赖的 Python 环境可能包含多个模块, uv 通过 pyproject.toml 提供更高效的管理方 式,并且可以避免 pip 的一些依赖冲突问题。此外, uv 的包管理速度远超 pip ,这对于 MCP 这样频繁管理依赖的项目来说是一个很大的优势。

2.MCP极简客户端搭建流程

2.1 创建 MCP 客户端项目

# 创建项目目录
uv init mcp-client
cd mcp-client

2.2 创建MCP客户端虚拟环境

# 创建虚拟环境
uv venv
# 激活虚拟环境
source .venv/bin/activate
这里需要注意的是,相比 pip uv 会自动识别当前项目主目录并创建虚拟环境。
然后即可通过 add 方法在虚拟环境中安装相关的库。
# 安装 MCP SDK
uv add mcp

2.3 编写基础 MCP 客户端

然后在当前项目主目录中创建 client.py

并写入以下代码
import asyncio # 让代码支持异步操作
from mcp import ClientSession # MCP 客户端会话管理
from contextlib import AsyncExitStack # 资源管理(确保客户端关闭时释放资源)class MCPClient:def __init__(self):"""初始化 MCP 客户端"""self.session = None # 先不连接 MCP 服务器self.exit_stack = AsyncExitStack() # 创建资源管理器async def connect_to_mock_server(self):"""模拟 MCP 服务器的连接(暂不连接真实服务器)"""print("✅ MCP 客户端已初始化,但未连接到服务器")async def chat_loop(self):"""运行交互式聊天循环"""print("\nMCP 客户端已启动!输入 'quit' 退出")while True:  # 无限循环,直到用户输入 'quit'try: query = input("\nQuery: ").strip() # 让用户输入问题if query.lower() == 'quit': # 如果用户输入 quit,退出循环breakprint(f"\n🤖 [Mock Response] 你说的是:{query}") # 返回模拟回复except Exception as e: # 发生错误时捕获异常print(f"\n⚠️ 发生错误: {str(e)}")async def cleanup(self):"""清理资源"""await self.exit_stack.aclose() # 关闭资源管理器async def main():client = MCPClient() # 创建 MCP 客户端try: await client.connect_to_mock_server() # 连接(模拟)服务器await client.chat_loop() # 进入聊天循环finally:await client.cleanup() # 确保退出时清理资源if __name__ == "__main__": #确保代码只能在 Python 直接运行时执行(而不是作为库导入时)asyncio.run(main())
这段代码能够初始化 MCP 客户端(但不连接服务器),并提供一个 交互式 CLI ,可以输入查询(但只返回模拟回复),通过输入 quit 退出程序 。需要注意的是,此时客户端没有关联任何大模型,因此只会 重复用户的输入。
MCP 中一个基础的客户端代码结构 总结如下
代码部分
作用
MCPClient.__init__()
初始化 MCP 客户端
connect_to_mock_server()
模拟 MCP 服务器连接
chat_loop()
提供交互式聊天界面
cleanup()
释放资源
main()
启动客户端
asyncio.run(main())
运行程序

2.4 运行 MCP 客户端

然后尝试运行这个极简的 MCP 客户端:
uv run client.py

3. MCP客户端接入DeepSeek在线模型流程

3.1 新增依赖

为了支持调用 DeepSeek 模型,以及在环境变量中读取 API-KEY 等信息,需要先安装如下依赖:
uv add mcp openai python-dotenv

3.2 创建.env文件

写入如下内容
BASE_URL = https://api.deepseek.com
MODEL = deepseek-chat
OPENAI_API_KEY = "DeepSeek API-Key"

3.3 修改client.py代码

import asyncio
import os
from openai import OpenAI
from dotenv import load_dotenv
from contextlib import AsyncExitStack# 加载 .env 文件,确保 API Key 受到保护
load_dotenv()class MCPClient:def  __init__(self):"""初始化 MCP 客户端"""self.exit_stack = AsyncExitStack()self.openai_api_key = os.getenv("OPENAI_API_KEY")  # 读取 OpenAI API Keyself.base_url = os.getenv("BASE_URL")  # 读取 BASE YRLself.model = os.getenv("MODEL")  # 读取 modelif not self.openai_api_key:raise ValueError("❌ 未找到 OpenAI API Key,请在 .env 文件中设置OPENAI_API_KEY")self.client = OpenAI(api_key=self.openai_api_key, base_url=self.base_url)async def process_query(self, query: str) -> str:"""调用 DeepSeek API 处理用户查询"""messages = [{"role": "system", "content": "你是一个智能助手,帮助用户回答问题。"},{"role": "user", "content": query}]try:# 调用 OpenAI APIresponse = await asyncio.get_event_loop().run_in_executor(None,lambda: self.client.chat.completions.create(model=self.model,messages=messages))return response.choices[0].message.contentexcept Exception as e:return f"⚠️ 调用 DeepSeek API 时出错: {str(e)}"async def chat_loop(self):"""运行交互式聊天循环"""print("\nMCP 客户端已启动!输入 'quit' 退出")while True:try:query = input("\nQuery: ").strip()if query.lower() == 'quit':breakresponse = await self.process_query(query)  # 发送用户输入到 OpenAIAPIprint(f"\n🤖 DeepSeek: {response}")except Exception as e:print(f"\n⚠️ 发生错误: {str(e)}")async def cleanup(self):"""清理资源"""await self.exit_stack.aclose()async def main():client = MCPClient()try:await client.chat_loop()finally:await client.cleanup()
if __name__ == "__main__":asyncio.run(main())

相关文章:

MCP客户端Client开发流程

1. uv工具入门使用指南 1.1 uv入门介绍 MCP开发要求借助uv进行虚拟环境创建和依赖管理。 uv 是一个Python 依赖管理工具,类似于pip 和 conda ,但它更快、更高效,并且可以更好地管理 Python 虚拟环境和依赖项。它的核心目标是 替代 pip 、…...

学习日记-day21-6.3

完成目标: 目录 知识点: 1.集合_哈希表存储过程说明 2.集合_哈希表源码查看 3.集合_哈希表无索引&哈希表有序无序详解 4.集合_TreeSet和TreeMap 5.集合_Hashtable和Vector&Vector源码分析 6.集合_Properties属性集 7.集合_集合嵌套 8.…...

C语言探索之旅:深入理解结构体的奥秘

目录 引言 一、什么是结构体? 二、结构体类型的声明和初始化 1、结构体的声明 2、结构体的初始化 3、结构体的特殊声明 4、结构体的自引用 5、结构体的重命名 三、结构体的内存对齐 1、对齐规则 2、为什么存在内存对齐? 3、修改默认对齐数 三…...

uniapp 开发企业微信小程序,如何区别生产环境和测试环境?来处理不同的服务请求

在 uniapp 开发企业微信小程序时,区分生产环境和测试环境是常见需求。以下是几种可靠的方法,帮助你根据环境处理不同的服务请求: 一、通过条件编译区分(推荐) 使用 uniapp 的 条件编译 语法,在代码中标记…...

Dockerfile常用指令介绍

Dockerfile常用指令介绍 Dockerfile是一个文本文件,用于定义Docker镜像的构建过程。下面介绍一些最常用的Dockerfile指令及其用法: 基础指令 FROM - 指定基础镜像 FROM python:3.9-slim这是Dockerfile的第一个指令,用于指定构建镜像的基础镜…...

Docker 容器化:核心技术原理与实践

哈喽,大家好,我是左手python! Docker 的基本概念与核心组件 Docker 是一个开源的容器化平台,能够将应用程序及其依赖项打包成一个容器,确保在任何环境中都能一致运行。Docker 的核心在于其容器化技术,这种…...

不确定性分析在LEAP能源-环境系统建模中的整合与应用

本内容突出与实例结合,紧密结合国家能源统计制度及《省级温室气体排放编制指南》,深入浅出地介绍针对不同级别研究对象时如何根据数据结构、可获取性、研究目的,构建合适的能源生产、转换、消费、温室气体排放(以碳排放为主&#…...

经典算法回顾之最小生成树

最小生成树(Minimum Spanning Tree,简称MST)是图论中的一个重要概念,主要用于解决加权无向图中连接所有顶点且总权重最小的树结构问题。本文对两种经典的算法即Prim算法和Kruskal算法进行回顾,并对后者的正确性给出简单…...

Ubuntu下实现nginx反向代理

1. 多个ngx实例安装 脚本已经在deepseek的指导下完成啦! deepseek写的脚本支持ubuntu/centos两种系统。 ins_prefix"/usr/local/" makefile_gen() {ngx$1 ngx_log_dir"/var/log/"$ngx"/"ngx_temp_path"/var/temp/"${ngx}…...

c++ QicsTable使用实例

效果图&#xff1a; #include <QicsTable.h> #include <QicsDataModelDefault.h> #include <QVBoxLayout> Demo1::Demo1(QWidget *parent) : QWidget(parent) { ui.setupUi(this); const int numRows 10; const int numCols 5; // create th…...

在WordPress上添加隐私政策页面

在如今的互联网时代&#xff0c;保护用户隐私已经成为每个网站管理员的责任。隐私政策不仅是法律要求&#xff0c;还能提高用户对网站的信任。本文将介绍两种常用方法&#xff0c;帮助你在WordPress上轻松创建并发布隐私政策页面。这些方法简单易行&#xff0c;符合中国用户的阅…...

二维 根据矩阵变换计算镜像旋转角度

在二维变换中&#xff0c;镜像&#xff08;Reflection&#xff09; 是一种特殊的线性变换&#xff0c;它会将图形对称地翻转到某个轴线或点。镜像的存在会显著影响圆弧变换后的参数&#xff08;圆心、半径、起始角度&#xff09;&#xff0c;尤其是在角度方向和旋转方向的处理上…...

你工作中涉及的安全方面的测试有哪些怎么回答

在面试或工作总结中&#xff0c;回答 **“工作中涉及的安全测试”** 时&#xff0c;可以结合具体场景、测试方法和工具&#xff0c;突出你的技术广度和深度。以下是结构化回答建议&#xff1a; --- ### **1. 分类说明安全测试范围** #### **(1) Web 应用安全测试** - **OWASP…...

阿里云ACP云计算备考笔记 (3)——云服务器ECS

目录 第一章 整体概览 第二章 ECS简介 1、产品概念 2、ECS对比本地IDC 3、BGP机房优势 第三章 ECS实例 1、实例规格族 2、实例系列 3、应用场景推荐选型 4、实例状态 5、创建实例 ① 完成基础配置 ② 完成网络和安全组配置 ③ 完成管理配置和高级选项 ④ 确认下单…...

Eigen实现非线性最小二乘拟合 + Gauss-Newton算法

下面是使用 Eigen 实现的 非线性最小二乘拟合 Gauss-Newton 算法 的完整示例&#xff0c;拟合模型为&#xff1a; 拟合目标模型&#xff1a; y exp ⁡ ( a x 2 b x c ) y \exp(a x^2 b x c) yexp(ax2bxc) 已知一组带噪声数据点 ( x i , y i ) (x_i, y_i) (xi​,yi​)&…...

区块链技术:原理、应用与发展趋势

区块链技术&#xff1a;原理、应用与发展趋势 引言 区块链作为一种去中心化的分布式账本技术&#xff0c;自2008年比特币白皮书发布以来&#xff0c;已经从简单的加密货币底层技术发展成为具有广泛应用前景的创新技术。区块链通过独特的数据结构和加密机制&#xff0c;实现了…...

从零开始:用Tkinter打造你的第一个Python桌面应用

目录 一、界面搭建&#xff1a;像搭积木一样组合控件 二、菜单系统&#xff1a;给应用装上“控制中枢” 三、事件驱动&#xff1a;让界面“活”起来 四、进阶技巧&#xff1a;打造专业级体验 五、部署发布&#xff1a;让作品触手可及 六、学习路径建议 在Python生态中&am…...

Web开发主流前后端框架总结

&#x1f5a5; 一、前端主流框架 前端框架的核心是提升用户界面开发效率&#xff0c;实现高交互性应用。当前三大主流框架各有侧重&#xff1a; React (Meta/Facebook) 核心特点&#xff1a;采用组件化架构与虚拟DOM技术&#xff08;减少真实DOM操作&#xff0c;优化渲染性能&…...

Java Spring Boot 自定义注解详解与实践

目录 一、自定义注解的场景与优势1.1 场景1.2 优势 二、创建自定义注解2.1 定义注解2.2 创建注解处理器 三、使用自定义注解3.1 在业务方法上使用注解3.2 配置类加载注解 四、总结 在 Spring Boot 中&#xff0c;自定义注解为我们提供了一种灵活且强大的方式来简化开发、增强代…...

GlobalSign、DigiCert、Sectigo三种SSL安全证书有什么区别?

‌GlobalSign、DigiCert和Sectigo是三家知名的SSL证书颁发机构&#xff0c;其产品在安全性、功能、价格和适用场景上存在一定差异。选择SSL证书就像为你的网站挑选最合身的“安全盔甲”&#xff0c;核心是匹配你的实际需求&#xff0c;避免过度配置或防护不足。 一、核心特点对…...

力扣面试150题--二叉搜索树中第k小的元素

Day 58 题目描述 思路 直接采取中序遍历&#xff0c;不过我们将k参与到中序遍历中&#xff0c;遍历到第k个元素就结束 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* …...

SQL Server Agent 不可用怎么办?

在 SQL Server Management Studio (SSMS) 中&#xff0c;SQL Server Agent 通常位于对象资源管理器&#xff08;Object Explorer&#xff09;的树形结构中&#xff0c;作为 SQL Server 实例的子节点。以下是详细说明和可能的原因&#xff1a; 1. SQL Server Agent 的位置 默认路…...

css-塞贝尔曲线

文章目录 1、定义2、使用和解释 1、定义 cubic-bezier() 函数定义了一个贝塞尔曲线(Cubic Bezier)语法&#xff1a;cubic-bezier(x1,y1,x2,y2) 2、使用和解释 x1,y1,x2,y2&#xff0c;表示两个点的坐标P1(x1,y1),P2(x2,y2)将以一条直线放在范围只有 1 的坐标轴中&#xff0c;并…...

Java并发编程哲学系列汇总

文章目录 并发编程基础并发编程进阶并发编程实践 并发编程基础 Java并发编程基础小结 Java线程池知识点小结 详解JUC包下各种锁的使用 并发编程利器Java CAS原子类全解 深入理解Java中的final关键字 Java并发容器深入解析&#xff1a;HashMap与ArrayList线程安全问题及解…...

docker使用proxy拉取镜像

前提条件&#xff0c;宿主机可以访问docker hub 虚拟机上telnet 宿主机7890能正常访问 下面的才是关键&#xff0c;上面部分自己想办法~ 3. 编辑 /etc/docker/daemon.json {"proxies": {"http-proxy": "http://192.168.100.1:7890","ht…...

服务端定时器的学习(一)

一、定时器 1、定时器是什么&#xff1f; 定时器不仅存在于硬件领域&#xff0c;在软件层面&#xff08;客户端、网页和服务端&#xff09;也普遍应用&#xff0c;核心功能都是高效管理大量延时任务。不同应用场景下&#xff0c;其实现方式和使用方法有所差异。 2、定时器解…...

【前端】vue 防抖和节流

在 Vue.js 中&#xff0c;防抖&#xff08;Debounce&#xff09; 和 节流&#xff08;Throttle&#xff09; 是优化高频事件&#xff08;如输入、滚动、点击&#xff09;的核心技术&#xff0c;可显著提升性能与用户体验。以下是具体实现方法和最佳实践&#xff1a; ⏳ 一、防抖…...

Modbus转EtherNET IP网关开启节能改造新范式

在现代工业生产和能源管理中&#xff0c;无锡耐特森Modbus转EtherNET IP网关MCN-EN3001发挥着至关重要的作用。通过将传统的串行通信协议Modbus转换为基于以太网的EtherNET IP协议&#xff0c;这种网关设备不仅提高了数据传输的效率&#xff0c;而且为能源管理和控制系统的现代…...

Android高级开发第四篇 - JNI性能优化技巧和高级调试方法

文章目录 Android高级开发第四篇 - JNI性能优化技巧和高级调试方法引言为什么JNI性能优化如此重要&#xff1f;第一部分&#xff1a;JNI性能基础知识JNI调用的性能开销何时使用JNI才有意义&#xff1f; 第二部分&#xff1a;核心性能优化技巧1. 减少JNI调用频率2. 高效的数组操…...

【PCB工艺】绘制原理图 + PCB设计大纲:最小核心板STM32F103ZET6

绘制原理图和PCB布线之间的联系,在绘制原理图的时候,考虑到后续的PCB设计+嵌入式软件代码的业务逻辑,需要在绘制原理图之初涉及到 硬件设计流程的前期规划。在嵌入式系统开发中,原理图设计是整个项目的基础,直接影响到后续的: PCB 布线效率和质量 ☆☆☆重点嵌入式软件的…...