【MCP 全栈教程】第 02 篇:MCP 架构三层模型——Host、Client、Server 各自做什么

本系列定位:从协议原理到 Server 开发、Client 开发、再到各大平台实战集成,系统化掌握 MCP(Model Context Protocol)全栈技术体系。


本篇你将学到

  • MCP 的三个参与者角色:Host、Client、Server 的职责边界
  • 为什么 Host 不直接连接 Server,而要为每个 Server 创建一个独立的 Client
  • 本地 Server(STDIO)与远程 Server(Streamable HTTP)的本质区别
  • 一个 Host 同时管理多个 Server 的典型架构
  • 本地 Server 的单客户端特性与远程 Server 的多客户端特性

学完本篇,你将清晰地理解 MCP 的架构层次,不会再混淆 Host、Client、Server 这三个概念。


一、为什么需要三层而不是两层

一个自然的疑问是:AI 应用为什么不直接连接 MCP Server,而要在中间插入一个 Client 层?

答案在于隔离与管理的需要。

考虑一个真实场景:Visual Studio Code(VS Code)同时连接了四个 MCP Server——Filesystem(本地文件系统)、Database(数据库)、Sentry(错误监控)、GitHub(代码托管)。

如果 VS Code 自己直接管理这四条连接,会面临几个问题:

问题说明
连接生命周期混乱每条连接的启动、健康检查、重连、关闭逻辑混在主进程里,任何一个 Server 的故障可能影响其他连接
能力管理复杂每个 Server 支持的能力不同(有的支持 Tools,有的还支持 Resources 和 Prompts),需要分别为每条连接维护能力信息
错误隔离困难一个 Server 的异常(如子进程崩溃、网络超时)可能波及整个应用

MCP 的解决方案是引入 Client 作为中间层。Host 为每个 Server 创建一个独立的 Client 实例,由这个 Client 负责与对应的 Server 的全部通信。Client 之间相互隔离,一个 Client 出问题不会影响其他 Client。

这就是三层架构的核心动机。


二、三个角色的精确定义

MCP 官方规范对三个角色给出了明确定义:

MCP Host(宿主)

Host 是协调和管理一个或多个 MCP Client 的 AI 应用。

Host 是用户直接交互的应用程序。典型例子:

Host 应用类型
Claude DesktopAI 对话助手
Claude CodeAI 编程工具
ChatGPTAI 对话助手
Visual Studio Code代码编辑器(通过 Copilot 等 AI 功能消费 MCP)
CursorAI 编程工具

Host 的核心职责:

  • 提供用户交互界面
  • 为每个要连接的 Server 创建一个独立的 Client
  • 管理所有 Client 的生命周期
  • 将各个 Client 发现到的工具、资源、提示词整合,提供给 LLM 使用
  • 处理用户授权(决定哪些工具调用需要用户审批)

MCP Client(客户端)

Client 是维护与一个 MCP Server 的连接,并从 Server 获取上下文的组件。

Client 不是独立运行的应用,它是 Host 内部的一个组件。每个 Client 只对应一个 Server。

Client 的核心职责:

  • 维护与对应 Server 的连接(STDIO 子进程或 HTTP 连接)
  • 发送 server/discover 请求,获取 Server 支持的版本和能力
  • 向 Server 发送 tools/list、resources/read 等请求
  • 接收 Server 的通知(如工具列表变更)
  • 将获取的结果返回给 Host

MCP Server(服务端)

Server 是向 MCP Client 提供上下文和能力的程序。

Server 是真正提供数据和功能的程序。它可以运行在本地(作为 Host 的子进程),也可以运行在远程(作为网络服务)。

Server 的核心职责:

  • 实现 Tools(可执行函数)、Resources(数据源)、Prompts(交互模板)
  • 响应 Client 的发现和列举请求
  • 执行工具调用并返回结果
  • 在能力变更时发送通知

三、用一张表理清三者关系

维度HostClientServer
是什么用户交互的 AI 应用Host 内部的连接管理组件提供数据和能力的程序
数量关系1 个 Host每个 Server 对应 1 个 Client可被多个 Host 连接
用户可见性用户直接操作用户不可见(内部组件)用户通过 Host 间接使用
运行位置用户设备Host 进程内本地子进程或远程服务
通信对象管理多个 Client与 1 个 Server 通信与 1 个或多个 Client 通信

一个简单的数量公式:

1 Host = N Client(每个 Client 对应一个 Server)

四、一个完整示例:VS Code 的多 Server 连接

以 VS Code 为例,展示 Host-Client-Server 架构的实际运作:

Visual Studio Code(Host)
  │
  ├── Client 1 ──── [STDIO] ──── Filesystem Server(本地进程)
  │                                  └─ Tools: read_file, write_file, search
  │                                  └─ Resources: 目录结构
  │
  ├── Client 2 ──── [STDIO] ──── Database Server(本地进程)
  │                                  └─ Tools: execute_sql, list_tables
  │                                  └─ Resources: 数据库模式
  │                                  └─ Prompts: SQL 查询模板
  │
  ├── Client 3 ──── [HTTP] ──── Sentry Server(远程服务)
  │                                  └─ Tools: get_errors, resolve_issue
  │                                  └─ Resources: 错误报告
  │
  └── Client 4 ──── [HTTP] ──── GitHub Server(远程服务)
                                      └─ Tools: create_pr, list_issues
                                      └─ Resources: 代码仓库信息

