一、MCP是什么?
MCP(Model Context Protocol,模型上下文协议)是由Anthropic在2024年发布的一个开放标准协议,旨在标准化和统一大语言模型(LLM)与外部数据源、工具之间的通信方式。
核心价值
- 统一标准:类似于USB-C接口,为不同的数据源、工具和应用提供统一的连接方式
- 解决问题:克服了传统AI系统因缺乏标准化接口而导致的集成困难、信息孤岛问题
- 简化开发:开发者无需为每个工具开发单独的适配代码,实现动态发现和集成
二、MCP架构设计
2.1 三层架构模型
MCP采用三层架构设计,实现了LLM与外部资源的有效解耦:
1
2
3
4
5
6
7
8
9
10
| ┌─────────────────────────────────────┐
│ MCP Host │
│ (AI应用环境,如Claude Desktop) │
├─────────────────────────────────────┤
│ MCP Client │
│ (集成在Host内,负责与Server通信) │
├─────────────────────────────────────┤
│ MCP Server │
│ (轻量级服务端,提供Tools/Resources) │
└─────────────────────────────────────┘
|
核心组件说明:
- MCP Host
- 运行AI模型的宿主环境(如Claude Desktop、DeepSeek应用)
- 管理客户端实例,控制连接权限
- 执行安全策略,聚合上下文信息
- MCP Client
- 集成在Host内部的客户端组件
- 负责与MCP Server通信
- 处理协议协商和消息路由
- 维持与Server的1:1隔离连接
- MCP Server
- 轻量级服务端,可本地或远程部署
- 提供三类核心功能:
- Tools:可执行函数(数据库查询、API调用等)
- Resources:只读数据源(文件、日志、数据库记录等)
- Prompts:预定义的任务模板
2.2 架构设计原则
- 简单性:Server设计简化,复杂协调由Host处理
- 可组合性:多个Server可无缝组合,支持模块化设计
- 隔离性:Server无法访问整个会话历史或其他Server的数据,由Host控制交互
- 可扩展性:功能可增量添加,保证向后兼容性
三、通信机制详解
3.1 JSON-RPC 2.0协议
MCP所有消息交互都遵循JSON-RPC 2.0规范,这是一个轻量级的远程过程调用协议。
基本消息结构:
1
2
3
4
5
6
7
8
9
10
11
| {
"jsonrpc": "2.0",
"id": 1,
"method": "call_tool",
"params": {
"tool_name": "sql_query",
"arguments": {
"query": "SELECT * FROM users WHERE age > 18"
}
}
}
|
四大消息类型:
| 消息类型 | 作用 | 示例 |
|---|
| Request | 发起请求,期望获得响应 | 调用工具请求 |
| Result | 成功响应请求 | 工具执行结果 |
| Error | 请求执行失败 | 错误码和错误描述 |
| Notification | 单向消息,不期望响应 | 工具列表更新通知 |
3.2 传输方式
本地通信
- 使用方式:通过stdio(标准输入输出)传输
- 适用场景:本地工具调用,同一机器上的进程通信
- 优势:低延迟,安全性高
1
| 应用进程 <--stdin/stdout--> MCP Server
|
远程通信
- 使用方式:基于SSE(Server-Sent Events)的HTTP长连接
- 组成:
- Client → Server:HTTP POST请求
- Server → Client:HTTP SSE长连接
- 适用场景:跨网络、远程服务调用
- 优势:支持异步数据流,适合高延迟网络
1
2
| 应用 --HTTP POST--> 远程Server
<-HTTP SSE-- 远程Server
|
四、核心功能模块
工具是MCP最常用的功能,允许LLM调用外部可执行函数。
实现方式:
1
2
3
4
5
6
7
8
9
10
11
12
| import mcp
@mcp.tool()
def write_to_database(data: dict) -> dict:
"""将数据写入数据库"""
db.insert(data)
return {"status": "success", "id": data.get("id")}
@mcp.tool()
def query_database(query: str) -> list:
"""查询数据库"""
return db.execute(query).fetchall()
|
工具调用流程:
- 发现阶段:Client通过
list_tools()方法获取Server支持的工具列表 - 执行阶段:LLM选择合适的工具,发送调用请求
- 返回阶段:Server执行工具,返回结果给LLM
4.2 Resources(资源)
资源提供只读的数据源访问,用于向LLM暴露结构化数据。
实现方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
| @mcp.resource("file://config.json")
def read_config() -> str:
"""读取配置文件"""
with open("config.json", "r") as f:
return f.read()
@mcp.resource("db://users")
def get_users_schema() -> dict:
"""获取用户表结构"""
return {
"columns": ["id", "name", "email"],
"types": ["int", "string", "string"]
}
|
特点:
- 由URI标识(如
file://path、db://table) - 只读性质,防止意外修改
- 支持流式返回大型资源
4.3 Prompts(提示)
预定义的对话模板,指导LLM完成特定任务。
实现方式:
1
2
3
4
5
6
7
8
9
10
| @mcp.prompt(
name="sql_generator",
description="根据自然语言生成SQL语句"
)
def sql_prompt(table_name: str, condition: str) -> str:
return f"""You are a SQL expert. Generate a SQL query for:
Table: {table_name}
Condition: {condition}
Return only the SQL query without explanation."""
|
优势:
- 提高LLM完成特定任务的准确率
- 减少prompt工程的重复工作
- 支持参数化,提供灵活的模板
五、动态发现机制
5.1 工具级动态发现
这是MCP的核心创新之一,允许AI模型实时发现并集成新工具。
工作流程:
1
2
3
4
| 1. Client启动 --> list_tools()
2. Server返回 --> [{name: "tool1"}, {name: "tool2"}]
3. 新增工具 --> Server发送 notifications/tools/list_changed
4. Client刷新 --> 重新获取工具列表
|
代码示例:
1
2
3
4
5
6
| # 客户端获取工具列表
tools = await session.list_tools()
# 输出:["sql_query", "read_file", "send_email"]
# Server新增工具时,自动通知Client
await session.notify_tools_changed()
|
5.2 服务级动态发现(2025年新增特性)
URI驱动发现:
1
2
3
4
5
6
7
8
9
| 用户输入 URI: mcp://api.service.com
↓
Client 解析 URI
↓
访问元数据端点: https://api.service.com/llms.txt
↓
服务端返回 JSON 描述文件(功能列表、API文档、认证方式)
↓
Client 自动配置工具调用权限
|
应用场景:
- 用户粘贴一个MCP URI到聊天窗口
- LLM自动识别并集成该服务(如股票API、天气服务)
- 无需手动配置,真正的即插即用
六、安全与权限控制
6.1 安全设计原则
- 本地化执行
- MCP Server默认运行在本地,避免敏感数据外泄
- 用户完全控制数据流向
- 操作确认机制
- 高风险操作(删除文件、修改数据库)需用户手动授权
- 避免LLM误操作造成的数据损失
- 企业级安全扩展
- JWT令牌认证
- RBAC权限模型
- IPsec隧道加密
- 满足金融、医疗等严格合规需求
6.2 权限控制示例:
1
2
3
4
5
6
7
8
9
10
11
| @mcp.tool(requires_confirmation=True)
def delete_database_record(record_id: int) -> dict:
"""删除数据库记录(需要用户确认)"""
# 此操作会在执行前弹出确认对话框
db.delete(record_id)
return {"status": "deleted"}
@mcp.tool(roles=["admin", "data_manager"])
def export_data(format: str) -> bytes:
"""导出数据(仅admin和data_manager角色可用)"""
return db.export(format)
|
七、与传统API的对比
| 能力 | 传统API | MCP协议 |
|---|
| 集成复杂度 | 需为每个工具开发适配代码 | 动态发现,无需预编码 |
| 工具扩展性 | 需重新部署应用 | 实时添加工具,Client自动更新 |
| 多源支持 | 依赖定制化开发 | 统一协议接入数据库、API、文件等 |
| 安全边界 | 依赖网络隔离 | 本地执行+细粒度权限控制 |
| 开发效率 | 每个新服务需重写客户端代码 | 一次实现,任意LLM可用 |
| 用户体验 | 需手动配置每个工具 | 自动发现,开箱即用 |
八、典型应用场景
场景1:智能客服系统
1
2
3
4
5
6
7
8
9
| 用户提问:我的订单号是12345,现在在哪里?
↓
LLM识别需要调用order_query工具
↓
MCP Client调用远程服务的query_tool
↓
Server返回订单状态信息
↓
LLM生成自然语言回复给用户
|
场景2:数据分析助手
1
2
3
4
5
6
7
8
9
| LLM需要分析销售数据
↓
通过Resource读取数据库表结构
↓
LLM生成SQL查询工具调用
↓
获取原始数据,LLM进行分析
↓
生成实时报表和可视化建议
|
场景3:自动化运维
1
2
3
4
5
6
7
8
9
| 监控告警触发
↓
LLM通过list_tools()发现可用的修复工具
↓
根据服务器日志和监控数据判断问题
↓
自动调用修复工具(如重启服务、清理缓存)
↓
验证修复结果,上报处理结果
|
场景4:跨平台协作
1
2
3
4
5
6
7
8
9
| LLM需要协调会议时间
↓
调用get_calendar工具查看日程
↓
调用list_users工具获取参与者列表
↓
调用send_meeting_invitation工具发送邀请
↓
集成Slack、邮箱、日历工具完成协调
|
九、连接生命周期
初始化阶段
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| Client → Server: 初始化请求
{
"protocol": "mcp/1",
"capabilities": {
"sampling": {},
"roots": {}
}
}
Server → Client: 初始化响应
{
"protocol": "mcp/1",
"capabilities": {
"tools": {},
"resources": {},
"prompts": {}
}
}
|
消息交换阶段
- Client发送请求(调用工具、获取资源等)
- Server处理请求并返回结果
- 双向支持Notification(无需响应的通知)
终止阶段
十、MCP的学习路径
初级阶段
- 理解MCP的基本概念和架构
- 学习JSON-RPC 2.0协议
- 尝试使用现有的MCP Server
中级阶段
- 开发简单的MCP Server(提供单个Tool)
- 理解Tools、Resources、Prompts三大功能
- 实现本地通信(stdio方式)
高级阶段
- 实现远程通信(HTTP SSE方式)
- 实现动态发现机制
- 添加安全认证和权限控制
- 优化Server性能和错误处理
十一、关键收获与总结
MCP的核心优势
- 灵活性
- 工具可热插拔,服务可动态扩展
- 无需重新部署客户端应用
- 安全性
- 标准化
- 统一协议降低集成成本
- 推动AI生态开放
- 减少重复开发工作
为什么MCP很重要
- 标准化大模型与外部系统的交互,就像USB-C统一了设备接口
- 动态发现机制使得即插即用成为可能,大幅降低集成复杂度
- 开放生态鼓励第三方开发者贡献MCP Server,形成工具库生态
参考资源
总结
MCP协议代表了大模型应用开发的新方向。通过标准化的通信协议、灵活的功能模块和动态发现机制,MCP使得大模型应用可以像搭积木一样组合各种功能,真正实现了”工具民主化”。
掌握MCP不仅能加深对AI应用架构的理解,还能帮助开发者构建更灵活、更安全、更易维护的AI系统。