摘要:MCP(Model Context Protocol)协议是 2026 年最热的 AI 技术趋势之一,它让大模型从"只会说"进化为"能做事"。阿里云百炼平台上线了业界首个全生命周期 MCP 服务,预置 20+ 云端服务和 50+ 本地服务。本文从 MCP 协议原理讲起,实战演示自定义 MCP Server 开发、函数计算 FC 部署、百炼 MCP 服务广场集成,以及与 Qwen3.7 智能体的联动,帮你构建真正能调用工具的 AI 应用。
1. 场景:为什么 AI 需要 MCP
去年我在做一个智能客服项目时,遇到一个让人抓狂的问题:Qwen 大模型能流利地回答用户问题,但无法查询订单状态、无法调用物流接口、无法操作数据库。大模型就像一个"只会说不会做"的顾问,关键时刻帮不上忙。
团队最初用 Function Call 解决,但很快发现每个 API 都要硬编码适配。10 个业务系统、20 个接口,意味着要写 200 个适配函数,维护成本直线上升。
1.1 Function Call 的局限性
传统 Function Call 的核心痛点:
- 硬编码绑定:每个 API 需要单独编写调用逻辑,模型和工具强耦合
- 跨平台适配成本高:同一工具在 Claude、Qwen、GPT 上要分别适配
- 工具无法复用:A 项目写的工具函数,B 项目几乎无法直接使用
- 缺乏统一标准:各厂商的 Function Call 格式各异,迁移成本极高
1.2 MCP 的核心价值
MCP 将 AI 模型与工具的关系从"硬编码依赖"转变为"协议驱动"。
就像 USB-C 统一了充电接口一样,MCP 统一了 AI 调用工具的接口。一个 MCP Server 写好之后,任何支持 MCP 协议的 AI 应用都能直接使用,无需二次开发。
根据阿里云官方数据,MCP 可将工具对接耗时从数天缩短至 5-10 分钟。
1.3 传统 Function Call vs MCP 架构对比

左边是传统模式,每个工具都需要单独适配;右边是 MCP 模式,通过统一协议实现"即插即用"。
2. MCP 协议核心概念
理解 MCP 协议的架构,是开发 MCP Server 的前提。MCP 协议基于 JSON-RPC 2.0,采用三层架构设计。
2.1 三层架构:Host、Client、Server
MCP 协议定义了三个核心角色:
- Host(宿主):发起连接的 AI 应用,如百炼智能体、Claude Desktop
- Client(客户端):Host 内部的连接器,负责与 Server 建立和维护通信
- Server(服务端):提供工具、资源和提示词的服务进程
一个 Host 可以包含多个 Client,每个 Client 连接一个 Server。这种设计让 AI 应用能同时调用多个工具服务。
2.2 传输模式:STDIO vs SSE
MCP 支持两种传输模式,适用不同场景:
| 传输模式 | 适用场景 | 通信方式 | 部署位置 |
|---|---|---|---|
| STDIO | 本地开发、桌面应用 | 标准输入输出 | 本地进程 |
| SSE | 云端部署、远程调用 | HTTP + Server-Sent Events | 云服务器 |
注意:MCP 2026-07-28 规范已引入 Streamable HTTP 作为新的远程传输标准,但 SSE 仍被广泛支持。阿里云百炼和函数计算 FC 目前主要支持 SSE 协议。
2.3 核心能力:Tools、Resources、Prompts
MCP Server 可以提供三种核心能力:
- Tools(工具):AI 可执行的函数,如查询数据库、调用 API
- Resources(资源):AI 可读取的数据,如文件内容、数据库记录
- Prompts(提示词):预定义的交互模板,引导用户使用特定功能
其中 Tools 是最核心的能力,也是本文实战的重点。
2.4 MCP 协议交互流程

