Spring AI 实战:如何使用 MCP Client 接入 MCP 天气查询服务

上一篇文章,我们搭建了一个 MCP 天气服务(Server),它运行在 localhost:8888,对外暴露了 get_weather 工具。但 Server 本身不会说话------它只会安静地等待被调用。

本文将构建一个 MCP Client 应用,让它连接天气服务,并通过大模型实现这样的对话:

用户:北京今天天气怎么样?

大模型:(自动调用 get_weather 工具)北京今天局部多云,温度 25°C...


1. MCP Client 的职责

如果把 MCP 比作 USB-C,那么:

  • MCP Server = 外接设备(U盘、显示器)
  • MCP Client = 电脑上的 USB 接口

Client 的核心职责:

  • 发现:连接到 Server,获取它暴露了哪些工具
  • 代理:把这些工具"翻译"成大模型能理解的格式
  • 执行:当大模型决定调用工具时,帮它把请求转发给 Server

在 Spring AI 中,这一切几乎都是自动的。MCP 基于 SSE(Server-Sent Events) 传输,但 SSE 只是载体。真正的通信发生在 JSON-RPC 2.0 消息层。


2. 项目搭建

2.1 POM 依赖

2.1.1 Spring Boot 依赖管理

Spring Boot 本身提供 BOM(spring-boot-dependencies)管理 Boot 生态,通常由父 POM 管理:

xml 复制代码
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.5.14</version>
    <relativePath/>
</parent>
2.1.2 Spring AI 依赖管理

Spring AI 也提供 BOM 来管理 Spring AI 生态,声明了 Spring AI 指定所有依赖的推荐版本:

xml 复制代码
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.1.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

统一管理 Spring AI 生态下所有组件的版本,你在 dependencies 中引入具体模块时无需再写版本号。

Spring AI 是一个多模块项目,包含:spring-ai-core、spring-ai-openai、spring-ai-mcp-server-webmvc 等。这些模块之间有严格的版本兼容关系。如果没有 BOM,你需要手动确保每个模块版本一致,容易出错。

2.1.3 添加依赖

添加 Spring Boot Web 和 Spring AI MCP 等相关依赖:

xml 复制代码
<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Spring AI OpenAI协议 模型 -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-model-openai</artifactId>
    </dependency>

    <!-- Spring AI MCP Client WebFlux -->
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
    </dependency>

    <!-- Spring Boot Lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
</dependencies>

注意 :Client 应用本身使用 Spring MVC(spring-boot-starter-web),但 MCP Client 传输层使用 WebFlux SSE(spring-ai-starter-mcp-client-webflux)。两者可以共存------MCP 的 WebFlux 传输是独立的响应式 HTTP 客户端,不会影响主应用的 Servlet 模型。

完整 POM 如下所示:

xml 复制代码
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <!-- 第一层:Spring Boot 父 POM,管理 Boot 生态 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.5.14</version>
        <relativePath/>
    </parent>

    <artifactId>chat-mcp-tool</artifactId>
    <name>chat-mcp-tool</name>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>17</java.version>
        <spring-ai.version>1.1.5</spring-ai.version>
    </properties>

    <!-- 第二层:导入 Spring AI BOM,管理 AI 生态 -->
    <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>

    <!-- 依赖 -->
    <dependencies>
        <!-- Spring Boot Web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- Spring AI OpenAI协议 模型 -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-openai</artifactId>
        </dependency>

        <!-- Spring AI MCP Client WebFlux -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
        </dependency>

        <!-- Spring Boot Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2.2 配置文件

application.yml 中配置 MCP Client 配置:

yaml 复制代码
server:
  port: 9999

spring:
  application:
    name: chat-mcp-tool
  ai:
    # MCP客户端配置
    mcp:
      client:
        enabled: true
        sse:
          connections:
            weather-server:
              url: http://localhost:8888
    # 模型配置
    openai:
      api-key: ${DASHSCOPE_API_KEY}
      base-url: https://dashscope.aliyuncs.com/compatible-mode
      chat:
        options:
          model: qwen3.5-35b-a3b
          temperature: 0.7

配置说明:

属性 含义
mcp.client.enabled 启用 MCP Client
sse.connections 定义 SSE 连接的 Server 列表,key(weather-server)是连接标识
url MCP Server 的 SSE 端点地址,即上一篇启动的服务

支持同时连接多个 MCP Server:

复制代码
sse:
  connections:
    weather-server:
      url: http://localhost:8888
    stock-server:
      url: http://localhost:8889

2.3 ChatClient 配置

ChatClient 是 Spring AI 的对话入口。这里不需要额外配置 MCP 工具,工具由 MCP Client 自动发现,并在 Controller 层动态注入:

java 复制代码
@Configuration
public class ChatConfig {
    // 远程 OpenAI 兼容协议大模型:百练
    @Bean
    public ChatClient chatClient(OpenAiChatModel chatModel) {
        return ChatClient.builder(chatModel)
                .build();
    }
}

2.4 对话控制器

在 ChatController 中定义对话入口:

java 复制代码
@Slf4j
@RestController
@RequestMapping("/api/v1/")
public class ChatController {

    @Autowired
    private ChatClient chatClient;

    @Autowired
    private ToolCallbackProvider toolCallbackProvider;

    @GetMapping(value = "/chat", produces = "text/plain;charset=UTF-8")
    public Flux<String> chatStream(
            @RequestParam(value = "message", defaultValue = "你是谁") String message) {

        Flux<String> result = chatClient
                .prompt()
                .user(message)
                .toolCallbacks(toolCallbackProvider)
                .stream()
                .content();

        log.info("chat: {}", message);
        return result;
    }
}

核心逻辑拆解:

代码 作用
chatClient.prompt() 开启一次对话请求
.user(message) 设置用户输入
.toolCallbacks(toolCallbackProvider) 关键:把 MCP Client 发现的工具注入本次对话
.stream().content() 流式输出大模型的回复文本

ToolCallbackProvider 是 Spring AI 自动装配的 Bean,它封装了所有通过 MCP Client 发现的远程工具。当大模型判断需要调用工具时,Spring AI 会自动:

  • 暂停文本生成
  • 向 MCP Server 发起工具调用请求
  • 拿到结果后,将结果送回大模型继续生成回复
  • 最终返回给用户

整个过程对开发者完全透明。


3. 运行与验证

3.1 启动服务

请先确保 MCP Server 已启动(端口 8888)。具体参考第一篇博文

直接运行主应用类 ChatMcpApplication

java 复制代码
@SpringBootApplication
public class ChatMcpApplication {

    public static void main(String[] args) {
        SpringApplication.run(ChatMcpApplication.class, args);
    }
}

或者使用如下命令启动 MCP Client(端口 9999):

bash 复制代码
mvn spring-boot:run

3.2 测试对话

浏览器中输入如下命令来查询北京天气:

bash 复制代码
http://localhost:9999/api/v1/chat?message=北京天气如何

预期会收到如下信息:

复制代码
北京的天气情况如下:
- 天气状况: 晴天
- 温度: 23°C (体感温度: 23°C)
- 湿度: 44%
- 风速: 11 km/h (SSE)
- 降水量: 0.0 mm
- 能见度: 10 公里
- 紫外线指数: 1

观测时间: 2026-05-01 05:37 PM

完整代码:chat-mcp-tool

相关推荐
少许极端4 小时前
AI修炼记2-MCP
人工智能·ai·mcp
Zhencode5 小时前
Python创建MCP服务
python·mcp
穷人小水滴7 小时前
(AI) 编写简单 MCP 工具 (mcp-run)
人工智能·ai·node.js·agent·mcp
g323086317 小时前
Langchain mcp 可视化界面
langchain·mcp
米小虾1 天前
MCP 协议深度解析:AI 时代的「USB-C」接口如何重塑智能体生态
人工智能·mcp
苏渡苇1 天前
DeepSeek V4 实战:自然语言生成 SQL + 智能优化引擎
ai·springboot·spring ai·deepseek·ai推理·deepseek v4·自然语言生成sql
库洛西鲁1 天前
OpenClaw 16G 内存怎么配模型?实测 3 套方案,最后一套跑满不卡
claude·mcp
JaydenAI1 天前
[MCP在LangChain中的应用-03]在Session构建的上下文中与MCP Server交互
python·langchain·ai编程·ai agent·mcp·fastmcp