環(huán)境要求:
當(dāng)前MCP要求python在3.10以上版本,且MCP開發(fā)要求借助uv進(jìn)行虛擬環(huán)境創(chuàng)建和依賴管理。
1. uv工具入門使用指南
1.1 uv入門介紹
uv 是一個(gè)Python 依賴管理工具,類似于pip 和 conda ,但它更快、更高效,并且可以更好地管理 Python 虛擬環(huán)境和依賴項(xiàng)。它的核心目標(biāo)是替代 pip 、 venv 和 pip-tools ,提供更好的性能和更低的管理開銷。
uv 的特點(diǎn):
- 速度更快:相比 pip , uv 采用 Rust 編寫,性能更優(yōu)。
- 支持 PEP 582:無需 virtualenv ,可以直接使用 pypackages 進(jìn)行管理。
- 兼容 pip :支持 requirements.txt 和 pyproject.toml 依賴管理。
- 替代 venv :提供 uv venv 進(jìn)行虛擬環(huán)境管理,比 venv 更輕量。
- 跨平臺(tái):支持 Windows、macOS 和 Linux。
1.2 uv安裝流程
使用pip安裝:
pip install uv
C:\Users\xxxx>pip install uv
Collecting uv
Downloading uv-0.7.2-py3-none-win_amd64.whl.metadata (11 kB)
Downloading uv-0.7.2-py3-none-win_amd64.whl (18.3 MB)
---------------------------------------- 18.3/18.3 MB 1.7 MB/s eta 0:00:00
Installing collected packages: uv
Successfully installed uv-0.7.2
[notice] A new release of pip is available: 24.0 -> 25.1.1
[notice] To update, run: python.exe -m pip install --upgrade pip
1.3 uv的基本用法介紹
- 安裝 Python 依賴
uv pip install requests
- 創(chuàng)建虛擬環(huán)境
uv venv myenv
- 激活虛擬環(huán)境
source myenv/bin/activate # Linux/macOS
myenv\Scripts\activate # Windows
- 直接運(yùn)行 Python 項(xiàng)目
如果項(xiàng)目中包含 pyproject.toml ,你可以直接運(yùn)行:
uv run script.py
2.MCP極簡(jiǎn)客戶端搭建流程
2.1 創(chuàng)建 MCP 客戶端項(xiàng)目
# 創(chuàng)建項(xiàng)目目錄
uv init weather
cd weather
D:\learning\mcp>uv init weather
Initialized project `weather` at `D:\learning\mcp\weather`
D:\learning\mcp>dir
驅(qū)動(dòng)器 D 中的卷是 Data
卷的序列號(hào)是 6668-32CF
D:\learning\mcp 的目錄
2025/05/05 11:55 <DIR> .
2025/05/05 10:36 <DIR> ..
2025/05/05 11:55 <DIR> weather
0 個(gè)文件 0 字節(jié)
4 個(gè)目錄 287,324,241,920 可用字節(jié)
D:\learning\mcp>
D:\learning\mcp>cd weather
D:\learning\mcp\weather>dir
驅(qū)動(dòng)器 D 中的卷是 Data
卷的序列號(hào)是 6668-32CF
D:\learning\mcp\weather 的目錄
2025/05/05 11:55 <DIR> .
2025/05/05 11:55 <DIR> ..
2025/05/05 11:55 5 .python-version
2025/05/05 11:55 85 main.py
2025/05/05 11:55 153 pyproject.toml
2025/05/05 11:55 0 README.md
4 個(gè)文件 243 字節(jié)
2 個(gè)目錄 287,324,241,920 可用字節(jié)
2.2 創(chuàng)建MCP客戶端虛擬環(huán)境
# 創(chuàng)建虛擬環(huán)境
uv venv
# 激活虛擬環(huán)境
source .venv/bin/activate # linux
.venv\Scripts\activate # windows
D:\learning\mcp\weather>uv venv
Using CPython 3.12.3 interpreter at: C:\Users\pq449\AppData\Local\Programs\Python\Python312\python.exe
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activate
D:\learning\mcp\weather>
激活后進(jìn)入mcp模式:
(weather) D:\learning\mcp\weather>
# 安裝 MCP SDK
uv add mcp
Prepared 22 packages in 875ms
???????????????????? [0/22] Installing wheels... warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
If the cache and target directories are on different filesystems, hardlinking may not be supported.
If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 22 packages in 109ms
+ annotated-types==0.7.0
+ anyio==4.9.0
+ certifi==2025.4.26
+ click==8.1.8
+ colorama==0.4.6
+ h11==0.16.0
+ httpcore==1.0.9
+ httpx==0.28.1
+ httpx-sse==0.4.0
+ idna==3.10
+ mcp==1.7.1
+ pydantic==2.11.4
+ pydantic-core==2.33.2
+ pydantic-settings==2.9.1
+ python-dotenv==1.1.0
+ python-multipart==0.0.20
+ sniffio==1.3.1
+ sse-starlette==2.3.4
+ starlette==0.46.2
+ typing-extensions==4.13.2
+ typing-inspection==0.4.0
+ uvicorn==0.34.2
(weather) D:\learning\mcp\weather>
2.3 編寫基礎(chǔ) MCP 客戶端
使用vscode打開上面已經(jīng)創(chuàng)建的項(xiàng)目,在項(xiàng)目?jī)?nèi)新建一個(gè)python文件,命名為client1.py,并輸入下面內(nèi)容

