news 2026/1/11 17:18:33

大模型开发实战:从零实现 MCP Server,吃透模型上下文协议核心原理

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
大模型开发实战:从零实现 MCP Server,吃透模型上下文协议核心原理

前言

大家好呀~ 我是菲菲,一名刚入门大模型开发的学妹!在跟着教程探索 Agent 与工具协作的过程中,“MCP 协议” 这个词频繁出现 —— 官网白皮书看着清晰易懂,可真要动手实操时,却总陷入 “一看就会、一写就懵” 的困境。后来发现,不只是我,很多初入行的小伙伴都对这个 “连接 Agent 与工具的桥梁” 感到困惑。
其实在 AI 时代,通过 MCP 协议让 Agent 获取业务上下文早已成为行业标配,“会调接口” 也成了 Agent 开发者的必备技能。为了帮自己和更多像我一样的初学者彻底吃透 MCP,我决定从 0 到 1 动手实现一个 MCP Server。这篇文章里,我会把自己的学习心得和实操过程毫无保留地分享出来:不仅会用通俗的语言拆解 MCP 协议的核心原理,还会手把手带大家完成代码实现,让每一位和我一样的学妹、学弟都能告别 “只听说过 MCP” 的尴尬,真正理解它的底层逻辑~ 跟着步骤一步步来,相信你也能轻松入门 MCP 开发!在 AI 时代,“会调接口” 已成为 Agent 开发者的必备技能。通过 MCP 协议让 Agent 获取业务上下文,早已成为行业标配,但官网白皮书往往 “一看就懂,一写就懵”。本文将手把手带您从 0 到 1 实现 MCP Server,全量剖析 MCP 协议及底层技术原理,让您彻底告别 “只听说过 MCP” 的尴尬。

一、MCP 协议核心概念解析

  1. 什么是 MCP?
    MCP(Model Context Protocol,模型上下文协议)是规范应用程序向大语言模型提供上下文的开放协议。其核心是实现 MCP Client 与 MCP Server 之间的标准化通信,让 Agent 开发与工具开发彻底解耦 —— 就像 Type-C 接口统一充电标准一样,MCP 统一了 Agent 调用工具的方式。
    简单来说,当 AI 客户端(MCP Host)需要获取上下文时,会通过集成的 MCP Client 向 MCP Server 发送请求,由 Server 返回模型所需的上下文数据。若 AI 客户端未集成 MCP Client,该协议则与 AI 无任何关联。
  2. 三大核心组件协作机制
    MCP 协议的正常运行依赖三个核心组件的协同工作:
    MCP Client:负责发送请求与接收响应,通常集成在 MCP Host 中,无需单独部署
    MCP Server:核心处理单元,负责接收请求、处理逻辑并返回上下文数据
    MCP Host:协议执行者,完整流程为:接收用户问题→选择工具→构建参数→通过 Client 调用 Server→解析结果→继续对话
    集成了 MCP Client 的智能体执行平台(如 IDEA LAB)或模型厂商的 Agent/AI 客户端(如 Cherry Studio),均可作为 MCP Host。以阿里云百练平台为例,MCP Host 即平台上的智能体应用,支持低代码、高代码等多种开发模式,可通过简单配置实现 MCP 服务调用。
  3. 与 Type-C、统一 function call 的关联
    若将 Agent 比作手机,工具接口比作充电线,那么 MCP Server 就相当于 Type-C 接口 —— 当所有 Agent/AI 客户端都集成 MCP Client,并用 MCP 协议调用工具时,就实现了 function call 的统一。这种标准化带来的价值,正如 Type-C 接口统一充电标准一样,打破了不同平台间的兼容性壁垒。
  4. 核心解决的两大问题
    简化模型调用流程:统一协议后,IDEA LAB、通义千问等平台的 AI 客户端内置 MCP Client,开发者只需将接口封装为 MCP Server 即可接入,选工具、拼参数、调接口、解析结果等流程由平台自动完成
    实现开发解耦:工具按 MCP Server 标准发布后,所有支持 MCP 协议的平台均可直接调用,无需关心 “选 - 拼 - 调 - 解” 全流程,实现工具开发与 Agent 开发的分离

