主题
理解 MCP 服务端
MCP 服务端是通过标准化协议接口向 AI 应用暴露特定能力的程序。
常见示例包括用于文档访问的文件系统服务端、用于数据查询的数据库服务端、用于代码管理的 GitHub 服务端、用于团队沟通的 Slack 服务端,以及用于日程安排的日历服务端。
服务端核心功能
服务端通过三个构建块提供功能:
| 功能 | 说明 | 示例 | 由谁控制 |
|---|---|---|---|
| 工具 | 你的 LLM 可以主动调用的函数,并由其根据用户请求决定何时使用。工具可以写入数据库、调用外部 API、修改文件或触发其他逻辑。 | 搜索航班 发送消息 创建日历事件 | 模型 |
| 资源 | 被动数据源,为上下文提供对信息的只读访问,例如文件内容、数据库模式或 API 文档。 | 检索文档 访问知识库 读取日历 | 应用 |
| 提示模板 | 预构建的指令模板,告诉模型如何使用特定的工具和资源。 | 规划假期 总结我的会议 起草电子邮件 | 用户 |
我们将使用一个假设场景来演示上述每项功能的作用,并展示它们如何协同工作。
工具
工具使 AI 模型能够执行操作。每个工具都定义了具有类型化输入和输出的特定操作。模型根据上下文请求执行工具。
工具如何工作
工具是 LLM 可以调用的、由 schema 定义的接口。MCP 使用 JSON Schema 进行验证。每个工具执行单一操作,并具有明确定义的输入和输出。工具在执行前可能需要用户同意,这有助于确保用户对模型所执行的操作保持控制。
协议操作:
| 方法 | 用途 | 返回 |
|---|---|---|
tools/list | 发现可用的工具 | 带有 schema 的工具定义数组 |
tools/call | 执行特定工具 | 工具执行结果 |
工具定义示例:
typescript
{
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"]
}
}示例:旅行预订
工具使 AI 应用能够代表用户执行操作。在旅行规划场景中,AI 应用可能会使用多个工具来帮助预订假期:
航班搜索
searchFlights(origin: "NYC", destination: "Barcelona", date: "2024-06-15")查询多家航空公司并返回结构化的航班选项。
日历锁定
createCalendarEvent(title: "Barcelona Trip", startDate: "2024-06-15", endDate: "2024-06-22")在用户的日历中标记旅行日期。
电子邮件通知
sendEmail(to: "team@work.com", subject: "Out of Office", body: "...")向同事发送自动化的外出自动回复消息。
用户交互模型
工具是模型控制的,这意味着 AI 模型可以自动发现并调用它们。然而,MCP 通过多种机制强调人工监督。
为了信任与安全,应用可以通过多种机制实现用户控制,例如:
- 在 UI 中显示可用的工具,使用户能够定义在特定交互中是否应提供某个工具
- 针对单个工具执行的审批对话框
- 用于预先批准某些安全操作的权限设置
- 显示所有工具执行及其结果的活动日志
资源
资源提供对信息的结构化访问,AI 应用可以检索这些信息并将其作为上下文提供给模型。
资源如何工作
资源暴露来自文件、API、数据库或 AI 理解上下文所需的任何其他来源的数据。应用可以直接访问这些信息,并决定如何使用它——无论是选择相关部分、使用嵌入进行搜索,还是将其全部传递给模型。
每个资源都有唯一的 URI(例如 file:///path/to/document.md),并声明其 MIME 类型以便进行适当的内容处理。
资源支持两种发现模式:
- 直接资源 - 指向特定数据的固定 URI。示例:
calendar://events/2024- 返回 2024 年的日历可用性 - 资源模板 - 带参数的动态 URI,用于灵活查询。示例:
travel://activities/{city}/{category}- 按城市和类别返回活动travel://activities/barcelona/museums- 返回巴塞罗那的所有博物馆
资源模板包含标题、描述和预期 MIME 类型等元数据,使其可被发现且具备自描述性。
协议操作:
| 方法 | 用途 | 返回 |
|---|---|---|
resources/list | 列出可用的直接资源 | 资源描述符数组 |
resources/templates/list | 发现资源模板 | 资源模板定义数组 |
resources/read | 检索资源内容 | 带元数据的资源数据 |
subscriptions/listen | 监控资源变化 | 更新通知流 |
要监视特定资源的变化,客户端发送一个 subscriptions/listen 请求,并在 resourceSubscriptions 过滤器中列出资源 URI。每当被监视的资源发生变化时,服务端会在生成的流上传递 notifications/resources/updated。
示例:获取旅行规划上下文
继续旅行规划的示例,资源为 AI 应用提供对相关信息的访问:
- 日历数据(
calendar://events/2024)- 检查用户可用性 - 旅行文档(
file:///Documents/Travel/passport.pdf)- 访问重要文档 - 既往行程(
trips://history/barcelona-2023)- 参考过去的旅行和偏好
AI 应用检索这些资源并决定如何处理它们,无论是使用嵌入或关键词搜索选择数据子集,还是将原始数据直接传递给模型。
在这种情况下,它向模型提供日历数据、天气信息和旅行偏好,使模型能够检查可用性、查询天气模式并参考过去的旅行偏好。
资源模板示例:
json
{
"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 机场时,系统可以建议 "Barcelona (BCN)" 或 "Barbados (BGI)"。
参数补全
动态资源支持参数补全。例如:
- 为
weather://forecast/{city}输入 "Par" 时,可能会建议 "Paris" 或 "Park City" - 为
flights://search/{airport}输入 "JFK" 时,可能会建议 "JFK - John F. Kennedy International"
系统帮助发现有效值,而无需用户了解确切的格式。
用户交互模型
资源是应用驱动的,这使它们在检索、处理和呈现可用上下文的方式上具有灵活性。常见的交互模式包括:
- 以熟悉的类文件夹结构浏览资源的树状或列表视图
- 用于查找特定资源的搜索和过滤界面
- 基于启发式规则或 AI 选择的自动上下文包含或智能建议
- 用于包含单个或多个资源的手动或批量选择界面
应用可以自由地通过任何适合其需求的界面模式实现资源发现。协议不强制规定特定的 UI 模式,允许实现带预览功能的资源选择器、基于当前对话上下文的智能建议、用于包含多个资源的批量选择,或与现有文件浏览器和数据浏览器的集成。
提示模板
提示模板提供可复用的模板。它们允许 MCP 服务端作者为某个领域提供参数化提示模板,或展示如何最好地使用该 MCP 服务端。
提示模板如何工作
提示模板是结构化的模板,定义了预期的输入和交互模式。它们是用户控制的,需要显式调用而非自动触发。提示模板可以感知上下文,引用可用的资源和工具以创建完整的工作流。与资源类似,提示模板支持参数补全,以帮助用户发现有效的参数值。
协议操作:
| 方法 | 用途 | 返回 |
|---|---|---|
prompts/list | 发现可用的提示模板 | 提示模板描述符数组 |
prompts/get | 检索提示模板详情 | 带参数的完整提示模板定义 |
示例:简化的工作流
提示模板为常见任务提供结构化模板。在旅行规划上下文中:
"Plan a vacation" 提示模板:
json
{
"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" } }
]
}提示模板系统不是非结构化的自然语言输入,而是支持:
- 选择 "Plan a vacation" 模板
- 结构化输入:Barcelona、7 天、$3000、["beaches", "architecture", "food"]
- 基于模板执行一致的工作流
用户交互模型
提示模板是用户控制的,需要显式调用。协议赋予实现者自由,以设计在其应用内感觉自然的界面。关键原则包括:
易于发现可用的提示模板
清晰描述每个提示模板的作用
带验证的自然参数输入
透明显示提示模板的底层模板 应用通常通过各种 UI 模式暴露提示模板,例如:
斜杠命令(输入 "/" 查看可用提示模板,如 /plan-vacation)
用于可搜索访问的命令面板
用于常用提示模板的专用 UI 按钮
建议相关提示模板的上下文菜单
将服务端组合在一起
MCP 的真正威力在多个服务端协同工作时显现,通过统一接口组合它们的专业能力。
示例:多服务端旅行规划
考虑一个个性化 AI 旅行规划应用,它连接了三个服务端:
- 旅行服务端 - 处理航班、酒店和行程
- 天气服务端 - 提供气候数据和预报
- 日历/邮件服务端 - 管理日程和通信
完整流程
用户调用带参数的提示模板:
json{ "prompt": "plan-vacation", "arguments": { "destination": "Barcelona", "departure_date": "2024-06-15", "return_date": "2024-06-22", "budget": 3000, "travelers": 2 } }用户选择要包含的资源:
calendar://my-calendar/June-2024(来自日历服务端)travel://preferences/europe(来自旅行服务端)travel://past-trips/Spain-2023(来自旅行服务端)
AI 使用工具处理请求:
AI 首先读取所有选定的资源以收集上下文——从日历中识别可用日期,从旅行偏好中了解偏好的航空公司和酒店类型,并从过去的旅行中发现以前喜欢的地点。
利用这些上下文,AI 随后执行 AI 应用提供的提示模板。在我们的示例中,AI 应用将所连接的 MCP 天气服务端的天气工具暴露给模型。由于天气会影响旅行计划,AI 在解释提示模板时选择调用
checkWeather()。因此,AI 执行一系列工具:
searchFlights()- 向航空公司查询从 NYC 到 Barcelona 的航班checkWeather()- 检索旅行日期的气候预报
然后 AI 使用这些信息创建预订和后续步骤,并在必要时请求用户批准:
bookHotel()- 在指定预算内查找酒店createCalendarEvent()- 将旅行添加到用户的日历sendEmail()- 发送包含旅行详情的确认信息
结果: 通过多个 MCP 服务端,用户研究并预订了一次根据其日程量身定制的 Barcelona 之旅。"Plan a Vacation" 提示模板引导 AI 跨不同服务端组合资源(日历可用性和旅行历史)与工具(搜索航班、预订酒店、更新日历)——收集上下文并执行预订。一项原本可能需要数小时的任务使用 MCP 在几分钟内完成。