MCP 架构详解:Host、MCP Client、MCP Server 的职责与代码实战
1. 引言
MCP(Model Context Protocol,模型上下文协议)是 Anthropic 于 2024 年底开源的一套开放协议,用于统一大语言模型应用与外部数据源、工具之间的连接方式。它把传统上碎片化的「插件开发」抽象为「客户端—服务器」的标准架构,让同一个 MCP Server 可以被不同的 AI 应用(Host)复用。
理解 MCP 架构,核心是分清三个角色:Host、MCP Client和MCP Server。本文将从职责边界、通信流程和代码实战三个层面展开,帮助你彻底搞懂它们各自负责什么。
2. 三个角色的职责总览
在 MCP 架构中,三个角色各司其职,形成一条清晰的调用链:
- Host:用户直接面对的 AI 应用,负责管理多个 MCP Client、维护用户会话、决定何时调用工具,并把结果组织成自然语言回复。
- MCP Client:Host 与 Server 之间的协议适配层,负责建立连接、发送请求、接收响应、处理协议生命周期。
- MCP Server:对外暴露能力的一方,提供工具(Tools)、资源(Resources)和提示词(Prompts),并执行实际业务逻辑。
一句话概括:Host 是大脑,Client 是神经,Server 是手脚。
3. Host 的职责
Host 是用户直接交互的应用程序,例如 Claude Desktop、Cursor、VS Code 插件或你正在使用的 CSDN 编辑器。Host 本身不直接与 MCP Server 通信,而是通过内部持有的一个或多个 MCP Client 完成。
Host 的核心职责包括:
- 管理客户端生命周期:启动时创建 MCP Client,关闭时销毁连接。
- 维护用户会话:保存对话上下文,决定在什么时机调用哪个工具。
- 聚合多 Server 能力:一个 Host 可以同时连接多个 MCP Server,例如一个连数据库、一个连 GitHub、一个连文件系统。
- 决策与编排:根据用户意图判断「是否需要调用工具」「调用哪个工具」「传什么参数」,并把工具返回结果融入最终回答。
- 权限与安全控制:决定是否允许某个 Server 执行敏感操作,例如写文件、发请求。
从代码角度看,Host 通常是一个业务应用,它内部持有 MCP Client 实例。下面是一个极简 Host 的伪代码示意:
# host.py —— 这是 Host 层,负责编排 import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): # Host 创建 MCP Client,并连接到本地 MCP Server 进程 server_params = StdioServerParameters( command="python", args=["math_server.py"] ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: # Host 通过 Client 初始化连接 await session.initialize() # Host 决定调用哪个工具 result = await session.call_tool("add", {"a": 3, "b": 5}) print("工具返回:", result) # Host 把结果组织成自然语言回复给用户 answer = f"计算结果为 {result.content[0].text}" print("Host 回复用户:", answer) if name == "main": asyncio.run(main())注意:上面的代码中,host.py同时扮演了 Host 和 Client 两个角色。在实际工程中,Host 可能是一个大型应用,而 Client 是它内部的一个模块。
4. MCP Client 的职责
MCP Client 是协议层面的「翻译官」,它负责把 Host 的意图翻译成 MCP 协议消息,并通过传输层发送给 Server。MCP Client 通常由官方 SDK 提供,开发者一般不需要从零实现。
MCP Client 的核心职责包括:
- 建立连接:通过 stdio、SSE 或 HTTP 等传输方式与 Server 建立通道。
- 协议握手:发送
initialize请求,协商协议版本与能力。 - 能力发现:调用
tools/list获取 Server 暴露的工具清单。 - 请求转发:把 Host 的调用意图封装为
tools/call请求发送给 Server。 - 响应解析:把 Server 返回的 JSON-RPC 响应解析为结构化数据,交还给 Host。
- 生命周期管理:处理
notifications/initialized、ping、关闭等协议事件。
在 Python 官方 SDK 中,ClientSession就是 MCP Client 的核心类。下面演示 Client 如何发现工具并调用:
# client_demo.py —— 聚焦 MCP Client 的协议行为 import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): server_params = StdioServerParameters( command="python", args=["math_server.py"] ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: # 1. 协议握手 await session.initialize() # 2. 能力发现:列出 Server 提供的所有工具 tools = await session.list_tools() print("Server 暴露的工具:") for tool in tools.tools: print(f" - {tool.name}: {tool.description}") # 3. 调用工具 result = await session.call_tool( "add", {"a": 10, "b": 20} ) print("调用结果:", result.content[0].text) asyncio.run(main())可以看到,MCP Client 屏蔽了底层 JSON-RPC 细节,开发者只需要调用initialize()、list_tools()、call_tool()这几个高层方法即可。
5. MCP Server 的职责
MCP Server 是能力的提供方,它运行在独立的进程或服务中,通过 MCP 协议暴露自己的工具、资源和提示词。Server 是开发者最常需要自己实现的部分。
MCP Server 的核心职责包括:
- 声明能力:通过
tools/list告诉 Client 自己提供哪些工具,每个工具的入参 schema 是什么。 - 执行工具:收到
tools/call请求后,执行真实业务逻辑并返回结果。 - 暴露资源:通过
resources/list和resources/read提供可读取的数据资源。 - 提供提示词:通过
prompts/list和prompts/get提供可复用的提示模板。 - 维护协议状态:处理初始化握手、能力协商、错误返回等协议细节。
下面用 Python 官方 SDK 实现一个最简单的 MCP Server,提供「加法」和「乘法」两个工具:
# math_server.py —— MCP Server 实现 from mcp.server.fastmcp import FastMCP 创建 Server 实例 mcp = FastMCP("MathServer") 用装饰器注册一个工具 @mcp.tool() def add(a: int, b: int) -> int: """计算两个整数的和""" return a + b @mcp.tool() def multiply(a: int, b: int) -> int: """计算两个整数的积""" return a * b if name == "main": # 以 stdio 方式运行,等待 Client 连接 mcp.run(transport="stdio")这个 Server 启动后,会通过标准输入输出与 Client 通信。Client 调用add工具时,Server 执行a + b并返回结果。
除了工具,Server 还可以暴露资源。下面演示如何注册一个只读资源:
# resource_server.py —— 暴露资源的 MCP Server from mcp.server.fastmcp import FastMCP mcp = FastMCP("ResourceServer") @mcp.resource("config://app") def get_config() -> str: """返回应用配置信息""" return "version=1.0.0\nmode=production" @mcp.tool() def echo(text: str) -> str: """原样返回输入文本""" return text if name == "main": mcp.run(transport="stdio")6. 三者协作的完整流程
下面用一个完整的时序来说明三者如何协作。假设用户对 Host 说:「帮我计算 123 乘以 456」。
- Host 理解意图:Host 判断需要调用数学工具,于是找到连接了 MathServer 的那个 MCP Client。
- Client 查询能力:Client 向 Server 发送
tools/list,拿到工具清单,发现multiply工具可用。 - Client 发起调用:Client 发送
tools/call,参数为{"a": 123, "b": 456}。 - Server 执行业务:Server 执行
123 * 456,返回结果56088。 - Client 回传结果:Client 把结果解析后交还给 Host。
- Host 组织回复:Host 把结果组织成自然语言:「123 乘以 456 的结果是 56088」并展示给用户。
下面给出一个完整的可运行示例,把 Host、Client、Server 串起来。先启动 Server,再运行 Client 端脚本:
# 完整实战:一个 Host 同时连接两个 Server import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def connect_to_server(command: str, args: list): """Host 内部创建 MCP Client 并连接指定 Server""" server_params = StdioServerParameters(command=command, args=args) read, write = await stdio_client(server_params).aenter() session = await ClientSession(read, write).aenter() await session.initialize() return session async def main(): # Host 同时连接两个 MCP Server math_session = await connect_to_server("python", ["math_server.py"]) resource_session = await connect_to_server("python", ["resource_server.py"]) # Host 编排:先调用数学工具 result = await math_session.call_tool("multiply", {"a": 123, "b": 456}) print("乘法结果:", result.content[0].text) 再读取资源 resources = await resource_session.list_resources() print("可用资源:", [r.uri for r in resources.resources]) 关闭连接 await math_session.aexit(None, None, None) await resource_session.aexit(None, None, None) asyncio.run(main())7. 三者的边界与常见误区
理解三者边界时,有几个常见误区需要澄清:
- 误区一:Host 就是 Client。实际上 Host 是业务应用,Client 是协议适配层。一个 Host 可以持有多个 Client,分别连接不同的 Server。
- 误区二:Server 必须远程部署。MCP Server 可以运行在本地进程(stdio),也可以远程部署(SSE/HTTP)。本地 Server 更安全,远程 Server 便于共享。
- 误区三:Client 需要自己实现协议。官方 SDK 已经封装好握手、发现、调用等细节,开发者通常只需要调用高层 API。
- 误区四:三者必须一一对应。实际中一个 Host 对应多个 Client,一个 Client 对应一个 Server,但一个 Server 可以被多个 Host 的多个 Client 同时连接。
8. 总结
MCP 架构通过三个角色的清晰分工,把 AI 应用与外部能力的集成标准化:
- Host负责用户交互、会话管理和工具调用决策,是应用的「大脑」。
- MCP Client负责协议通信、能力发现和请求转发,是连接双方的「神经」。
- MCP Server负责暴露工具、资源和提示词并执行真实业务逻辑,是提供能力的「手脚」。
在实际开发中,你通常只需要自己实现 MCP Server,而 Host 和 Client 大多由应用框架或官方 SDK 提供。理解三者的职责边界,能帮助你在设计 AI 应用时做出更合理的架构决策。
