工学云
150.99MB · 2026-02-11
在第二篇文章中,我们讲了MCP的通信协议和数据传输。
那么在第三篇文章中,我们就来讲讲服务端的核心原语,MCP 原语是 MCP 中最重要的概念。它们定义了客户端和服务器之间可以相互提供哪些信息。这些原语明确规定了可以与 AI 应用共享的上下文信息类型以及可以执行的操作范围。这和我们之前提到的核心能力息息相关,所以看懂这一篇非常重要,让我们接下来一起看看吧。
如果你对前面的内容感兴趣,可以点击这里跳转
MCP (Model Context Protocol) 技术理解 - 第一篇
MCP (Model Context Protocol) 技术理解 - 第二篇
MCP 定义了服务器可以公开的三个核心原语:
接下来我们来各自详细地介绍三种核心原语:
Tools是定义在模式中的接口,LLM可以调用这些接口。MCP 使用 JSON Schema 进行验证。每个Tool都执行单一操作,并具有明确定义的输入和输出。工具可能需要在执行前获得用户许可,这有助于确保用户对模型执行的操作保持控制
我们其实在前面已经说的很明白了,LLM可以通过Tools接口来替我们执行操作,而不止于仅仅给我们回复该怎么做。但是要注意的是我们实现Tools接口应该要保持单一职责原则,即一个Tool就保证它自己的功能,不要混杂着其他操作在其中。
下面是官方给的Tool的方法:
| 方法 | 目的 | 返回 |
|---|---|---|
tools/list | 探索可用工具 | 包含模式的工具定义数组 |
tools/call | 执行特定工具 | 工具执行结果 |
那么该如何定义一个Tool呢?下面是一个示例:
{
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"]
}
}
来个示例吧,假如我们想搜索某地到某地的对应日期的所有航班,我们的该如何调用,下面是例子: 查询多家航空公司并返回结构化的航班选项
searchFlights(origin: "NYC", destination: "Barcelona", date: "2024-06-15")
工具由模型控制,这意味着模型可以自动发现并调用它们。但是要注意的是,调用工具是一个很敏感的操作,我们对敏感操作要保证人为监督。
为了确保信任和安全,应用程序可以通过各种机制实现用户控制,例如:
通过权限校验和安全性确认,我们就可以保证某些敏感的Tool calling不会被滥用。
Resources提供结构化的信息访问,人工智能应用程序可以检索这些信息并将其作为上下文提供给模型。
那么Resources是如何运作的? Resources可以从文件、API、数据库或AI理解上下文所需的任何其他来源获取数据。应用程序可以直接访问这些信息,并决定如何使用它们——无论是选择相关部分、使用embedding进行搜索,还是将所有信息传递给模型。
MCP是如何“发现”Resources的?
Resources支持两种发现模式:
直接资源- 指向特定数据的固定 URI。例如:calendar://events/2024- 返回 2024 年的日历可用性
资源模板——带有参数的动态 URI,可实现灵活的查询。示例:
travel://activities/{city}/{category}- 按城市和类别返回活动travel://activities/barcelona/museums- 返回巴塞罗那所有博物馆值得注意的是,每个 resource 有唯一的 URI 标识,支持文本和二进制内容,这里很重要
那么Resources有什么方法?
| 方法 | 目的 | 返回 |
|---|---|---|
resources/list | 列出可用的直接资源 | 资源描述符数组 |
resources/templates/list | 发现资源模板 | 资源模板定义数组 |
resources/read | 获取资源内容 | 包含元数据的资源数据 |
resources/subscribe | 监控资源变化 | 订阅确认 |
不好懂?我们来看个例子缓解一下:)
以旅行规划为例,资源为AI应用程序提供相关信息的访问权限:
calendar://events/2024)- 检查用户日程以保证可行性)- 获取重要文件trips://history/barcelona-2023) - 参考过去的旅行和偏好AI 应用会检索这些资源并决定如何处理它们,无论是使用embedding或关键词搜索选择数据子集,还是将原始数据直接传递给模型。在这种情况下,它向模型提供日历数据、天气信息和旅行偏好,使模型能够检查可用性、查找天气模式并参考过去的旅行偏好。
资源模板示例:
{
"uriTemplate": "weather://forecast/{city}/{date}",
"name": "weather-forecast",
"title": "Weather Forecast",
"description": "Get weather forecast for any city and date",
"mimeType": "application/json"
}
{
"uriTemplate": "travel://flights/{origin}/{destination}",
"name": "flight-search",
"title": "Flight Search",
"description": "Search available flights between cities",
"mimeType": "application/json"
}
这些模板支持灵活的查询方式。例如,用户可以查询任意城市/日期组合的天气预报。对于航班查询,用户可以搜索任意两个机场之间的航线。当用户输入“NYC”作为机场,origin并尝试输入“Bar”作为destination机场时,系统可以建议“巴塞罗那 (BCN)”或“巴巴多斯 (BGI)”
Prompts提供可重用的模板。它们允许 MCP 服务器作者为域提供参数化提示符,或展示如何最佳地使用 MCP 服务器。
那么Prompts是如何运作的?Prompts是结构化的模板,用于定义预期输入和交互模式。它们由用户控制,需要显式调用而非自动触发。Prompts可以感知上下文,引用可用Resource和Tools来创建全面的工作流程。与Resources类似,Prompts支持参数补全,帮助用户发现有效的参数值。
| 方法 | 目的 | 返回 |
|---|---|---|
prompts/list | 发现可用提示 | 提示描述符数组 |
prompts/get | 获取提示详情 | 包含参数的完整提示定义 |
那么Prompts到底有什么用呢?简单来说,prompt是一个预定义的、可重用的提示词模板,能够帮助用户快速调用常见的 AI 交互模式,也就是为常见任务提供结构化模板。
这里的关键词是“常见任务”,“结构化模板”。
听不懂?来个例子吧,我们还是以假期规划为例子
我们可以为”计划一次假期“编写以下的prompts
{
"name": "plan-vacation",
"title": "Plan a vacation",
"description": "Guide through vacation planning process",
"arguments": [
{ "name": "destination", "type": "string", "required": true },
{ "name": "duration", "type": "number", "description": "days" },
{ "name": "budget", "type": "number", "required": false },
{ "name": "interests", "type": "array", "items": { "type": "string" } }
]
}
难道我们不支持非结构化的输入输出吗?系统并非不接受非结构化的自然语言输入,而是支持:
prompts由用户控制,需要显式调用。该协议赋予实现者自由,使其能够设计出与应用程序环境相协调的自然界面。其关键原则包括:
应用程序通常通过各种用户界面模式显示prompts信息,例如:
以notion为例子,这些都是你能直接使用的prompts模板
这一篇我们讲了服务器的三个核心原语,每一个都在MCP里面发挥至关重要的作用,理解这一块非常重要!下一篇我们讲客户端的核心原语。