在这里插入图片描述

肖哥弹架构 跟大家“弹弹” 大模型MCP 设计与实战应用,需要代码关注

欢迎 关注,点赞,留言。

关注公号Solomon肖哥弹架构获取更多精彩内容

历史热点文章

⚠️ 原创不易 搬运必究

Model Context Protocol(MCP)是连接AI应用与外部数据源、工具的核心开放协议,被誉为“AI世界的USB标准”。本文从协议基础、架构设计到10大功能场景,全面解析MCP如何通过标准化接口实现安全、可扩展的AI能力集成。涵盖Stdio与SSE通信原理、Java SDK实现、Spring AI整合,并结合智能编程助手、电商数据分析等真实案例,展示MCP在工具调用、资源管理、提示词模板等场景下的完整通信流程。

一、什么是MCP介绍

1. MCP 是什么?

MCP 是一个开放标准,用于在AI应用程序(如ChatGPT)外部数据源、工具(Servers) 之间建立安全的通信桥梁。

你可以把它想象成AI世界的USB协议:它定义了一套标准化的接口,让不同的“外围设备”(数据源、API、函数)可以即插即用地被AI调用,而无需每次都为新的工具重新构建整个系统。

核心角色:

  • 客户端 (Client) :通常是AI应用本身,例如ChatGPT客户端、Claude客户端或你自行开发的AI应用。它发出请求(如“读取这个文件”、“执行这个SQL查询”)。
  • 服务器 (Server) :提供具体资源和工具的一方。例如,一个连接到GitHub的服务器、一个数据库连接器或一个计算器工具。服务器需要实现MCP协议来告知客户端它提供了哪些功能。
  • 传输层 (Transport) :Client和Server之间的通信方式,通常是标准输入/输出(stdio)或网络套接字(sockets)。

2. 为什么需要 MCP?解决了什么问题?

在没有MCP之前,如果你想为ChatGPT等AI添加自定义功能(比如访问公司内部的数据库),通常会面临以下挑战:

  • 安全性问题:直接让AI模型访问敏感数据或系统是非常危险的。
  • 开发复杂性:需要为每个工具编写大量的胶水代码和适配器,过程繁琐且不易维护。
  • 缺乏标准化:每个工具都有自己的集成方式,没有统一的规范,导致生态碎片化。
  • 权限控制薄弱:难以对AI可以访问的工具和数据进行细粒度的权限管理。

MCP 通过提供一个标准协议来解决这些问题,使得工具开发者和AI应用开发者可以遵循同一套规则,实现无缝集成。

3. MCP 的核心功能(协议设计要点)

MCP协议的设计围绕几个核心功能展开,主要通过不同类型的“资源”来体现:

a. 工具(Tools)

这是MCP最强大的功能之一。Server可以向Client注册一系列可调用的函数(工具)。当用户提出需求时,AI可以决定调用哪个工具,并生成正确的参数。

  • 示例:一个“天气预报”工具、一个“执行SQL查询”工具、一个“发送邮件”工具。
  • 流程Client(AI) -> (请求调用工具weather.getForecast,参数为location="北京") -> Server -> (执行真正API调用) -> Server -> (返回结果给Client) -> Client(AI) -> (将结果整合到回复中给用户)。
b. 数据源(Resources)

Server可以将其管理的数据以“可读资源”的形式暴露给Client。AI可以请求读取这些资源的内容,但通常不能直接写入。

  • 示例:文件系统中的文件、数据库中的表、GitHub仓库的issue列表。
  • 特点:支持类似URL的路径(如file:///path/to/file.txtgithub://owner/repo/issues)来标识资源,实现了数据的抽象和统一访问。
c. 提示词模板(Prompts)

Server可以预定义一些高质量的提示词模板(Prompts),Client(AI)可以直接调用这些模板来引导模型的行为或生成特定格式的内容。这促进了提示词的复用和共享。

  • 示例:一个“代码审查”提示词模板、一个“新闻稿生成器”模板。
  • 流程:用户选择使用某个模板 -> Client向Server请求该模板的内容 -> Server返回预设的提示词 -> Client将其填入对话中。
d. 采样参数(Sampling Parameters)

Server可以建议模型使用特定的推理参数(如温度、top-p等),以便为特定任务优化模型的输出效果。

4. MCP 的工作流程与通信方式

MCP基于JSON-RPC 2.0协议,这是一种轻量级的远程过程调用协议。Client和Server之间通过交换JSON格式的消息进行通信。

基本流程:

  1. 初始化 (Handshake) :Server启动后,与Client交换初始化消息,协商协议版本。
  2. 交换能力 (Capabilities Exchange) :Server告知Client它支持哪些功能(如提供了哪些Tools、Resources等)。Client也会告知Server它需要哪些功能。
  3. 请求/响应 (Request/Response) :在会话中,Client根据需要向Server发送请求(如resources_readtools_call),Server执行相应操作并返回结果。
  4. 通知 (Notifications) :Server也可以主动向Client发送通知(例如,某个被监控的文件内容更改了)。

5. 核心优势

  • 安全:AI模型本身不直接访问系统,所有访问都通过MCP Server这个代理进行。可以对Server进行严格的权限控制和审计。
  • 可扩展:任何人都可以编写MCP Server来提供新的功能,极大地丰富了AI的能力边界。
  • 标准化:统一的协议使得工具可以跨不同的AI客户端(如ChatGPT, Claude, Copilot)使用。
  • 隔离性:工具和数据的逻辑与AI主程序分离,更加清晰和易于维护。

6. 实际应用与生态

  • OpenAI ChatGPT:已经支持MCP,用户可以通过配置本地的MCP Server来让ChatGPT访问他们的代码库、本地文件等(需谨慎设置权限)。
  • Anthropic Claude:也积极支持MCP,生态中有大量为Claude开发的Server。
  • 开发社区:已经涌现出大量开源的MCP Server,用于连接:
    • GitHub, JIRA, Confluence
    • 本地文件系统
    • 数据库(MySQL, PostgreSQL)
    • 浏览器操作
    • 等等。

总结来说,Model Context Protocol (MCP) 是一个为AI时代设计的、用于安全连接核心模型与外部工具和数据的关键协议。它通过标准化和抽象,正在构建一个充满活力的工具生态,是推动AI智能体(Agent)发展的重要基础设施之一。

二、Java MCP SDK架构设计

在这里插入图片描述

  • 客户端/服务器层:
    • McpClient负责处理客户端操作,
    • 而McpServer则管理服务端协议操作。
    • 二者均通过McpSession实现通信管理。
  • 会话层(McpSession):
    • 通过McpClientSession和McpServerSession实现方案来管理通信模式及状态。
  • 传输层(McpTransport):
    • 负责JSON-RPC消息的序列化与反序列化,并支持多种传输实现方案。
  • 通讯层(Communication Layer)
    • SSE 和 Stdio 是 MCP 客户端(你的 Spring AI 应用)与 MCP 服务器(提供工具、资源和知识的独立进程)之间建立的两种不同的通信传输层(Transport)

1. Stdio原理

1.1. Stdio (标准输入/输出)
  • 是什么:这是一种进程间通信(IPC) 方式。客户端(Spring AI 应用)会直接启动(Spawn) 服务器进程,并通过操作系统的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)流与它进行通信。
  • 工作原理
    1. Spring AI 应用程序启动。
    2. 根据配置,它启动指定的 MCP 服务器进程(例如一个 Python 脚本或一个编译好的二进制文件)。
    3. 客户端通过 stdin 向服务器发送请求(JSON-RPC 消息)。
    4. 服务器通过 stdout 返回响应(JSON-RPC 消息)。
    5. 服务器的日志和错误信息通过 stderr 输出,通常由客户端记录。
  • 优点
    • 简单直接:配置相对简单,非常适合本地开发和调试。
    • 强生命周期关联:客户端管理服务器的生命周期(启动、停止)。客户端退出,服务器通常也会被终止。
  • 缺点
    • 紧密耦合:服务器必须与客户端运行在同一台机器上。
    • 灵活性差:难以连接到远程或已经正在运行的服务器。
  • 典型配置(application.yml)
    spring:
      ai:
        mcp:
          clients:
            my-stdio-server:
              connection:
                type: stdio
                # 启动服务器进程的命令
                command: "python"
                # 传递给命令的参数
                args:
                  - "/path/to/your/mcp_server_script.py"
              # 可选的服务器元数据
              metadata:
                name: "My Tool Server"
    

2. SSE原理

