一文带你了解 ModelContextProtocol
概念介绍的差不多了,作为 AI 模型的能力拓展,近几个月来,MCP概念爆火,网上的MCP平台展览了许多实用的MCP。做 AI 应用开发,掌握这个能力势在必得,希望这篇文章能帮助到大家。
什么是 MCP
简介
ModelContextProtocol 是一个开源标准,用于将人工智能应用与外部系统连接起来。
通过MCP,像Claude或ChatGPT这样的AI应用可以连接数据源(如本地文件、数据库)、工具(如搜索引擎、计算器)和工作流程(如专门提示)——使它们能够访问关键信息并执行任务。
可以把MCP想象成AI应用的USB-C接口。正如USB-C提供了连接电子设备的标准化方式,MCP也提供了将AI应用与外部系统连接的标准化方式。
MCP的数据标准
MCP 使用 JSON-RPC 2.0 协议封装消息,确保请求和响应的结构化处理
示例
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"tools": [
{
"name": "add",
"description": "Add two numbers",
"inputSchema": {
"properties": {
"a": { "title": "A", "type": "integer" },
"b": { "title": "B", "type": "integer" }
},
"required": ["a", "b"],
"title": "addArguments",
"type": "object"
}
}
]
}
}
格式
// 请求
{
"jsonrpc": "2.0",
"id": "number | string",
"method": "string",
"params": "object" // 可选
}
// 响应
{
"jsonrpc": "2.0",
"id": "number | string",
"result": "object", // 成功时返回
"error": { // 失败时返回
"code": "number",
"message": "string",
"data": "unknown" // 可选
}
}
// 通知
{
"jsonrpc": "2.0",
"method": "string",
"params": "object" // 可选
}
MCP原语
MCP原语(Model Communication Protocol Primitives)是该协议中最重要的概念,定义了客户端与服务器之间能够相互提供的核心能力。这些原语明确了可以与AI应用共享的上下文信息类型以及可执行的操作范围。
服务器端核心原语
工具(Tools)
可执行函数,AI应用可以调用这些函数来执行具体操作(例如文件操作、API调用、数据库查询)
Tips: ToolsCall 和 FunctionCal l不是一个概念, FunctionCall 指的是模型本身根据用户提供的方法,在大模型语言生成过程,根据上下文判断是否需要通过FunctionCall调用,返回方法调用信息让客户端去处理FunctionCall的结果, 而 Tool Call 则是要求MCP服务端将工具调用结果返回给客户端,两者的执行主体不同
// 客户端请求服务端获取航班信息的函数调用
{
name: "searchFlights",
description: "Search for available flights",
inputSchema: {
type: "object",
properties: {
origin: { type: "string", description: "Departure city" },
destination: { type: "string", description: "Arrival city" },
date: { type: "string", format: "date", description: "Travel date" }
},
required: ["origin", "destination", "date"]
}
}
资源(Resources)
为AI应用提供上下文信息的数据源(例如文件内容、数据库记录、API响应), 例如下面的例子,获取出发和目的地的航班信息,相对于工具调用获取的信息, 通过资源获取的信息更加直接,可以采用这种规范,实现客户端与用户交互选择要使用的资源 3
{
"uriTemplate": "travel://flights/{origin}/{destination}",
"name": "flight-search",
"title": "Flight Search",
"description": "Search available flights between cities",
"mimeType": "application/json"
}
- 提示(Prompts)
帮助构建与语言模型交互的可复用模板,关键方法:
| Method | Purpose | Returns |
|---|---|---|
| prompts/list | 客户端请求服务端可用的模板列表 | 模板列表 |
| prompts/get | 客户端请求服务端可用的模板详情 | 完整的模板信息及其需要的参数 |
客户端原语
MCP还定义了客户端支持服务端调用的原语,Client - Server 链路建立过程中,不仅服务端会携带自己支持的原语,客户端也会携带支持的原语信息发送给服务端,突破了传统的客户端→服务器单向请求模式。
采样(Sampling)
在服务器响应客户端请求过程中,允许服务器反向请求客户端获取大模型决策后的信息,利用其结果完善自身逻辑。
// 向客户端发起请求,要求 llm 回答问题
{
messages: [
{
role: "assistant",
content: "Analyze these flight options and recommend the best choice:\n" +
"[47 flights with prices, times, airlines, and layovers]\n" +
"User preferences: morning departure, max 1 layover"
}
],
modelPreferences: {
hints: [{
name: "claude-sonnet-4-20250514" // Suggested model
}],
costPriority: 0.3, // Less concerned about API cost
speedPriority: 0.2, // Can wait for thorough analysis
intelligencePriority: 0.9 // Need complex trade-off evaluation
},
systemPrompt: "You are a travel expert helping users find the best flights based on their preferences",
maxTokens: 1500
}
引导(Elicitation)
允许服务器向用户请求额外信息。当需要获取用户更多输入或确认操作时,可通过elicitation 主动获取客户端的选择,这个过程看起来就像是在引导用户做选择和填空题。
// 要求客户端在服务端提供的选项中获取值
{
method: "elicitation/requestInput",
params: {
message: "Please confirm your Barcelona vacation booking details:",
schema: {
type: "object",
properties: {
confirmBooking: {
type: "boolean",
description: "Confirm the booking (Flights + Hotel = $3,000)"
},
seatPreference: {
type: "string",
enum: ["window", "aisle", "no preference"],
description: "Preferred seat type for flights"
},
roomType: {
type: "string",
enum: ["sea view", "city view", "garden view"],
description: "Preferred room type at hotel"
},
travelInsurance: {
type: "boolean",
default: false,
description: "Add travel insurance ($150)"
}
},
required: ["confirmBooking"]
}
}
}
根(Roots)
通过 file:// URI 类似的方案,允许客户端主动选择资源边界。客户端拥有本地策略限制的情况,实现服务器行为与客户端策略的实时同步。
初始连接阶段
-
客户端 → 服务器
"你好,我支持roots功能!"
客户端在首次连接时告知服务器其支持roots功能 -
服务器 → 客户端
"你有哪些roots?"
服务器使用roots/list接口查询客户端可用的roots -
客户端 → 服务器
"请在这些边界内操作"
客户端返回当前配置的roots列表(定义操作边界)
动态更新阶段
-
用户 → 客户端
"我想修改操作边界"
用户通过客户端界面更新roots配置(调整操作范围) -
客户端 → 服务器
"Roots已变更"
客户端通过notifications/roots/list_changed通知服务器roots配置变化
(仅在roots实际发生增减时触发) -
服务器 → 客户端
"请重新提供roots列表"
服务器再次使用roots/list请求最新roots数据 -
客户端 → 服务器
"更新后的操作边界如下"
客户端响应最新的roots配置
接入MCP
传输层处理客户端和服务器之间的实际通信,现在定义了多种传输机制:
Stdio(本地启动)
通过启动指令,启动本地编写好的MCP服务器,一般用upx或npx启动,使用标准输入/输出进行通信, 多用于本地调用与调试,可以支持通过json导入启动配置:
{
"mcpServers": {
"OC8HYPJki-82QnxDhU4Xr": {
"name": "@cherry/filesystem",
"type": "inMemory",
"args": [
"/Users/username/Desktop",
"/path/to/other/allowed/dir"
],
"shouldConfig": true,
"isActive": true,
"provider": "CherryAI",
"installSource": "builtin"
}
}
}
SSE(单向)
使用 Server-Sent Events (SSE) 进行服务器向客户端的消息传输。其流程大概分为以下几步:
1、发送初始化连接请求,客户端携带自身支持的原语和MCP协议版本;服务的响应请求并返回自身支持的原语
// 请求
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18", //协议版本
"capabilities": {
"elicitation": {} // 支持的能力
},
"clientInfo": {
"name": "example-client",
"version": "1.0.0"
}
}
}
// 返回
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"protocolVersion": "2025-06-18",
"capabilities": {
"tools": {
"listChanged": true // 支持动态刷新工具列表
},
"resources": {} // 支持资源获取
},
"serverInfo": {
"name": "example-server",
"version": "1.0.0"
}
}
}
2、在初始化连接完成后 ,客户端根据服务端能力配置初始化(tool\prompt\resource)的处理逻辑,服务端也根据客户端要求配置策略(elicitation,real-time fresh tool),客户端实时拉去最新服务端信息,也完成三次握手建立传输层连接。
{
"jsonrpc": "2.0",
"method": "notifications/initialized"
}
// 服务端告诉客户端tool刷新
{
"jsonrpc": "2.0",
"method": "notifications/tools/list_changed"
}
//客户端更新
{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/list"
}
结语
概念介绍的差不多了,作为 AI 模型的能力拓展,近几个月来,MCP概念爆火,网上的MCP平台展览了许多实用的MCP。做 AI 应用开发,掌握这个能力势在必得,希望这篇文章能帮助到大家
更多推荐



所有评论(0)