当前位置: 首页 > news >正文

Java开发MCP服务器

前言

预训练的大语言模型虽然强大,但是知识库停留在训练的那一刻,无法获取实时的数据,导致大模型在某些场景下表现的很不好。

例如,你询问大模型关于实时天气、实时新闻的看法,大模型要么无法回答,要么胡乱编造结果,这显然不是我们想看到的结果。

好在,MCP 协议的诞生,打通了 AI 应用和外部系统的集成问题,大模型不仅可以获取互联网上公开的最新数据,甚至可以访问企业内部系统的保密数据,只要你开发好相应的MCP服务器即可。

本文通过一个“天气MCP服务器”为例。

MCP服务器开发

MCP 是 Model Context Protocol 的缩写,中文译为“模型上下文协议”。

协议即标准,有了标准,厂商就可以根据标准开发并封装成依赖包,减少重复开发的成本。官方提供了各语言的开发包,以 Java 为例,仓库地址:https://github.com/modelcontextprotocol/java-sdk

在 Spring 项目中,为了更好的集成 MCP,Spring 做了进一步的封装。

首先,引入spring-ai-bom

<dependencyManagement><dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-bom</artifactId><version>${spring-ai.version}</version><type>pom</type><scope>import</scope></dependency></dependencies>
</dependencyManagement>

如果通过webmvc的方式集成,就引入spring-ai-starter-mcp-server-webmvc

<dependencies><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-server-webmvc</artifactId></dependency>
</dependencies>

到这里,环境就搭建好了。

MCP 服务器,最核心的是 Tool 的开发。Tool 是供 MCP 客户端调用的工具,由大模型负责推理该调用哪个 Tool。在代码层面,Tool 就是一个普通的 Java 方法,额外要做的,就是对这个方法加以描述,让大模型能理解,这个方法是干什么用的,需要哪些参数。

如下所示,方法weatherQuery就是一个 Tool,通过@Tool注解对方法加以描述,让 Spring 知道有这么个 Tool。为了简单,这里数据是随机生成的。

@Service
public class WeatherService {@Tool(name = "weather_query", description = "根据商品关键字搜索商品,返回一个商品列表")public String weatherQuery(@ToolParam(description = "位置", required = true) String location) {// 天气、温度 随机生成int temperature = ThreadLocalRandom.current().nextInt(10, 40);String[] weathers = {"晴", "多云", "阴", "小雨", "中雨", "大雨", "雨夹雪", "大雪"};String weatherText = weathers[ThreadLocalRandom.current().nextInt(weathers.length)];return "location=%s,temperature=%d°C,weatherText=%s".formatted(location, temperature, weatherText);}
}

最后,将包含 Tool 的对象封装到 ToolCallbackProvider,注册到 Spring 上下文容器,再由 Spring 注册到 MCP 服务器。

@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}@Beanpublic ToolCallbackProvider toolCallbackProvider(WeatherService weatherService) {return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();}
}

启动 Spring 应用,访问http://127.0.0.1:8080/sse能打开新的会话,表示MCP服务正常。

MCP 服务器默认由两个端点:

  • /sse sse连接,创建会话的端点
  • **/mcp/message **MCP客户端和服务器消息收发的端点

如果像修改端点,可以通过如下配置:

spring:ai:mcp:server:enabled: truetype: syncsse-endpoint: /ssesse-message-endpoint: /mcp/message

MCP客户端测试

MCP 服务器开发好以后,可以对外发布,然后添加到大模型服务平台,供AI应用调用。

当然,我们也可以先通过 MCP 客户端本地调试下,确保没问题,再发布。

开发 MCP 客户端,需要先引入依赖

<dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>

然后,构建 McpSyncClient 和服务器建立连接,并通信。

如下所示,先初始化,再列举服务器支持的 Tools。

