理解 MCP 服务器
社区译文;来源: MCP 80041ab0
MCP 服务器是通过标准化协议接口向 AI 应用开放特定能力的程序。
常见示例包括用于访问文档的文件系统服务器、用于查询数据的数据库服务器、用于管理代码的 GitHub 服务器、用于团队沟通的 Slack 服务器,以及用于日程安排的日历服务器。
服务器核心功能
服务器通过三种构建块提供功能:
| 功能 | 说明 | 示例 | 控制方 |
|---|---|---|---|
| 工具 | LLM 可以主动调用的函数;模型会根据用户请求决定何时使用。工具可以写入数据库、调用外部 API、修改文件或触发其他逻辑。 | 搜索航班 发送消息 创建日历事件 | 模型 |
| 资源 | 被动数据源,为上下文提供只读信息,例如文件内容、数据库模式或 API 文档。 | 检索文档 访问知识库 读取日历 | 应用 |
| 提示词 | 预先构建的指令模板,指导模型使用特定工具和资源。 | 规划假期 总结会议 起草电子邮件 | 用户 |
下面使用一个假想场景说明这些功能各自的作用,以及它们如何协同工作。
工具
工具让 AI 模型能够执行操作。每个工具都以带类型的输入和输出定义一项具体操作。模型根据上下文请求执行工具。
工具如何工作
工具是 LLM 可以调用、由 schema 定义的接口。MCP 使用 JSON Schema 进行验证。每个工具执行单一操作,并具有明确的输入与输出。工具在执行前可能要求用户同意,从而帮助用户保持对模型操作的控制。
协议操作:
| 方法 | 用途 | 返回值 |
|---|---|---|
tools/list | 发现可用工具 | 包含 schema 的工具定义数组 |
tools/call | 执行指定工具 | 工具执行结果 |
工具定义示例:
{
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: "[email protected]", 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 应用会检索这些资源并决定如何处理:使用嵌入或关键词搜索选择数据子集,或者将原始数据直接传给模型。
在此示例中,应用向模型提供日历数据、天气信息和旅行偏好,使其能够检查空闲时间、查询天气规律,并参考过去的旅行偏好。
资源模板示例:
{
"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"
}这些模板支持灵活查询。对于天气数据,用户可以访问任意城市与日期组合的预报;对于航班,用户可以搜索任意两个机场之间的航线。当用户已在 origin 机场字段中输入 “NYC”,并开始在 destination 机场字段中输入 “Bar” 时,系统可以建议 “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 | 获取提示词详情 | 包含参数的完整提示词定义 |
示例:简化工作流
提示词为常见任务提供结构化模板。在旅行规划场景中:
“规划假期”提示词:
{
"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 days、$3000、[“beaches”, “architecture”, “food”]
- 基于模板一致地执行工作流
用户交互模型
提示词由用户控制,需要显式调用。协议允许实现者自由设计符合应用使用习惯的界面。核心原则包括:
- 便于发现可用提示词
- 清楚说明每个提示词的用途
- 使用校验提供自然的参数输入体验
- 透明展示提示词的底层模板
应用通常会通过多种 UI 模式开放提示词,例如:
- 斜杠命令(输入 “/” 查看
/plan-vacation等可用提示词) - 可搜索的命令面板
- 常用提示词的专用 UI 按钮
- 推荐相关提示词的上下文菜单
组合多个服务器
当多个服务器通过统一界面协同工作、组合各自的专门能力时,MCP 才能充分发挥价值。
示例:多服务器旅行规划
设想一个个性化 AI 旅行规划应用,它连接了三个服务器:
- 旅行服务器:处理航班、酒店和行程
- 天气服务器:提供气候数据和天气预报
- 日历/邮件服务器:管理日程和通信
完整流程
用户调用带参数的提示词:
{ "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 服务器,用户完成了符合自身日程的巴塞罗那行程研究与预订。“Plan a Vacation”提示词指导 AI 组合来自不同服务器的资源(日历空闲时间和旅行历史)与工具(搜索航班、预订酒店、更新日历),在收集上下文的同时执行预订。原本可能需要数小时的任务,借助 MCP 可以在数分钟内完成。