MCP 前段时间在 AI 领域 引发了 广泛关注,特别是在 各大海内外技术社区 中,大家热烈讨论,热度非常高,本文将带领大家使用 java 语言实现一个 mcp,揭开 mcp 这神秘的面纱,本文最后也推荐给大家一些常用的 MCP 服务,开箱即用 0 成本,希望对大家有一定的帮助。

概念

MCPModel Context Protocol,即模型上下文协议)是由 AnthropicClaude 的母公司)于 2024年11月 开源发布的一项 全新技术

MCP 是为了解决大模型虽然强大,但是有时候无法获取实时信息以及访问特定工具!而 MCP 是一种让AI能够"伸出手"使用外部工具和服务的协议,让AI变得更加强大和实用。

想象一下,你正在和AI助手聊天,突然想让它帮你搜索最新的新闻,或者查看你的文件,甚至操作数据库——有了MCP,这些都成为可能!

简单来说,MCP 是一个 AI 大模型的标准化工具箱

大模型可以通过这些工具与 外界互动获取信息,并 完成具体任务

在日常工作和学习中,我们经常需要与 浏览器文件数据库代码仓库 等外部工具进行交互。

MCP的工作原理

  1. 服务器(Server):提供特定功能的工具,比如网页搜索、文件访问等
  2. 客户端(Client):在AI应用中与服务器保持连接
  3. 传输(Transport):客户端和服务器之间的通信方式
  4. 主机(Host):启动连接的应用程序,如Cherry Studio或Claude Desktop、Cline、Cursor、WindSurf

Java 实现 MCP Server 以及常用 MCP 服务分享

上图图说明了MCP协议就像是现在日常使用的USB协议,让AI和外部工具之间可以方便地传输数据和指令。

Java 实现 MCP Server 以及常用 MCP 服务分享

大白话,其实 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、一双勤劳的双手

项目搭建

  1. 直接使用 spring脚手架搭建,注意 springboot 版本一定要大于 3.4x,不然不支持 Spring AI,新项目就直接无脑上 JDK17+SpringBoot3 吧。
  2. 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

  3. 新建一个天气服务,本地就直接模拟,实际开发可以直接调用第三方 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 参数是否必填以及含义

  4. 新增一个配置类,将工具暴露出来: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();
        }
    }
  5. 最后配置一下 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
  6. 最后启动项目,日志中打印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();
        }
      .....省略
  7. 编写测试用例访问 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服务器 -> 添加服务器,如下图填写:

Java 实现 MCP Server 以及常用 MCP 服务分享

点击启用之后连接成功之后,查看工具可以看到我们自己写的两个工具:

Java 实现 MCP Server 以及常用 MCP 服务分享

然后打开助手,勾选我们添加的 MCP 开始对话,就可以看到调用了我们自己的接口,可以看到请求响应参数:

Java 实现 MCP Server 以及常用 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/

参考链接

spring-ai/reference

MCP 官方文档

Spring ai alibaba 示例仓库

mcp官方示例仓库

一文彻底搞懂 MCP:AI 大模型的标准化工具箱

文章目录