说明:本文由 Codex 根据作者提供的主题、素材与公开资料辅助生成,属于 AI 生成/整理内容,非作者原创。请读者自行甄别并交叉验证。
先说结论#
MCP,也就是 Model Context Protocol,是一种把 AI 应用连接到外部系统的开放协议。
在聊天应用里,可以先这样理解:
聊天应用是 Host;
Host 为每个 MCP Server 建立一个 MCP Client;
MCP Server 提供 Tools、Resources、Prompts;
模型决定是否需要使用工具;
Host/Client 负责把工具调用发给对应 Server;
Server 执行后把结果返回;
Host 再把结果放回对话上下文,让模型生成最终回答。MCP 不是一个模型,也不是一个 Agent 框架。它更像一个标准连接层,解决的是:
AI 应用如何用统一方式发现外部能力、调用外部工具、读取外部上下文。为什么聊天应用需要 MCP#
普通聊天应用只依赖模型自身能力时,能力边界很明显:
- 模型不知道实时数据。
- 模型不能直接访问本地文件、数据库、浏览器、代码仓库或业务系统。
- 模型不能直接执行操作,例如发请求、创建工单、查询订单、读文件。
如果每接入一个外部系统都手写一套集成,就会出现典型的 N x M 问题:
N 个 AI 应用
x
M 个外部工具或数据源
=
大量重复连接逻辑MCP 的目标是把这部分连接方式标准化。
对聊天应用来说,MCP 带来的核心价值是:
- 用统一协议连接多个工具和数据源。
- 运行时发现工具,而不是把工具写死在应用里。
- 把本地工具和远程工具放进同一套调用模型里。
- 把工具调用、资源读取、用户授权和安全审计变成可管理的流程。
三个角色:Host、Client、Server#
理解 MCP,最重要的是区分 Host、Client、Server。
Host#
Host 是用户真正使用的 AI 应用。
例如:
- 聊天应用。
- IDE 助手。
- 桌面 AI 客户端。
- Agent 工作台。
Host 负责整体用户体验:
- 管理对话。
- 调用模型。
- 展示消息、工具调用和结果。
- 管理用户配置的 MCP Server。
- 决定哪些工具暴露给模型。
- 做用户确认、权限控制和安全提示。
在聊天应用里,Host 就是整个 Chat 产品本身。
Client#
MCP Client 是 Host 内部的协议连接组件。
一个容易混淆的点是:用户通常不会直接看到 MCP Client。
它的职责是:
- 和某一个 MCP Server 建立连接。
- 完成初始化和能力协商。
- 请求工具列表、资源列表、Prompt 列表。
- 发送
tools/call等协议请求。 - 接收 Server 的响应和通知。
通常是:
一个 MCP Server 对应一个 MCP Client 连接。如果聊天应用连接了 5 个 MCP Server,Host 内部通常就会维护 5 个 MCP Client。
Server#
MCP Server 是提供上下文和能力的程序。
它可以运行在本机,也可以运行在远程服务器。
常见 MCP Server 类型包括:
- 文件系统 Server:读取指定目录下的文件。
- 数据库 Server:执行查询或读取 schema。
- GitHub Server:查询 issue、PR、代码仓库。
- 日历 Server:读取或创建日程。
- 搜索 Server:调用搜索引擎。
- 内部系统 Server:暴露某个业务系统的安全接口。
Server 不直接和模型聊天。它提供的是标准化能力:
我有哪些工具;
我有哪些资源;
我有哪些 Prompt 模板;
你可以按协议来调用。Server 暴露的三类能力#
MCP Server 最核心的三类能力是:
- Tools
- Resources
- Prompts
它们都可以给聊天应用提供能力,但控制方式不同。
| 类型 | 作用 | 谁通常控制 | 示例 |
|---|---|---|---|
| Tools | 执行动作 | 模型提出,Host/用户确认 | 查询天气、发请求、写文件、查数据库 |
| Resources | 提供上下文数据 | 应用选择或用户选择 | 文件内容、数据库 schema、API 文档 |
| Prompts | 提供可复用任务模板 | 用户显式选择 | 总结会议、生成报告、分析仓库 |
Tools:模型可以调用的函数#
Tools 是 MCP 在聊天应用里最容易被感知的部分。
一个 Tool 可以理解为:
由 MCP Server 提供的、带结构化参数的可执行函数。例如一个天气工具可以长这样:
{
"name": "get_weather",
"description": "Get current weather information for a location",
"inputSchema": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
}
},
"required": ["location"]
}
}聊天应用拿到这个定义后,可以把它转换成模型可理解的工具描述。
当用户问:
今天上海天气怎么样?模型可能决定调用:
{
"name": "get_weather",
"arguments": {
"location": "Shanghai"
}
}Host 再通过 MCP Client 向对应 Server 发送 tools/call 请求。
Resources:模型可用的上下文来源#
Resources 更像“可读取的数据”。
它不强调执行动作,而强调给模型补充上下文。
例如:
file:///notes/project.mddb://schema/userscalendar://events/2026-06repo://readme
Resources 可以是固定 URI,也可以是模板:
repo://files/{path}
weather://forecast/{city}/{date}在聊天应用里,Resources 通常对应这些 UI:
- 文件选择器。
- 知识库列表。
- 数据源浏览器。
- 当前会话可用上下文。
- “添加到上下文”的按钮。
重要区别是:
Tool 是让模型做事;
Resource 是给模型看资料。当然,实际产品里两者会配合使用:先读 Resource 获取上下文,再调用 Tool 执行动作。
Prompts:可复用的任务模板#
Prompts 是 MCP Server 提供的结构化提示词模板。
它适合表达某类固定工作流。
例如:
/summarize-meeting/review-pr/plan-release/analyze-logs
Prompt 可以有参数:
{
"name": "review-pr",
"arguments": [
{
"name": "pull_request_url",
"required": true
}
]
}在聊天应用里,Prompts 可以做成:
- slash command。
- 命令面板。
- 快捷按钮。
- 某个 MCP Server 的推荐操作。
Prompts 的重点不是让模型自动调用,而是让用户显式选择某个任务模板。
MCP 的两层结构#
MCP 可以分成两层看:
Data Layer
Transport LayerData Layer#
Data Layer 定义消息格式和语义。
它基于 JSON-RPC 2.0,包括:
- 初始化。
- 能力协商。
- 工具发现。
- 工具调用。
- 资源读取。
- Prompt 获取。
- 通知。
- 进度。
- 取消。
- 错误。
聊天应用真正关心的多数逻辑都在这一层。
例如:
tools/list
tools/call
resources/list
resources/read
prompts/list
prompts/getTransport Layer#
Transport Layer 负责 Client 和 Server 怎么通信。
当前标准传输方式主要有两种:
| 传输 | 常见场景 | 特点 |
|---|---|---|
| stdio | 本地 MCP Server | Host 启动子进程,通过 stdin/stdout 传 JSON-RPC |
| Streamable HTTP | 远程 MCP Server | 通过 HTTP POST/GET 通信,可配合 SSE 流式传输 |
这意味着同一套 MCP 协议可以跑在不同连接方式上。
聊天应用可以同时连接:
- 本地文件系统 MCP Server,使用 stdio。
- 云端搜索 MCP Server,使用 Streamable HTTP。
- 企业内部 API MCP Server,使用 HTTP + OAuth。
典型调用流程#
下面用聊天应用视角,梳理一次完整 MCP 工具调用。
1. 用户配置 MCP Server#
用户在聊天应用里添加一个 MCP Server。
本地 Server 配置可能类似:
{
"name": "filesystem",
"transport": "stdio",
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/example/Documents"]
}远程 Server 配置可能类似:
{
"name": "search",
"transport": "http",
"url": "https://mcp.example.com/mcp"
}这些只是示意,实际配置取决于具体客户端和 Server。
2. Host 创建 MCP Client#
聊天应用启动或用户启用 Server 时,Host 会为这个 Server 创建一个 MCP Client。
如果是 stdio:
Host 启动 Server 子进程
Client 通过 stdin/stdout 通信如果是 Streamable HTTP:
Client 连接远程 MCP endpoint
通过 HTTP 发送 JSON-RPC 请求3. 初始化与能力协商#
连接建立后,Client 和 Server 会进行初始化。
初始化阶段会协商:
- 使用哪个协议版本。
- Client 支持哪些能力。
- Server 支持哪些能力。
- Server 信息。
这一步很重要,因为 MCP 是有状态协议。
聊天应用不能假设所有 Server 都支持相同能力,而是要根据初始化结果决定后续可用功能。
4. 发现 Tools、Resources、Prompts#
如果 Server 声明支持工具,Client 可以调用:
tools/list如果 Server 支持资源:
resources/list
resources/templates/list如果 Server 支持 Prompt:
prompts/list聊天应用会把这些能力整理进自己的状态中。
例如 UI 里可能展示:
filesystem
- read_file
- list_directory
search
- web_search
- fetch_url也可以让用户为每个会话选择启用哪些 Server 或 Tools。
5. 用户发起对话#
用户输入:
帮我总结这个目录下最近修改的 Markdown 文件。聊天应用构造模型请求时,会把当前可用工具描述交给模型。
这里有一个产品设计点:
不是所有工具都应该默认暴露给模型。更稳妥的做法是:
- 按会话选择 MCP Server。
- 按 Server 选择可用工具。
- 对高风险工具要求用户确认。
- 对写操作、删除操作、外部发送操作默认更严格。
6. 模型决定调用工具#
模型看到用户意图和工具列表后,可能决定调用:
list_directory
read_file这一步不是 MCP Server 主动决定的。
更准确地说:
模型提出工具调用意图;
Host 决定是否允许;
MCP Client 负责执行协议调用;
MCP Server 执行真实逻辑。7. Host 做权限检查和用户确认#
在真正调用工具前,Host 应该检查:
- 这个 Server 是否被当前会话启用。
- 这个 Tool 是否允许被模型调用。
- 参数是否在允许范围内。
- 是否需要用户确认。
- 是否会读取敏感数据。
- 是否会修改外部系统。
例如:
read_file: 可以预授权某个目录。
delete_file: 必须每次确认。
send_email: 必须展示收件人和正文后确认。
query_database: 只允许只读查询。MCP 官方规范也强调,工具调用应当有人类监督,应用应提供清晰的 UI 让用户知道暴露了哪些工具、调用了哪些工具。
8. Client 调用 tools/call#
确认通过后,MCP Client 向对应 Server 发请求:
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {
"path": "/notes/today.md"
}
}
}Server 执行逻辑后返回结果。
结果可能包含:
- 文本。
- 图片。
- 音频。
- 资源链接。
- 嵌入资源。
- 结构化内容。
- 错误信息。
9. Host 把结果回填给模型#
工具结果不是最终回答。
Host 需要把工具结果作为上下文交回模型:
工具 read_file 返回了文件内容;
模型阅读工具结果;
模型生成面向用户的总结。这就是聊天应用里的关键闭环:
用户消息
-> 模型判断需要工具
-> MCP 工具调用
-> 工具结果回到模型
-> 模型生成最终回答10. UI 展示调用过程#
一个成熟的聊天应用不应该只展示最终回答。
还应该展示:
- 哪个 MCP Server 被调用。
- 调用了哪个 Tool。
- 调用参数是什么。
- 是否经过用户确认。
- 调用状态:等待、执行中、成功、失败、取消。
- 工具返回摘要。
- 错误和重试入口。
这样用户才能理解模型为什么这样回答,也能发现错误工具调用。
一张流程图#
sequenceDiagram
participant User as User
participant Host as Chat Host
participant LLM as LLM
participant Client as MCP Client
participant Server as MCP Server
Host->>Client: initialize
Client->>Server: initialize
Server-->>Client: capabilities
Client->>Server: tools/list
Server-->>Client: tool definitions
User->>Host: 发送问题
Host->>LLM: 用户问题 + 可用工具
LLM-->>Host: 请求调用工具
Host->>User: 可选确认
User-->>Host: 同意
Host->>Client: tools/call
Client->>Server: tools/call
Server-->>Client: tool result
Client-->>Host: tool result
Host->>LLM: 工具结果
LLM-->>Host: 最终回答
Host-->>User: 展示回答和工具调用记录MCP Tool 和模型 Function Calling 的区别#
MCP Tools 很容易和模型 API 的 Function Calling 混淆。
它们确实相关,但层次不同。
| 对比项 | Function Calling | MCP Tools |
|---|---|---|
| 所属层次 | 模型 API 能力 | AI 应用和外部系统之间的协议能力 |
| 工具定义来源 | 应用代码手动传给模型 | MCP Server 动态暴露 |
| 发现机制 | 通常由应用静态组织 | tools/list 动态发现 |
| 执行位置 | 应用自己执行函数 | MCP Client 调用 MCP Server 执行 |
| 复用方式 | 每个应用自己集成 | 一个 Server 可被多个 MCP Host 使用 |
| 关注重点 | 让模型输出结构化调用 | 标准化工具、资源、Prompt 的连接与调用 |
可以这样理解:
Function Calling 是模型和应用之间的工具调用表达方式;
MCP 是应用和外部工具/数据源之间的标准连接方式。在真实聊天应用里,两者经常一起出现:
- Host 从 MCP Server 获取工具定义。
- Host 把工具定义转换成模型 API 支持的工具格式。
- 模型通过 Function Calling 表达要调用哪个工具。
- Host 把这个调用映射成 MCP
tools/call。 - Server 执行后返回结果。
- Host 再把结果交回模型。
本地 MCP Server 和远程 MCP Server#
MCP Server 可以本地运行,也可以远程运行。
本地 Server#
本地 Server 常见于桌面应用或 IDE。
优点:
- 可以访问本机文件或本地工具。
- 延迟低。
- 不一定需要网络。
- 适合开发者工具场景。
风险:
- 本地权限可能很大。
- 如果暴露文件系统、Shell、浏览器等能力,必须限制范围。
- stdio Server 的启动命令、参数和环境变量要谨慎管理。
远程 Server#
远程 Server 常见于 SaaS、企业系统和云服务。
优点:
- 易于集中部署和更新。
- 可以对接后端系统。
- 可以使用标准 HTTP 鉴权。
- 多个客户端可以复用同一服务。
风险:
- 需要处理 OAuth、Token、租户隔离和网络安全。
- 需要清楚区分用户身份和服务身份。
- 需要审计工具调用。
聊天应用应该怎么设计 MCP UI#
从产品实现角度,MCP 不只是协议问题,也是一套用户体验问题。
一个聊天应用至少需要考虑这些界面。
Server 管理#
用于添加、删除、启用、禁用 MCP Server。
应该展示:
- Server 名称。
- 连接方式。
- 连接状态。
- 支持的能力。
- 认证状态。
- 最近错误。
Tool 选择#
用户应该能知道当前会话启用了哪些工具。
常见做法:
- 每个会话独立选择可用 Server。
- 每个 Server 可以展开查看 Tools。
- 高风险 Tools 默认关闭。
- 工具说明来自 Server,但 UI 应提示这些说明不等于安全保证。
调用确认#
对可能产生副作用的工具,应展示确认框。
确认信息至少包括:
- Server。
- Tool。
- 参数。
- 操作影响。
- 是否会写入外部系统。
- 是否会发送数据到远程服务。
调用时间线#
聊天消息里可以展示工具调用过程。
例如:
MCP: filesystem / list_directory
MCP: filesystem / read_file
MCP: search / web_search这样用户能理解模型回答的来源。
错误处理#
MCP 调用失败很常见。
可能原因包括:
- Server 没启动。
- 初始化失败。
- 协议版本不兼容。
- Tool 参数不合法。
- 用户拒绝授权。
- OAuth Token 过期。
- 远程 Server 返回 401/403/500。
- stdio Server 输出了非 JSON-RPC 内容。
聊天应用应该把错误分层展示,不要只给一个“工具调用失败”。
安全边界#
MCP 给模型接入了真实世界能力,因此安全边界非常重要。
1. 工具不是天然可信的#
Tool 的名称、描述、参数 schema 都来自 MCP Server。
如果 Server 不可信,工具描述也不可信。
聊天应用不应该因为工具描述写着“安全读取文件”,就默认认为它真的安全。
2. 用户要知道暴露了什么#
Host 应该清楚告诉用户:
- 当前启用了哪些 MCP Server。
- 每个 Server 暴露了哪些 Tools。
- 哪些 Resources 可能被读取。
- 哪些操作需要确认。
3. 最小权限#
文件系统 Server 不应该默认访问整个磁盘。
数据库 Server 不应该默认拥有写权限。
远程 API Server 不应该默认拥有全量 Token。
较好的方式是:
按 Server 限制权限;
按 Tool 限制权限;
按会话限制权限;
按用户确认提升权限。4. 远程 Server 使用标准认证#
HTTP 传输下,MCP 规范提供了基于 OAuth 的授权机制。
实现时要注意:
- 使用 HTTPS。
- 使用 Bearer Token。
- Token 不放在 URL query 中。
- 客户端要实现 PKCE。
- Server 要校验 Token audience。
- 不要把收到的 Token 原样转发给下游服务。
5. 本地 HTTP Server 要防 DNS rebinding#
如果本地 MCP Server 使用 Streamable HTTP,而不是 stdio,需要特别小心。
官方规范建议:
- 校验
Originheader。 - 本地服务绑定到
127.0.0.1,不要绑定0.0.0.0。 - 对连接做认证。
否则远程网页可能通过 DNS rebinding 攻击访问本地 MCP Server。
常见误解#
误解一:MCP Server 就是 Agent#
不对。
MCP Server 提供工具、资源和 Prompt。它可以很复杂,但它不是必须具备自主规划能力的 Agent。
Agent 通常在 Host 或应用层实现。
误解二:MCP 会替代 RAG#
不会。
MCP 可以暴露 Resources,也可以暴露搜索或检索 Tools,但 RAG 是如何选择、切分、召回和注入上下文的方法。
两者是互补关系。
误解三:MCP Tool 可以让模型直接执行任意代码#
协议本身只定义调用方式,不要求工具能执行任意代码。
一个 Tool 能做什么,取决于 Server 的实现和 Host 的权限控制。
误解四:连接了 MCP Server,就应该把所有工具给模型#
不建议。
工具越多,模型选择成本越高,误调用风险也越高。
更好的方式是按会话、按任务、按用户选择启用工具。
误解五:MCP 只适合桌面应用#
不对。
stdio 很适合本地桌面和 IDE 场景;Streamable HTTP 更适合远程服务、SaaS 和企业系统。
一个最小聊天应用架构#
一个支持 MCP 的聊天应用,可以拆成这些模块:
Chat UI
- 消息展示
- MCP Server 选择
- Tool 调用展示
- 用户确认弹窗
Conversation State
- 当前会话消息
- 当前启用的 Server/Tools
- 工具调用记录
MCP Manager
- Server 配置
- Client 生命周期
- 初始化和能力发现
- 连接状态
Tool Router
- 模型工具调用 -> MCP Server
- 参数校验
- 权限检查
- 调用取消和超时
Model Adapter
- 把 MCP Tools 转换成模型工具描述
- 把工具结果回填给模型
- 组织最终回答关键点是:
MCP Manager 负责协议连接;
Tool Router 负责调用治理;
Model Adapter 负责模型格式适配;
Chat UI 负责让用户看见并控制这一切。不要把这些逻辑全部塞进一个“发送消息”函数里,否则后续会很难维护。
小结#
MCP 在聊天应用中的核心链路是:
连接 Server
-> 初始化和能力协商
-> 发现 Tools/Resources/Prompts
-> 用户对话
-> 模型提出工具调用
-> Host 做权限与确认
-> MCP Client 调用 Server
-> Server 返回结果
-> Host 把结果交回模型
-> 模型生成最终回答理解 MCP 时,最重要的不是记住某个 SDK API,而是分清这些边界:
- Host 管用户体验和模型调用。
- Client 管协议连接。
- Server 管外部能力。
- Tools 用来执行动作。
- Resources 用来提供上下文。
- Prompts 用来复用工作流。
- 安全控制必须由 Host 和 Server 共同实现。
MCP 让聊天应用从“只会回答”变成“能连接上下文、使用工具、执行工作流”,但它也把权限、审计和用户确认推到了产品设计的中心位置。