import asyncio
from contextlib import AsyncExitStack
class MCPClient:
def __init__(self):
"""初始化 MCP 客戶端"""
self.session = None
self.exit_stack = AsyncExitStack()
async def connect_to_mock_server(self):
"""模擬 MCP 服務(wù)器的連接(暫不連接真實(shí)服務(wù)器)"""
print("? MCP 客戶端已初始化,但未連接到服務(wù)器")
async def chat_loop(self):
"""運(yùn)行交互式聊天循環(huán)"""
print("\nMCP 客戶端已啟動(dòng)!輸入 'quit' 退出")
while True:
try:
query = input("\nQuery: ").strip()
if query.lower() == 'quit':
break
print(f"\n?? [Mock Response] 你說的是:{query}")
except Exception as e:
print(f"\n? 發(fā)生錯(cuò)誤: {str(e)}")
async def cleanup(self):
"""清理資源"""
await self.exit_stack.aclose()
async def main():
client = MCPClient()
try:
await client.connect_to_mock_server()
await client.chat_loop()
finally:
await client.cleanup()
if __name__ == "__main__":
asyncio.run(main())
這段代碼能夠初始化 MCP 客戶端(但不連接服務(wù)器),并提供一個(gè) 交互式 CLI,可以輸入查詢(但只返回模擬回復(fù)),通過輸入 quit 退出程序。需要注意的是,當(dāng)前這個(gè)程序只是模擬一個(gè)客戶端,并沒有連接任何大模型,因此只會(huì)重復(fù)用戶的輸入。
運(yùn)行效果如下:
在vscode的Terminal下面創(chuàng)建并激活虛擬環(huán)境:
PS D:\learning\mcp\weather> uv venv
Using CPython 3.12.3 interpreter at: C:\Users\pq449\AppData\Local\Programs\Python\Python312\python.exe
Creating virtual environment at: .venv
Activate with: .venv\Scripts\activate
PS D:\learning\mcp\weather> .\.venv\Scripts\activate
(weather) PS D:\learning\mcp\weather>
如果出現(xiàn)下面錯(cuò)誤,則表示沒有權(quán)限,可以設(shè)置下權(quán)限
PS D:\learning\mcp\weather> Set-ExecutionPolicy RemoteSigned -Scope CurrentUser

執(zhí)行腳本:
uv run client1.py
效果如下:

3. MCP客戶端接入在線大模型
現(xiàn)在我們嘗試在客戶端中接入在線大模型進(jìn)行對(duì)話。由于OpenAI和DeepSeek調(diào)用方法幾乎一樣,所以這個(gè)client可以同時(shí)支持對(duì)接GPT模型和DeepSeek模型。
3.1 新增依賴
為了支持調(diào)用OpenAI模型,以及在環(huán)境變量中讀取API-KEY等信息,需要先安裝如下依賴:
uv add mcp openai python-dotenv
(weather) PS D:\learning\mcp\weather> uv add mcp openai python-dotenv
Resolved 27 packages in 1.14s
Prepared 4 packages in 989ms
???????????????????? [0/4] Installing wheels...
warning: Failed to hardlink files; falling back to full copy. This may lead to degraded performance.
If the cache and target directories are on different filesystems, hardlinking may not be supported.
If this is intentional, set `export UV_LINK_MODE=copy` or use `--link-mode=copy` to suppress this warning.
Installed 4 packages in 419ms
+ distro==1.9.0
+ jiter==0.9.0
+ openai==1.77.0
+ tqdm==4.67.1
(weather) PS D:\learning\mcp\weather>
3.2 創(chuàng)建.env文件
接下來創(chuàng)建.env文件,并在env文件中進(jìn)行相應(yīng)的大模型設(shè)置。
BASE_URL=https://api.siliconflow.cn/v1 # 大模型API地址
MODEL=deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B #模型名稱
OPENAI_API_KEY="xxxxxxx" #你的API key
3.3 編寫client代碼
新建一個(gè)client2.py,把client1.py代碼拷貝過來修改如下:
import asyncio
import os
from openai import OpenAI
from dotenv import load_dotenv
from contextlib import AsyncExitStack
# 加載 .env 文件,確保 API Key 受到保護(hù)
load_dotenv()
class MCPClient:
def __init__(self):
"""初始化 MCP 客戶端"""
self.exit_stack = AsyncExitStack()
self.openai_api_key = os.getenv("OPENAI_API_KEY") # 讀取 OpenAI API Key
self.base_url = os.getenv("BASE_URL") # 讀取 BASE YRL
self.model = os.getenv("MODEL") # 讀取 model
if not self.openai_api_key:
raise ValueError("? 未找到 OpenAI API Key,請(qǐng)?jiān)?.env 文件中設(shè)置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:
"""調(diào)用 OpenAI API 處理用戶查詢"""
messages = [
{"role": "system", "content": "你是一個(gè)智能助手,幫助用戶回答問題。"},
{"role": "user", "content": query}
]
try:
# 調(diào)用 OpenAI API
response = 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.content
except Exception as e:
return f"? 調(diào)用 OpenAI API 時(shí)出錯(cuò): {str(e)}"
async def chat_loop(self):
"""運(yùn)行交互式聊天循環(huán)"""
while True:
try:
query = input("\n你: ").strip()
if query.lower() == 'quit':
break
response = await self.process_query(query) # 發(fā)送用戶輸入到 OpenAI API
print(f"\n?? OpenAI: {response}")
except Exception as e:
print(f"\n? 發(fā)生錯(cuò)誤: {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())
3.4 運(yùn)行代碼
uv run client2.py
效果如下:
