Agent开发 - MCP Client使用MCP Server的几种方式(Spring AI)

前置声明: windows系统

一、MCP Client通过mcp.json方式使用MCP Server(Claude Desktop 格式的 JSON 文件,目前仅支持 stdio 连接方式)

1. 引入pom依赖

java 复制代码
<!-- 添加Spring AI MCP Client starter依赖 -->
<!-- Source: https://mvnrepository.com/artifact/org.springframework.ai/spring-ai-mcp-client-spring-boot-starter -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
    <version>1.0.0-M6</version>
    <scope>compile</scope>
</dependency>

2. 添加application.yml配置:

java 复制代码
spring:  
  ai:
    # mcp client 客户端配置
    mcp:
      client:
        stdio:
          servers-configuration: classpath:mcp-servers.json

注意:

复制代码
1. 指定MCP服务器配置文件路径(推荐)为项目resources目录下的json文件。   
2. 流程: classpath:mcp-servers.json → 读取资源目录里打包进 jar 的文件,打包部署后依然            正常生效(推荐配置文件写法)→ Spring Boot 应用启动时读取(放在 resources 下,打进    jar)
2. 项目根目录的 .mcp.json → 不属于 classpath 资源,Spring 默认不会读取,仅给 Claude      Code IDE 使用
4. classpath:mcp-servers.json对应文件位置:src/main/resources/mcp-servers.json
5. 编译后会自动复制mcp-servers.json到 target/classes/mcp-servers.json,Spring 就能读到。

3. 在resources目录下添加mcp-servers.json文件:(推荐②)

① 配置文件如下:(开发上传到git不推荐 这种形式,包含api_key敏感信息

踩坑点: windows系统加.cmd才能找到npx命令

java 复制代码
{
    "mcpServers": {
      "amap-maps": {
        "command": "npx.cmd",
        "args": [
          "-y",
          "@amap/amap-maps-mcp-server"
        ],
        "env": {
          "AMAP_MAPS_API_KEY": "your_key_here"
        }
      }
    }
  }

② 我更推荐这种形式,将api_key放到我们电脑的系统环境变量中,避免git提交上去,json配置如下:

java 复制代码
{
  "mcpServers": {
    "amap-maps": {
      "command": "npx.cmd",
      "args": [
        "-y",
        "@amap/amap-maps-mcp-server"
      ]
    }
  }
}

配置系统环境变量:

检验系统环境变量是否能正确读取到,打开cmd输入命令:

bash 复制代码
echo %AMAP_MAPS_API_KEY%

输出密钥就说明能正确读取到。

接下来重点踩坑点 ,必须关闭idea再重新打开,这样才能将修改的环境变量刷新到idea中!

如此,json文件就配置好了!

踩坑点总结:

  1. mcp-servers.json文件放在resources目录下,而不是项目根目录

  2. json文件中windows系统使用npx.cmd而不是npx,否则找不到命令

  3. 将高德地图api_key写入系统环境变量后,一定关闭idea再打开进行刷新

4. 编写MCP Client调用MCP Server与大模型对话进行工具调用的代码:

java 复制代码
/**
     * 注入MCP服务后与AI进行对话
     * @param userMessage 用户提问
     * @param chatId 会话id
     * @return AI回复
     */
    public String doChatWithMcp(String userMessage,String chatId){
        ChatResponse chatResponse = chatClient
                .prompt()
                .user(userMessage)
                .advisors(spec -> spec.param(CHAT_MEMORY_CONVERSATION_ID_KEY, chatId)
                        .param(CHAT_MEMORY_RETRIEVE_SIZE_KEY, 10))
                .tools(toolCallbackProvider)
                .call()
                .chatResponse();

        String content = chatResponse.getResult().getOutput().getText();
        log.info("MCP invoke result - content: {}",content);
        return content;
    }

5. 编写测试代码进行真实调用的集成测试

java 复制代码
@SpringBootTest
@DisplayName("调用MCP服务中的工具与AI交互")
public class DoChatWithMcpTest {
    @Resource
    private LoveApp loveApp;

    @Test
    @DisplayName("测试高德地图MCP Server是否能正确调用")
    void loveAppDoChatWithMcp(){
        String chatId = UUID.randomUUID().toString();
        String userMessage = "我想搜索下北京市海淀区五道口附近5km内适合约会的咖啡厅,推荐三个即可";
        String result = loveApp.doChatWithMcp(userMessage, chatId);
        Assert.notNull(result,"大模型应该回复有内容的信息");
    }
}

6. 观察控制台日志,查看启动测试方法后,用户向大模型发送的两次请求内容

可以看到用户携带MCP信息向模型发送第一次请求后,返回的要调用的工具名是maps_around_search,AI回复的消息类型是ASSISTANT。

可以看到模型返回的信息中包含TOOL和高德的工具名maps_around_search,调用完工具拿到结果返回给大模型的消息类型是TOOL。

所以,我们成功调用了高德地图MCP Server且仅调用了一个工具maps_around_search。

高德开放平台控制台也可以看到只调用了一个工具。调用MCP Server的工具成功!

7. 一些疑问

① 为什么mcp-servers.json中没有设置env中的AMAP_MAPS_API_KEY,我们启动程序仍然可以读取到呢?

🔧 env 字段的作用

在 mcp-servers.json 中的 env 字段不是读取环境变量,而是设置/覆盖该 MCP Server 进程的环境变量。

✅ 正确的理解

{

"mcpServers": {

"amap-maps": {

"command": "npx.cmd",

"args": "-y", "@amap/amap-maps-mcp-server",

"env": {

"AMAP_MAPS_API_KEY": "abc123" // ← 这是设置,不是读取!

}

}

}

}

  • env 字段:为这个 MCP Server 子进程设置环境变量

  • 如果设置了,会覆盖系统环境变量中同名的值

- 优先级:JSON 中的 env > 系统环境变量


📊 环境变量优先级(从高到低)

1️⃣ mcp-servers.json 中的 "env" 配置

2️⃣ 系统/用户环境变量(Windows 环境变量)

3️⃣ ~/.amap/config.json(如果有)

我们env中没有设置api_key,所以当前流程是:

  1. mcp-servers.json 中没有 env 配置

  2. npx 启动 MCP Server 时继承父进程的环境变量

  3. 你的系统环境变量中设置了 AMAP_MAPS_API_KEY

  4. MCP Server 成功读取到该环境变量

二、(直接写入配置文件,这种方式同时支持stdio和SSE连接方式)

相关推荐
仓三28 分钟前
从 Prompt Engineering 到 Context Engineering:2026 年 Agent 性能提升的隐藏杠杆
java·prompt·context
许彰午37 分钟前
07-SqlBuilder六法
java·开发语言·低代码·架构
孙69034242 分钟前
Spring 注入多例 Bean
java·spring
Jul1en_43 分钟前
【Java 脚手架】封装通用工具类-3
java·开发语言·redis·缓存·ai·bootstrap·rabbitmq
边境悍匪1 小时前
springboot常用注解
java·spring boot·学习
captain3762 小时前
文件与IO(2)
java·开发语言·windows·java-ee
mqiqe2 小时前
AgentScope Java 2.0 集成 Chat Completions Web:一行依赖让你的 Agent 变身 OpenAI 兼容服务
java·开发语言·前端
qq_589666052 小时前
Java微服务介绍及应用
java·开发语言·微服务
OPEN-F2 小时前
C++进阶教程:运算符重载与类型转换
java·c++·算法