二、MCP 技术原理深度拆解

MCP 协议的底层技术支撑主要包括 SSE(数据传输方式)、JSON-RPC 2.0(数据格式规范)和 MCP 自身的通信流程定义,三者共同构成了完整的技术体系。

  1. SSE:实时数据传输的核心载体
    SSE(Server-Sent Events)是基于 HTTP 协议的 Web 技术,专门用于服务器向客户端实时推送数据。其核心原理是通过建立持久 HTTP 连接,将 “请求 - 响应” 模式伪装成 “长时间下载”,让数据源源不断流向客户端。
    关键特性与规范
    基于 HTTP/1.1,复用现有基础设施,浏览器原生支持
    响应格式固定:Content-Type 为 text/event-stream,需设置 Cache-Control: no-cache 和 Connection: keep-alive
    消息体包含四个固定字段:
    data:实际负载数据
    id:事件序号,用于断线续传
    event:事件类型,前端通过 addEventListener 监听
    retry:断线重连间隔(毫秒)
    实现方式灵活:Spring 框架可通过同步阻塞的 SseEmitter 或响应式的 Flux实现
    两种技术栈实现对比
技术栈模型API对象适用场景备注
Spring MVC+Servlet同步阻塞SseEmitter连接数可控、开发简单Tomcat 线程数≈连接数
Spring WebFlux + Reactor异步非阻塞Flux超高并发、低延迟Netty 事件循环,少量线程支撑海量连接
  1. JSON-RPC 2.0:标准化消息格式
    JSON-RPC 2.0 是无状态、轻量级的远程过程调用协议,定义了 MCP Client 与 MCP Server 之间的通信格式,确保两端能零差异解析数据。
    核心消息结构(四固定字段)
字段要求类型作用
jsonrpc必选固定值 “2.0”协议版本号
method必选string远端要执行的函数名
jsonrpc可选object/array入参数据
jsonrpc可选string/number/null请求匹配符,无 id 视为通知(不期待回复)
jsonrpc二选一-成功返回 result,失败返回 error

