2.1 宿主、客户端、服务端:三角的职责边界


2.1 宿主、客户端、服务端:三角的职责边界

本节摘要:理解 MCP 的第一个,也是最容易被误解的一个概念,就是三个角色的职责边界。多数人第一次接触会以为「服务端直接和大模型对话」——这是错的。MCP 用一个清晰的三角划分了职责:宿主(Host) 是用户对话的 LLM 应用(Claude Desktop、Cursor、IDE),客户端(Client) 是宿主内部「说 MCP 的那一半」,服务端(Server) 是你用 SDK 写的、只负责暴露能力的东西。三者之间有一条铁律:服务端从不直接和模型对话。本节讲透这个三角,这是后续所有内容的地基——不先破除误解,后面每一章都会带着错误预期读下去。

一、三个角色:各自做什么

先看一张完整的三角图,再逐个拆解:

┌─────────────────────┐ │ 宿主 Host │ │ (Claude / Cursor / │ │ IDE / Agent 运行时)│ │ │ │ ┌─────────────┐ │ │ │ 大模型 LLM │ │ ◄── 真正的推理在这里发生 │ └─────────────┘ │ │ │ │ │ ┌─────────────┐ │ │ │ 客户端 A │──┼──┐ (说 MCP 的那一半) │ │ 客户端 B │──┼──┤ 一个宿主对每个服务端跑一个客户端 │ └─────────────┘ │ │ └─────────────────────┘ │ │ MCP 协议(JSON-RPC) ┌──────────────┼──────────────┐ ▼ ▼ ▼ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ 服务端 A │ │ 服务端 B │ │ 服务端 C │ │(你写的) │ │(别人写的) │ │(你写的) │ │ 工具/资源/ │ │ 工具/资源/ │ │ 工具/资源/ │ │ 提示词 │ │ 提示词 │ │ 提示词 │ └────────────┘ └────────────┘ └────────────┘

逐个看每个角色的职责:

角色 是什么 谁开发 关键职责
宿主(Host) 用户对话的 LLM 应用 宿主厂商(Claude、Cursor 等) 跑模型、管对话、决定何时调用工具
客户端(Client) 宿主内部「说 MCP 的那一半」 宿主厂商(或你用 SDK 自研) 用 MCP 协议连服务端、转发请求
服务端(Server) 你用本 SDK 写的东西 暴露工具/资源/提示词,执行业务逻辑

二、铁律:服务端从不直接和模型对话

这是本节最重要的一句话:

服务端从不直接和大模型对话。

这句话的反面,就是很多人脑子里的错误模型:「我写的服务端会调用模型 API」。不会。服务端只做一件事:收到客户端发来的请求,执行业务逻辑,返回结果。它既不知道有模型存在,也不关心模型在干什么。

真正的模型推理,只发生在宿主内部。整条数据流是这样的:

模型在宿主里推理 │ ▼ 「我需要调用 add 工具」 宿主把请求交给客户端 │ ▼ 客户端用 MCP 协议发给服务端 服务端执行 add(1, 2) │ ▼ 返回 3 客户端把结果交回宿主 │ ▼ 宿主把结果喂回模型 模型继续推理:「结果是 3,所以……」

服务端在这条链路里,只是一个被动的能力提供者——它被问、它回答,从不主动找模型。

⚠️ 注意:这个边界不是任性设计,而是有深刻理由的。如果服务端能直接调模型,就会出现「每个服务端都要管模型 API Key、管对话历史、管 token 成本」的混乱——而把这些集中在宿主,服务端就能保持「纯粹的业务逻辑单元」。这个分工是 MCP 协议能在跨厂商(不同宿主、不同模型)环境下统一工作的根本前提。

三、为什么要有「客户端」这一层

你可能会问:宿主为什么不直接连服务端,中间非要隔一个「客户端」?

答案在于一对多。一个宿主(Claude Desktop)通常会同时连多个服务端——一个查数据库、一个读文件、一个调外部 API。宿主为每个连上的服务端,跑一个独立的客户端实例:

Claude Desktop(宿主) ├── 客户端 A ──► 数据库服务端 ├── 客户端 B ──► 文件系统服务端 └── 客户端 C ──► 外部 API 服务端

每个客户端封装了「连这一个服务端」所需的全部状态:协议版本、能力声明、会话、订阅、错误恢复。这种「一宿主多客户端」的模型,让宿主能用统一的对话界面,编排来自不同服务端的能力。

💡 技巧:这个「多客户端」模型也是第 10 章会讲的会话组(ClientSessionGroup) 的灵感来源——当你自己写 Host 时,会话组正是帮你管理「一堆客户端」的抽象。

四、本 SDK 同时给你两端

理解了三角,你就能理解本 SDK 的定位:它同时给你服务端与客户端两套工具

你想做的事 用 SDK 的哪部分 导入入口
写一个暴露能力的服务端 服务端 API from mcp.server import MCPServer
写一个消费 MCP 服务的客户端 客户端 API from mcp import Client
写自己的 Host(编排多服务) 客户端 API + 会话组 Client + ClientSessionGroup

注意导入路径的有意区分:服务端多一层 .server,客户端是顶层。这个细节在第 1 章提过,这里再看一眼它的设计意图——让两端的边界在导入时就清晰,避免混用。

本教程的章节安排也对应这个划分:第 38 章讲服务端主线,第 910 章讲客户端主线。两端各自完整,又在架构(本章)、传输(第 8 章)、认证(第 11 章)这些横切章节交汇。

五、常见误解澄清

收尾时,把几个最常见的误解列一下,帮你巩固正确模型:

误解 真相
「服务端调用模型 API」 错。服务端从不和模型对话,模型只在宿主里推理
「客户端和服务端是同一个进程」 不一定。本地(stdio)是两个进程,内存连接才同进程,远程(HTTP)是两台机器
「一个宿主只连一个服务端」 错。一个宿主通常连多个,每个跑一个客户端实例
「SDK 既能写宿主又能写服务端」 部分。SDK 给你客户端与服务端,写宿主还需要你把模型推理拼进来
「MCP 是模型 API 的替代」 错。MCP 是「让模型用你的代码」的协议,模型 API 是另一回事

本节要点回顾

  1. 三角划分:宿主(跑模型)→ 客户端(说 MCP)→ 服务端(暴露能力),职责清晰。
  2. 铁律:服务端从不直接和模型对话,模型推理只发生在宿主里。
  3. 服务端是被动的能力提供者:被问、回答,不主动找模型。
  4. 一个宿主连多个服务端,每个跑一个独立客户端实例,这是「多客户端」模型。
  5. 本 SDK 同时提供服务端与客户端两套工具,导入路径有意区分(mcp.server vs mcp)。
  6. 「服务端调模型 API」是最常见的误解,真相是模型与代码被三角隔开。

三角边界清楚了,下一节我们看这三者之间传递的「能力」到底分哪几类——用「谁决定调用」这个视角,重新理解工具、资源、提示词。


作者与出处
原作者: 灏天文库
来源:modelcontextprotocol
许可证:MIT
整理: 灏天文库整理
由灏天文库结构化整理,提供目录导航、全文检索与在线阅读,便于系统化学习
发布者: 作者: 灏天文库 转发
评论区 (0)
U