2.1. SSE (Server-Sent Events)
  • 是什么:这是一种基于 HTTP 的通信协议。客户端通过向一个预先定义好的 URL 发起一个持久的 HTTP 连接,来与一个已经独立运行的 MCP 服务器进行通信。服务器可以通过这个连接向客户端“推送”一系列事件(数据)。
  • 工作原理
    1. MCP 服务器作为一个独立的服务先行启动,并在某个主机和端口上监听 HTTP 请求(例如 http://localhost:8000)。
    2. 该服务器会暴露一个特定的 SSE 端点(例如 /sse)。
    3. 客户端启动后,根据配置,会向这个 SSE 端点发起一个 HTTP GET 请求,并保持连接打开。
    4. 客户端通过这个 HTTP 连接向服务器发送请求(JSON-RPC 消息)。
    5. 服务器通过同一个 HTTP 连接流式地返回响应(JSON-RPC 消息)。
  • 优点
    • 解耦和灵活性:客户端和服务器是完全独立的进程,甚至可以运行在不同的机器上。服务器可以预先启动并被多个客户端共享。
    • 更适合云和分布式环境:这是微服务架构中更自然的通信方式。
    • 缺点
      • 配置稍复杂,需要确保网络可达,并且服务器已提前运行。
      • 客户端的生命周期不管理服务器。
  • 典型配置(application.yml)
      spring:
        ai:
          mcp:
            clients:
              my-sse-server:
                connection:
                  type: sse
                  # 到正在运行的 MCP 服务器的 SSE 端点 URL
                  url: "http://localhost:8000/sse"
                metadata:
                  name: "My Remote Tool Server"
    

3. Stdio与SSE 对比

特性 Stdio (标准输入/输出) SSE (服务器发送事件)
通信方式 进程标准流 (stdin/stdout) HTTP 协议
启动方式 由客户端启动服务器进程 服务器必须预先独立运行
生命周期管理 客户端管理服务器 客户端不管理服务器
网络要求 本地进程,无网络要求 需要网络连接(可本地可远程)
部署场景 本地开发、单机应用 分布式系统、微服务、云环境
耦合度 紧耦合 松耦合
3.1. 如何选择?
  • 选择 Stdio:当你正在开发或测试一个 MCP 服务器,或者你的应用是简单的单体架构,所有东西都运行在同一台本地机器上时。这是最简单快捷的方式。
  • 选择 SSE:当你的 MCP 服务器是一个长期运行的服务(例如数据库查询服务、公司内部知识库服务),或者你需要让多个 AI 应用(客户端) 连接到同一个共享的服务器时,或者你需要进行远程连接时。
3.2 场景案例说明
3.2.1 适用 Stdio (标准输入/输出) 的业务场景

这些场景的特点是:工具高度个性化、与主应用生命周期绑定、无需共享、通常在单机环境下运行。

(1). 个人数据分析与可视化助手
  • 业务描述:一个财务分析师使用一个内部的Spring AI应用来查询公司数据库。AI代理可以编写SQL、执行查询、并将结果转换成图表或摘要。
  • 为何使用Stdio
    • 安全性:数据库凭证可能通过环境变量传递给MCP服务器,进程间通信(Stdio)比网络通信(SSE)更安全,数据不流经网络。
    • 独立性:每个分析师本地运行的AI应用都启动自己独立的数据库连接服务器,互不干扰。
    • 简单性:无需搭建和维护一个始终运行的“数据库查询服务”,即开即用。
  • 实现:MCP服务器是一个封装了数据库驱动和查询逻辑的Python脚本,通过Stdio由Spring AI应用启动。
(2). 本地代码库分析与重构工具
  • 业务描述:一个开发者使用IDE插件(基于Spring AI)与代码库交互。AI可以理解项目结构、检索特定文件、甚至根据要求生成重构代码。
  • 为何使用Stdio
    • 上下文绑定:这个工具紧密绑定到开发者当前打开的特定项目。每次打开新项目,都可能需要一个新的服务器实例来处理该项目的上下文。
    • 性能:文件系统操作是本地IO,通过Stdio通信延迟极低。
    • 无共享需求:不需要其他用户来访问我这个特定的项目代码库。
  • 实现:MCP服务器是一个用Rust或Go编写的二进制文件,内置了语法分析器,能够快速遍历和解析代码。IDE插件为每个项目工作区启动一个该服务器的实例。
(3). 个人日历/邮件管理助手
  • 业务描述:一个AI助手帮助用户管理日程(如:“把我明天下午两点到四点的会议标记为忙”)或分类邮件(如:“找出所有来自客户A的未读邮件并总结要点”)。
  • 为何使用Stdio
    • 凭证隔离:每个用户的OAuth令牌等敏感信息完全隔离在自己的本地进程中。
    • 隐私性强:用户的个人邮件和日历数据永远不会离开本地机器去连接一个远程服务。
    • 生命周期一致:用户关闭AI应用,对应的邮件/日历服务器进程也随之终止,不会在后台遗留任何可能泄露数据的进程。
  • 实现:MCP服务器是一个小型的、需要用户授权一次的应用,它直接调用Gmail或Outlook的API。每个用户运行自己的AI应用时都会启动自己的这个服务器。
3.2.2 适用 SSE (服务器发送事件) 的业务场景

这些场景的特点是:工具是共享的、中心化的、需要长期运行、并为多个消费者提供服务。

(1). 公司内部知识库问答
  • 业务描述:一个公司部署了一个内部的ChatGPT,所有员工都可以用它来查询员工手册、公司政策、技术文档、项目报告等。
  • 为何使用SSE
    • 中心化数据源:知识库(如Confluence, Notion)的索引和嵌入向量存储在一个中央服务器上,保持单一数据源,避免每个员工本地都复制一份巨大的索引。
    • 可维护性:知识库更新后,运维团队只需要更新一个中央MCP服务器,所有用户立即就能获取到最新信息。
    • 资源共享:一个强大的中央服务器可以同时为成百上千个员工客户端提供服务,经济高效。
  • 实现:一个长期运行的“知识库服务器”暴露了SSE端点。所有员工的AI客户端都配置连接到这个统一的服务器URL(如 http://knowledge-base-mcp:8000/sse)。
(2). 实时金融市场数据查询
  • 业务描述:交易员使用AI助手查询实时股票价格、外汇汇率、新闻情绪分析等。
  • 为何使用SSE
    • 实时数据流:SSE天生支持服务器向客户端“推送”实时数据流,非常适合金融市场这种数据持续变化的场景。
    • 连接外部数据源:中央MCP服务器维护着与Bloomberg、Reuters等昂贵数据源的单一、高效连接,并将其数据广播给所有授权的交易员客户端。
    • 权限控制:可以在中央服务器上统一实施复杂的权限管理(例如,谁可以访问哪些股票的数据)。
  • 实现:一个高性能的“市场数据服务器”订阅了多个数据feed,并将其通过MCP接口暴露。交易员的终端AI应用通过SSE连接到它。
(3). 共享的软件部署与运维(DevOps)工具集
  • 业务描述:开发者和运维人员通过AI指令来执行标准操作,如:“将微服务A部署到预发环境”或“重启欧洲区的所有API网关实例”。
  • 为何使用SSE
    • 集中化管控与审计:所有部署操作都必须通过一个中央网关进行,以便记录日志、审计跟踪和实施安全策略。不能允许每个人在本地都有部署权限。
    • 状态管理:中央服务器维护着基础设施的全局状态,避免多个本地客户端同时操作导致的状态冲突和竞态条件。
    • 高可用性:这个工具集需要7x24小时可用,不能因为某个用户关闭了本地客户端就停止服务。
  • 实现:一个“DevOps工具服务器”集成了Kubernetes、Terraform、Ansible等工具的API,并暴露为SSE端点。工程师们通过连接这个统一端口的AI客户端来执行操作。
3.2.3 小结总结对比
场景特征 Stdio 业务场景 SSE 业务场景
数据/资源 本地、个人化 共享、中心化
生命周期 短暂,随用户会话开始结束 长期运行,独立
部署模式 单机、桌面应用 客户端-服务器、微服务
主要优势 简单、安全、隐私 可维护、可扩展、资源共享
类比 单玩家游戏 大型多人在线游戏(MMO)
3.3 通信层设计
3.3.1 stdio协议
(1). 核心概念:它如何工作?

Stdio传输的核心思想是:MCP客户端(Client)和服务器(Server)是两个独立的本地进程。客户端作为“父进程”,启动服务器这个“子进程”,然后它们通过操作系统提供的标准输入(stdin)、标准输出(stdout)和标准错误(stderr)管道进行通信。

通用理解:

  • 传输层(Transport) :Stdio(标准输入/输出流)
  • 应用层协议(Protocol) :JSON-RPC 2.0
  • 数据格式(Format) :JSON

生命周期如下:

  1. 启动:MCP客户端(例如Spring AI应用)根据配置,使用指定的命令(如 python /path/to/server.py启动服务器进程。
  2. 连接:客户端获取到子进程的 stdin(用于向服务器数据)和 stdout(用于从服务器数据)流。
  3. 通信
    • 客户端 -> 服务器:将JSON-RPC消息写入服务器的 stdin
    • 客户端 <- 服务器:从服务器的 stdout 读取JSON-RPC消息。
  4. 日志:服务器的日志和错误信息会写入 stderr,通常由客户端捕获并记录,用于调试。
  5. 终止:当客户端退出或不再需要服务器时,它会终止服务器子进程。
(2). 协议细节:消息格式与交换

既然传输层是原始的字节流,就需要一个规则来界定每条消息的边界。MCP over Stdio 采用了一个非常简单且通用的标准。

1. 消息格式(Framing)

每条JSON-RPC消息都必须遵循以下格式,以确保接收方能正确解析:

  1. Header:一个必需的头部,格式为:Content-Length: <number>\r\n
    • <number> 是后面数据部分的字节长度(Byte Length),必须是十进制数字。
    • \r\n(回车换行)结束。
  2. Separator:一个额外的 \r\n 用来分隔头部和主体。
  3. Body:一个完整的JSON-RPC 2.0对象,其长度必须严格等于Header中声明的 <number>

格式模板:

Content-Length: <N>\r\n
\r\n
<JSON Data of exactly N bytes>

2. 一个完整的消息示例

假设服务器要发送这样一个JSON-RPC通知:

{"jsonrpc": "2.0", "method": "log", "params": {"message": "Server started!"}}
  1. 计算Body的字节长度(假设使用UTF-8编码)。这个字符串的长度是 75 字节。
  2. 构建整个消息:
Content-Length: 75\r\n
\r\n
{"jsonrpc": "2.0", "method": "log", "params": {"message": "Server started!"}}

(注意:第二行是两个字符 \r\n,不是一个空行。最后一行没有 \r\n)

这个完整的字节序列会被写入 stdout。客户端则从 stdout 读取数据,先解析 Content-Length 头,知道接下来要读取75个字节,然后读取这75个字节并将其解析为JSON。

(3). 会话流程示例

简单的MCP初始化会话。

  1. 客户端启动服务器:执行命令 python mcp_server.py
  2. 服务器发送初始化消息stdout
    Content-Length: 180\r\n
    \r\n
    {
      "jsonrpc": "2.0",
      "method": "initialize",
      "params": {
        "protocolVersion": "2024-11-05",
        "capabilities": {},
        "clientInfo": { "name": "My Client", "version": "1.0" }
      },
      "id": 1
    }
    
  3. 客户端响应初始化stdin
    Content-Length: 125\r\n
    \r\n
    {
      "jsonrpc": "2.0",
      "id": 1,
      "result": {
        "protocolVersion": "2024-11-05",
        "capabilities": {},
        "serverInfo": { "name": "My Server", "version": "1.0" }
      }
    }
    
  4. 客户端通知服务器初始化完成stdin
    Content-Length: 65\r\n
    \r\n
    {"jsonrpc":"2.0","method":"initialized","params":{}}
    
  5. 此后,双方可以自由地进行请求(Request)、响应(Response)和通知(Notification) 。例如,客户端请求列出所有工具:
    Content-Length: 55\r\n
    \r\n
    {"jsonrpc":"2.0","id":"2","method":"tools/list"}
    
    服务器响应:
    Content-Length: 120\r\n
    \r\n
    {"jsonrpc":"2.0","id":"2","result":{"tools":[{"name":"my_tool","description":"A great tool","inputSchema":{}}]}}
    
(4).为什么MCP选择Stdio?
  1. 极致的简单性:无需处理网络端口、防火墙、SSL证书等复杂问题。对于本地工具来说,这是最简单的连接方式。
  2. 强大的安全性:通信完全发生在机器内部的进程之间,数据不会暴露在网络上。非常适合处理敏感数据(如个人文档、本地环境信息)。
  3. 完美的生命周期管理:客户端对服务器拥有完全的控制权。“同生共死”的模式非常适合作为应用程序的一个集成功能。
  4. 跨平台兼容性:几乎所有编程语言都支持启动子进程并与其stdin/stdout交互。
  5. 天然隔离:每个客户端实例都可以启动自己独立的服务器进程,彼此完全隔离,不会相互干扰。
3.3.3 sse 协议
(1). 核心概念

SSE(Server-Sent Events) 协议本身。一种非常简单、高效且标准的基于HTTP的轻量级协议,用于实现服务器到客户端的单向数据流(Server-to-Client Streaming)

SSE 的核心目的很简单:让服务器能够通过一个持久的HTTP连接,主动向客户端(通常是Web浏览器)推送数据。

它与WebSocket不同:

  • SSE:是单向的(服务器 -> 客户端)。客户端发起连接,服务器可以随时发送消息。
  • WebSocket:是双向的(服务器 <-> 客户端),更像一个TCP Socket,双方可以随时相互发送消息。

对于MCP这类场景(客户端发送一个请求,服务器流式返回一系列事件),SSE 的单向特性完全足够,且实现起来更简单。

(1). 技术细节:如何工作?

1. 客户端行为 (The Client)

客户端(如浏览器中的JavaScript或Spring AI应用)的行为非常简单:

  1. 使用 EventSource API 向服务器的一个特定URL发起一个普通的 HTTP GET 请求。
  2. 这个请求会包含一个标准的 Header:Accept: text/event-stream,告诉服务器“我希望能接收事件流”。
  3. 客户端然后保持这个连接打开,等待服务器发送数据。

示例代码 (JavaScript):

const eventSource = new EventSource('http://localhost:8000/sse');

eventSource.onmessage = (event) => {
  // 当收到服务器发来的消息时触发
  console.log('New message:', event.data);
};

eventSource.onerror = (error) => {
  // 处理错误(如连接中断)
  console.error('EventSource error:', error);
};

2. 服务器行为 (The Server)

服务器的响应非常关键,必须遵循SSE的格式:

  1. 状态码:返回 HTTP 200 OK 状态码。

  2. Headers:设置两个重要的响应头(Response Headers):

    • Content-Type: text/event-stream:声明这是一个事件流。
    • Cache-Control: no-cache:确保数据不被缓存。
    • Connection: keep-alive:保持连接活跃。
  3. 响应体(Body) :不再是一个完整的JSON对象,而是一个流式文本。这个文本由一系列遵循特定格式的“消息”组成,每条消息以两个换行符 \n\n 结尾。

(3). SSE 消息格式

这是SSE协议的核心。服务器发送的每条消息由以下几类字段组成(字段名不分大小写),每个字段后跟一个换行符 \n

字段 描述 示例 说明
data: 消息的内容。是唯一必需的字段。 data: {"text": "Hello"} 如果内容有多行,可以用多个 data: 行。
event: 事件类型。一个自定义的字符串标识符。 event: status_update 客户端可以根据不同事件类型触发不同的监听器。默认是 message
id: 消息ID。用于重连机制。 id: 12345 客户端断线重连时,会通过 Last-Event-ID 头告知服务器最后收到的ID。
retry: 重连时间。建议客户端断线后多久(毫秒)重连。 retry: 3000 不是指令,只是建议。
: 注释行。服务器发送的注释,会被客户端忽略。 : This is a comment 常用于保持连接活跃(发送心跳)。

一条完整的消息以两个换行符 \n\n 结束。

(4). 一个完整的SSE会话示例

让我们看一个MCP服务器可能返回的SSE流示例。假设客户端请求列出可用的工具。

客户端请求:

GET /sse HTTP/1.1
Host: localhost:8000
Accept: text/event-stream
Cache-Control: no-cache

服务器响应流:

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive

# 服务器开始发送流式消息:
event: result
data: {"jsonrpc": "2.0", "result": {"tools": ["tool_a", "tool_b"]}, "id": 1}

# 过了一会儿,服务器推送一个通知(不需要客户端请求):
event: notification
data: {"jsonrpc": "2.0", "method": "log", "params": {"message": "Server is healthy"}}

# 发送一个心跳包(注释),防止连接超时
: ping

# 另一条正儿八经的响应
event: result
data: {"jsonrpc": "2.0", "result": {"thought": "I'm thinking...", "output": "Done!"}, "id": 2}

(注意:在实际的MCP中,data 字段的内容是严格的JSON-RPC消息格式)

客户端解析:

  1. 收到第一条消息,eventresult,数据是一个JSON-RPC响应,id: 1 对应客户端之前发送的某个请求。
  2. 收到第二条消息,eventnotification,这是一个服务器主动发起的日志通知。
  3. 忽略注释行 : ping
  4. 收到最后一条消息,id2 的请求的响应。
(5). 为什么MCP选择SSE?
  1. 基于HTTP:无需引入像WebSocket (ws://) 这样的新协议,更容易在现有的网络基础设施、代理和防火墙中部署和调试。
  2. 内置重连机制:通过 idretry 字段,SSE协议原生支持断线重连和消息恢复,提供了很好的鲁棒性。
  3. 简单性:文本格式非常人类可读,易于实现和调试。服务器端不需要复杂的帧处理逻辑。
  4. 完美匹配“请求-流式响应”模型:MCP的交互模式是客户端发送一个JSON-RPC请求,服务器可能会流式地返回多个中间事件(如思考过程、进度更新),最后是一个完成事件。SSE天然适合这种“一个请求,多个响应事件”的模式。

4. MCP 客户端

在这里插入图片描述

MCP客户端是模型上下文协议(MCP)架构中的核心组件,负责建立和管理与MCP服务器的连接。它实现了协议客户端功能,具体包括:

  • 协议版本协商以确保与服务器的兼容性
  • 能力协商以确定可用功能
  • 消息传输与JSON-RPC通信
  • 工具发现与执行
  • 资源访问与管理
  • 提示词系统交互
  • 可选功能:
    • 根节点管理
    • 采样支持
  • 同步与异步操作
  • 传输选项:
    • 基于Stdio的进程间通信传输
    • 基于Java HttpClient的SSE客户端传输
    • 支持响应式HTTP流式传输的WebFlux SSE客户端传输
4.1 Spring AI MCP 客户端整合
  • spring-ai-starter-mcp-client - Core starter providing STDIO and HTTP-based SSE support
  • spring-ai-starter-mcp-client-webflux - WebFlux-based SSE transport implementation

5. MCP 服务端

在这里插入图片描述

MCP服务器是模型上下文协议(MCP)架构中的基础组件,为客户端提供工具、资源和能力。它实现了协议的服务端功能,具体负责:

  • 服务端协议操作实现
    • 工具暴露与发现
    • 基于URI访问的资源管理
    • 提示词模板的提供与处理
    • 与客户端的能力协商
    • 结构化日志记录与通知
  • 并发客户端连接管理
  • 同步与异步API支持
  • 传输实现方案:
    • 基于Stdio的进程间通信传输
    • 基于Servlet的SSE服务端传输
    • 支持响应式HTTP流式传输的WebFlux SSE服务端传输
    • 基于Servlet HTTP流式传输的WebMVC SSE服务端传输
5.1 Spring AI MCP 服务端整合
  • spring-ai-starter-mcp-server - Core server with STDIO transport support
  • spring-ai-starter-mcp-server-webmvc - Spring MVC-based SSE transport implementation
  • spring-ai-starter-mcp-server-webflux - WebFlux-based SSE transport implementation

三、总体协议格式 (The Frame)

MCP 的通信建立在 JSON-RPC 2.0 之上。这意味着所有在 Client 和 Server 之间传输的消息,无论是请求、响应还是通知,都遵循一个固定的顶层结构。

所有消息都必须是以下四种类型之一:

  1. Request (请求) : 期望得到响应的消息。
  2. Response (响应) : 对请求的成功回复。
  3. Error (错误) : 对请求的错误回复。
  4. Notification (通知) : 不期望得到响应的消息。

固定格式如下:

类型 必需字段 说明 示例 (简化)
Request jsonrpc, id, method, params 调用一个方法 {"jsonrpc": "2.0", "id": 1, "method": "tools/list", "params": {...}}
Response jsonrpc, id, result 请求成功返回 {"jsonrpc": "2.0", "id": 1, "result": {...}}
Error jsonrpc, id, error 请求失败返回 {"jsonrpc": "2.0", "id": 1, "error": {"code": -32601, "message": "Method not found"}}
Notification jsonrpc, method, params 发送一个事件 {"jsonrpc": "2.0", "method": "notifications/resources/updated", "params": {...}}

关键点:

  • jsonrpc: 永远为 "2.0"
  • id: 请求和响应/错误的唯一关联ID(字符串或数字)。
  • method: 要调用的方法名称,格式为 "category/action"(如 "tools/call")。
  • params: 调用方法所需的参数(对象)。
  • result: 成功响应时返回的数据(对象)。
  • error: 错误响应时返回的错误信息(对象)。

1. 消息类型

MCP协议中存在两个层次的消息类型:

  1. 传输层格式 (Wire Format - 4种) :这是JSON-RPC 2.0标准定义的、在线路上实际传输的底层帧类型。所有MCP消息都必须被包装成这4种之一才能进行传输。
  2. 应用层消息类型 (Application Message Types - 远多于4种) :这是MCP协议在JSON-RPC之上定义的具体业务消息。它们决定了method是什么、paramsresult的结构如何。这才是关心的“不同业务的请求与响应数据格式”。
1.1 传输层格式 (4种基础类型)

schema.ts 中,这4种基础类型被明确定义:

// 1. 请求 (期望响应)
export interface JSONRPCRequest extends Request {
  jsonrpc: typeof JSONRPC_VERSION; // "2.0"
  id: RequestId; // 必需
  method: string;
  params?: {...};
}

// 2. 通知 (不期望响应)
export interface JSONRPCNotification extends Notification {
  jsonrpc: typeof JSONRPC_VERSION; // "2.0"
  method: string;
  params?: {...};
}

// 3. 成功响应
export interface JSONRPCResponse {
  jsonrpc: typeof JSONRPC_VERSION; // "2.0"
  id: RequestId; // 必需,与请求ID对应
  result: Result; // 必需
}

// 4. 错误响应
export interface JSONRPCError {
  jsonrpc: typeof JSONRPC_VERSION; // "2.0"
  id: RequestId; // 必需,与请求ID对应
  error: { // 必需
    code: number;
    message: string;
    data?: unknown;
  };
}

结论:在线上传输的每一帧,确实是这4种JSON-RPC 2.0基本类型之一。可以将它们视为承载MCP具体内容的信封

1.2 应用层消息类型 (海量业务类型)

MCP协议的核心在于它定义了大量的具体method及其对应的paramsresult结构。这些才是真正的“功能设计”。

以下是完整的分类统计:

类别 方向 消息类型 (method) TypeScript 接口名 (请求/通知) TypeScript 接口名 (响应) 数量
初始化 C→S "initialize" InitializeRequest InitializeResult 1
C→S "notifications/initialized" InitializedNotification - 1
资源 C→S "resources/list" ListResourcesRequest ListResourcesResult 1
C→S "resources/templates/list" ListResourceTemplatesRequest ListResourceTemplatesResult 1
C→S "resources/read" ReadResourceRequest ReadResourceResult 1
C→S "resources/subscribe" SubscribeRequest EmptyResult 1
C→S "resources/unsubscribe" UnsubscribeRequest EmptyResult 1
S→C "notifications/resources/updated" ResourceUpdatedNotification - 1
S→C "notifications/resources/list_changed" ResourceListChangedNotification - 1
工具 C→S "tools/list" ListToolsRequest ListToolsResult 1
C→S "tools/call" CallToolRequest CallToolResult 1
S→C "notifications/tools/list_changed" ToolListChangedNotification - 1
提示词 C→S "prompts/list" ListPromptsRequest ListPromptsResult 1
C→S "prompts/get" GetPromptRequest GetPromptResult 1
S→C "notifications/prompts/list_changed" PromptListChangedNotification - 1
采样 S→C "sampling/createMessage" CreateMessageRequest CreateMessageResult 1
补全 C→S "completion/complete" CompleteRequest CompleteResult 1
根目录 S→C "roots/list" ListRootsRequest ListRootsResult 1
C→S "notifications/roots/list_changed" RootsListChangedNotification - 1
征询 S→C "elicitation/create" ElicitRequest ElicitResult 1
日志 C→S "logging/setLevel" SetLevelRequest EmptyResult 1
S→C "notifications/message" LoggingMessageNotification - 1
通用 C↔S "ping" PingRequest EmptyResult 1
C↔S "notifications/progress" ProgressNotification - 1
C↔S "notifications/cancelled" CancelledNotification - 1

EmptyResult 是一种特殊的响应类型,表示成功但无具体数据返回。C→S表示Client to Server,S→C表示Server to Client,C↔S表示双向。

最终结论

  1. 传输格式是固定的4种:所有MCP业务消息都必须使用 JSONRPCRequest, JSONRPCResponse, JSONRPCError, JSONRPCNotification 这4种JSON-RPC 2.0格式进行封装和传输。
  2. 业务消息是多样的:MCP协议在之上定义了至少29种具体的请求/通知类型(由method字段区分)和15种响应类型,总共 44种 具体的应用层消息结构。这才是协议功能丰富性的体现。

四、功能场景 (业务请求与响应)

MCP 协议包含了10个核心功能领域,每个领域下包含若干种请求(Request)、响应(Result)和通知(Notification)。以下是完整的分类和清单:

1. 初始化 (Initialization)

在这里插入图片描述

  • 要解决的问题:Client 和 Server 如何安全地建立连接?如何协商双方都支持的协议版本和功能?如何识别对方身份?
  • 具体作用
    • 能力交换 (capabilities) :Client 和 Server 互相告知自己支持哪些功能(如是否支持工具、资源、日志等)。这是后续所有交互的基础,避免调用对方不支持的接口。
    • 版本协商 (protocolVersion) :确保双方使用兼容的 MCP 协议版本进行通信。
    • 身份识别 (clientInfo, serverInfo) :交换名称和版本信息,用于日志记录和调试。
    • 指令传递 (instructions) :Server 可以向 Client 提供一段文本说明,Client 可能会将其加入 LLM 的系统提示词中,帮助 LLM 更好地理解如何使用这个 Server。
  • 目的: 建立连接,交换版本信息和双方能力。
  • 请求: InitializeRequest (method: "initialize")
  • 响应: InitializeResult
  • 通知: InitializedNotification (method: "notifications/initialized") - 客户端告知服务器初始化已完成。

2. 资源管理 (Resources)

在这里插入图片描述

  • 要解决的问题:如何让 LLM 安全地读取外部数据(如代码库、文档、数据库记录),而无需让其直接访问文件系统或数据库?
  • 具体作用
    • 发现 (list, templates/list) :Client 可以浏览 Server 提供了哪些数据资源。资源模板(URI Templates)允许通过参数化动态构造资源路径(如 github://owner/{repo}/issues)。
    • 读取 (read) :Client 请求读取某个特定 URI 的资源内容(如 file:///project/src/main.js)。Server 负责执行实际的读取操作,并将内容以安全的方式(文本或 Base64 编码的二进制数据)返回给 Client。
    • 订阅/通知 (subscribe, unsubscribe, updated) :Client 可以订阅它关心的资源。当该资源发生变化时(如文件被修改),Server 会主动推送通知,Client 可以据此决定是否重新读取。这解决了数据新鲜度的问题。
  • 目的: 服务器向客户端提供可读取的数据资源(如文件、数据库内容)。
  • 请求:
    • ListResourcesRequest (method: "resources/list") - 列出可用资源
    • ListResourceTemplatesRequest (method: "resources/templates/list") - 列出资源URI模板
    • ReadResourceRequest (method: "resources/read") - 读取特定资源内容
    • SubscribeRequest (method: "resources/subscribe") - 订阅资源更新
    • UnsubscribeRequest (method: "resources/unsubscribe") - 取消订阅
  • 响应:
    • ListResourcesResult
    • ListResourceTemplatesResult
    • ReadResourceResult
  • 通知:
    • ResourceUpdatedNotification (method: "notifications/resources/updated") - 服务器告知客户端某个资源已更新
    • ResourceListChangedNotification (method: "notifications/resources/list_changed") - 服务器告知客户端资源列表已变更

3. 工具调用 (Tools)

在这里插入图片描述

  • 要解决的问题:如何让 LLM 安全地执行操作(如运行代码、调用 API、操作数据库),而无需赋予其直接执行系统命令的权限?
  • 具体作用
    • 发现 (list) :Client 浏览 Server 提供了哪些可调用的函数(工具)。
    • 调用 (call) :LLM 根据上下文决定调用哪个工具并生成参数,Client 代为执行调用。Server 执行实际操作并返回结果。
    • 安全与控制
      • 输入验证:每个工具都定义了 inputSchema(JSON Schema),Server 会严格校验参数,防止非法调用。
      • 权限隔离:工具的执行被限制在 Server 的沙箱环境中,Server 决定了工具实际能访问的系统权限。
      • 错误处理:工具本身的错误会在 CallToolResult 中返回(isError: true),而不是导致整个 MCP 连接中断,这让 LLM 有机会得知错误并进行自我修正。
  • 目的: 服务器向客户端提供可执行的函数(工具),客户端(AI)可以决定调用它们。
  • 请求:
    • ListToolsRequest (method: "tools/list") - 列出可用工具
    • CallToolRequest (method: "tools/call") - 调用一个工具
  • 响应:
    • ListToolsResult
    • CallToolResult - 包含工具执行后的结构化(structuredContent)和非结构化(content)结果
  • 通知:
    • ToolListChangedNotification (method: "notifications/tools/list_changed") - 服务器告知客户端工具列表已变更

4. 提示词模板 (Prompts)

在这里插入图片描述

  • 要解决的问题:如何让 LLM 应用的最佳实践(精心设计的提示词)得以复用和共享,而不是每次都由用户或开发者重新编写?
  • 具体作用
    • 模板库 (list) :Server 可以提供一个预定义的、高质量的提示词模板库(如“代码审查”、“总结文档”、“生成单元测试”)。
    • 渲染与获取 (get) :Client 可以通过名称请求一个模板,并提供参数(arguments),Server 返回一个已经填充好的、可直接使用的消息列表(messages)。这极大地提升了提示工程的可维护性和一致性。
  • 目的: 服务器提供预定义的提示词模板,客户端可以填充参数后使用。
  • 请求:
    • ListPromptsRequest (method: "prompts/list") - 列出提示词模板
    • GetPromptRequest (method: "prompts/get") - 获取一个模板的具体内容
  • 响应:
    • ListPromptsResult
    • GetPromptResult - 包含填充好的消息列表(messages)
  • 通知:
    • PromptListChangedNotification (method: "notifications/prompts/list_changed") - 服务器告知客户端提示词列表已变更

5. 采样 (Sampling) - 由Server发起

在这里插入图片描述

  • 要解决的问题:如果 Server 需要 LLM 的帮助来完成其任务该怎么办?(例如,一个代码分析工具可能需要 LLM 来解释一段复杂代码的功能)。MCP 是双向的,Server 也能“使用” Client 的 LLM 能力。
  • 具体作用
    • 反向请求:Server 可以向 Client 发起请求,要求使用 LLM 生成内容。
    • 人机回环 (Human-in-the-loop) :这个请求通常需要经过用户确认(查看请求内容并批准),解决了自动调用 LLM 可能带来的成本和不可控问题。
    • 模型偏好:Server 可以表达它对模型的选择偏好(如更智能的、更快的或更便宜的),但最终决定权在 Client 和用户手中。
  • 目的: 服务器请求客户端使用LLM生成内容。这是MCP双向通信的体现,服务器也可以“调用”客户端的能力。
  • 请求: CreateMessageRequest (method: "sampling/createMessage") - 服务器请求客户端采样LLM
  • 响应: CreateMessageResult - 客户端返回LLM生成的结果

6. 自动补全 (Completion)

在这里插入图片描述

  • 要解决的问题:在填充提示词参数或资源模板时,如何为用户或 Client 提供智能的自动补全建议,以提升体验和准确性?
  • 具体作用
    • 上下文感知的补全:Client 告诉 Server 正在为哪个提示词或资源模板的哪个参数进行补全,并提供已输入的值。Server 可以根据当前上下文返回最相关的补全选项列表(如补全文件名、函数名、API 端点等)。
  • 目的: 为提示词或资源模板的参数提供自动补全建议。
  • 请求: CompleteRequest (method: "completion/complete")
  • 响应: CompleteResult - 包含补全选项列表(values)

7. 根目录管理 (Roots) - 由Server发起

在这里插入图片描述

  • 要解决的问题:许多工具和资源需要基于文件系统工作(如代码库操作)。Server 如何知道它被允许在哪些目录下工作?如何避免越权访问?
  • 具体作用
    • 安全的工作区界定:Server 向 Client 询问其有权访问的“根目录”列表(例如,用户在 IDE 中打开的项目文件夹)。
    • 权限控制:Client(代表用户)明确地告诉 Server 它的工作边界在哪里(file:///path/to/my/project)。Server 只能在这些约定的目录内进行操作,完美解决了安全边界问题。
  • 目的: 服务器向客户端查询其有权访问的文件系统根目录(如工作区文件夹)。
  • 请求: ListRootsRequest (method: "roots/list") - 服务器请求客户端列出根目录
  • 响应: ListRootsResult - 客户端返回根目录列表
  • 通知: RootsListChangedNotification (method: "notifications/roots/list_changed") - 客户端告知服务器根目录列表已变更

8. 信息征询 (Elicitation) - 由Server发起

在这里插入图片描述

  • 要解决的问题:当 Server 执行一个操作需要更多信息或用户确认时(例如,“你要删除这个文件吗?”或“请提供你的 API 密钥”),它如何与用户交互?
  • 具体作用
    • 与用户交互的通道:Server 可以通过 Client 向用户弹出一个表单或对话框,征询必要信息或确认。
    • 结构化输入:通过 requestedSchema 定义需要收集的信息的结构(仅限原始类型,如字符串、数字、枚举),确保输入的有效性和明确性。
  • 目的: 服务器通过客户端向用户征询更多信息(例如弹出一个表单让用户填写)。
  • 请求: ElicitRequest (method: "elicitation/create") - 服务器请求客户端向用户征询信息
  • 响应: ElicitResult - 客户端返回用户的操作结果(接受/拒绝/取消)和表单数据

9. 日志 (Logging)

在这里插入图片描述

  • 要解决的问题:如何监控和调试 Server 的运行状态?如何让 Server 向用户报告信息、警告和错误?
  • 具体作用
    • 可观测性:Server 可以将内部日志信息发送给 Client,Client 可以将其展示在控制台或日志窗口中,方便开发者调试 Server 的行为。
    • 级别控制:Client 可以动态地设置 Server 的日志级别(如从 debugerror),以控制日志的详细程度。
  • 目的: 服务器向客户端发送日志消息,客户端可以控制日志级别。
  • 请求: SetLevelRequest (method: "logging/setLevel") - 客户端设置服务器日志级别
  • 通知: LoggingMessageNotification (method: "notifications/message") - 服务器向客户端发送一条日志

10. 通用与维护 (Utilities)

在这里插入图片描述

  • 要解决的问题:如何维护连接的健康度?如何管理长时间运行的操作?
  • 具体作用
    • 心跳检测 (ping) :用于检查对端是否依然存活,防止连接僵死。
    • 进度报告 (progress) :对于耗时长的操作(如处理大文件),Server 可以定期向 Client 发送进度通知,让用户知道操作仍在进行中。
    • 取消操作 (cancelled) :用户或 Client 可以主动取消一个正在进行的请求,Server 接收到后应尽力停止相关操作以节省资源。
  • 目的: 连接维护、进度报告和取消操作。
  • 请求: PingRequest (method: "ping") - 心跳检测,可由任何一方发起
  • 响应: EmptyResult - 对Ping等的空响应
  • 通知:
    • ProgressNotification (method: "notifications/progress") - 报告长时间运行操作的进度
    • CancelledNotification (method: "notifications/cancelled") - 取消一个正在进行的请求(可由任何一方发起)

11. 小结总结

(1). 协议层展示了MCP协议的核心特点:

  1. 总体格式: MCP 严格遵循 JSON-RPC 2.0 规范,所有消息都封装在 Request, Response, Error, Notification 这四种固定格式中。
  2. 功能数量: 协议涵盖了 10个大类 的功能场景(初始化、资源、工具、提示词、采样、补全、根目录、征询、日志、通用)。
  3. 双向性: 这是一个双向协议。虽然大部分请求由 Client 发起(如读资源、调用工具),但 Server 也可以主动向 Client 发起请求(如 sampling/createMessage, roots/list, elicitation/create),这使得 Server 的能力非常强大。
  4. 扩展性: 通过 experimental 字段和未定义的 _meta 字段,协议保留了良好的扩展性。

(2).流程图展示了MCP协议的核心特点:

  1. 双向性:采样、根目录、征询等功能由Server主动发起
  2. 安全性:通过初始化协商、根目录界定等机制确保安全边界
  3. 异步性:通过订阅和通知机制实现实时更新
  4. 结构化:所有输入输出都有严格的结构定义(Schema)
  5. 用户参与:关键操作(如采样、征询)需要用户确认,体现"人机回环"设计

(3).MCP 的每个类别都像是一块精心设计的积木,共同构建了一个安全、强大且灵活的系统:

  • Resources & Tools 是核心,提供了 数据功能
  • Prompts & Completion 提升了 易用性和智能化
  • Initialization 确保了连接的 安全性和可靠性
  • Sampling, Roots, Elicitation 实现了 双向通信,让 Server 也变得强大而智能。
  • Logging & Utilities 提供了 可观测性和可维护性

最终,所有这些设计都服务于同一个目标:在绝对的安全边界内,最大限度地扩展 LLM 的能力

五、10大功能场景业务案例说明

1. 智能代码助手平台

1.1 业务场景描述

Acme Corp 开发了一个智能代码助手平台。开发者使用 VS Code 插件(Client) 与公司内部的 AI 编程助手 Server 交互。这个 Server 为开发者提供智能编程支持。

1.2 MCP 交互流程
1. 初始化 (Initialization) - 建立安全连接

场景:开发者启动 VS Code,插件连接到公司的代码助手 Server。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "init_001",
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": {},
      "resources": {},
      "sampling": {},
      "roots": {
        "listChanged": true
      }
    },
    "clientInfo": {
      "name": "vscode-code-helper",
      "version": "1.4.2",
      "title": "VS Code智能编程助手"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "init_001",
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "tools": {
        "listChanged": true
      },
      "resources": {
        "subscribe": true,
        "listChanged": true
      },
      "prompts": {
        "listChanged": true
      },
      "logging": {}
    },
    "serverInfo": {
      "name": "acme-code-assistant",
      "version": "2.3.1",
      "title": "Acme智能代码助手"
    },
    "instructions": "我可以帮助你编写代码、审查代码、生成测试用例、重构代码和解释复杂逻辑。请告诉我你需要什么帮助。"
  }
}
2. 根目录 (Roots) - 界定工作边界

场景:Server 需要知道能在哪里工作。
在这里插入图片描述

请求 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "roots_001",
  "method": "roots/list",
  "params": {
    "_meta": {
      "progressToken": "roots_progress_123"
    }
  }
}

响应 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "roots_001",
  "result": {
    "roots": [
      {
        "uri": "file:///Users/developer/projects/acme-app",
        "name": "acme-app项目",
        "_meta": {
          "projectType": "python"
        }
      },
      {
        "uri": "file:///Users/developer/projects/shared-lib",
        "name": "共享库",
        "_meta": {
          "projectType": "typescript"
        }
      }
    ]
  }
}
3. 资源 (Resources) - 获取代码上下文

场景:开发者问:“帮我分析当前文件的main函数”

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "read_001",
  "method": "resources/read",
  "params": {
    "uri": "file:///Users/developer/projects/acme-app/src/main.py",
    "_meta": {
      "purpose": "code_analysis"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "read_001",
  "result": {
    "contents": [
      {
        "uri": "file:///Users/developer/projects/acme-app/src/main.py",
        "mimeType": "text/x-python",
        "text": "def main():\n    print("Hello, World!")\n    result = calculate_sum(10, 20)\n    print(f"Result: {result}")\n\ndef calculate_sum(a, b):\n    return a + b\n\nif __name__ == "__main__":\n    main()",
        "annotations": {
          "audience": ["assistant"],
          "priority": 0.9
        }
      }
    ]
  }
}
4. 工具 (Tools) - 执行代码操作

场景:AI 建议:“需要我帮你重构这个函数吗?”

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "tool_001",
  "method": "tools/call",
  "params": {
    "name": "refactor_function",
    "arguments": {
      "file_path": "src/main.py",
      "function_name": "calculate_sum",
      "refactor_type": "add_type_hints",
      "complexity": "simple"
    },
    "_meta": {
      "progressToken": "refactor_progress_456"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "tool_001",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "已成功为函数 calculate_sum 添加类型提示",
        "annotations": {
          "audience": ["user"]
        }
      }
    ],
    "structuredContent": {
      "refactored_code": "def calculate_sum(a: int, b: int) -> int:\n    return a + b",
      "original_code": "def calculate_sum(a, b):\n    return a + b",
      "changes_made": ["added_type_hints"]
    },
    "isError": false
  }
}
5. 提示词 (Prompts) - 使用最佳实践

场景:开发者想要生成单元测试。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "prompt_001",
  "method": "prompts/get",
  "params": {
    "name": "generate_unit_test",
    "arguments": {
      "language": "python",
      "function_name": "calculate_sum",
      "test_framework": "pytest",
      "complexity": "comprehensive"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "prompt_001",
  "result": {
    "description": "为Python函数生成全面的pytest单元测试",
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "请为以下Python函数生成全面的pytest单元测试,包含正常情况和边界情况测试:\n\ndef calculate_sum(a: int, b: int) -> int:\n    return a + b\n\n要求:\n1. 使用pytest框架\n2. 包含至少5个测试用例\n3. 包含边界值测试\n4. 包含错误情况测试(如果适用)\n5. 使用清晰的测试命名"
        }
      }
    ]
  }
}
6. 采样 (Sampling) - Server 寻求帮助

