MCP 在聊天应用中的基本原理:Server、Tools 与调用流程

This article is extracted from the chat log with AI. Please identify it with caution.

说明:本文由 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.md
  • db://schema/users
  • calendar://events/2026-06
  • repo://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 Layer

Data Layer#

Data Layer 定义消息格式和语义。

它基于 JSON-RPC 2.0,包括:

  • 初始化。
  • 能力协商。
  • 工具发现。
  • 工具调用。
  • 资源读取。
  • Prompt 获取。
  • 通知。
  • 进度。
  • 取消。
  • 错误。

聊天应用真正关心的多数逻辑都在这一层。

例如:

tools/list
tools/call
resources/list
resources/read
prompts/list
prompts/get

Transport Layer#

Transport Layer 负责 Client 和 Server 怎么通信。

当前标准传输方式主要有两种:

传输常见场景特点
stdio本地 MCP ServerHost 启动子进程,通过 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 CallingMCP Tools
所属层次模型 API 能力AI 应用和外部系统之间的协议能力
工具定义来源应用代码手动传给模型MCP Server 动态暴露
发现机制通常由应用静态组织tools/list 动态发现
执行位置应用自己执行函数MCP Client 调用 MCP Server 执行
复用方式每个应用自己集成一个 Server 可被多个 MCP Host 使用
关注重点让模型输出结构化调用标准化工具、资源、Prompt 的连接与调用

可以这样理解:

Function Calling 是模型和应用之间的工具调用表达方式;
MCP 是应用和外部工具/数据源之间的标准连接方式。

在真实聊天应用里,两者经常一起出现:

  1. Host 从 MCP Server 获取工具定义。
  2. Host 把工具定义转换成模型 API 支持的工具格式。
  3. 模型通过 Function Calling 表达要调用哪个工具。
  4. Host 把这个调用映射成 MCP tools/call
  5. Server 执行后返回结果。
  6. 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,需要特别小心。

官方规范建议:

  • 校验 Origin header。
  • 本地服务绑定到 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 让聊天应用从“只会回答”变成“能连接上下文、使用工具、执行工作流”,但它也把权限、审计和用户确认推到了产品设计的中心位置。

参考资料#

本文共 6099 字,创建于 Jun 29, 2026

相关标签: LLM, AI, Agent, ByAI