当前位置: 首页 > 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.dtcms.com/a/335402.html

相关文章:

  • 云计算-K8s 实战:Pod、安全上下文、HPA 、CRD、网络策略、亲和性等功能配置实操指南
  • 大模型提示词(Prompt)终极指南:从原理到实战,让AI输出质量提升300%
  • PS复刻八一电影制片厂经典片头
  • Pandas 2.0 + Arrow 加速、Dask vs Ray、Plotly 可视化:数据分析的未来
  • Centos中内存CPU硬盘的查询
  • MySQL库表操作
  • 基于多Agent的AFSIM复杂场景脚本生成技术(使用Claude Code)
  • 【牛客刷题】 计算01串通过相邻交换变成目标串的最大交换次数
  • 【深度学习-基础知识】单机多卡和多机多卡训练
  • 【Linux系统】动静态库的制作
  • 接口参数校验工具类ValidationParamUtils,让参数校验从“繁琐、重复”变得“省事、简单”!
  • Python文本过滤与清理完全指南:从基础到高级工程实践
  • go基础学习笔记
  • RAG 分块中表格填补简明示例:Markdown、HTML、Excel、Doc
  • C++核心语言元素与构建块全解析:从语法规范到高效设计
  • 编译器生成的合成访问方法(Synthetic Accessor Method)
  • TensorRT-LLM.V1.1.0rc0:在无 GitHub 访问权限的服务器上编译 TensorRT-LLM 的完整实践
  • Linux容器基石:LXC核心概念与实践指南
  • Flink Stream API核心概念继承体系
  • 代码随想录算法训练营四十四天|图论part02
  • 像海绵一样吸收技术书籍的高效学习方法
  • [Go]包管理发展之路(Go Modules VS GOPATH)
  • 【Jenkins】02 - 自动化部署配置
  • 简单的 VSCode 设置
  • 利用vscode时进行调试,即使设置justMyCode为False仍然失败,如何解决?
  • 嵌入式练习项目——————抓包获取天气信息
  • 【Linux | 网络】高级IO
  • SQL性能优化全攻略
  • 基于libcurl与epoll的高性能异步FTP客户端
  • 数据准备|生成折线图