在做CodeStyle(码蜂)项目的过程中,算是把MCP(Model Context Protocol)协议和Spring AI的实现完整啃了一遍()。MCP现在基本上是AI工具生态的标准化协议了,但国内相关的深入文章感觉还不多()。搞了两个月,踩了不少坑,在这分享给有需要的师傅们~()
一、MCP协议深度解析
1.1 为什么需要MCP?
在MCP出现之前,AI模型与外部工具的集成说白了就是”百花齐放、各自为战”的状态()。OpenAI有Function Calling、Anthropic有Tool Use、Google有Function Declaration——每种模型都有自己的一套工具调用协议。开发者如果要支持多种模型,就得写多套适配代码,更麻烦的是工具提供方(比如数据库、API服务)也要为每种模型适配一套接口。这基本上就是个N×M的问题()
MCP解决的就是这个问题:定义一套通用的、模型无关的、开放的工具交互标准。感觉有点像USB协议之于外设——你不需要为每个USB设备分别写驱动,插上就能用。MCP让任何AI模型都能直接”即插即用”地使用任何MCP兼容的工具,把生态接入的N×M问题降维成了N+M。说白了就是做了一个统一的”接口层”()
1.2 协议架构与三大原语
MCP采用经典的Client-Server架构,基于JSON-RPC 2.0通信:
MCP Client (AI IDE/Host) MCP Server (Tool Provider)
例如:Cursor、Claude Desktop 例如:数据库工具、文件系统、
Cherry Studio、Windsurf API网关、代码模板库
MCP协议定义了三个核心原语(Primitives),师傅们直接看这个表就清楚了():
| 原语 | 方向 | 典型方法 | 用途 |
|---|---|---|---|
| Tools | Client→Server | tools/list, tools/call | AI调用外部工具执行操作(查数据库、调API、生成代码) |
| Resources | Client→Server | resources/list, resources/read | AI读取外部数据源(文件内容、配置、文档) |
| Prompts | Server→Client | prompts/list, prompts/get | 服务端提供预置提示词模板,指导AI如何使用工具 |
1.3 传输层:stdio vs HTTP
MCP支持两种传输方式:stdio(标准输入输出)——MCP Server作为子进程启动,通过stdin/stdout跟Client通信,零网络配置、天然隔离,IDE(Cursor、Windsurf)基本上都走这个方式;HTTP+SSE——MCP Server作为HTTP服务运行,适合远程工具或者需要水平扩展的场景。CodeStyle的远程检索模式用的就是HTTP方式()
二、Spring AI的MCP实现
Spring AI从2.0版本开始深度集成MCP,提供开箱即用的McpServer和McpClient。核心设计其实就是注解驱动——开发者只需在方法上加个@Tool注解,然后框架自动完成扫描注解→提取方法签名和参数类型→生成JSON Schema→注册为MCP Tool→暴露给MCP Client。对于Java技术栈的师傅们来说,这个体验算是非常丝滑了()
@Component
public class CodestyleTools {
@Tool(description = "搜索代码模板库,匹配最佳实践的代码模板")
public List<TemplateResult> codestyleSearch(
@ToolParam(description = "搜索关键词,如CRUD、分页查询") String keyword,
@ToolParam(description = "编程语言:Java, TypeScript, Python等") String language
) {
return searchService.search(keyword, language);
}
@Tool(description = "根据模板路径获取完整模板内容")
public String getTemplateByPath(
@ToolParam(description = "模板路径")
String path
) {
return templateService.loadTemplate(path);
}
}
还有个容易被忽略但非常重要的优化——Tool Group:每个MCP工具的Schema(名称、描述、参数类型)都会占用AI的上下文窗口token。通过codestyle.tool-group配置实现按需暴露,比如-Dcodestyle.tool-group=template直接只暴露模板相关工具(3个),比暴露全部(6个)节省约60%的token。说白了,不是工具越多越好,而是越精准越好()
三、CodeStyle系统架构设计
CodeStyle的完整系统架构分为四层:AI IDE层→MCP Server层→CodeStyle管理后台→数据存储层。最核心的设计其实是两阶段渐进式RAG检索()
阶段一:轻量预览。用户搜索的时候,系统不直接加载所有匹配模板的完整内容,而是只查meta.json索引文件(轻量级元数据汇总),返回每个模板的description、分类、标签等摘要信息。一次搜索匹配15个模板,也才消耗几百个token()
阶段二:按需加载。用户/AI从预览列表里挑了感兴趣的模板,然后通过getTemplateByPath加载完整内容。如果本地缓存不存在(首次使用),就直接从远程仓库同步下载过来()
这个设计的收益算是非常显著了:直接减少约80%的无效上下文消耗。假设搜索”CRUD模板”匹配15个结果,每个完整模板约2000 tokens,一次性加载就是30000 tokens——加上对话历史和系统提示词,很容易就超出模型上下文窗口了。这是我在做这个项目时学到的最重要的一课:不是返回越多越好,而是返回越精准越好()
检索引擎支持双模式切换:本地Lucene模式(SmartChineseAnalyzer中文智能分词、零依赖、SHA256增量同步)适合个人开发者和离线环境;远程Open API模式(Elasticsearch ik_max_word分词、AccessKey+SecretKey HMAC签名认证)适合团队和企业多用户共享。感觉这块设计得还挺灵活的()
四、总结与展望
MCP协议为AI工具生态带来了真正的统一接口。对工具提供方(比如CodeStyle),只需实现一次MCP Server,就能直接让所有主流AI IDE使用。Spring AI的注解驱动实现让Java开发者几乎零学习成本,算是很友好了()
CodeStyle在此基础上构建了完整的代码知识库体系——从模板制作、存储、检索到IDE内代码生成,形成闭环。目前项目已在GitHub开源,核心代码约15000行Java+5000行Vue,两个版本迭代下来,架构算是相对稳定了。最让我有成就感的是两阶段渐进式检索这个设计——说实话一开始完全没想到上下文窗口会是个问题,踩了坑才改过来的()
项目地址:CodeStyle(码蜂) | MCP Codestyle Server,欢迎各位师傅来玩~
说实话,MCP这个协议一开始看文档的时候感觉挺抽象的,但真正跟着Spring AI的实现走一遍,然后自己动手搭一个MCP Server出来,其实也没那么难()核心思想其实就是——定义一套标准的工具描述协议,让AI能直接理解和调用你的工具,然后把协议细节全部交给框架处理。这块虽然概念不少,但跟着做一遍也就能上手了()。接下来打算再看看MCP在资源(Resources)和提示词(Prompts)方面的更多玩法,感觉可挖的东西还挺多的,继续努力吧()