完整范式示例

  • 请求示例:
{"jsonrpc":"2.0","method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{"sampling":{},"roots":{"listChanged":true}},"clientInfo":{"name":"mcp-inspector","version":"0.9.0"}},"id":0}
  • 成功响应示例:
{"jsonrpc":"2.0","id":0,"result":{"capabilities":{"tools":{"listChanged":true}},"serverInfo":{"name":"SpringBoot MCP Server","version":"1.0.0"},"protocolVersion":"2024-11-05"}}
  1. MCP 协议:全生命周期通信规范
    MCP 协议在 SSE+JSON-RPC 2.0 基础上,定义了 “两通道、四步骤” 的全生命周期通信流程,明确了 “怎么连、怎么握手、怎么调工具、怎么结束” 的标准流程。
    通信两通道(缺一不可)
通信作用通道类型方向
SSE Stream (GET /sse)服务器→客户端推送事件Server-Sent Events单向
HTTP POST Endpoint客户端→服务器发起调用HTTP双向请求 - 响应

通信四步骤
连:客户端发送 GET /sse 请求,建立 SSE 长连接,用于接收服务器推送
取:服务器返回 event: endpoint 消息,提供客户端后续通信的 POST 端点 URI
握:客户端向 POST 端点发送两包 JSON-RPC:
initialize 请求:协商协议版本和能力
notifications/initialized 通知:确认握手完成
用:正常会话阶段,支持 tools/list(获取工具列表)、tools/call(调用具体工具),服务器通过 SSE 流推送状态更新
断:任一端关闭 SSE 连接,会话结束

三、从零实现 MCP Server(实战教程)

任何语言 / 框架实现 MCP Server,只需满足三个条件:开启 SSE 端点、开启 POST 端点、实现 “四步骤” 所需接口。以下将用 Spring Boot+WebFlux+Jackson 技术栈,带您实现一个完整的 MCP Server。

  1. 项目准备
    技术栈与依赖
    核心框架:Spring Boot + WebFlux
    序列化工具:Jackson
    测试工具:MCP Inspector、内置 HTML 测试页面
    项目结构

springboot-mcp-server/
├── pom.xml
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/
│ │ │ ├── HelloWorldApplication.java
│ │ │ ├── config/ // HTTP配置
│ │ │ │ └── McpConfig.java
│ │ │ └── mcp/
│ │ │ ├── protocol/ // JSON-RPC 2.0请求响应模型
│ │ │ │ ├── McpRequest.java
│ │ │ │ └── McpResponse.java
│ │ │ ├── transport/ // 传输端点(SSE+POST)
│ │ │ │ └── SseTransport.java
│ │ │ ├── server/ // MCP协议处理逻辑
│ │ │ │ └── McpServerHandler.java
│ │ │ └── tools/ // 工具注册与调用
│ │ │ └── McpToolRegistry.java
│ │ └── resources/
│ │ ├── application.properties
│ │ └── static/
│ │ └── mcp-test.html // 内置测试页面
│ └── test/
│ └── java/com/example/HelloWorldApplicationTests.java
└── README.md

  1. 核心组件实现
    (1)SSE 端点与 POST 端点构建(SseTransport.java)
    首先实现 MCP 协议要求的两通道,确保客户端能建立连接并发送请求。
    SSE 端点(GET /sse):
/** * 标准MCP SSE端点 - 客户端连接此端点接收服务器推送消息 */@GetMapping(value="/sse",produces=MediaType.TEXT_EVENT_STREAM_VALUE)publicFlux<ServerSentEvent<String>>sseEndpoint(@RequestParam(required=false)StringclientId,ServerHttpRequestrequest){// 安全检查:验证Origin头防止DNS重绑定攻击Stringorigin=request.getHeaders().getFirst("Origin");if(origin!=null&&!isValidOrigin(origin)){System.err.println("Invalid origin rejected: "+origin);returnFlux.error(newSecurityException("Invalid origin"));}StringsessionId=clientId!=null?clientId:"client-"+System.currentTimeMillis();// 为每个客户端创建独立消息流Sinks.Many<ServerSentEvent<String>>sink=Sinks.many().multicast().onBackpressureBuffer();clientSinks.put(sessionId,sink);System.out.println("MCP SSE client connected: "+sessionId+" from origin: "+origin);// 30秒心跳流,维持连接Flux<ServerSentEvent<String>>heartbeat=Flux.interval(Duration.ofSeconds(30)).map(tick->ServerSentEvent.<String>builder().event("ping").data("{\"type\":\"ping\"}").build());// 合并消息流与心跳流,发送endpoint事件(MCP协议要求)returnFlux.merge(sink.asFlux(),heartbeat).doOnSubscribe(subscription->{try{StringendpointUri=getBaseUrl(request)+"/message/"+sessionId;// 发送endpoint事件,提供POST通信地址ServerSentEvent<String>endpointEvent=ServerSentEvent.<String>builder().event("endpoint").data(endpointUri).build();sink.tryEmitNext(endpointEvent);System.out.println("Sent endpoint event to client: "+sessionId+" with URI: "+endpointUri);}catch(Exceptione){System.err.println("Error sending endpoint event: "+e.getMessage());}}).doOnCancel(()->{System.out.println("MCP SSE client disconnected: "+sessionId);clientSinks.remove(sessionId);sink.tryEmitComplete();}).doOnError(error->{System.err.println("MCP SSE error for client "+sessionId+": "+error.getMessage());clientSinks.remove(sessionId);}).onErrorResume(error->{System.err.println("SSE stream error, attempting to recover: "+error.getMessage());returnFlux.empty();});}

POST 端点(POST /message/{sessionId}):

/** * 处理客户端MCP请求 - 客户端通过POST发送JSON-RPC消息 */@PostMapping(value="/message/{sessionId}",consumes=MediaType.APPLICATION_JSON_VALUE)publicMono<Void>handleSessionMessage(@PathVariableStringsessionId,@RequestBodyStringmessageJson,ServerHttpRequestrequest){returnhandleMessageInternal(sessionId,messageJson,request);}privateMono<Void>handleMessageInternal(StringsessionId,StringmessageJson,ServerHttpRequestrequest){returnMono.fromRunnable(()->{try{// 安全校验与消息解析Stringorigin=request.getHeaders().getFirst("Origin");if(origin!=null&&!isValidOrigin(origin)){System.err.println("Invalid origin rejected for message: "+origin);return;}McpRequestmcpRequest=objectMapper.readValue(messageJson,McpRequest.class);System.out.println("Received MCP request: "+mcpRequest.getMethod()+" (id: "+mcpRequest.getId()+") from session: "+sessionId);// 处理请求并通过SSE返回响应McpResponseresponse=serverHandler.handleRequest(mcpRequest);if(response!=null){sendMessageToClient(sessionId,response);}}catch(Exceptione){System.err.println("Error processing MCP message: "+e.getMessage());e.printStackTrace();// 发送错误响应try{McpRequestmcpReq=objectMapper.readValue(messageJson,McpRequest.class);McpResponseerrorResponse=newMcpResponse();errorResponse.setId(mcpReq.getId());errorResponse.setError(newMcpResponse.McpError(-32603,"Internal error: "+e.getMessage()));sendMessageToClient(sessionId,errorResponse);}catch(Exceptionex){System.err.println("Error sending error response: "+ex.getMessage());}}});}/** * 向指定客户端发送MCP响应消息 */publicvoidsendMessageToClient(StringsessionId,Objectmessage){Sinks.Many<ServerSentEvent<String>>sink=clientSinks.get(sessionId);if(sink!=null){try{StringjsonData=objectMapper.writeValueAsString(message);ServerSentEvent<String>event=ServerSentEvent.<String>builder().event("message").data(jsonData).build();sink.tryEmitNext(event);System.out.println("Sent MCP message to client: "+sessionId);}catch(Exceptione){System.err.println("Error sending message to client "+sessionId+": "+e.getMessage());}}else{System.err.println("No active connection found for session: "+sessionId);}}

(2)协议核心逻辑处理(McpServerHandler.java)
实现 MCP 通信 “四步骤” 中的握手与工具调用逻辑,处理 initialize、tools/list、tools/call 等关键请求。

publicMcpResponsehandleRequest(McpRequestrequest){Stringmethod=request.getMethod();Stringid=request.getId();Map<String,Object>params=request.getParams();try{switch(method){// 处理初始化请求:协商协议版本与能力case"initialize":returnhandleInitialize(id,params);// 处理工具列表请求:返回可用工具case"tools/list":returnhandleListTools(id);// 处理工具调用请求:执行具体工具逻辑case"tools/call":returnhandleCallTool(id,params);// 客户端初始化完成通知:无需返回响应case"notifications/initialized":this.initialized=true;System.out.println("Client initialization completed");returnnull;// 未知方法处理default:McpResponseerrorResponse=newMcpResponse();errorResponse.setId(id);errorResponse.setError(newMcpResponse.McpError(-32601,"Method not found: "+method));returnerrorResponse;}}catch(Exceptione){System.err.println("Error handling request "+method+": "+e.getMessage());McpResponseerrorResponse=newMcpResponse();errorResponse.setId(id);errorResponse.setError(newMcpResponse.McpError(-32603,"Internal error: "+e.getMessage()));returnerrorResponse;}}
  1. 测试验证
    方式一:使用 MCP Inspector 测试
    启动 Spring Boot 应用,默认端口 8080
    打开 MCP Inspector v0.9.0
    选择 “SSE Transport”,输入 URL:http://localhost:8080/sse
    点击 “Connect”,按顺序执行:
    Initialize(初始化握手)
    List Tools(获取工具列表)
    Call Tools(调用具体工具)
    方式二:使用内置测试页面
    访问:http://localhost:8080/mcp-test.html
    点击 “Connect to MCP Server” 建立连接
    依次执行:Initialize → List Tools → Call Hello World → Get Time → Echo Message,验证全流程
  2. 实现效果
    通过上述代码,我们完成的 MCP Server 具备以下能力:
    支持 SSE 长连接建立与心跳维持
    按 MCP 协议要求发送 endpoint 事件
    处理 initialize 握手流程,协商协议能力
    支持工具列表查询与具体工具调用
    异常处理与错误响应反馈

四、总结

MCP 协议通过 SSE(传输通道)+ JSON-RPC 2.0(数据格式)+ 标准化流程(通信规范)的组合,成功解决了 Agent 与工具之间的协作难题。通过亲手实现 MCP Server,我们不仅掌握了 “两通道、四步骤” 的核心流程,更理解了其 “解耦开发、统一标准” 的设计理念。
在大模型应用开发日益普及的今天,MCP 作为连接 Agent 与工具的 “桥梁”,正在重塑行业开发模式。掌握 MCP 技术原理,将帮助开发者在 Agent 开发领域构建更灵活、更具兼容性的应用系统,为业务创新提供强大支撑。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2025/12/24 18:08:23

swf视频格式转换vob视频格式的快捷方式分享

日常生活中&#xff0c;我们经常需要将SWF动画格式转换为通用的MPG视频格式。MPG作为国际标准化组织认可的视频格式&#xff0c;具有出色的兼容性和稳定的播放性能。许多朋友想知道swf怎么转换成vob格式。接下来为您讲解swf视频格式转换vob视频格式的方式。 第一步&#xff1a;…

作者头像 李华
网站建设 2025/12/24 6:56:11

【腾讯元器】学术炼金废弃回收站

&#x1f9d4; 这里是九年义务漏网鲨鱼&#xff0c;研究生在读&#xff0c;主要研究方向是人脸伪造检测,长期致力于研究多模态大模型技术&#xff1b;国家奖学金获得者&#xff0c;国家级大创项目一项&#xff0c;发明专利一篇&#xff0c;多篇论文在投&#xff0c;蓝桥杯国家级…

作者头像 李华
网站建设 2025/12/27 7:06:13

智泊-最新AGI大模型全栈课12期|2025年9月

站在2025年中回望&#xff0c;我们正经历一场比移动互联网更深刻的技术革命&#xff1a;人工智能不再只是工具&#xff0c;而正在演变为具备理解、推理、行动与交互能力的“新型智能体”。从问答助手到自主科研代理&#xff0c;从虚拟客服到能在物理世界中操作机械臂的具身系统…

作者头像 李华
网站建设 2025/12/27 7:06:10

AI超级员工系统源码,一天量产1000条爆款短视频

温馨提示&#xff1a;文末有资源获取方式核心突破&#xff1a;告别繁琐&#xff0c;拥抱极速智能创作传统的短视频制作&#xff0c;从文案策划、演员拍摄、后期剪辑到多语种适配&#xff0c;流程冗长&#xff0c;成本高昂&#xff0c;严重制约了规模化产出。春哥团队AI超级员工…

作者头像 李华
网站建设 2025/12/27 7:06:07

Flink学习笔记:状态类型和应用

今天就来了解一下 Flink 的状态以及应用&#xff0c;首先第一个问题是&#xff1a;什么是有状态计算&#xff1f;基本概念在数据流处理中&#xff0c;大部分操作都是每次只处理一个事件&#xff0c;比如对输入的数据进行结构化解析&#xff0c;这类操作我们称为无状态计算。而有…

作者头像 李华