场景:Server 在代码分析中遇到复杂逻辑,需要 LLM 帮助理解。

在这里插入图片描述

请求 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "sample_001",
  "method": "sampling/createMessage",
  "params": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "请解释以下代码片段的算法复杂度,并用大O表示法表示:\n\ndef find_duplicates(items):\n    seen = set()\n    duplicates = []\n    for item in items:\n        if item in seen:\n            duplicates.append(item)\n        else:\n            seen.add(item)\n    return duplicates"
        }
      }
    ],
    "maxTokens": 500,
    "temperature": 0.3,
    "systemPrompt": "你是一个专业的计算机科学教授,擅长分析算法复杂度。",
    "includeContext": "thisServer",
    "modelPreferences": {
      "hints": [{"name": "claude"}],
      "intelligencePriority": 0.9,
      "speedPriority": 0.2
    }
  }
}

响应 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "sample_001",
  "result": {
    "role": "assistant",
    "content": {
      "type": "text",
      "text": "这个算法的复杂度是O(n),其中n是输入列表items的长度。\n\n分析:\n1. 遍历列表一次:O(n)\n2. 集合的查找和插入操作平均都是O(1)\n3. 列表追加操作平均是O(1)\n\n因此总体时间复杂度是线性的O(n)。空间复杂度也是O(n),因为最坏情况下需要存储所有元素。"
    },
    "model": "claude-3-sonnet-20240229",
    "stopReason": "endTurn"
  }
}
7. 补全 (Completion) - 智能代码补全

