下面用网络图片搜索 MCP 服务来作为mcp开发的示例

MCP 服务端开发

首先在 找到相应功能的网站生成对应的 API Key:
新建一个模块的项目,引入必要的依赖

包括 Lombok、hutool 工具库和 Spring AI MCP 服务端依赖。 引入MCP服务端的依赖

        <!-- 引入 WebMVC-->
         <dependency>
             <groupId>org.springframework.ai</groupId>
             <artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId>
             <version>1.0.0-M6</version>
         </dependency>

引入这个依赖后,会自动注册 SSE 端点,供客户端调用。包括消息和 SSE 传输端点:(默认开启SSE传输 ,要开启stdio传输的话要通过参数开启)

在 resources 目录下编写服务端配置文件。

这里我们编写两套配置方案,分别实现 stdio 和 SSE 模式的传输。

  1. stdio 配置文件 application-stdio.yml(需关闭 web 支持):

 spring:
   ai:
     mcp:
       server:
         name: yu-image-search-mcp-server  # 服务名称(唯一标识)
         version: 0.0.1                    # 服务版本
         type: SYNC                        # 同步通信模式
         stdio: true                       # 开启 stdio 传输(核心开关)
   main:
     web-application-type: none  # 关闭 Web 服务(无需监听 HTTP 端口)
     banner-mode: off            # 关闭启动日志横幅(简化输出)
  1. SSE 配置文件 application-sse.yml(需关闭 stdio 模式):

 spring:
   ai:
     mcp: 
       server:
         name: yu-image-search-mcp-server  # 服务名称(唯一标识)
         version: 0.0.1
         type: SYNC                        # 通信模式:同步
         stdio: false                      # 关闭 stdio 传输模式(核心开关),启用 SSE 模式(基于 HTTP 的服务端推送)
          

然后编写主配置文件 application.yml,可以灵活指定激活哪套配置:

 spring:
   application:
     name: yu-image-search-mcp-server
   profiles:  # 多环境配置激活开关
     active: stdio    # 2. 指定默认激活的配置环境(对应 application-{active}.yml 配置文件)
 ​
 # Web服务端口配置(仅SSE模式生效)
 server:
   port: 8127  # 定义Web容器监听端口(如Tomcat)
编写图片搜索服务类

tools 包下新建 ImageSearchTool,使用 @Tool 注解标注方法,作为 MCP 服务提供的工具。

 package com.yupi.yuimagesearchmcpserver.tools;
 ​
 import cn.hutool.core.util.StrUtil;
 import cn.hutool.http.HttpUtil;
 import cn.hutool.json.JSONObject;
 import cn.hutool.json.JSONUtil;
 import org.springframework.ai.tool.annotation.Tool;
 import org.springframework.ai.tool.annotation.ToolParam;
 import org.springframework.stereotype.Service;
 ​
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;
 ​
 @Service//标记该层为业务处理逻辑层,生成的对象会被放入 Spring 的 IoC 容器中管理
 public class ImageSearchTool {
 ​
     private static final String API_KEY = "你的API_KEY";
 ​
     private static final String API_URL = "https://api.pexels.com/v1/search";     //Pexels 提供的图片搜索接口地址
 ​
     @Tool(description = "search image from web")
     public String searchImage(@ToolParam(description = "Search query keyword") String query) {
         try {
             return String.join(",", searchMediumImages(query));   //获取中等尺寸图片的 URL 列表。String.join():将 List<String> 中的 URL 用逗号拼接成一个字符串
         } catch (Exception e) {
             return "Error search image: " + e.getMessage();
         }
     }
 ​
     /**
      * 搜索中等尺寸的图片列表
      * @param query
      * @return
      */
     public List<String> searchMediumImages(String query) {           //query 参数,传入的搜索关键词
         // 设置请求头(包含API密钥)
         Map<String, String> headers = new HashMap<>();
         headers.put("Authorization", API_KEY);
 ​
         // 设置请求参数(仅包含query,可根据文档补充page、per_page等参数)
         Map<String, Object> params = new HashMap<>();
         params.put("query", query);
 ​
         // 发送 GET 请求
         String response = HttpUtil.createGet(API_URL)   //使用工具类 HttpUtil 创建一个 GET 请求,目标地址为 API_URL(Pexels 搜索接口)。
                 .addHeaders(headers)                   //为请求添加之前构建的请求头
                 .form(params)                         //为请求添加查询参数
                 .execute()                           //执行该 HTTP 请求。
                 .body();                           //获取响应的 body 部分(即 API 返回的 JSON 字符串)。
 ​
         // 解析响应JSON
         return JSONUtil.parseObj(response)      //使用工具类 JSONUtil 将响应字符串 response 解析为JSON
                 .getJSONArray("photos")        // 从 JSON 对象中获取键为 photos 的数组(Pexels API 中,photos 数组包含搜索到的图片信息)。
                 .stream()
                 .map(photoObj -> (JSONObject) photoObj)
                 .map(photoObj -> photoObj.getJSONObject("src"))
                 .map(photo -> photo.getStr("medium"))
                 .filter(StrUtil::isNotBlank)            //过滤掉空字符串(确保返回的 URL 有效)。
                 .collect(Collectors.toList());         //将流中的元素收集为 List<String>(最终的图片 URL 列表)。
     }
 }
