spring ai 实战-MCP

MCP 是什么

MCP,全称是 Model Context Protocol(模型上下文协议)。它是由 Anthropic 开源,旨在解决大模型与外部世界"沟通不畅"的问题。

它不是一个具体的框架或技术,而是一个通用开源标准协议,用于安全、高效地连接智能体应用与外部工具。其核心理念就是赋予智能体应用类似 USB 接口的功能:只需遵守统一的协议,就能标准化地调用各种外部工具,从而实现即插即用。你完全可以把 MCP 理解为是智能体连接外部工具的 USB 接口

比如,以前如果你想让大模型读取你的数据库,你必须为这个特定的智能体写一段专门的 function call 代码。如果你换一个智能体,这代码可能就得重新写一遍。现在有了 MCP 后,你只需要把数据库的一些列操作包装成一个 MCP Server。任何支持 MCP 的客户端(如 Claude Desktop, Cursor,Cline等)都能直接连接上这个server使用工具,无需重复造轮子。

借助MCP,工具都遵循统一的调用协议,智能体则能够更加丝滑地与外部工具交互。社区中已经公开了大量可用的 MCP Server 工具,而这些工具的功能和能力,将直接决定智能体在实际任务中的执行效果。

MCP的工作流程

第一阶段:初始化(工具说明获取) 智能体初始化的时候,会通过 MCP 协议向所有连接的 MCP Server 使用JSON-RPC 协议请求工具说明书。MCP Server 负责提供并确保这些说明书是标准化的JSON格式。

第二阶段:决策(大模型规划) 智能体将用户的原始问题和获取到的所有标准化工具说明,一同发送给大模型。大模型根据这些信息进行规划,并返回一个清晰的工具调用指令。

第三阶段:调用(执行与结果回传) 智能体接收到指令后,立即通过 MCP 协议请求对应的 MCP Server 执行工具操作。MCP Server 完成实际的工具逻辑(如数据库查询),并将原始执行结果返回给智能体。

第四阶段:总结(生成最终回复) 智能体将用户原始问题+工具执行的最终结果+完整的对话历史,再次发回给大模型。大模型基于这个结果进行总结,生成一段自然语言回复,输出给用户

spring ai 开发MCP server

stdio 方式

依赖
xml 复制代码
	<dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
        </dependency>


        <!--webflux 应用 使用这个,和webmvc 包冲突,两个只能用一个-->
<!--        <dependency>-->
<!--            <groupId>org.springframework.ai</groupId>-->
<!--            <artifactId>spring-ai-starter-mcp-server-webflux</artifactId>-->
<!--        </dependency>-->
定义tools
java 复制代码
package com.lujia.ai.springaimcpserver.service;


import org.springframework.ai.tool.annotation.Tool;
import org.springframework.stereotype.Service;

@Service
public class WeatherMcpService {
    /**
     * 定义天气查询工具
     *
     * @param city
     * @return
     */
    @Tool(name = "getWeather", description = "根据城市名称查询天气信息")
    public String getWeather(String city) {

        //模拟查询天气
        return switch (city) {
            case "广州" -> "广州: 晴, 25°C";
            case "郑州" -> "郑州: 多云, 22°C";
            case "深圳" -> "深圳: 小雨, 28°C";
            default -> city + ": 下雪, -20°C";
        };
    }
}

定义ToolCallbackProvider 来注册toolObjects

java 复制代码
@Configuration
public class McpConfiguration {

    /**
     * ToolCallbackProvider ,会扫描 WeatherService 里面的@Tool的方法,
     * @param weatherService
     * @return
     */
    @Bean
    public ToolCallbackProvider weatherTools(WeatherMcpService weatherService) {
        return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
    }
}
配置
yaml 复制代码
spring:
  main:
    #  非web应用
    web-application-type: none
    # 关闭banner
    banner-mode: off

  ai:
    mcp:
      server:
        name: mcp-server
        version: 1.0.0
        # 这里有三种 类型定义MCP server ,代表交互方式的不同 stdio 表示通过控制台输入输出交互
        stdio: true
        enabled: true
        type: SYNC