场景:开发者在输入代码时,需要智能补全。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "complete_001",
  "method": "completion/complete",
  "params": {
    "ref": {
      "type": "ref/resource",
      "uri": "file:///Users/developer/projects/acme-app/src/utils.py"
    },
    "argument": {
      "name": "import_statement",
      "value": "from utils im"
    },
    "context": {
      "arguments": {
        "current_file": "src/main.py",
        "project_type": "python"
      }
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "complete_001",
  "result": {
    "completion": {
      "values": [
        "from utils import calculate_sum",
        "from utils import format_result",
        "from utils import validate_input",
        "from utils import *"
      ],
      "total": 8,
      "hasMore": true
    }
  }
}
8. 征询 (Elicitation) - 获取用户输入

场景:Server 需要用户决定重构策略。

在这里插入图片描述

请求 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "elicit_001",
  "method": "elicitation/create",
  "params": {
    "message": "检测到calculate_sum函数可能需要进行性能优化。请选择优化策略:",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "optimization_strategy": {
          "type": "string",
          "title": "优化策略",
          "description": "选择性能优化方法",
          "enum": ["memoization", "vectorization", "parallelization", "algorithm_change"],
          "enumNames": ["记忆化缓存", "向量化计算", "并行处理", "算法变更"]
        },
        "urgency": {
          "type": "string",
          "title": "紧急程度",
          "description": "优化任务的紧急程度",
          "enum": ["high", "medium", "low"],
          "enumNames": ["高", "中", "低"]
        }
      },
      "required": ["optimization_strategy"]
    }
  }
}

