深入了解MCP协议如何彻底改变后台管理系统的数据交互方式,助力企业实现智能化升级。
本文重点阐述:MCP协议在AI编程中的关键作用、如何通过该协议将ERP系统与AI模型无缝对接,以及这套协议的未来应用潜力。

什么是 MCP?
官方定义:Model Context Protocol(MCP)是一种开放协议,能够使LLM应用与外部数据源及工具实现高效集成。无论你是在构建AI驱动的IDE、优化聊天交互,还是打造自定义AI工作流,MCP都提供了一套标准化方案,将LLM与其所需的上下文环境紧密连接。
简单来说,MCP就是一个数据通信协议,专门用于约定应用程序与大模型之间的数据传输与对接方式。
本文主要聚焦于MCP在SSE+HTTP模式下的具体实现。
先看一个实际案例:
背景场景
- 一台服务器通过Ollama部署了多个模型,供公司内部员工使用。
- 另一台服务器运行着公司的ERP系统,管理大量业务数据。
- 你刚刚从技术社区了解到MCP这个概念。
在这样的架构中,我们能实现哪些创新应用?
参考截图效果:
左上角是CherryStudio客户端,右侧是ERP系统,中间是Ollama运行的7B通义千问开源模型。通过CherryStudio的MCP协议接入功能,我们能够直接与ERP系统通信,完成数据查询和操作。
如果把这个场景迁移到手机端的Siri或小爱同学呢?Siri可以通过快捷指令实现,小爱同学有小爱技能,虽然体验不如直接内置MCP流畅,但这个方向确实充满潜力。
设计分析
先了解MCP的架构设计时序图:
sequenceDiagram
participant User as User
participant CherryStudio as CherryStudio
participant Server as Server
participant Ollama as Ollama
User->>CherryStudio: 打开软件
CherryStudio-->>Server: **SSE** 兄弟,我们聊会
Server--)CherryStudio: **SSE** 好,你有事的话 POST 这个地址(endpoint)
CherryStudio-->>Server: **POST** 兄弟,自我介绍一下(initalize)
Server--)CherryStudio: **SSE** 好,这是我的基本信息(serverInfo)
CherryStudio-->>Server: **POST** 兄弟,我收到了,我准备好了(initialized)
CherryStudio-->>Server: POST: 兄弟,你有MCP的工具吗(tools/list)
Server--)CherryStudio: **SSE** 我提供了几个工具(tools)
User->>CherryStudio: 输入: 禁用张三的账号
CherryStudio->>Ollama: POST: 带工具调用 `禁用张三的账号`
Ollama-)CherryStudio: 意图识别: {工具:禁用账号,参数:张三}
CherryStudio-->>Server: **POST** 请求发送 {工具:禁用账号,参数:张三}
Server-->>CherryStudio: 执行工具并 **SSE** 推送结果
CherryStudio->>Ollama: 整理下收到的结果
Ollama-)CherryStudio: 返回处理后的结果
CherryStudio-)User: 显示给用户看
开始实现
有了架构图,实现路径就清晰了。虽然官网提供了现成SDK,但自行手写一遍能更深入理解原理。我们直接在项目中从零实现。
技术栈
- 运行环境:Ja va17
- 框架:SpringBoot
- ORM:JPA
直接开始编码。
MCP基础数据结构
基础结构
{
"id": 0,
"jsonrpc": "2.0"
}
请求结构(继承基础结构)
所有发送给MCP服务器的请求都遵循以下模板:
interface Request {
// 请求ID
id: number
// 协议版本,固定2.0
jsonrpc: "2.0";
// 请求方法
method: string;
// 请求参数
params?: { ... };
}
例如初始化请求:
{
"id": 0,
"jsonrpc": "2.0",
"method": "initalize",
"params": {
"capabilities": {},
"clientInfo": {
// 客户端名称、版本等信息
}
}
}
函数调用请求:
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "disableUserByName",
"arguments": {
"name": "张三"
}
}
}
响应结构(继承基础结构)
所有通过SSE推送给客户端的响应格式如下:
interface Response {
id: 0;
jsonrpc: "2.0";
result: {
// 返回数据
};
error: {
// 错误信息
};
}
SSE服务实现
在SpringBoot中开启SSE服务非常简单:
public final static ConcurrentHashMapEMITTERS = new ConcurrentHashMap<>(); @GetMapping(value = "sse", produces = MediaType.TEXT_EVENT_STREAM_VALUE) public SseEmitter connect() throws IOException { String uuid = UUID.randomUUID().toString(); SseEmitter emitter = new SseEmitter(); sseEmitter.send(SseEmitter.event() .name("endpoint") .data("/mcp/messages?sessionId=" + uuid) .build() ); EMITTERS.put(uuid, emitter); // 可添加心跳机制 emitter.onCompletion(() -> EMITTERS.remove(uuid)); emitter.onTimeout(() -> EMITTERS.remove(uuid)); return emitter; }
关键点:MCP要求连接建立后,服务端必须立即发送一次消息,内容为客户端后续发送POST请求的目标URL。
该服务启动后,客户端即可通过它接收服务端下发的消息。
Message POST API
接下来实现相对复杂的POST接口:
@PostMapping("messages")
public Json messages(HttpServletRequest request, @RequestBody McpRequest mcpRequest) {
String uuid = request.getParameter("sessionId");
if (Objects.isNull(uuid)) {
return Json.error("sessionId is required");
}
String method = mcpRequest.getMethod();
switch(method){
case "initalize":
// 初始化请求,返回服务器信息
break;
case "tools/call":
// 工具调用请求,返回执行结果
break;
case "tools/list":
// 工具列表请求,返回工具列表
break;
default:
}
}
注意:所有响应都不直接通过HTTP返回,而是通过已建立的SSE通道推送回去。
1、初始化
初始化请求需要返回服务器基础信息:
{
id: id,
jsonrpc: "2.0",
result: {
capabilities: {},
serverInfo: {
name: "服务器名称",
version: "1.0.0"
}
}
}
至此,客户端已能显示服务器基础信息。
2、请求工具列表
当客户端请求工具列表时,服务端需返回以下结构:
{
"id": 0,
"jsonrpc": "2.0",
"result": {
"tools": [
{
"name": "disableUserByName",
"description": "禁用一个用户的账号",
"inputSchema": {
"type": "object",
"properties": {
"nickname": {
"type": "string",
"description": "名称"
}
},
"required": ["nickname"]
}
}
]
}
}
3、执行工具
当服务端需要执行工具时,收到的请求结构:
{
"id": 1,
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "disableUserByName",
"arguments": {
"name": "张三"
}
}
}
执行业务逻辑后,返回结果结构:
{
"id": 1,
"jsonrpc": "2.0",
"result": {
"content": [
{
"type": "text",
"text": "好,张三被我干掉了"
}
]
}
}
至此,整个流程基本打通。
基于注解的封装
既然使用Ja va和SpringBoot,我们可用@McpMethod注解配合Reflections实现工具自动注册:
@McpMethod("modifyEmailByName")
@Description("modify user new email by name")
public String modifyEmailByName(
@Description("the name of user, e.g. 凌小云")
String name,
@Description("the new email of user, e.g. example@domain.com")
String email) {
List userList = filter(new UserEntity().setNickname(name));
DATA_NOT_FOUND.when(userList.isEmpty(), "没有叫 " + name + " 的用户");
userList.forEach(user -> {
updateToDatabase(get(user.getId()).setEmail(email));
});
return "已经将 " + userList.size() + " 个叫 " + name + " 的用户邮箱修改为 " + email;
}
只要标记了@McpMethod注解,MCP服务器就会自动注册该方法。随后通过CherryStudio等工具即可直接调用。
只需动口,无需动手。
总结
通过上述流程,我们成功搭建了一个基础MCP服务。这套机制完全可以应用于其他系统,借助大模型改造系统的使用方式,效果非常显著。
当然,仍有许多问题需要解决,例如权限控制——这才是真正需要重点攻克的方向。
