本文目标
  • mcp协议理解
  • mcp server生产级部署方案
    • 如何支持集群部署
    • 如何和hertz结合。
    • 如何支持header中加k/v
  • Agent如何集成MCP

1 前置聊聊

1.1 JSON-RPC 2.0协议

JSON-RPC 2.0 的核心价值可以概括为:在分布式系统中提供一种极其简单、轻量级、语言中立且可靠的远程过程调用协议。
1、request:一个合法的 JSON-RPC 2.0 请求必须包含以下字段:
2、 response
  • 成功的响应结构:
  • 错误响应结构:

1.2 泛化调用的业务场景

大家在日常开发工作中,是否遇到过这样的业务场景:团队需要快速搭建一个统一的配置化平台,用以对接和集成公司内各种各样的下游服务?典型的例子包括但不限于:
  • 压测平台: 需要便捷地调用无数个业务的 RPC 接口来构造压测流量。
  • 调度平台(Job系统): 需要定时、可靠地触发数百个不同的服务方法来完成抓取、计算、清理等任务。
  • 低代码平台/工作流引擎: 需要通过“拖拽”方式配置一个节点,就能调用一个具体的服务接口来实现业务逻辑。
  • 网关配置后台: 需要动态地接入和管理新的后端服务接口。
针对这类需求,一个典型的实现方案通常包含以下两个核心部分:
  • 接口接入:通过配置形式保存接口的元数据信息,例如 PSM、方法名、请求结构与响应结构等;
  • 接口执行:定义统一的执行接口ExecuteAction,屏蔽不同接口的调用差异,实现通用、可扩展的调用能力。ExcuteAction做的事情就是统一接口调用,包括接口的 request和resposne。
    • request

    • Response

 1.3 没有mcp之前,agent如何把tool调用标准化

在没有MCP时,一个Agent应用,如何快速接入业务的接口呢?可以采用上面泛化调用的方案。
部分大模型不具备function call能力,而且每个模型的functaion call方式不同 ,为了兼容这些场景,我们需要开发一个执行Tool的模块:包含工具识别+执行:
screenshot-20250914-095240
这个方案只是一个agent应用粒度的统一tool调用的方案。MCP协议是从行业角度提出的tool调用的统一方案,而且MCP还推动了更多业务方主动提供MCP tool。

2 MCP协议理解

2.1 介绍

MCP作用就是:将tool调用标准化化。即 request和response 转换成Json-rpc 2.0协议格式。
Model Context Protocol(模型上下文协议)是 Anthropic 在推出的用于 LLM 应用和外部数据源(Resources)或工具(Tools)通信的标准协议,遵循 JSON-RPC 2.0 的基础消息格式。
可以把 MCP 想象成 AI 应用程序的 USB-C 接口,规范了应用程序如何为 LLMs 提供上下文。
screenshot-20250914-095539
采用客户端-服务器架构,包含以下核心组件:
MCP主机(MCP Hosts)
  • 发起请求的LLM应用程序
  • 可以是IDE、AI工具或其他应用
MCP客户端(MCP Clients)
  • 运行在主机程序内部
  • 与MCP Server保持1:1连接
  • 负责协议通信和请求转发
MCP服务器(MCP Servers)
  • 提供工具、资源和提示词服务
  • 运行在本地或远程环境
  • 支持多种传输协议
资源层(Resources)
  • 本地资源:文件、数据库等
  • 远程资源:API、云服务等
screenshot-20250914-095925

2.2 四种资源tool/resource/prompt/resourcetemplate

2.2.1 为什么要划分为四种?

这四种类型完美地概括了计算机科学中最基本的交互范式,任何你能想到的客户端-服务器交互,几乎都可以被归类为“执行一个动作”、“获取一些数据”、“获取如何操作的指导”或“发现如何获取数据”。
  • 执行(Do) -> Tool :“我能为你做什么?” (函数调用)
  • 读取(Read/Observe) -> Resource:“我能让你读/观察什么?” (静态或动态数据)
  • 指导(Guide) -> Prompt :“我能为你提供什么预制提示词?” (可复用的指令模板)
  • 发现(Discover) -> ResourceTemplate :“你需要读取什么,告诉我参数,我帮你生成资源URI?” (参数化资源URI生成器)

2.2.2 每一种资源统一一个reqeust/response

每种资源的request和reponse报文:
1、 执行特定的TOOL
Data 定义了tool返回的的数据通用结构
Reqeust

Response

2、获取特定prompt
Data 定义了message的数据通用结构
Request

Response

3、读取特定 Resource
定义了resource资源的数据格式
Request

Response

2.3 三种传输协议

  • Stdio:本地调用场景
  • Streamable HTTP远程调用场景
2025 年 3 月 26 日MCP 引入了一项关键更新:用 Streamable HTTP 替代原先的 HTTP + SSE(2024-11-05) 作为默认传输方式。
SE不支持 多实例部署StreamableHTTP 传输天然支持多实例部署
  • SSE(HTTP+Server-Sent Events):远程调用场景(已废弃)

2.3.1 SSE Server – 异步双向通信

SSE 介绍

HTTP SSE(Server-Sent Events,服务器发送事件)不支持客户端主动向服务器多次发送请求,其核心设计是单向通信模式。为了实现异步的双向通信模式,mcp引入了/sse和/messge两个endpoint 来实现异步双向传输
SSE通过双端点实现异步双向通信:
  • /sse端点:建立持久SSE连接用于接收服务器推送,负责服务器到客户端的实时推送(单向流),用于传递响应和通知
  • /message端点:用来接受用户请求,,通过协程异步把返回放到SSE的队列中通过SSE发送出去