响应 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "elicit_001",
  "result": {
    "action": "accept",
    "content": {
      "optimization_strategy": "memoization",
      "urgency": "medium"
    }
  }
}
9. 日志 (Logging) - 监控与调试

场景:监控 Server 的运行状态。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "log_001",
  "method": "logging/setLevel",
  "params": {
    "level": "debug"
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "log_001",
  "result": {}
}

通知 (Server → Client):

{
  "jsonrpc": "2.0",
  "method": "notifications/message",
  "params": {
    "level": "info",
    "logger": "code_analyzer",
    "data": "开始静态代码分析,正在解析AST..."
  }
}
10. 通用与维护 (Utilities) - 连接维护

场景:保持连接健康,管理长时间操作。

在这里插入图片描述

心跳检测 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "ping_001",
  "method": "ping"
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "ping_001",
  "result": {}
}

进度通知 (Server → Client):

{
  "jsonrpc": "2.0",
  "method": "notifications/progress",
  "params": {
    "progressToken": "refactor_progress_456",
    "progress": 75,
    "total": 100,
    "message": "正在应用代码重构更改..."
  }
}

取消通知 (Client → Server):

{
  "jsonrpc": "2.0",
  "method": "notifications/cancelled",
  "params": {
    "requestId": "tool_001",
    "reason": "用户手动取消了重构操作"
  }
}
11. 小结总结:一个完整的智能编程会话
  1. 初始化建立安全连接
  2. 根目录界定工作边界
  3. 资源获取代码文件
  4. 工具执行代码重构
  5. 提示词使用最佳实践生成测试
  6. 采样Server 寻求 LLM 帮助理解复杂代码
  7. 补全为开发者提供智能代码建议
  8. 征询让用户做出重要决策
  9. 日志监控整个流程的运行状态
  10. 通用功能确保连接稳定和操作可控

