# 1. 前言
# 1.1 MCP出现背景
近一年来,尽管GPT-4、Claude Sonnet 3.7和Deepseek R1等AI模型持续取得突破,但市场上大多数AI应用依然以独立服务形式存在,与传统系统缺乏有效融合。这种局面一方面源于企业对敏感数据安全的严格管控和复杂审批流程,另一方面则反映了技术层面上缺乏一个开放、通用且广受共识的协议标准,使得诸如联网搜索、发送邮件和发布博客等多功能集成变得异常困难。
在这样的背景下,Claude团队提出了MCP(Model Context Protocol),旨在建立统一的协议标准,推动AI应用与现有服务的高效整合。它的推出促进了大模型与传统系统间的互联融合,吸引了众多企业与开源社区的积极响应,共同探索打造更紧密的数字生态体系。
- 官方博客:https://www.anthropic.com/news/model-context-protocol (opens new window)
- 官方文档:https://modelcontextprotocol.io/introduction (opens new window)
# 1.2 MCP协议概述
# 1.2.1 MCP是什么
模型上下文协议(MCP):一种标准化接口,旨在实现AI模型与外部工具和资源之间的无缝交互,打破数据孤岛,促进不同系统之间的互操作性。在MCP出现之前,AI应用与外部工具的交互依赖于手动API连接、插件接口和Agent框架等方法,这些方法存在复杂性高、可扩展性差等问题。
# 1.2.2 MCP工作流程
由3个核心组件构成:MCP主机、MCP客户端和MCP服务器。这些组件协同工作,实现AI应用与外部工具和数据源之间的无缝通信。
- MCP主机:提供执行AI任务的环境,并运行MCP客户端。
- MCP客户端:作为主机环境的中介,与MCP服务端保持1:1连接,与服务端进行通信。
- MCP服务端:提供外部系统和操作的访问权限,具备工具、资源和提示三种核心能力。
传输层是MCP架构中的关键组成部分,负责在MCP客户端和MCP服务器之间实现安全、双向的通信,通信流程的具体步骤:
- 初始请求:MCP客户端向MCP服务器发送初始请求,查询服务器的功能和可用工具。
- 初始响应:MCP服务器接收到请求后,返回一个初始响应,列出其提供的工具、资源和提示,供客户端使用。
- 持续通知:建立连接后,MCP服务器持续向客户端发送通知,实时更新服务器状态或任务进度,确保客户端能及时获取最新信息。
MCP服务端生命周期包含以下3个阶段:
- 创建阶段:涉及服务器注册、安装程序部署和代码完整性验证。此阶段面临的风险包括名称冲突、安装程序伪造和代码注入/后门。
- 运行阶段:服务器在此阶段处理请求、执行工具调用,并与外部资源进行交互。风险包括工具名称冲突、斜杠命令重叠和沙箱逃逸。
- 更新阶段:确保服务器保持安全、最新,并适应不断变化的需求。风险包括更新后权限持续、版本控制问题和旧版本配置漂移。
# 1.2.3 MCP与函数调用对比
这两种技术都旨在增强 AI 模型与外部数据的交互能力,但 MCP 不止可以增强 AI 模型,还可以是其他的应用系统。
- MCP(Model Context Protocol),模型上下文协议
- Function Calling,函数调用
类别 | MCP(Model Context Protocol) | Function Calling |
---|---|---|
性质 | 协议 | 功能 |
范围 | 通用(多数据源、多功能) | 特定场景(单一数据源或功能) |
目标 | 统一接口,实现互操作 | 扩展模型能力 |
实现 | 基于标准协议 | 依赖于特定模型实现 |
开发复杂度 | 低:通过统一协议实现多源兼容 | 高:需要为每个任务单独开发函数 |
复用性 | 高:一次开发,可多场景使用 | 低:函数通常为特定任务设计 |
灵活性 | 高:支持动态适配和扩展 | 低:功能扩展需额外开发 |
常见场景 | 复杂场景,如跨平台数据访问与整合 | 简单任务,如个人助手、单模型大纲 |
MCP 与 Function Calling 是具有一定联系,但侧重点不同的两个技术概念。前者则侧重于描述函数的规范化执行,后者侧重于描述 LLM 本身具有的结构化函数调用能力,二者是分配与执行的关系。
- Function Calling 帮助 LLM 决定它想要做什么。
- MCP 确保工具可靠可用、可发现和可执行,而无需自定义集成所有内容。
例如,Agent 可能会使用函数调用说“我需要搜索 Web”。该请求可以通过 MCP 进行路由,以便从可用的 Web 搜索工具中进行选择,调用正确的工具,并以标准格式返回结果。
# 1.3 MCP相关资源
如果只是作为使用者,可以去社区寻找现成的MCP服务端和客户端来用。
- MCP服务端资源:https://github.com/punkpeye/awesome-mcp-servers (opens new window)
- MCP客户端资源:https://github.com/punkpeye/awesome-mcp-clients (opens new window)
- MCP学习资源:https://github.com/yzfly/Awesome-MCP-ZH (opens new window)
# 2. Qwen3原生支持MCP协议
# 2.1 Qwen3系列模型概述
阿里正式开源的Qwen3系列模型,包含2个MoE模型、6个稠密模型。
- 项目地址:https://github.com/QwenLM/Qwen3 (opens new window)
- 官方博客:https://qwenlm.github.io/zh/blog/qwen3 (opens new window)
- 模型地址:https://huggingface.co/collections/Qwen/qwen3-67dd247413f0e2e4f653967f (opens new window)
它具有以下5大关键特性:
- 8种参数大小的稠密与MoE模型:0.6B、1.7B、4B、8B、14B、32B和Qwen3-235B-A22B(2350亿总参数和220亿激活参数)、Qwen3-30B-A3B(300亿总参数和30亿激活参数);
- 引入混合思考模式:用户可切换“思考模式、“非思考模式”,自己控制思考程度;
- 推理能力提升:在数学、代码生成和常识逻辑推理方面超越QwQ(思考模式)和Qwen2.5 instruct models(非思考模式);
- 支持MCP,Agent能力提升:可以在思考和非思考模式下实现大语言模型与外部数据源和工具的集成,并完成复杂任务;
- 支持119种语言和方言:具备多语言理解、推理、指令跟随和生成能力。
# 2.2 Qwen3使用MCP示例
Qwen3优化了模型的Agent和代码能力,同时也对MCP做了原生支持。下面是官方示例,展示Qwen3是如何思考并与环境进行交互的。
# 3. MCP服务端开发与Cursor接入
# 3.1 MCP的Python SDK
MCP提供了多种语言的官方SDK,以下是官方的Python SDK,可用于开发服务端和客户端程序。
# 3.2 开发MCP服务端
实验环境:Macbook Pro 2021,M1 pro芯片,16G内存,1024G存储,macOS Sonoma 14.5系统,Python3.10.9环境
# 3.2.1 准备MCP服务端
MCP的Python SDK最低支持到3.10版本,官方建议使用 uv (opens new window) 来管理 Python 项目。
$ curl -LsSf https://astral.sh/uv/install.sh | sh
$ uv init weather
$ cd weather
$ uv add "mcp[cli]" httpx
$ touch weather.py
2
3
4
5
写入代码如下:
from typing import Any
import httpx
from mcp.server.fastmcp import FastMCP
# Initialize FastMCP server
mcp = FastMCP("weather")
# Constants
NWS_API_BASE = "https://api.weather.gov"
USER_AGENT = "weather-app/1.0"
async def make_nws_request(url: str) -> dict[str, Any] | None:
"""Make a request to the NWS API with proper error handling."""
headers = {
"User-Agent": USER_AGENT,
"Accept": "application/geo+json"
}
async with httpx.AsyncClient() as client:
try:
response = await client.get(url, headers=headers, timeout=30.0)
response.raise_for_status()
return response.json()
except Exception:
return None
def format_alert(feature: dict) -> str:
"""Format an alert feature into a readable string."""
props = feature["properties"]
return f"""
Event: {props.get('event', 'Unknown')}
Area: {props.get('areaDesc', 'Unknown')}
Severity: {props.get('severity', 'Unknown')}
Description: {props.get('description', 'No description available')}
Instructions: {props.get('instruction', 'No specific instructions provided')}
"""
@mcp.tool()
async def get_alerts(state: str) -> str:
"""Get weather alerts for a US state.
Args:
state: Two-letter US state code (e.g. CA, NY)
"""
url = f"{NWS_API_BASE}/alerts/active/area/{state}"
data = await make_nws_request(url)
if not data or "features" not in data:
return "Unable to fetch alerts or no alerts found."
if not data["features"]:
return "No active alerts for this state."
alerts = [format_alert(feature) for feature in data["features"]]
return "\n---\n".join(alerts)
@mcp.tool()
async def get_forecast(latitude: float, longitude: float) -> str:
"""Get weather forecast for a location.
Args:
latitude: Latitude of the location
longitude: Longitude of the location
"""
# First get the forecast grid endpoint
points_url = f"{NWS_API_BASE}/points/{latitude},{longitude}"
points_data = await make_nws_request(points_url)
if not points_data:
return "Unable to fetch forecast data for this location."
# Get the forecast URL from the points response
forecast_url = points_data["properties"]["forecast"]
forecast_data = await make_nws_request(forecast_url)
if not forecast_data:
return "Unable to fetch detailed forecast."
# Format the periods into a readable forecast
periods = forecast_data["properties"]["periods"]
forecasts = []
for period in periods[:5]: # Only show next 5 periods
forecast = f"""
{period['name']}:
Temperature: {period['temperature']}°{period['temperatureUnit']}
Wind: {period['windSpeed']} {period['windDirection']}
Forecast: {period['detailedForecast']}
"""
forecasts.append(forecast)
return "\n---\n".join(forecasts)
if __name__ == "__main__":
# Initialize and run the server
mcp.run(transport='stdio')
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# 3.2.2 启动MCP服务端
下面将启动服务并使用MCP-Inspector进行调试。
$ mcp dev weather.py
看到如下日志,说明MCP服务端程序启动成功。
访问 http://127.0.0.1:6274
地址即可进行功能测试。
# 3.3 Cursor接入MCP服务端
可以通过一些支持 MCP Server 的客户端进行调试,比如Cursor。
- 设置 ——> MCP ——> Add new MCP server
- 类型选择 command,名称可以自定义,执行的命令如下,需要指定路径。
uv --directory /Users/yoyo/Workspace/test_workspace/weather run weather.py
接入成功后如下图所示:
在Cursor里使用MCP服务端的效果如下:
# 4. 参考资料
[1] MCP 终极指南 from Guangzheng Li (opens new window)
[2] 一文看懂:MCP(大模型上下文协议) from 知乎 (opens new window)
[3] 一个专为中文用户打造的 MCP资源合集 from Github (opens new window)
[4] 精选的 MCP Server 列表 from Github (opens new window)
[5] 精选的 MCP Client 列表 from Github (opens new window)
[6] 从零开始教你打造一个MCP客户端 from 知乎 (opens new window)
[7] FastMCP快速构建MCP Server from Github (opens new window)
[8] MCP + 数据库,一种比 RAG 检索效果更好的新方式!from 微信公众号 (opens new window)
[9] 首篇MCP技术生态全面综述:核心组件、工作流程、生命周期 from 微信公众号 (opens new window)
[10] Claude MCP 简介 from Claude MCP (opens new window)
[11] MCP、function calling 这两者有什么区别?与AI Agent 是什么关系?from 知乎 (opens new window)
[12] LLMs的函数调用(Function Call)和MCP——直观的对比解释 from 知乎 (opens new window)
[13] Model Context Protocol(MCP) 编程极速入门 from Github (opens new window)
[14] 因为Manus爆火的 Claude MCP,90%人的认知可能都是错的 from 微信公众号 (opens new window)
[15] 阿里Qwen3深夜开源!8款模型、集成MCP,性能超DeepSeek-R1 from 知乎 (opens new window)
[16] MCP Server 开发实战指南(Python版)from Ryan-ZOE (opens new window)