在主类中通过定义 ToolCallbackProvider Bean 来注册工具:
 @SpringBootApplication
 public class YuImageSearchMcpServerApplication {
 ​
     public static void main(String[] args) {
         SpringApplication.run(YuImageSearchMcpServerApplication.class, args);
     }
 ​
     @Bean
     public ToolCallbackProvider imageSearchTools(ImageSearchTool imageSearchTool) {
         return MethodToolCallbackProvider.builder()
                 .toolObjects(imageSearchTool)
                 .build();
     }
 }

至此就开发完成了,最后使用 Maven Package 命令打包,会在 target 目录下生成可执行的 JAR 包,等会儿客户端调用时会依赖这个文件。

客户端开发

接下来直接在项目中开发客户端,调用刚才创建的图片搜索服务。

先引入必要的 MCP 客户端依赖
 <dependency>
     <groupId>org.springframework.ai</groupId>
     <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
     <version>1.0.0-M6</version>
 </dependency>
编写对应传输方式的配置文件

用 stdio 传输方式。在 mcp-servers.json 配置文件中新增 MCP Server 的配置,通过 java 命令执行我们刚刚打包好的 jar 包。代码如下:

 {
   "mcpServers": {                                       // MCP 服务配置的根节点,用于管理多个 MCP 服务
     "yu-image-search-mcp-server": {                    // 服务的唯一标识名称(与 Spring Boot 应用名对应)
       "command": "java",                              // 启动服务的核心命令:使用 Java 命令
       "args": [                                      // 传递给 Java 命令的参数列表
         "-Dspring.ai.mcp.server.stdio=true",        // 启用 stdio 传输模式(通过标准输入输出流通信)
         "-Dspring.main.web-application-type=none",  // 关闭 Web 服务(不启动 Tomcat 等容器)
         "-Dlogging.pattern.console=",               // 清空控制台日志格式(简化输出,仅保留必要信息)
         "-jar",                                     // Java 命令固定参数:表示后续为可执行 JAR 包路径
         "yu-image-search-mcp-server/target/yu-image-search-mcp-server-0.0.1-SNAPSHOT.jar"  // 服务的 JAR 包路径(编译后的可执行文件)
       ],
       "env": {}                                     // 启动服务时需要设置的环境变量(当前为空,无需额外环境变量)
     }
   }
 }

用 SSE 连接方式

1.修改 MCP 服务端的配置文件,激活 SSE 的配置:

2.修改客户端的配置文件,添加 SSE 配置,同时要注释原有的 stdio 配置以避免端口冲突:

 spring:
   ai:
     mcp:
       client:
         sse:
           connections:
             server1:
               url: http://localhost:8127
         # stdio:
         # servers-configuration: classpath:mcp-servers.json   //指向 `mcp-servers.json` 配置
测试运行。编写单元测试代码
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