这个案例展示了 MCP 如何在一个真实的业务场景中协调工作,为开发者提供安全、智能、高效的编程辅助体验。每个功能都解决了特定环节的具体问题,共同构成了一个完整的智能编程解决方案。

2. 智能电商数据分析平台

2.1 业务场景描述

StyleHub 是一家时尚电商公司,他们使用 数据分析仪表板(Client) 与内部的 智能商业分析 Server 交互。这个 Server 为业务团队提供数据查询、分析和洞察服务。

2.2 MCP 交互流程
1. 初始化 (Initialization) - 建立安全连接

场景:业务分析师打开数据分析仪表板,系统连接到智能分析 Server。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_init_001",
  "method": "initialize",
  "params": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "resources": {},
      "tools": {},
      "elicitation": {},
      "sampling": {
        "listChanged": true
      }
    },
    "clientInfo": {
      "name": "stylehub-dashboard",
      "version": "3.2.0",
      "title": "StyleHub商业智能仪表板"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_init_001",
  "result": {
    "protocolVersion": "2025-06-18",
    "capabilities": {
      "resources": {
        "subscribe": true,
        "listChanged": true
      },
      "tools": {
        "listChanged": true
      },
      "completions": {},
      "logging": {}
    },
    "serverInfo": {
      "name": "stylehub-bi-server",
      "version": "4.1.2",
      "title": "StyleHub智能商业分析引擎"
    },
    "instructions": "我可以分析销售数据、预测趋势、生成业务报告、识别市场机会和提供数据洞察。支持查询2024年销售数据、客户行为分析和库存优化建议。"
  }
}
2. 根目录 (Roots) - 界定数据访问范围

