从零开始学MCP(四)- 认识MCP clients

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

相关推荐
QT 小鲜肉1 小时前
【孙子兵法之下篇】010. 孙子兵法·地形篇深度解析与现代应用
人工智能·笔记·读书·孙子兵法
用户377833043491 小时前
( 教学 )Agent 构建 Prompt(提示词)6. 输出修正解析器 OutputFixingParser
人工智能·langchain
浪浪山_大橙子1 小时前
使用Electron+Vue3开发Qwen3 2B桌面应用:从想法到实现的完整指南
前端·人工智能
亚马逊云开发者1 小时前
【Agentic AI for Data系列】Kiro实战:DuckDB vs Spark技术选型全流程
人工智能
QT 小鲜肉1 小时前
【孙子兵法之下篇】010. 孙子兵法·地形篇
人工智能·笔记·读书·孙子兵法
Jay20021111 小时前
【机器学习】30 基于内容的过滤算法
人工智能·算法·机器学习
爱打代码的小林2 小时前
python基础(pandas库)
服务器·python·pandas
极客BIM工作室2 小时前
ControlNet里的“隐形连接器”:零卷积(Zero Convolution)的工作流程
人工智能·机器学习