VS Code 作为 Host,为每个 Server 创建一个独立的 Client。Client 1 和 Client 2 通过 STDIO 连接本地 Server(VS Code 直接启动这些 Server 的子进程),Client 3 和 Client 4 通过 Streamable HTTP 连接远程 Server。

当用户问 GitHub Copilot"帮我查看最近的错误日志"时,VS Code 的处理流程:

1. Copilot(LLM)决定需要调用 Sentry 的 get_errors 工具
2. Host 找到管理 Sentry Server 的 Client 3
3. Client 3 向 Sentry Server 发送 tools/call 请求
4. Sentry Server 执行查询,返回错误列表
5. Client 3 将结果返回给 Host
6. Host 将结果交给 Copilot 整合进回复
7. 用户看到"最近有 3 个错误……"的回答

关键点:Host 充当了路由器的角色——LLM 说出要调用哪个工具,Host 根据工具名找到对应的 Client,由 Client 完成实际调用。


五、本地 Server vs 远程 Server

MCP 的两种传输方式决定了 Server 有两种部署形态。这两种形态在连接模型上有重要区别。

本地 Server(STDIO 传输)

特性说明
运行位置Host 所在的同一台机器上
通信方式标准输入/输出流(STDIO)
启动方式Host 以子进程方式启动 Server
客户端数量通常只服务单个 Client(因为子进程的 stdin/stdout 是独占的)
性能无网络开销,进程间直接通信
典型场景文件系统访问、本地数据库、本地开发工具

本地 Server 的生命周期与 Client 绑定:Host 启动 Client 时创建子进程,Client 关闭时子进程终止。

远程 Server(Streamable HTTP 传输)

特性说明
运行位置远程服务器(可以是云服务、企业内网等)
通信方式HTTP POST + 可选的 SSE(Server-Sent Events)
启动方式Server 作为独立服务运行,不依赖 Client
客户端数量通常同时服务多个 Client(多用户共享)
性能有网络延迟,但支持连接复用
典型场景云端 API 服务、企业共享数据库、第三方平台(Sentry、GitHub 等)

远程 Server 的生命周期独立于任何 Client。Sentry 官方的 MCP Server 一直在 Sentry 平台上运行,任何获得授权的 Client 都可以连接。

对比总结

维度本地 Server(STDIO)远程 Server(Streamable HTTP)
部署方式Host 子进程独立网络服务
客户端模型一对一一对多
启动控制Host 控制自主运行
认证方式无需(进程隔离即可)OAuth / Bearer Token / API Key
安全边界操作系统进程隔离网络安全(TLS + 认证)
适用场景个人开发工具、敏感本地数据团队共享、云端服务、第三方平台

六、Server 这个词的语义陷阱

MCP 文档中有一个容易混淆的点:Server 指的是提供上下文数据的程序,跟它运行在哪里无关。

这意味着:

  • Filesystem Server 运行在本地(通过 STDIO),但它依然是"Server"
  • Sentry Server 运行在 Sentry 的云端(通过 HTTP),它也是"Server"

"本地"和"远程"描述的是运行位置和传输方式,不是 Server 的角色定义。无论运行在哪里,只要它通过 MCP 协议向 Client 提供上下文,它就是 Server。

Claude Desktop 启动 Filesystem Server 时,Server 运行在 Claude Desktop 所在的同一台机器上。这不是"Client 自己充当 Server"——Client 和 Server 是两个独立的角色,只是恰好运行在同一台机器上,通过 STDIO 通信。


七、Host 如何选择工具

当 Host 连接了多个 Server,每个 Server 可能都暴露了多个工具。LLM 面对的是所有 Server 的所有工具的并集。

Host 通常采用以下策略管理多 Server 的工具命名空间:

策略说明示例
前缀隔离在工具名前加 Server 名称前缀filesystem_read_file、sentry_get_errors
能力描述注入将工具名和描述注入 LLM 的 system prompt“你可以使用以下工具:filesystem_read_file(读取文件),sentry_get_errors(查询错误)……”
路由分发LLM 选择了某个工具后,Host 根据前缀找到对应的 Clientfilesystem_read_file → Client 1 → Filesystem Server

不同的 Host 实现可能采用不同的命名空间策略。例如:

  • Claude Desktop 使用 Server 名称作为前缀
  • Hermes Agent 使用 mcp_{server_name}_{tool_name} 的三段式命名
  • VS Code 有自己的工具路由机制

无论命名方式如何,核心原则不变:Host 是工具的路由器,Client 是到每个 Server 的专属通道。


本篇小结

知识点核心内容
三层架构Host(AI 应用)→ Client(连接管理组件)→ Server(能力提供者)
引入 Client 层的原因连接隔离、能力管理、错误隔离
Host 职责用户交互 + 多 Client 管理 + 工具路由 + 用户授权
Client 职责与一个 Server 的全部通信,1:1 对应
Server 职责实现 Tools/Resources/Prompts,响应请求
本地 ServerSTDIO 传输,Host 子进程,一对一
远程 ServerStreamable HTTP 传输,独立服务,一对多
Server 语义指提供上下文的程序,与运行位置无关
工具路由Host 通过命名空间前缀将工具调用路由到对应的 Client

下篇预告

第 03 篇:MCP 双层设计——数据层与传输层
深入 MCP 的两层架构:数据层(JSON-RPC 2.0 消息格式、发现机制、核心原语)和传输层(连接建立、消息帧、授权),理解协议语义如何在所有传输上保持一致。


如果本篇内容对你有帮助,欢迎点赞收藏!有任何疑问,欢迎在评论区交流。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