# 控制台不打印日志
logging:
  level:
    root: OFF
使用

这里使用 vs code 插件cline ,

首先编译打包我们的jar 包,在cline mcp 注册配置中,添加一下配置,args 里面填写你的jar 包绝对路径,保存即可注册mcp server,之后就可以使用了

效果如下:

sse 方式

SSE(Server-Sent Events)模式基于 HTTP,采用双端点架构:sse-message-endpoint 是 MCP Client 用来向服务器发送请求、调用工具的接口,客户端通过约定的 JSON-RPC 协议将参数传入并获取响应。sse-endpoint 则是 MCP Client 用来监听服务器主动推送消息的通道,比如工具列表更新、状态变更等。二者配合构成了 MCP SSE 的核心通信机制,使客户端既能主动发起操作,也能实时接收服务器推送的变化,实现双向互动和高效协作,

目前官方已经不推荐使用这种方式

sse 和stdio 代码都一样,只是配置修改即可

yaml 复制代码
server:
  port: 8080
#    context-path: /test

spring:
  application:
    name: mcp-weather-sse
  ai:
    mcp:
      server:
        enabled: true
        name: weather-sse-server
        version: 1.0.0
        type: SYNC
        capabilities:
          tool: true
          resource: false
          prompt: false
          completion: false
        sse-message-endpoint: /mcp/messages   # 客户端向 MCP Server 发送指令("写信")
        sse-endpoint: /sse                    # 客户端订阅服务器推送消息("听收音机")
  servlet:
    encoding:
      force: true
      charset: UTF-8
      enabled: true

启动服务,在cline mcp配置中添加下面就可以使用

json 复制代码
{
  "mcpServers": {
    "weather-sse": {
      "type": "sse",
        //mcp服务暴露的端口地址
      "url": "http://127.0.0.1:8080/sse",
      "autoApprove": [],
      "timeout": 60,
      "disabled": false
    }
  }
}

streamable http

StreamableHTTP 是MCP在2025年3月26日正式提出的最新官方传输标准,用来改进传统 SSE 在长连接、大数据流和双端点管理上的局限。它通过 单一 HTTP 端点实现请求发送与流式响应接收,支持 断续重连和未确认消息重发,保证长时间任务或增量输出的稳定可靠,同时简化了客户端与服务器的交互模型,是官方推荐替代SSE的方案

代码还还是一样,只需要修改配置文件即可

yaml 复制代码
server:
  port: 8080
spring:
  application:
    name: mcp-weather-streamable
  ai:
    mcp:
      server:
        ## 这个地方改成STATELESS,就是无状态模式
        protocol: STREAMABLE
        name: streamable-mcp-server
        version: 1.0.0
        type: SYNC
        instructions: "这个服务是用来查询城市天气的。"
        resource-change-notification: true
        tool-change-notification: true
        prompt-change-notification: true
        streamable-http:
          mcp-endpoint: /api/mcp
          keep-alive-interval: 30s
  servlet:
    encoding:
          charset: UTF-8
          force: true
          enabled: true

protocol:STREAMABLE 表示开启 Streamable HTTP 模式;

instructions:用于定义 MCP Server 的提示词,指导模型行为;

streamable-http.mcp-endpoint:指定服务的端口路径,与SSE的不同,这边一个端口就可以实现双向通信;keep-alive-interval:设置 HTTP 连接心跳间隔,保证长连接稳定。

其中protocol 还可以直接切换成 STATELESS。在 无状态模式下,MCP Server 不会在内存中保存客户端会话,也不会分配或要求 Mcp-Session-Id。每个请求都是独立处理的,服务器不会记录多轮对话历史或流式事件状态。这种模式适合 单次调用、无历史依赖的工具或 API,例如一次性计算、查询数据库、或者获取即时信息的场景,不需要断点重连或多轮交互。