整个流程中,大模型负责"决策"(调用哪个工具),MCP Server 负责"执行"(实际操作),两者通过标准协议解耦。
3. 百炼 MCP 服务广场体验
阿里云百炼平台上线了业界首个全生命周期 MCP 服务,无需管理资源、开发部署、工程运维,5 分钟即可搭建一个连接 MCP 服务的智能体。
3.1 预置服务概览
百炼 MCP 服务广场提供丰富的预置服务:
- 20+ 云端服务:高德地图、天气查询、网页解析、知识图谱记忆等
- 50+ 本地服务:文件系统、数据库操作、Git 管理等
- 持续扩展中:社区贡献的 MCP Server 不断接入
3.2 热门 MCP Server 体验
以高德地图 MCP Server 为例,在百炼控制台的操作流程:
Why:以下步骤展示如何在百炼平台零代码集成官方 MCP 服务,这是最快速的入门方式。
步骤一:登录百炼控制台,进入 MCP 服务广场
步骤二:搜索"高德地图",点击开通服务
步骤三:填写高德开放平台获取的 API-KEY
步骤四:进入智能体管理,创建或选择一个智能体
步骤五:在智能体配置中,添加已开通的 MCP 服务
步骤六:发布智能体,开始对话测试
3.3 通过 Responses API 调用 MCP
Why:除了控制台操作,百炼还支持通过 API 方式调用 MCP 服务,适合需要编程集成的场景。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 配置 MCP 工具
mcp_tool = {
"type": "mcp",
"server_protocol": "sse",
"server_label": "WebParser",
"server_description": "网页解析MCP服务,用于解析网页内容。",
"server_url": "https://dashscope.aliyuncs.com/api/v1/mcps/WebParser/sse",
"headers": {
"Authorization": "Bearer " + os.getenv("DASHSCOPE_API_KEY")
}
}
response = client.responses.create(
model="qwen3.7-plus",
input="https://help.aliyun.com/zh/model-studio/mcp 里支持哪些模型?",
tools=[mcp_tool]
)
print(response.output_text)
百炼支持 Qwen3.7-Max、Qwen3.7-Plus、Qwen3.6-Plus 等系列模型调用 MCP 服务,最多可添加 10 个 MCP Server。
4. 自定义 MCP Server 开发实战
当预置 MCP Server 无法满足业务需求时,我们需要开发自定义 MCP Server。本节实战开发一个"代码审查"MCP Server。
4.1 环境准备
Why:FastMCP 是目前最流行的 Python MCP 开发框架,日下载量超过 400 万,用装饰器即可将 Python 函数转为 MCP 工具,极大降低开发门槛。
# 创建项目目录
mkdir code-review-mcp && cd code-review-mcp
# 创建虚拟环境
python3 -m venv venv
source venv/bin/activate
# 安装 MCP SDK(包含 FastMCP)
pip install "mcp[cli]"
4.2 开发代码审查 MCP Server
Why:以下代码实现了一个完整的 MCP Server,包含工具定义、SSE 传输和错误处理。每个 Tool 都有清晰的描述,帮助大模型准确判断何时调用。
# server.py
"""代码审查 MCP Server - 提供静态代码分析和审查建议"""
import re
import json
from mcp.server.fastmcp import FastMCP
# 创建 MCP Server 实例
mcp = FastMCP(
"CodeReview",
host="0.0.0.0",
port=8080
)
@mcp.tool()
def check_code_style(code: str, language: str = "python") -> str:
"""检查代码风格问题,返回发现的问题列表。
Args:
code: 待检查的源代码字符串
language: 编程语言,支持 python/java/javascript
"""
issues = []
# 检查行长度
for i, line in enumerate(code.split("\n"), 1):
if len(line) > 120:
issues.append(f"第{i}行: 行长度超过120字符 ({len(line)}字符)")
# 检查 Python 命名规范
if language == "python":
for i, line in enumerate(code.split("\n"), 1):
if re.match(r"^\s*def\s+[A-Z]", line):
issues.append(f"第{i}行: 函数名应使用蛇形命名法(snake_case)")
# 检查 TODO/FIXME 标记
for i, line in enumerate(code.split("\n"), 1):
if re.search(r"(TODO|FIXME|HACK|XXX)", line, re.IGNORECASE):
issues.append(f"第{i}行: 发现待处理标记 - {line.strip()}")
if not issues:
return json.dumps({
"result": "pass", "message": "代码风格检查通过"}, ensure_ascii=False)
return json.dumps({
"result": "warning",
"issue_count": len(issues),
"issues": issues
}, ensure_ascii=False)
@mcp.tool()
def count_code_metrics(code: str) -> str:
"""统计代码度量指标,包括行数、函数数、注释率等。
Args:
code: 待统计的源代码字符串
"""
lines = code.split("\n")
total_lines = len(lines)
blank_lines = sum(1 for line in lines if not line.strip())
comment_lines = sum(1 for line in lines if line.strip().startswith("#"))
code_lines = total_lines - blank_lines - comment_lines
function_count = len(re.findall(r"^\s*def\s+\w+", code, re.MULTILINE))
comment_ratio = round(comment_lines / max(code_lines, 1) * 100, 1)
return json.dumps({
"total_lines": total_lines,
"code_lines": code_lines,
"comment_lines": comment_lines,
"blank_lines": blank_lines,
"function_count": function_count,
"comment_ratio": f"{comment_ratio}%"
}, ensure_ascii=False)
@mcp.tool()
def detect_security_risks(code: str) -> str:
"""检测代码中的安全风险,如SQL注入、硬编码密码等。
Args:
code: 待检测的源代码字符串
"""
risks = []
# 检测 SQL 注入风险
if re.search(r"execute\s*\(\s*[\"'].*%s", code) or re.search(
r"f\".*SELECT.*FROM", code, re.IGNORECASE
):
risks.append({
"level": "HIGH",
"type": "SQL注入风险",
"description": "检测到可能的SQL拼接,建议使用参数化查询"
})
# 检测硬编码密码
if re.search(r"(password|passwd|pwd|secret)\s*=\s*[\"'][^\"']+[\"']", code, re.IGNORECASE):
risks.append({
"level": "HIGH",
"type": "硬编码密码",
"description": "检测到硬编码的密码或密钥,建议使用环境变量"
})
# 检测 eval 使用
if re.search(r"\beval\s*\(", code):
risks.append({
"level": "HIGH",
"type": "危险函数eval",
"description": "使用eval()存在代码注入风险,建议使用ast.literal_eval"
})
# 检测异常捕获过宽
if re.search(r"except\s*:", code) or re.search(r"except\s+Exception\s*:", code):
risks.append({
"level": "MEDIUM",
"type": "异常捕获过宽",
"description": "捕获所有异常可能隐藏真实问题,建议捕获具体异常类型"
})
if not risks:
return json.dumps({
"result": "safe", "message": "未检测到明显安全风险"}, ensure_ascii=False)
return json.dumps({
"result": "risk",
"risk_count": len(risks),
"risks": risks
}, ensure_ascii=False)
if __name__ == "__main__":
# 以 SSE 模式启动,适配云端部署
mcp.run(transport="sse")
4.3 本地测试
Why:使用 MCP Inspector 工具可以在浏览器中可视化测试 MCP Server,验证工具定义和返回结果是否正确。
# 方式一:使用 MCP Inspector 测试(推荐)
mcp dev server.py
# 方式二:直接启动 SSE 服务
python server.py
# 输出: Uvicorn running on http://0.0.0.0:8080
启动后,访问 Inspector 界面可以查看注册的工具列表、输入参数测试、查看返回结果。
4.4 关键开发要点
开发 MCP Server 时,有几个关键点需要注意:
- 工具描述要精准:
docstring是大模型判断是否调用该工具的依据,描述越清晰,调用准确率越高 - 参数类型要明确:使用 Python 类型注解,FastMCP 会自动生成 JSON Schema
- 返回值要结构化:建议返回 JSON 字符串,方便大模型解析
- 错误处理要完善:工具内部异常不要抛出,应返回友好的错误信息
5. 函数计算 FC 部署 MCP Server
开发完 MCP Server 后,需要部署到云端才能被远程 AI 应用调用。阿里云函数计算 FC 是部署 MCP Server 的最佳选择。
5.1 为什么选择函数计算
函数计算 FC 部署 MCP Server 的优势:
- 弹性扩缩容:流量高峰自动扩容,空闲缩至零,按实际调用计费
- 零改造上云:FC 提供 MCP Runtime,STDIO 模式的 Server 无需修改即可转为 SSE 远端服务
- 3AZ 高可用:默认跨可用区部署,单 AZ 故障自动切换
- 安全隔离:基于 MicroVM 的轻量级安全虚拟化,防止进程逃逸攻击
- 临时凭证:支持执行角色动态获取临时 Token,无需硬编码 AK/SK
5.2 代码打包
Why:函数计算部署需要将代码和依赖一起打包,确保运行时环境完整。
# 安装依赖到项目目录
pip install "mcp[cli]" -t .
# 打包代码和依赖
zip -r code-review-mcp.zip .
5.3 创建 FC 函数
登录函数计算 Function AI 控制台,按以下步骤操作:
步骤一:创建空白项目,选择 MCP 场景
步骤二:新建服务,选择"MCP 服务"
步骤三:配置 MCP 服务参数
Why:以下配置确保 MCP Server 以 SSE 协议对外暴露,并开启鉴权保障安全。
| 配置项 | 说明 | 推荐值 |
|---|---|---|
| 传输类型 | SSE 协议或 STDIO | SSE 协议 |
| SSE 路径 | SSE 端点路径 | /sse |
| 监听端口 | 进程监听端口 | 8080 |
| 开启鉴权 | Bearer Token 鉴权 | 建议开启 |
| 运行环境 | Python 运行时 | Python 3.10 |
| 启动命令 | 服务启动命令 | python3 server.py |
| 选择仓库 | 代码上传方式 | 代码包上传 |
步骤四:资源配置
Why:MCP SSE 依赖 session 会话机制,建议开启极速模式并预置快照,避免冷启动和会话丢失。
| 配置项 | 推荐值 | 原因 |
|---|---|---|
| 实例规格 | 1 vCPU / 2 GB | MCP Server 通常计算量不大 |
| 弹性策略 | 极速模式 | SSE 长连接需要亲和性调度 |
| 预置快照数 | 1 | 确保至少一个热实例 |
| 实例限额 | 1(起步) | 根据流量逐步调整 |
步骤五:点击"预览&部署"
5.4 部署验证
Why:部署后需要验证 MCP Server 是否正常工作,包括 SSE 连接和工具调用。
# 获取 FC 生成的 SSE 端点地址
# 格式示例: https://xxxxx.cn-beijing.fc.aliyuncs.com/sse
# 测试 SSE 连接
curl -N https://xxxxx.cn-beijing.fc.aliyuncs.com/sse
# 测试工具列表(通过 MCP 协议)
curl -X POST https://xxxxx.cn-beijing.fc.aliyuncs.com/sse \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
部署成功后,FC 控制台会显示 SSE 连接地址和生成的 Schema,可直接在控制台测试工具效果。
6. 与 Qwen3.7 智能体联动
MCP Server 部署完成后,下一步是将它集成到百炼智能体中,实现端到端的工具调用。
6.1 在百炼智能体中集成自定义 MCP Server
步骤一:进入百炼 MCP 管理,点击"创建 MCP 服务"
步骤二:选择"使用脚本部署"或"http"方式
- 如果 MCP Server 已部署在 FC 上,选择 http 方式
- 填入 FC 生成的 SSE 端点地址和鉴权 Token
步骤三:配置服务名称和描述
Why:服务描述会传递给大模型,帮助模型理解何时应该调用该工具。描述越精准,调用准确率越高。
服务名称: 代码审查助手
描述: 提供代码风格检查、度量统计和安全风险检测能力。当用户需要代码审查、代码质量分析或安全扫描时调用此服务。
步骤四:在智能体配置中添加该 MCP 服务
6.2 端到端测试
Why:以下代码演示通过百炼 Responses API 调用自定义 MCP Server,验证完整链路是否通畅。
import os
from openai import OpenAI
client = OpenAI(
api_key=os.getenv("DASHSCOPE_API_KEY"),
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
# 配置自定义 MCP Server
mcp_tool = {
"type": "mcp",
"server_protocol": "sse",
"server_label": "CodeReview",
"server_description": "代码审查MCP服务,提供代码风格检查、度量统计和安全风险检测。",
"server_url": "https://your-fc-endpoint.cn-beijing.fc.aliyuncs.com/sse",
"headers": {
"Authorization": "Bearer " + os.getenv("MCP_SERVER_TOKEN")
}
}
# 测试:让智能体审查代码
test_code = """
def GetUser(id):
password = "hardcoded_secret_123"
sql = f"SELECT * FROM users WHERE id = {id}"
result = eval(sql)
return result
"""
response = client.responses.create(
model="qwen3.7-plus",
input=f"请审查以下代码的安全性和质量:\n```python\n{test_code}\n```",
tools=[mcp_tool]
)
print(response.output_text)
预期输出中,智能体会自动调用 detect_security_risks 和 check_code_style 工具,发现硬编码密码、SQL 注入风险和命名规范问题,并给出修复建议。
6.3 调用链路全景
完整的调用链路如下:
用户提问 → 百炼智能体(Qwen3.7)→ 判断需要调用工具 → MCP Client 发起 tools/list → 获取工具列表 → 选择合适工具 → MCP Client 发起 tools/call → FC 上的 MCP Server 执行 → 返回结果 → 大模型生成回复
7. 避坑指南
在 MCP Server 开发和部署过程中,我踩过不少坑,这里分享五个最常见的。
坑1:STDIO vs SSE 模式选择
问题:本地开发用 STDIO 没问题,部署到云端后无法连接。
原因:STDIO 通过标准输入输出通信,只能在同一进程内使用。云端部署必须使用 SSE 或 Streamable HTTP。
解决方案:
- 本地开发和测试:使用 STDIO 模式(
mcp.run(transport="stdio")) - 云端部署:使用 SSE 模式(
mcp.run(transport="sse")) - 函数计算 FC 的 MCP Runtime 可以自动将 STDIO 转为 SSE,无需改代码
坑2:MCP Server 冷启动延迟
问题:首次调用 MCP Server 响应时间长达 3-5 秒,影响用户体验。
原因:函数计算的基础模式下,实例从零启动需要加载 Python 运行时和依赖包。
解决方案:
- 开启函数计算的极速模式,预置 1 个快照
- 设置实例限额 ≥ 1,保持至少一个热实例
- 优化依赖包大小,移除不必要的库
- 使用 Provisioned Concurrency 预热实例
坑3:工具描述影响调用准确率
问题:大模型经常调用错误的工具,或者该调用时不调用。
原因:工具的 docstring 描述不够清晰,大模型无法准确判断何时应该调用。
解决方案:
# ❌ 模糊描述——大模型不知道何时该用
@mcp.tool()
def check(code: str) -> str:
"""检查代码"""
pass
# ✅ 精准描述——大模型能准确判断调用时机
@mcp.tool()
def detect_security_risks(code: str) -> str:
"""检测代码中的安全风险,如SQL注入、硬编码密码、eval使用等。
当用户要求安全扫描、安全审查、漏洞检测时调用此工具。"""
pass
关键原则:描述中包含触发场景(何时调用)和功能说明(做什么)。
坑4:SSE 长连接与函数计算超时冲突
问题:SSE 连接建立后,一段时间无请求就断开,导致后续调用失败。
原因:函数计算默认执行超时为 60 秒,SSE 长连接可能超过此限制。
解决方案:
- 在 FC 控制台将函数超时时间调整为 300 秒或更长
- 开启极速模式,利用亲和性调度保持会话
- 客户端实现自动重连机制
- MCP 2026-07-28 规范的无状态化设计从根本上解决了此问题
坑5:MCP 安全——工具注入攻击防范
问题:恶意 MCP Server 可能通过工具描述诱导大模型执行危险操作。
原因:MCP 协议允许 Server 自定义工具描述和行为,缺乏沙箱隔离的 Server 可能被利用。
解决方案:
- 只使用来源可信的 MCP Server,核实源代码
- 开启函数计算的 Bearer Token 鉴权
- 使用 FC 的临时凭证机制,避免硬编码 AK/SK
- 为 MCP Server 配置最小权限的执行角色
- 对工具返回结果做敏感信息过滤
8. 总结与下一步
MCP 核心价值回顾
本文从 MCP 协议原理到实战部署,完整覆盖了 MCP Server 开发的全流程:
- MCP 协议:统一了 AI 调用工具的接口,从"硬编码"到"即插即用"
- 百炼 MCP 服务广场:20+ 云端服务 + 50+ 本地服务,5 分钟搭建智能体
- 自定义开发:FastMCP 框架让开发 MCP Server 像写普通函数一样简单
- 函数计算部署:零改造上云,弹性扩缩容,按调用计费
- 智能体联动:Qwen3.7 + MCP,让 AI 从"只会说"进化为"能做事"
技术选型建议
| 场景 | 推荐方案 |
|---|---|
| 快速验证 | 百炼 MCP 服务广场 + 官方预置服务 |
| 定制化需求 | FastMCP 开发 + 函数计算 FC 部署 |
| 企业级生产 | FC 极速模式 + MSE Nacos 注册中心 + 鉴权 |
| 多服务编排 | 百炼工作流 + 多个 MCP Server |
系列预告
本文是 AI Agent 开发系列的第一篇,后续文章将深入探讨:
- AI Agent 框架实战:Qwen-Agent + MCP 构建多步推理智能体
- MCP 网关设计:大规模 MCP Server 的注册、发现与治理
- Streamable HTTP 实战:MCP 新一代传输协议的迁移指南
MCP 正在重新定义 AI 应用的开发范式。掌握 MCP Server 开发,就是掌握了让 AI "动手做事"的关键能力。