核心要点

  • MCP 是 Host / Client / Server 三组件架构:Host 是承载 LLM 的应用(如 Claude 桌面端、IDE),Client 是 Host 内部与某个 Server 一对一连接的连接器,Server 是对外暴露能力的提供方

  • 一个 Host 内可有多个 Client,每个 Client 与一个 Server 保持 1:1 连接,从而同时接入多个 Server

  • 正向能力(Server→Client):Tools(可调用的动作)、Resources(可读数据)、Prompts(可复用模板)

  • 其它双向能力:Sampling(Server 反向请求 Host 的 LLM 生成,Server→Host)、Elicitation(Server 向用户索要补充信息);以及 Roots(由 Host/Client 向 Server 声明可访问的文件/目录边界,方向是 Host/Client→Server,与前两者相反)

  • 底层基于 JSON-RPC 2.0 收发消息,能力在连接初始化时协商确定

标准回答

三个核心组件

MCP(Model Context Protocol)把"模型如何接外部能力"标准化,整体是 Host / Client / Server 三层:

  • Host(宿主):真正承载 LLM、面向用户的应用,比如 Claude 桌面端、支持 MCP 的 IDE、或你自研的 Agent 应用。它管理用户交互、决定调哪些能力、并持有若干 Client。
  • Client(客户端 / 连接器):运行在 Host 内部,与单个 Server 建立并维护 一对一(1:1) 的连接。它是 Host 与某个 Server 之间的专属"接线员",负责协议握手、消息收发、能力协商。
  • Server(服务端):能力的提供方,对外暴露 Tools / Resources / Prompts。它可以是本地进程,也可以是远程服务,背后往往封装着某个 API、数据库或内部系统。

三者关系:一个 Host 里可以同时有多个 Client,每个 Client 各连一个 Server,于是同一个应用就能同时接入文件系统、数据库、第三方 API 等多个 Server。

两个方向的能力("双向")

MCP 的能力不是单向的,分两个方向:

正向是 Server → Client 提供能力,有三类:

  • Tools(动作):模型可调用的函数,会执行操作或带参数查询。
  • Resources(数据):可被读取 / 引用的上下文内容,用 URI 标识。
  • Prompts(模板):预置的提示词或工作流模板,供用户 / 客户端选用。

另一类是 Server 主动发起、反向借力的能力(Server → Host / 用户):

  • Sampling:Server 在处理过程中反过来请求 Host 的 LLM 帮它生成一段内容(比如 Server 需要模型总结一下再继续),让算力留在 Host 侧、也便于统一管控。
  • Elicitation:Server 执行到一半发现信息不够时,向用户索要补充输入。

此外还有 Roots,但它的方向相反——是 Host / Client 向 Server 声明"你被允许访问哪些文件/目录"的边界(Host/Client→Server),用于划定作用范围,别把它和上面 Server 发起的两项混为一类。

正是这套双向设计,让 Server 不只是被动被调用的工具,还能与 Host 的模型与用户互动。

底层协议

MCP 的消息收发基于 JSON-RPC 2.0,请求 / 响应 / 通知都按它的格式走。具体支持哪些能力,在连接初始化阶段由双方"能力协商"确定,之后才开始正常交互。

常见误区

⚠️ 常见踩坑

常见误解一:把 Client 当成"用户的浏览器 / 终端"——其实 Client 是 Host 内部与单个 Server 1:1 的连接器,是程序内的组件,不是终端用户。误解二:以为 MCP 只是"模型调工具"的单向通道——它是双向的,Server 还能通过 Sampling 反向请求 Host 的 LLM、通过 Elicitation 向用户要信息。误解三:把 Host 和 Server 混为一谈——Host 是承载模型的应用方,Server 是提供能力的供给方,二者职责相反。

追问

追问 1Host 和 Client 都在"客户端这边",它们到底有什么分工?为什么要拆成两层?

Host 是面向用户、承载 LLM 的整个应用,管全局:用户交互、上下文、决定调用哪些能力、对多个连接做编排与权限控制。Client 则是 Host 内部一个很专一的组件——每个 Client 只负责和一个 Server 的连接,处理这条连接上的协议握手、消息收发、能力协商。

拆成两层是为了"一对多"的干净解耦:一个 Host 往往要同时接好几个 Server(文件、数据库、API……)。如果不拆,Host 就得自己处理每个 Server 各自的连接状态;拆出 Client 后,每个 Server 对应一个独立的 1:1 Client,连接互相隔离、互不影响,Host 只需在更高层做统一编排。可以类比:Host 是应用主体,Client 是它为每个外部服务各开的一根专线。

追问 2Sampling 这个反向能力解决了什么问题?为什么不让 Server 自己调一个模型就好?

Sampling 让 Server 在执行任务途中,反过来请求 Host 那边的 LLM 帮它生成 / 推理一段内容,再拿结果继续。它解决的是"Server 也需要模型能力,但不该自带模型"的矛盾。

如果让每个 Server 各自接一个自己的模型,会带来一堆问题:每个 Server 都要配密钥、各自计费、各自选型,安全和成本失控;用户也无法统一看到 / 控制模型被怎么用。通过 Sampling 把生成请求收回到 Host 侧,好处是:算力和模型选择集中在 Host,统一管控与计费;用户可对这类请求做审批 / 可见性控制(防止 Server 偷偷大量调用模型);Server 自身保持轻量,不必内嵌模型。本质是把"要不要、用什么模型生成"的决策权和成本留在用户掌控的 Host 一侧。

追问 3MCP 为什么选用 JSON-RPC 2.0 作为底层?能力协商是怎么发生的?

选 JSON-RPC 2.0 是因为它简单、成熟、语言无关:有清晰的请求 / 响应 / 通知三种消息形态,天然支持双向调用(这点正契合 MCP 的双向能力),且 JSON 几乎所有语言都能轻松解析,不必发明新格式。这让不同语言写的 Host 与 Server 能可靠互通。

能力协商发生在连接建立的初始化阶段:Client 与 Server 握手时互相声明各自支持的协议版本与能力(比如这个 Server 提供哪些 Tools/Resources/Prompts、是否支持 Sampling / Elicitation 等)。双方据此确定本次连接"能用什么、不能用什么",对齐之后才进入正常的消息交互。这样既能向前兼容不同版本,也避免一方调用另一方根本不支持的能力。

🔗 相似问题

同一考点的不同问法,面试官可能换着问,一起刷更稳

没找到想看的面试题?把你想看的告诉我们 →

延伸学习

按主题分类的相关资源,便于系统复习