MCP协议是什么?Java后端五分钟搞懂Model Context Protocol,把自己变成LLM的工具
MCP的本质是LLM调工具的标准化协议。对Java后端来说开发MCP Server就是写Spring Bean加​​Tool​​注解简单得很。难点在协议理解、传输模式选择、客户端适配、踩坑处理。写过Spring AI的Function Calling是不是觉得LLM调工具这事儿已经搞定了我去年也是这么想的。直到Anthropic推了MCPCursor、Claude Desktop、Windsurf全跟进我才反应过来--Function Calling是能调MCP是标准地调。这俩不是替代关系是层次不同。这篇文章讲Java后端怎么开发MCP Server让自家业务系统变成Claude/Cursor能直接用的工具。适合正在搞AI工程化的Java开发读完能跑通第一个MCP Server。MCP到底是个啥Model Context ProtocolAnthropic 2024年11月推出的开放协议。说白了就是LLM与应用系统之间的通信标准。后端视角理解MCP之于LLM相当于JDBC之于数据库。JDBC让Java代码用统一接口操作不同数据库MCP让LLM用统一协议调用不同应用系统。一次开发MCP Server所有支持MCP的客户端Claude Desktop、Cursor、Windsurf、Continue都能用你的工具。协议层基于JSON-RPC 2.0三大原语Tools工具调用、Resources资源读取、Prompts提示词模板。传输层两种stdio本地进程通信和SSE/HTTP远程通信。我的体感是MCP不是又一个Function Calling它是把LLM调工具这件事协议化、标准化。以前每家LLM厂商自己定义工具调用格式OpenAI一套、Anthropic一套、Google一套开发者要适配多次。MCP出来后写一次MCP Server所有客户端通吃。为啥需要MCPFunction Calling的问题很明显。第一每个LLM厂商格式不同OpenAI的tools参数结构和Anthropic的tool_use完全两套业务代码要写多份适配。第二工具定义散落在应用代码里没法复用--A项目写的查订单工具B项目要重新写。第三工具调用和业务系统耦合没法独立部署、独立升级。MCP的解法是解耦。把工具能力抽成独立的MCP Server业务系统专注于实现工具逻辑LLM客户端专注于调用。MCP Server就像微服务架构里的一个独立服务有自己的进程、自己的生命周期。举个具体场景。我们有个内部工单系统以前接Claude要写一套Function Calling接Cursor要再写一套接自家产品还要再适配。改成MCP Server后写一次三个客户端都能用维护成本降了三分之二。扯远了说回MCP本身。这玩意儿2024年底推出2025年生态爆发2026年Spring AI 1.0正式集成MCP Server支持。现在是上车的最佳时机--早了没受众晚了烂大街。Java开发MCP ServerSpring AI 1.0提供了spring-ai-mcp-server-spring-boot-starter开发MCP Server跟写普通Spring Bean一样简单。依赖就引这一个starter版本由Spring AI BOM统一管别单独指定版本号。application.yml关键配置spring: ai: mcp: server: name: order-query-server version: 1.0.0 # stdio模式适合本地客户端Claude Desktop # sse模式适合远程客户端Cursor云端 type: STDIO # 工具调用超时别设太长LLM等不起 request-timeout: 30s核心MCP Server代码用真实业务对象Service public class OrderQueryService { private final OrderMapper orderMapper; private final OrderStatusDecoder statusDecoder; public OrderQueryService(OrderMapper orderMapper, OrderStatusDecoder statusDecoder) { this.orderMapper orderMapper; this.statusDecoder statusDecoder; } /** * Tool注解标记这是MCP工具方法LLM能调用 * name和description必填LLM靠description判断何时调用 */ Tool(name query_order, description 根据订单号查询订单状态、金额、物流信息。输入订单号返回订单详情。) public OrderDetail queryOrder(ToolParam(description 订单号纯数字) String orderId) { // MCP工具方法本质就是普通Java方法LLM传入参数返回结果 // 别在这里写复杂逻辑LLM等不起超时30秒就断了 Order order orderMapper.selectById(orderId); if (order null) { throw new ToolExecutionException(订单不存在: orderId); } return OrderDetail.builder() .orderId(order.getId()) .status(statusDecoder.decode(order.getStatus())) .amount(order.getAmount()) .logisticsNo(order.getLogisticsNo()) .build(); } Tool(name refund_order, description 申请订单退款。需要订单号和退款原因。仅支持已发货前的订单。) public RefundResult refundOrder(ToolParam(description 订单号) String orderId, ToolParam(description 退款原因不超过200字) String reason) { // 退款涉及状态变更必须做幂等校验 // MCP工具被LLM重复调用是常事别假设只调一次 return refundService.process(orderId, reason); } }这里边有几个坑得提一下。Tool的description是LLM判断何时调用的唯一依据必须写清楚这个工具干什么、输入什么、输出什么。我一开始写得简略Claude老调错工具--用户问查物流它调了refund_order。后来把description改成根据订单号查询订单状态、金额、物流信息调用准确率从70%到95%。ToolParam的description同样重要LLM靠它理解参数含义。订单号要写纯数字否则Claude会把ORD-2026-001这种带前缀的字符串传进来数据库查不到。工具方法里别写复杂逻辑。MCP工具本质是LLM的外挂函数调用链路是LLM-MCP协议-Java方法-返回结果。中间任何一步慢了LLM会超时重试重复调用。30秒超时是我的经验值再长Claude Desktop会断开。异常必须用ToolExecutionException包装。我踩过坑直接抛RuntimeExceptionClaude收到的是空响应无法理解失败原因会一直重试。改成ToolExecutionException后错误信息会传回LLM它能看到订单不存在然后告诉用户。接入Claude Desktop测试MCP Server开发完要接到客户端测试。Claude Desktop是最常用的本地客户端。配置文件在claude_desktop_config.json位置Mac是~/Library/Application Support/Claude/Windows是%APPDATA%\Claude\。{ mcpServers: { order-query-server: { command: java, args: [-jar, /path/to/order-mcp-server.jar], env: { DEEPSEEK_API_KEY: sk-xxx } } } }配置完重启Claude Desktop在对话框里看到工具图标亮起就说明MCP Server连上了。实测效果。我问Claude帮我查下订单20260723001的状态它会自动调用query_order工具拿到结果后用自然语言回复您的订单已发货物流单号SF1234567890预计明天送达。整个过程用户无感知就像Claude自己知道订单信息一样。真香。第一次跑通的时候我在工位上乐了半天旁边同事以为我中奖了。踩过的坑坑一stdio模式下日志不能打到stdout。stdio传输用stdout传JSON-RPC消息日志打到stdout会污染协议流Claude Desktop直接断连。必须把日志打到stderr或文件。这个坑我查了两天日志一加就挂最后才反应过来。坑二工具方法不能有同名重载。MCP协议用方法名做唯一标识Java的重载在MCP层面会冲突。两个queryOrder方法一个传String一个传LongMCP Server启动报错。解法是改名--queryOrderById和queryOrderByName。坑三返回对象必须可序列化。LLM拿到的结果是JSON返回对象的字段要全部可序列化。我返回过一个含LocalDateTime的对象Claude收到的是空对象因为Jackson默认不认LocalDateTime。加JsonFormat或配jackson-datatype-jsr310模块。坑四sse模式要单独暴露端口。stdio模式是本地进程通信sse模式是HTTP服务要单独开端口。我一开始把MCP Server和业务系统塞一个进程结果MCP端口被业务流量冲垮。后来拆成独立进程问题解决。坑五权限沙箱。Claude Desktop对MCP Server有权限限制文件系统访问、网络访问都受控。我的工具要读/etc/config/order.json被沙箱拦了。解法是把配置改成环境变量传入或者用Claude Desktop的权限配置显式授权。MCP vs Function Calling这俩不是替代关系是层次不同。Function Calling是LLM厂商定义的工具调用格式OpenAI、Anthropic、Google各有各的。MCP是Anthropic推出的开放协议标准化了LLM怎么发现工具、怎么调用工具、怎么传参、怎么返回结果。选型上如果只用一家LLMFunction Calling够用简单直接。如果要支持多客户端Claude Desktop、Cursor、自家产品MCP一次开发通吃维护成本低。我的判断是MCP会成为事实标准就像REST之于Web API。现在投入MCP是给未来铺路。面试官会怎么问这块的问题套路我面过几个候选人整理一下。Q1MCP和Function Calling什么关系Function Calling是LLM厂商定义的工具调用格式每家不同。MCP是Anthropic推出的开放协议标准化了工具发现、调用、传参、返回的完整流程。MCP在协议层Function Calling在能力层。MCP Server一次开发所有支持MCP的客户端通吃。Q2MCP三大原语是什么Tools工具调用、Resources资源读取、Prompts提示词模板。Tools是LLM调用业务方法比如查订单。Resources是LLM读取静态资源比如配置文件。Prompts是LLM使用预定义的提示词模板比如代码review模板。生产中Tools用得最多。Q3stdio和sse两种传输模式怎么选stdio是本地进程通信适合Claude Desktop这种本地客户端延迟低但只能本机用。sse是HTTP服务适合远程客户端Cursor云端、自家产品能跨网络但延迟高。本地工具用stdio对外服务用sse。Q4MCP Server开发有什么坑五个坑。stdio模式日志不能打stdout会污染协议流。工具方法不能同名重载MCP按名识别。返回对象必须可序列化LocalDateTime要加注解。sse模式要单独端口别和业务塞一起。Claude Desktop权限沙箱限制文件和网络访问。Q5大厂追问字节/百度会问什么字节会问MCP协议的JSON-RPC 2.0底层、sse模式的长连接管理。百度会问MCP与Function Calling的协议差异、MCP在RAG中的应用。核心都是你有没有真的开发过MCP Server、踩过哪些坑。回头看MCP的本质是LLM调工具的标准化协议。对Java后端来说开发MCP Server就是写Spring Bean加Tool注解简单得很。难点在协议理解、传输模式选择、客户端适配、踩坑处理。我的判断是MCP会成事实标准。现在投入是给未来铺路。等Claude Desktop、Cursor、Windsurf都普及了再写MCP就跟现在写REST API一样自然。