由于无状态模式无法保留上下文或中途恢复,它不适合依赖会话连续性的多轮交互、长连接流式推送或复杂工具链操作;但它的优势是 简单、易扩展、适合 serverless 或微服务架构

启动服务,在vscode cline 中配置即可使用

json 复制代码
{
  "mcpServers": {
    "weather-streamable": {
      "url": "http://127.0.0.1:8080/api/mcp",
      "type": "streamableHttp",
      "timeout": 60,
      "disabled": false
    }
  }
}

spring ai 开发 mcp client

client 依赖
xml 复制代码
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-mcp-client</artifactId>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-starter-model-deepseek</artifactId>
        </dependency>
配置client
yaml 复制代码
spring:
  ai:
    deepseek:
      api-key: 你的apikey
      base-url: https://api.deepseek.com/
    mcp:
      client:
        enabled: true
        name: my-mcp-client
        version: 1.0.0
        request-timeout: 60s
        type: SYNC
        stdio:
          connections:
            weather-stdio:
              command: java
              args:
                - -jar
                - "D:\\ideafile\\springAI\\spring-ai-mcp-server\\target\\spring-ai-mcp-server-0.0.1-SNAPSHOT.jar"
        sse:
          connections:
            weather-sse:
              url: http://127.0.0.1:8003
              sse-endpoint: /sse
        streamable-http:
          connections:
            weather-streamable:
              url: http://127.0.0.1:8004/
              endpoint: api/mcp
使用
java 复制代码
@RestController
@RequestMapping("/test")
public class TestController {



    // 官网上也可以这样注入
    @Autowired
    private List<McpSyncClient> mcpSyncClients;  // For sync client

// OR
    // 官网上也可以这样注入
    @Autowired
    private List<McpAsyncClient> mcpAsyncClients;  // For async client


    @Autowired
    private SyncMcpToolCallbackProvider toolCallbackProvider;
    @Autowired
    private DeepSeekChatModel chatModel;
    private ChatClient chatClient;

    @PostConstruct
    public void init() {
        /**
         * 将MCP Client的工具注入到 ChatClient
         */
        ToolCallback[] toolCallbacks = toolCallbackProvider.getToolCallbacks();

        this.chatClient = ChatClient.builder(chatModel).defaultTools(Arrays.asList(toolCallbacks)).build();
    }

    /**
     * 智能体调用
     */
    @GetMapping("/chat")
    public String chat(String userMessage) {
        return chatClient.prompt().user(userMessage).call().content();
    }
}
相关推荐
智驭未来掌门人几秒前
一个网关,三种接法,一个能落地的 Agent:llm-api-gateway-cli 项目介绍
人工智能
wordbaby15 分钟前
混合检索:两全其美的艺术
人工智能·算法
小溪学编程16 分钟前
Java BufferedReader 详解:从基础用法到性能优化
java·python·性能优化
Amy1870211182324 分钟前
数据中心电气接点测温:从“被动抢修”到“主动预警”的安全革命
人工智能·安全
HZero.chen34 分钟前
Java 匿名类简介
java·匿名类
用户31268748772036 分钟前
Java 泛型擦除到底擦掉了什么?类型安全与桥接方法深度拆解
java
jimmyleeee38 分钟前
GEN AI安全:威胁全景---从训练到运行的攻防实战
人工智能·安全
暖焰核心43 分钟前
继承全解——继承、默认成员函数、切片、隐藏与虚继承
java·前端·javascript
君顾11 小时前
外卖CPS系统开发实战指南:从架构设计到部署全流程解析
java·开发语言·外卖
阿里云大数据AI技术1 小时前
DataWorks Data Agent 实战课堂(八):数据质量巡检服务
人工智能·agent