MCP客户端由Host应用实例化,与特定的MCP服务器通信。Host应用,如Claude.ai或IDE(Cursor),管理整体用户体验并协调多个客户端。每个客户端处理与一个服务器的一次直接通信。
⚠️注意: Host是与用户交互的应用,而Client是连接服务器的组件。
核心功能
除了可以使用服务器提供的上下文,客户端还可以向服务器提供多种功能。这些客户端功能使服务器开发者能够构建更丰富的交互。
| 功能 | 解释 | 示例 |
|---|---|---|
| Elicitation(引导) | Elicitation允让服务器在交互过程中能够向用户请求特定信息,为服务器根据需求收集信息提供了一种结构化方法。 | 一个预订旅行的服务器可能会询问用户对飞机座位、房间类型或联系电话的偏好来完成预订。 |
| Roots(根) | Roots允许客户端指定服务器应关注的目录,并通过协调机制传达预期范围 | 一个用于预订旅行的服务器可以访问特定的目录,从中可以读取用户的日历。 |
| Sampling(采样) | Sampling允许服务器通过客户端向大模型发起请求,从而启用agentic工作流。这种方法使客户端完全控制用户权限和安全措施。 | 一个用于预订旅行的服务器可能会向LLM发送航班列表,并请求LLM为用户选择最佳航班。 |
Elicitation(引导)
Elicitation(引导)允许服务器在交互过程中向用户请求特定信息,从而创建更具动态性和响应性的工作流。
概述
Elicitation(引导)为服务器提供了一种结构化的方式来根据需要收集必要的信息。服务器可以暂停其操作来请求用户的特定输入,而不是要求预先提供所有信息或在数据丢失时失效。这创建了更灵活的交互,服务器可以适应用户需求,而不是遵循严格的模式。
Elicitation flow:

上述流程图支持动态信息收集。服务器可以在需要时请求特定的数据,用户通过合适的UI界面提供信息,服务器继续使用新获取的上下文进行处理。
Elicitation components example:
css
{
method: "elicitation/requestInput",
params: {
message: "Please confirm your Wuhan 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"]
}
}
}
TypeScript
示例: 假期预订审批
示例:假期预订审批
旅游预订服务器通过最终的预订确认过程展示了Elicitation(引导)的力量。当用户选择了他们理想的武汉度假套餐后,服务器需要在继续任务之前获取最终批准和任何缺失的详细信息。
服务器通过一个结构化的请求来获取预订确认,该请求包括行程摘要(武汉1月1日至3日的航班,海滨酒店,总计3000元)和任何其他偏好,如座位选择、房间类型或旅行保险。
随着预订的进行,服务器会获取完成预订所需的联系方式。它可能会向旅行者询问关于航班预订、酒店的特殊要求或紧急联系方式等详细信息。
用户交互模型
Elicitation(引导)交互旨在清晰、情境化,并尊重用户意愿:
请求演示: 客户端显示启发请求,并清楚地说明哪个服务器在请求、为什么需要信息以及如何使用信息。请求的消息解释了其目的,而schema提供了结构和验证方式。
响应选项: 用户可以通过合适的UI控件(文本字段、下拉菜单、复选框)提供客户端所请求的信息,拒绝提供不想解释的信息,或取消整个操作。客户端在将响应返回给服务器之前,根据提供的schema对其进行验证。
隐私注意事项: Elicitation从不请求密码或API密钥。客户端会警告可疑请求,并让用户在发送前检查数据。
Roots(根)
Roots定义了服务器操作的文件系统边界,允许客户端指定服务器应该关注哪些文件夹。
概述
Roots是客户与服务器通信文件系统访问边界的一种机制。它们由文件URI组成,指示服务器可以操作的目录,帮助服务器了解可用文件和文件夹的范围。虽然Roots根节点传达了预期的边界,但它们并不强制执行安全限制。实际的安全性必须在操作系统级别通过文件权限和(或)沙盒强制来执行。
Root的结构:
json
{
"uri": "file:///Users/agent/travel-planning",
"name": "Travel Planning Workspace"
}
JSON
Roots是专门的文件系统路径,并且始终使用 file:// URI 的方案。它们帮助服务器了解项目边界、工作空间组织和可访问目录。当用户处理不同的项目或文件夹时,根列表可以动态更新,当边界发生变化时,服务器会通过 roots/list_changed 接收通知。
示例:旅行计划工作空间
处理多个客户行程的旅行agent得益于组织文件系统访问的Roots(根)。考虑采用一个带有不同目录的工作空间,用于旅行计划的各个方面。
- file:///Users/agent/travel-templates - 可重用的行程模板和资源
- file:///Users/agent/client-documents - 客户护照和旅行证件
当agent创建武汉的行程时,表现良好的服务器会尊重这些边界- 访问模板、保存新行程并在指定的Roots中引用客户端文档。服务器通常通过使用根目录中的相对路径或使用遵守Roots边界的文件搜索工具来访问Roots中的文件。
如果agent打开一个归档文件夹,如 file:///Users/agent/archive/2023-trips ,客户端通过更新根列表 roots/list_changed 。
对于遵守Roots边界的server的完整实现,在官方仓库 filesystem server 中查看。
设计理念
Roots根作为客户端和服务器之间的协调机制,而不是安全边界。该规范要求服务器"应该尊重Roots边界",而不是它们"必须执行",因为服务器运行的代码是客户端无法控制的。
Roots当服务器受到信任或审查,用户了解其咨询性质,并且目标是防止事故而不是阻止恶意行为时,Roots的表现是最好的。它们擅长于上下文范围界定(告诉服务器应该关注哪里)、事故预防(帮助表现好的服务器保持在边界内)和工作流组织(例如自动管理项目边界)。
用户交互模型
Roots根通常由Host应用根据用户操作自动管理,尽管有些应用可能会暴露人为的Root管理:
自动根检测: 当用户打开文件夹时,客户端自动将其暴露为根。打开旅行工作空间允许客户端将该目录暴露为根目录,从而帮助服务器了解哪些行程和文档在当前工作的范围内。
手动配置根: 高级用户可以通过配置指定根。例如:为可重用资源添加 /travel-templates ,同时排除包含财务记录的目录。
Sampling(采样)
Sampling采样允许服务器通过客户端向大模型发起请求,在保持安全性和用户可控的同时启用agentic操作。
概述
Sampling采样使服务器能够执行需要AI才能完成的任务,而无需直接与AI大模型集成或付费。相反,服务器可以请求已经具有AI大模型访问权限的客户端代替自己处理这些任务。这种方法使客户端完全控制用户权限和安全措施。由于采样请求发生在其他操作的上下文中(如分析数据的工具),并且作为单独的大模型调用进行处理,因此它们在不同上下文中保持清晰的边界,从而允许更有效地使用上下文窗口。
Sampling flow:

上述流程图通过多个 human-in-the-loop 的检查点确保安全性。在初始请求和生成的响应返回到服务器之前,用户可以查看并修改它们。
请求参数示例:
swift
{
messages: [
{
role: "user",
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
}
TypeScript
示例:航班分析工具
考虑实现一个带有 findBestFlight 工具的旅行预订服务器,该工具使用采样来分析可用航班并推荐最佳选择。当用户询问"为我预订下个月去武汉的最佳航班"时,该工具需要AI的帮助来进行评估分析。
该工具查询航空公司API并收集47个航班选项。然后,它请求AI协助分析这些选项:"分析这些航班选项并推荐最佳选择:[47个航班,包括价格、时间、航空公司和中转] 用户偏好:早上出发,最多中转一次。"
客户发起采样请求,允许AI评估进行评估分析,比如:red-eye flights(夜班航班)更便宜,早晨出发更方便。以此给出三个最佳建议。
用户交互模型
虽然不是必需的,但采样的设计是为了允许human-in-the-loop(人机回路)进行控制。用户可以通过多种机制进行监督:
审批控制: 采样请求可能需要用户明确同意。客户端可以显示服务器想要分析什么以及为什么。用户可以批准、拒绝或修改请求。
透明度功能: 客户端可以显示确切的提示、模型选择和令牌限制,允许用户在返回样本给服务器之前查看AI的响应。
配置选项: 用户可以设置模型参数,给值得信任的操作配置自动审批权限,或者要求所有内容都需要人为审批。客户端可以提供编辑敏感信息的选项。
安全考虑: 在采样过程中,客户端和服务器都必须适当地处理敏感数据。客户端应实施速率限制并验证所有消息内容。human-in-the-loop 人机交互设计确保了服务器发起的AI交互在未经用户明确同意的情况下不会危及安全或访问敏感数据。
欢迎加入我的【ima知识库】 从零开始学MCP