SSE

 

搭建SSE Server

使用 github.com/mark3labs/mcp-go 搭建举例

SSE Server验证

方式1 postman验证
  • STEP1 通过 /sse接口建立 SSE 连接。执行结果会获取到一个/messge?sessionId=xxx

001

  • STEP2 通过/message访问发送请求。 通过第一步获取到 sessionid信息
操作 参数
tool_list 通过/message发送一个请求

tool:list

结果通过sse发送过去

tool_list2

call_tool  通过/message发送一个请求

call1

结果通过sse发送过去 call2

出现错误时

方式2 通过定义client验证

 2.3.2 StreamableHttp Server – 同步双向通信

StreamableHttp 介绍

StreamableHTTP实际上实现的是同步双向通信,StreamableHTTP使用单一端点(/mcp)处理请求,支持两种响应模式:
  • 标准同步模式:Content-Type: application/json,立即返回完整响应
  • 流式模式:Content-Type: text/event-stream,当需要发送通知时升级为SSE流。
HTTP

搭建Streamable Http Server

EndPoint配置
  • 默认StreamableHTTP传输协议使用单一端点来处理所有请求,默认端点路径是 /mcp。 streamable_http.go:142
  • 自定义: 您可以通过 WithEndpointPath() 选项自定义端点路径:

Streamable Http Server 验证

下面例子是部署了有状态server(默认是有状态),需要通过init获取mcp-session-id,在线上部署时,可以部署无状态server。
操作 参数
初始化 4bb1c597-2949-4ecc-8bd2-11031a62f103
执行tool 003

002

Prompt 相关请求 003
resources  004

需要升级 SSE 的核心场景

Demo
  • 注册一个streamable tool,如下通过server.SendNotificationToClient 可以把chunk内容发送到streamableHttpSession#notificationChannel, 再通过SSE 把notificationChannel数据发送到客户端。

  • 通过postman验证

    3

  • 通过client来验证。

    代码

输出:

如何实现
  • 【服务端】McpServer,自动升级SSE的代码如下:
    • stream_http server会自动开启一个SSE链接,监听streamableHttpSession#notificationChannel,把notificationChannel中数据通过sse发送到客户端。

      010

  通过监听notificationChannel来实现SSE自动升级,如果有升级SSE的场景,直接往notificationChannel写入数据就行。由notificationChannel定义,接受请求都是JSONRPCNotification类型的。 所以,SSE都是针对notify类型的。

 

  • 【客户端】根据response content_type自动识别SSE,如果是sse则将流式结果全部处理完成之后在封装成mcp.ToolCallResul

1

2

业务接口是一个SSE 流式接口如何封装成一个Tool

直接注册tool时时候,把流式内容转成一次返回。

 

 

2.3.3 Stdio Server

使用场景

  1. 命令行工具
  • CLI 实用程序,可被 LLM 调用
  • 本地开发和测试 MCP 实现
  • 系统管理工具
2. 桌面应用集成
  • IDE 插件和文本编辑器扩展
  • 本地生产力工具
  • 文件系统浏览器
3. 子进程通信
  • 父进程管理 MCP 服务器
  • 进程级隔离和安全性
  • 单用户场景

搭建Stdio Server

服务启动之后,验证
1

 

客户端使用Stdio Server

不需要启动Stdio server,直接使用 client.NewStdioMCPClient 即可

3 MCP Server生产级部署方案

如果要线上可用的话,需要满足如下功能:

  • MCPServer支持多实例部署
  • MCPServer集成hertz服务中
  • McpClient支持多服务器客户端管理,即需要连接到多个不同类型的MCP服务器
  • Mcp调用过程支持header中添加k/v

3.1 开源工具

使用 github.com/mark3labs/mcp-go,如果SDK有问题,可以直接https://deepwiki.com/mark3labs/mcp-go 这里问答吧
go get github.com/mark3labs/mcp-go@latest

3.2 Servers: 多实例部署

最终方案:使用Streamble HTTP 部署 + 无状态模式
  1. Streamable HTTP Server VS SSE Server
SSE不支持 多实例部署。🔥Streamable HTTP 传输天然支持多实例部署 。因为:
  • SSE 是由 /sse 和 /message 两个endpoint组成
  • Streamabel Http 是由一个/mcp endpoint组成
  1. 无状态模式是多实例部署的理想选择。因为它消除了会话粘性的需求。客户端可以与任何服务器实例通信,负载均衡器可以自由地将请求分发到不同的实例。这种模式提供了最佳的可扩展性和容错能力。

 

3.3 Client:多服务器客户端的管理(支持连接到多个不同类型的MCP服务器)

官网没有定义MltiServerClient,而是在 index.mdx:367-419中给出了思路和demo代码。这种方案实现比较简单.
这里需要问题就是在定义tool到时候指定一个serverName。这里有个方案就是在注册tool时,必须保证tool的name是唯一的。

 

2.4 支持header中添加k/v

直接使用transport.WithHTTPHeaders就可以,不需要修改源码

 

2.5 集成hertz

使用 hertz最新版本提供的工具类adaptor.HertzHandler 来集成MCP Server。

2.5.1 Streamable Http Server + Hertz

2.5.2 SSE Server + Hertz (不建议再构建SSE mcp server)

4 Agent集成MCP

111

 

  • 提示词

    • 执行流程

      • 调用豆包接口,可以参考方舟平台demo封装下如下

        • 测试:

a678b9aa-b17c-490a-b6ab-1a258704a680

分类&标签