场景:Server 需要知道可以访问哪些数据源。

在这里插入图片描述

请求 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_roots_001",
  "method": "roots/list",
  "params": {
    "_meta": {
      "progressToken": "bi_roots_progress_789",
      "purpose": "data_access_boundary"
    }
  }
}

响应 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_roots_001",
  "result": {
    "roots": [
      {
        "uri": "bigquery://stylehub-prod/sales_2024",
        "name": "2024销售数据",
        "_meta": {
          "data_sensitivity": "confidential",
          "access_level": "read_only"
        }
      },
      {
        "uri": "bigquery://stylehub-prod/customer_analytics",
        "name": "客户分析数据",
        "_meta": {
          "data_sensitivity": "restricted",
          "access_level": "read_only"
        }
      },
      {
        "uri": "bigquery://stylehub-prod/inventory_management",
        "name": "库存管理数据",
        "_meta": {
          "data_sensitivity": "internal",
          "access_level": "read_write"
        }
      }
    ]
  }
}
3. 资源 (Resources) - 获取数据资源

场景:分析师想要查看最近的销售数据。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_read_001",
  "method": "resources/read",
  "params": {
    "uri": "bigquery://stylehub-prod/sales_2024/Q3_womens_fashion",
    "_meta": {
      "analysis_purpose": "trend_analysis",
      "time_range": "2024-07-01 to 2024-09-30"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_read_001",
  "result": {
    "contents": [
      {
        "uri": "bigquery://stylehub-prod/sales_2024/Q3_womens_fashion",
        "mimeType": "application/json",
        "text": "{\n  "metadata": {\n    "dataset": "Q3_womens_fashion",\n    "record_count": 125000,\n    "time_period": "2024-Q3"\n  },\n  "summary": {\n    "total_sales": 2850000,\n    "total_orders": 45600,\n    "average_order_value": 62.50,\n    "top_category": "dresses",\n    "growth_rate": 0.15\n  },\n  "sample_records": [\n    {"date": "2024-07-15", "category": "dresses", "sales": 125000, "orders": 890},\n    {"date": "2024-08-22", "category": "accessories", "sales": 85600, "orders": 1250}\n  ]\n}",
        "annotations": {
          "audience": ["user", "assistant"],
          "priority": 0.8,
          "lastModified": "2024-10-01T08:30:00Z"
        }
      }
    ]
  }
}
4. 工具 (Tools) - 执行数据分析

场景:AI 建议:“需要我进行销售趋势预测吗?”

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_tool_001",
  "method": "tools/call",
  "params": {
    "name": "predict_sales_trend",
    "arguments": {
      "product_category": "womens_dresses",
      "time_period": "next_quarter",
      "confidence_level": 0.95,
      "include_seasonality": true,
      "market_factors": ["holiday_season", "economic_indicator"]
    },
    "_meta": {
      "progressToken": "prediction_progress_2024",
      "business_unit": "womens_fashion"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_tool_001",
  "result": {
    "content": [
      {
        "type": "text",
        "text": "基于历史数据和市场趋势分析,预测女装品类下季度销售额将增长12-15%,主要受假日季节和新产品线推出推动。",
        "annotations": {
          "audience": ["user"]
        }
      }
    ],
    "structuredContent": {
      "prediction": {
        "category": "womens_dresses",
        "period": "2024-Q4",
        "predicted_growth": 0.135,
        "confidence_interval": [0.12, 0.15],
        "key_drivers": ["holiday_season", "new_product_launch"],
        "risk_factors": ["economic_downturn", "competitor_activity"]
      },
      "model_metadata": {
        "model_version": "sales_forecast_v3.2",
        "training_data_until": "2024-09-30",
        "accuracy_score": 0.89
      }
    },
    "isError": false
  }
}
5. 提示词 (Prompts) - 使用分析模板

场景:分析师想要生成标准格式的业务报告。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_prompt_001",
  "method": "prompts/get",
  "params": {
    "name": "generate_quarterly_business_review",
    "arguments": {
      "quarter": "Q3",
      "department": "womens_fashion",
      "report_type": "executive_summary",
      "include_comparative": true,
      "highlight_trends": true
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_prompt_001",
  "result": {
    "description": "生成女装品类2024年第三季度执行业务回顾报告",
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "请生成2024年第三季度女装品类执行业务回顾报告。报告应包含:\n\n1. 关键业绩指标(销售额、订单数、平均订单价值)\n2. 同比和环比增长分析\n3. 热销产品和品类表现\n4. 库存周转率和sell-through rate\n5. 市场趋势和竞争分析\n6. 下季度展望和建议\n\n使用专业商务语言,包含数据可视化建议,突出重点成就和挑战。"
        }
      }
    ],
    "_meta": {
      "report_template": "executive_quarterly_review_v2",
      "expected_length": "3-5_pages"
    }
  }
}
6. 采样 (Sampling) - Server 寻求解释帮助

场景:Server 发现异常数据模式,需要 LLM 帮助解释原因。

在这里插入图片描述

请求 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_sample_001",
  "method": "sampling/createMessage",
  "params": {
    "messages": [
      {
        "role": "user",
        "content": {
          "type": "text",
          "text": "分析以下销售异常模式并提出可能的解释:\n\n7月15日销售额异常高峰(比平日高300%),但8月10日出现显著下降(比预期低40%)。同期社交媒体提及量增加250%,但客户满意度评分下降15%。请分析可能的原因和关联因素。"
        }
      }
    ],
    "maxTokens": 800,
    "temperature": 0.2,
    "systemPrompt": "你是一名资深商业分析师,擅长从数据中提取洞察和解释异常模式。",
    "includeContext": "allServers",
    "modelPreferences": {
      "hints": [{"name": "claude"}],
      "intelligencePriority": 0.95,
      "costPriority": 0.3
    },
    "_meta": {
      "analysis_type": "anomaly_detection",
      "business_impact": "high"
    }
  }
}

响应 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_sample_001",
  "result": {
    "role": "assistant",
    "content": {
      "type": "text",
      "text": "基于数据分析,7月15日的销售高峰很可能由以下因素导致:\n1. 夏季促销活动推动短期销量激增\n2. 网红营销带来流量高峰但可能吸引非目标客户\n3. 8月10日的下降可能是促销后疲劳和库存短缺的综合结果\n\n建议:优化促销节奏,改进目标客户定位,加强库存预测。"
    },
    "model": "claude-3-opus-20240229",
    "stopReason": "endTurn",
    "_meta": {
      "analysis_confidence": 0.87,
      "key_insights": ["promotion_timing", "customer_segmentation", "inventory_management"]
    }
  }
}
7. 补全 (Completion) - 智能查询补全