相关新闻

Python数据分析实战:从Pandas数据处理到电商用户行为分析

Python数据分析实战:从Pandas数据处理到电商用户行为分析

很多同学在入门数据分析时,面对海量的教程和零散的知识点,常常感到无从下手,既想掌握Python编程,又想精通数据分析、数据挖掘和可视化,甚至了解大数据生态。网上资料虽多,但体系化、能串联从零基础到项目实…

2026/10/31 22:13:10 阅读更多 →
OpenCourseCatalog:如何高效获取全球顶尖高校的公开课资源?

OpenCourseCatalog:如何高效获取全球顶尖高校的公开课资源?

OpenCourseCatalog:如何高效获取全球顶尖高校的公开课资源? 【免费下载链接】OpenCourseCatalog Bilibili 公开课目录 项目地址: https://gitcode.com/gh_mirrors/op/OpenCourseCatalog OpenCourseCatalog是一个专注于整理和收集Bilibili上全球顶…

2026/10/31 22:13:10 阅读更多 →
呆啵宠物:你的专属桌面AI伴侣,重新定义数字陪伴体验

呆啵宠物:你的专属桌面AI伴侣,重新定义数字陪伴体验

呆啵宠物:你的专属桌面AI伴侣,重新定义数字陪伴体验 【免费下载链接】DyberPet Desktop Cyber Pet Framework based on PySide6 项目地址: https://gitcode.com/GitHub_Trending/dy/DyberPet 你是否曾幻想过,让心爱的二次元角色真正&q…

2026/10/31 22:13:09 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年,我大部分时间都在跟浏览器标签页打交道,直到第一次把桌面应用跑起来,才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词,最开始是在某段时间频繁出现在同事的讨论里,一个用HTML…

2026/11/1 0:24:43 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介:亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档,主要面向智能锁安装人员、终端用户及售后维护者,帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件,大小4.37MB,内容结构清晰&#xff…

2026/11/1 10:36:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统,整车要求空载跑到8m/s,电机转速已经拉到额定点,驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令,转速纹丝不动,三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/11/1 10:36:51 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年,用它写过嵌入式驱动、做过游戏服务端,也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词,我其实挺感慨的——这门语言的难点从来不是语法多,而是知识点之间的耦合太深…

2026/11/1 1:06:58 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介:亚太天能T109滑盖智能锁产品说明书以PDF格式发布,适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开,先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能,再给出完整安装步骤&…

2026/11/1 10:35:11 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历:翻开源码注释、论文摘要或者一份专业报告,每个字都认识,连在一起却像天书。想找人聊聊,身边要么没人懂,要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型,几秒钟之后&a…

2026/11/1 9:35:41 阅读更多 →

日新闻

周新闻

月新闻