public static void main(String[] args) {McpClientTransport transport = new HttpClientSseClientTransport("http://127.0.0.1:8080/sse");McpSyncClient client = McpClient.sync(transport).requestTimeout(Duration.ofSeconds(10)).capabilities(McpSchema.ClientCapabilities.builder().roots(false).build()).build();// 初始化McpSchema.InitializeResult initialize = client.initialize();// 列举服务器支持的ToolsMcpSchema.ListToolsResult tools = client.listTools();for (McpSchema.Tool tool : tools.tools()) {System.err.println(tool);}client.closeGracefully();
}

正常情况下应该有下图所示的输出

客户端发起 Tool 调用,代码示例:

McpSchema.CallToolRequest callToolRequest = new McpSchema.CallToolRequest("weather_query", Map.of("location", "杭州"));
McpSchema.CallToolResult callToolResult = client.callTool(callToolRequest);
System.err.println(callToolResult.content());

正常应该得到结果

[TextContent[audience=null, priority=null, text="location=杭州,temperature=38°C,weatherText=中雨"]]

部署到大模型服务平台

自己写 MCP 客户端去调用 MCP 服务器是没有意义的,MCP 服务器对外部署后,可以注册到大模型服务平台,供所有AI应用调用,增强AI应用的能力。

这里以阿里云的百炼为例,官网地址:https://bailian.console.aliyun.com

注册账号后,在“MCP管理”页面创建MCP服务,如下图所示:

依次填写MCP服务的名称、描述、和服务配置。因为MCP服务器我们已经开发部署完了,所以这里选http的安装方式,填写MCP服务器地址即可。

平台会创建MCP客户端和MCP服务器通信,列举服务器支持的所有工具。

可以在页面上,直接对工具发起调用,进行调试。

MCP 服务调试完成,就可以直接添加到智能体,在用户和大模型对话时,大模型会智能判断何时调用哪个工具。

例如,我们问天气相关的问题,大模型就会判断该调用天气工具了,然后MCP客户端就会发起工具调用,然后再把天气结果喂给大模型,由大模型推理回答。

![](https://i-blog.csdnimg.cn/img_convert/1bf74d2deb88bbef0542c8339d48dc22.png

http://www.xdnf.cn/news/1318591.html

相关文章:

  • thingsboard 服务器在2核CPU、2G内存资源配置下如何调优提速,适合开发/演示
  • vue封装请求拦截器 响应拦截器
  • 计算机网络 Session 劫持 原理和防御措施
  • 给纯小白的Python操作 PDF 笔记
  • 【算法】模拟专题
  • nertctl使用了解
  • B站 韩顺平 笔记 (Day 21)
  • Windows平台Frida逆向分析环境完整搭建指南
  • 机器学习05-朴素贝叶斯算法
  • 攻防世界—unseping(反序列化)
  • python的邮件发送及配置
  • 逆向Shell实战——红队技巧 vs 蓝队防御全攻略
  • Matlab数字信号处理——基于最小均方误差(MMSE)估计的自适应脉冲压缩算法复现
  • React 基础实战:从组件到案例全解析
  • Mysql笔记-错误条件\处理程序
  • 【Java后端】Spring Boot 集成 MyBatis 全攻略
  • 【前端基础】19、CSS的flex布局
  • 麒麟V10静默安装Oracle11g:lsnrctl、tnsping等文件大小为0的解决方案
  • 【编程实践】关于S3DIS数据集的问题
  • 官方正版在线安装office 365安装工具
  • react 错误边界
  • Linux系统分析 CPU 性能问题的工具汇总
  • STM32学习笔记13-通信协议I2CMPU6050
  • 海洋牧场助力可持续发展,保护海洋生态平衡
  • C语言学习笔记之文件操作
  • 基于Vue的个人博客网站的设计与实现/基于node.js的博客系统的设计与实现#express框架、vscode
  • 网络原理与编程实战:从 TCP/IP 到 HTTP/HTTPS
  • C++零拷贝网络编程实战:从理论到生产环境的性能优化之路
  • 01数据结构-插入排序
  • 如何让AI视频模型(如Veo)开口说中文?一个顶级提示词的深度拆解