场景:分析师在输入查询时,需要智能补全。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_complete_001",
  "method": "completion/complete",
  "params": {
    "ref": {
      "type": "ref/resource", 
      "uri": "bigquery://stylehub-prod/sales_2024"
    },
    "argument": {
      "name": "product_category_query",
      "value": "女装连衣"
    },
    "context": {
      "arguments": {
        "season": "Q3_2024",
        "region": "north_america",
        "customer_segment": "premium"
      }
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_complete_001",
  "result": {
    "completion": {
      "values": [
        "女装连衣裙夏季系列",
        "女装连衣裙新品上市",
        "女装连衣裙促销活动",
        "女装连衣裙销量排名",
        "女装连衣裙库存状态"
      ],
      "total": 12,
      "hasMore": true
    }
  }
}
8. 征询 (Elicitation) - 获取业务决策

场景:Server 发现库存风险,需要业务方决策。

在这里插入图片描述

请求 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_elicit_001",
  "method": "elicitation/create",
  "params": {
    "message": "检测到连衣裙库存周转率低于预期,存在积压风险。请选择处理策略:",
    "requestedSchema": {
      "type": "object",
      "properties": {
        "action_strategy": {
          "type": "string",
          "title": "处理策略",
          "description": "选择库存优化方法",
          "enum": ["promotional_discount", "bundle_offer", "inventory_transfer", "marketing_campaign"],
          "enumNames": ["促销折扣", "捆绑销售", "库存调拨", "营销活动"]
        },
        "discount_level": {
          "type": "number",
          "title": "折扣力度",
          "description": "如果选择促销,请指定折扣比例",
          "minimum": 0.1,
          "maximum": 0.5
        },
        "timeframe": {
          "type": "string", 
          "title": "执行时间",
          "description": "计划执行时间",
          "enum": ["immediate", "next_week", "next_month"],
          "enumNames": ["立即", "下周", "下月"]
        }
      },
      "required": ["action_strategy", "timeframe"]
    }
  }
}

响应 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_elicit_001",
  "result": {
    "action": "accept",
    "content": {
      "action_strategy": "promotional_discount",
      "discount_level": 0.3,
      "timeframe": "next_week",
      "additional_notes": "建议结合社交媒体推广"
    }
  }
}
9. 日志 (Logging) - 监控分析过程

场景:监控数据分析任务的执行状态。

在这里插入图片描述

请求 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_log_001",
  "method": "logging/setLevel",
  "params": {
    "level": "info"
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_log_001",
  "result": {}
}

通知 (Server → Client):

{
  "jsonrpc": "2.0",
  "method": "notifications/message",
  "params": {
    "level": "info",
    "logger": "sales_forecast_engine",
    "data": {
      "message": "开始执行Q4销售预测模型训练",
      "dataset_size": "1.2M records",
      "expected_duration": "15-20 minutes",
      "model_type": "time_series_forecast"
    }
  }
}
10. 通用与维护 (Utilities) - 系统管理

场景:管理长时间运行的数据分析任务。

在这里插入图片描述

心跳检测 (Client → Server):

{
  "jsonrpc": "2.0",
  "id": "bi_ping_001",
  "method": "ping",
  "params": {
    "_meta": {
      "client_session": "session_bi_20241015"
    }
  }
}

响应 (Server → Client):

{
  "jsonrpc": "2.0",
  "id": "bi_ping_001",
  "result": {
    "_meta": {
      "server_status": "healthy",
      "active_connections": 42,
      "memory_usage": "65%"
    }
  }
}

进度通知 (Server → Client):

{
  "jsonrpc": "2.0",
  "method": "notifications/progress",
  "params": {
    "progressToken": "prediction_progress_2024",
    "progress": 60,
    "total": 100,
    "message": "正在训练预测模型,已完成特征工程阶段",
    "current_step": "model_training",
    "estimated_remaining": "00:08:30"
  }
}

取消通知 (Client → Server):

{
  "jsonrpc": "2.0",
  "method": "notifications/cancelled",
  "params": {
    "requestId": "bi_tool_001",
    "reason": "业务需求变更,需要调整预测参数",
    "initiated_by": "business_analyst",
    "timestamp": "2024-10-15T14:30:00Z"
  }
}
11. 总结:完整的电商数据分析场景
  1. 初始化建立安全的数据连接
  2. 根目录界定数据访问权限边界
  3. 资源获取销售数据和报表
  4. 工具执行数据分析和预测
  5. 提示词使用标准模板生成业务报告
  6. 采样Server 寻求 LLM 解释数据异常
  7. 补全为分析师提供智能查询建议
  8. 征询让业务方做出库存管理决策
  9. 日志监控整个分析流程的执行
  10. 通用功能确保系统稳定和任务管理

这个电商案例展示了 MCP 如何在一个完全不同的业务领域(商业智能分析)中协调工作,为业务团队提供数据驱动的决策支持。每个功能都解决了数据分析流程中的特定环节问题,共同构成了一个完整的智能商业分析解决方案。

六、MCP 通信完整流程

在这里插入图片描述

1. 详细的调用流程顺序

阶段一:强制初始化阶段 (Mandatory Initialization)
  1. 建立传输层连接
    • Client 启动 Server 进程(stdio)或连接到 Server 的 socket
    • 建立基于 JSON-RPC 2.0 的通信通道
  2. 客户端发送 InitializeRequest
    {
      "jsonrpc": "2.0",
      "id": "init_1",
      "method": "initialize",
      "params": {
        "protocolVersion": "2025-06-18",
        "capabilities": {...},
        "clientInfo": {...}
      }
    }
    
  3. 服务端响应 InitializeResult
    {
      "jsonrpc": "2.0",
      "id": "init_1",
      "result": {
        "protocolVersion": "2025-06-18",
        "capabilities": {...},
        "serverInfo": {...},
        "instructions": "..."
      }
    }
    
  4. 客户端发送 InitializedNotification
    {
      "jsonrpc": "2.0",
      "method": "notifications/initialized"
    }
    

⚠️ 重要规则:在初始化完成之前,Client 不能发送任何其他请求(除了 ping),Server 也不能发送任何其他消息。

阶段二:能力发现阶段 (Capability Discovery) - 可选
  1. 客户端探索服务端能力
    • resources/list - 发现可用的数据资源
    • tools/list - 发现可用的工具函数
    • prompts/list - 发现可用的提示词模板
    • roots/list - Server 可能主动请求根目录信息
阶段三:主通信循环 (Main Communication Loop)
  1. 客户端发起的请求 (Client → Server)
    • resources/read - 读取数据资源
    • tools/call - 调用工具函数
    • prompts/get - 获取提示词模板
    • completion/complete - 请求补全建议
    • logging/setLevel - 设置日志级别
  2. 服务端发起的请求 (Server → Client) - 体现双向性
    • sampling/createMessage - 请求使用 LLM 生成内容
    • roots/list - 请求工作根目录信息
    • elicitation/create - 请求用户输入或决策
  3. 异步通知 (双向)
    • notifications/progress - 进度更新
    • notifications/message - 日志消息
    • notifications/cancelled - 取消操作
    • notifications/*/list_changed - 列表变更通知
    • notifications/resources/updated - 资源更新通知
  4. 维护通信
    • ping/pong - 心跳检测,可由任一方发起
阶段四:连接终止 (Connection Termination)
  1. 正常关闭
    • Client 或 Server 主动关闭连接
    • 所有进行中的操作应该被妥善处理
  2. 异常关闭
    • 传输层错误
    • 协议错误
    • 超时

2. 关键顺序规则

  1. 初始化优先: initializeinitializeResultinitializedNotification 必须最先完成
  2. 请求-响应匹配: 每个 Request 必须有对应的 Response 或 Error
  3. 通知无响应: Notification 不需要响应
  4. ID 唯一性: 每个 Request 必须有唯一 ID,Response 使用相同 ID
  5. 双向通信: Server 也可以主动发起 Request,Client 必须响应

3. 错误处理顺序

  1. 协议错误: 立即断开连接
  2. 方法不存在: 返回 METHOD_NOT_FOUND error
  3. 参数错误: 返回 INVALID_PARAMS error
  4. 处理错误: 在 Result 中返回 isError: true(对于工具调用)
  5. 取消操作: 发送 notifications/cancelled 通知

4. 心跳机制

// Client 发送 ping
{
  "jsonrpc": "2.0",
  "id": "ping_123",
  "method": "ping"
}

// Server 响应 pong
{
  "jsonrpc": "2.0",
  "id": "ping_123",
  "result": {}
}

5. 典型会话示例

  1. Client 启动并初始化连接
  2. Client 发现 Server 有哪些资源和工具
  3. Client 读取需要的数据资源
  4. Client 调用工具进行处理
  5. Server 在处理过程中发送进度通知
  6. Server 需要时请求用户决策(征询)
  7. Server 需要时使用 Client 的 LLM 能力(采样)
  8. 循环执行 3-7 直到任务完成
  9. Client 或 Server 关闭连接

这个流程确保了 MCP 协议的可靠性、安全性和灵活性,支持复杂的双向交互场景。

Logo

更多推荐