Java 实现 MCP Server 以及常用 MCP 服务分享
MCP 前段时间在 AI 领域 引发了 广泛关注,特别是在 各大海内外技术社区 中,大家热烈讨论,热度非常高,本文将带领大家使用 java 语言实现一个 mcp,揭开 mcp 这神秘的面纱,本文最后也推荐给大家一些常用的 MCP 服务,开箱即用 0 成本,希望对大家有一定的帮助。
概念
MCP(Model Context Protocol,即模型上下文协议)是由 Anthropic(Claude 的母公司)于 2024年11月 开源发布的一项 全新技术。
MCP 是为了解决大模型虽然强大,但是有时候无法获取实时信息以及访问特定工具!而 MCP 是一种让AI能够"伸出手"使用外部工具和服务的协议,让AI变得更加强大和实用。
想象一下,你正在和AI助手聊天,突然想让它帮你搜索最新的新闻,或者查看你的文件,甚至操作数据库——有了MCP,这些都成为可能!
简单来说,MCP 是一个 AI 大模型的标准化工具箱。
大模型可以通过这些工具与 外界互动,获取信息,并 完成具体任务。
在日常工作和学习中,我们经常需要与 浏览器、文件、数据库 和 代码仓库 等外部工具进行交互。
MCP的工作原理
- 服务器(Server):提供特定功能的工具,比如网页搜索、文件访问等
- 客户端(Client):在AI应用中与服务器保持连接
- 传输(Transport):客户端和服务器之间的通信方式
- 主机(Host):启动连接的应用程序,如Cherry Studio或Claude Desktop、Cline、Cursor、WindSurf
上图图说明了MCP协议就像是现在日常使用的USB协议,让AI和外部工具之间可以方便地传输数据和指令。
大白话,其实 MCP 就是对以前的 FunctionCall 进行标准化,早期大模型支持 FunctionCall 都是自家按照自己的路线走,导致不能用,自己家有自己家的标准,导致对接多家 FunctionCall 模型麻烦,Claude 发布了 MCP 协议,类似于 jdbc 标准,大家都按照统一的协议进行传输,大家一起开发 MCP 服务供大家使用,也不用对这个概念过于神秘化。
Java实现一个 MCP Server
官方 mcp 文档可参考:https://modelcontextprotocol.io/quickstart/server
在 AI 方面用 python 语言实现更优雅,作为 javaer 还是打算用 java 实现,感兴趣的朋友可以参考官方文档也提供不同语言的 SDK 快速集成。
博主使用 Spring AI 简易实现,学会儿了可以举一反三,官方文档很多示例,可以多看多练。
前提条件
1、 JDK17/21、Spring Boot 3.4.x+、Spring AI 1.0.0-M6+
2、支持 MCP 的客户端,我这里使用 Cherry Studio
3、一个支持 FunctionCall 的大模型,可以是 ollama 自建或者 云 API(推荐硅基流动)。
4、一双勤劳的双手
项目搭建
- 直接使用 spring脚手架搭建,注意 springboot 版本一定要大于 3.4x,不然不支持 Spring AI,新项目就直接无脑上 JDK17+SpringBoot3 吧。
pom 引入如下核心依赖:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.4.4</version> <relativePath/> </parent> <groupId>com.lcry</groupId> <artifactId>java-mcp-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>java-mcp-demo</name> <description>java-mcp-demo</description> <url/> <developers> <developer> <name>lcry</name> <url>https://www.51it.wang</url> </developer> </developers> <properties> <java.version>17</java.version> <spring-ai.version>1.0.0-M7</spring-ai.version> </properties> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-starter-mcp-server-webflux</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-SNAPSHOT</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <releases> <enabled>false</enabled> </releases> </repository> <repository> <name>Central Portal Snapshots</name> <id>central-portal-snapshots</id> <url>https://central.sonatype.com/repository/maven-snapshots/</url> <releases> <enabled>false</enabled> </releases> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </project>
核心依赖是:spring-ai-starter-mcp-server-webflux
更多实现可以参考 spring ai 官方完整文档:https://docs.spring.io/spring-ai/reference/1.0/api/mcp/mcp-server-boot-starter-docs.html
新建一个天气服务,本地就直接模拟,实际开发可以直接调用第三方 API:WeatherService.java 如下:
import org.springframework.ai.tool.annotation.Tool; import org.springframework.ai.tool.annotation.ToolParam; import org.springframework.stereotype.Service; /** * WeatherService * * @author lcry * @since 2025/04/22 21:11 */ @Service public class WeatherService { @Tool(description = "根据城市名称获取天气预报信息") public String getWeather(@ToolParam(description = "城市") String cityName) { return cityName + "天气阳光明媚~"; } @Tool(description = "根据城市名称获取空气质量") public String getAirQuality(@ToolParam(description = "城市") String cityName) { return cityName + "空气质量很好 by: lcry~"; } }
@Tool注解标记是一个工具,description 描述工具的作用,方便 AI 识别并调用。
@ToolParam 注解标记参数信息,告知 AI 参数是否必填以及含义
新增一个配置类,将工具暴露出来:ToolConfig.java
/** * ToolConfig * * @author lcry * @since 2025/04/22 21:08 */ @Component public class ToolConfig { @Bean public ToolCallbackProvider myTools(WeatherService weatherService) { return MethodToolCallbackProvider.builder() .toolObjects(weatherService) .build(); } }
最后配置一下 mcp server 的一些配置:application.yml
spring: application: name: java-mcp-demo # main: # 必须禁用控制台日志和 banner,否则会干扰通信 # web-application-type: none # STDIO必须禁用web应用类型 # banner-mode: off # STDIO禁用banner --- # Using spring-ai-starter-mcp-server spring: ai: mcp: server: name: stdio-mcp-server version: 1.0.0 type: SYNC --- # Using spring-ai-starter-mcp-server-webmvc spring: ai: mcp: server: name: webmvc-mcp-server version: 1.0.0 type: SYNC sse-message-endpoint: /mcp/messages --- # Using spring-ai-starter-mcp-server-webflux spring: ai: mcp: server: name: webflux-mcp-server version: 1.0.0 type: ASYNC # Recommended for reactive applications sse-message-endpoint: /mcp/messages
最后启动项目,日志中打印
Registered tools: 2, notification: true
则成功。通过
spring-ai-starter-mcp-server-webflux
方式,对外暴露端点就是sse:public class McpServerProperties { public static final String CONFIG_PREFIX = "spring.ai.mcp.server"; private boolean enabled = true; private boolean stdio = false; private String name = "mcp-server"; private String version = "1.0.0"; private String instructions = null; private boolean resourceChangeNotification = true; private boolean toolChangeNotification = true; private boolean promptChangeNotification = true; private String baseUrl = ""; private String sseEndpoint = "/sse"; private String sseMessageEndpoint = "/mcp/message"; private ServerType type; private Map<String, String> toolResponseMimeType; public McpServerProperties() { this.type = McpServerProperties.ServerType.SYNC; this.toolResponseMimeType = new HashMap(); } .....省略
编写测试用例访问 MCP Server:
/** * @author lcry */ public class ClientSse { public static void main(String[] args) { var transport = new WebFluxSseClientTransport(WebClient.builder().baseUrl("http://localhost:8080")); var client = McpClient.sync(transport).build(); client.initialize(); client.ping(); // 列出并展示可用的工具 McpSchema.ListToolsResult toolsList = client.listTools(); System.out.println("可用工具 = " + toolsList); // 获取成都的天气 McpSchema.CallToolResult weatherForecastResult = client.callTool(new McpSchema.CallToolRequest("getWeather", Map.of("cityName", "成都"))); System.out.println("返回结果: " + weatherForecastResult.content()); client.closeGracefully(); } }
日志成功打印则一个简单的 MCP Server 实现完成,通过 sse 的方式进行交互:
20:29:54.434 [reactor-http-nio-2] INFO io.modelcontextprotocol.client.McpAsyncClient -- Server response with Protocol: 2024-11-05, Capabilities: ServerCapabilities[experimental=null, logging=LoggingCapabilities[], prompts=null, resources=null, tools=ToolCapabilities[listChanged=true]], Info: Implementation[name=webflux-mcp-server, version=1.0.0] and Instructions null 可用工具 = ListToolsResult[tools=[Tool[name=getWeather, description=根据城市名称获取天气预报信息, inputSchema=JsonSchema[type=object, properties={cityName={type=string, description=城市}}, required=[cityName], additionalProperties=false]], Tool[name=getAirQuality, description=根据城市名称获取空气质量, inputSchema=JsonSchema[type=object, properties={cityName={type=string, description=城市}}, required=[cityName], additionalProperties=false]]], nextCursor=null] 返回结果: [TextContent[audience=null, priority=null, text="成都天气阳光明媚~"]]
客户端使用
搭建完服务端之后,我们就可以在支持 MCP 客户端进行添加使用了,我这里以cherry studio 演示:
以此点击左下角齿轮 -> MCP服务器 -> 添加服务器,如下图填写:
点击启用之后连接成功之后,查看工具可以看到我们自己写的两个工具:
然后打开助手,勾选我们添加的 MCP 开始对话,就可以看到调用了我们自己的接口,可以看到请求响应参数:
Claude使用
如果你想直接在本地模式下使用,首先将 java 项目打包成 jar,执行下面命令:
mvn clean package -Dmaven.test.skip=true
然后 claude 配置 MCP 配置:
{
"mcpServers": {
"weather-starter-webmvc-server": {
"command": "java",
"args": [
"-Dspring.ai.mcp.server.stdio=true",
"-Dspring.main.web-application-type=none",
"-Dlogging.pattern.console=",
"-jar",
"/absolute/path/target/java-mcp-demo-0.0.1-SNAPSHOT.jar" # 这里改成你打包后的绝对路径位置
]
}
}
}
其实就是本地运行,注意需要提前安装 java 不然无法运行哦。
代码分享
本案例完整代码见 github 仓库:https://github.com/Lcry/java-mcp-demo.git
总结
通过本文可以用java语言实现一个简单的 mcp server服务,但是对springboot版本和jdk都有一定的要求,对于老项目2.x的和1.8的项目可以通过langchain4j的框架实现,适配度更高,spring ai由于还没有发布正式版,还不能正式用于生产项目,M6版本之前对starter等命名都做了一定条件,还不具备生产可用的稳定版本,但是看spring ai的开发进度和spring生态的支持,只要推广开前途可简,如果非要上生产Java语言可以选择langchain4j框架,相对来说稳定一些和手动档扩展性更强。
在 AI 飞速发展的时代,我们也要关注一些前沿的技术持续学习,让自己能够有足够的竞争力,这两天刷到说传智播客都已经准备ts了,当初实习还看过它家的视频,没想到吧,培训班机构这几年也是特别卷了,互联网真是一言难尽,持续学习吧,AI 还是能干很多事情的,即便是转行也能有一定的基础。
最后的最后,AI 虽然很强大,但是请注意安全问题,防止将自己的隐私数据偷偷的上传了:
MCP 虽然功能强大,并且拥有广泛的应用前景,但在实际使用过程中,务必注意安全问题。在允许模型操作本地文件之前,建议提前对 HOST 可访问的目录和文件范围进行严格限制,以防止敏感信息泄露,避免产生开盒、信息泄密等安全风险。
另外,模型必须支持 Function Calling(允许模型调用外部工具以增强自身能力) 才能正常使用 MCP 功能。
MCP 公开服务推荐
在此推荐一些公开的MCP服务聚合的平台,可以方便的找到常用的 mcp,无需再全部自己开发了。
modelscope MCP广场:https://modelscope.cn/mcp
MCP市场:https://mcpmarket.cn/
MCP搜:https://mcp.so/
glama 开源MCP:https://glama.ai/mcp/servers
smithery:https://smithery.ai/
Mcp Servers:https://mcpservers.org/
MCP run:https://www.mcp.run/
参考链接
商业转载请联系作者获得授权,非商业转载请注明本文出处及文章链接