SpringAI学习笔记-MCP客户端简单示例

MCP客户端是AI与外部世界交互的桥梁。在AI系统中,大模型虽然具备强大的认知能力,却常常受限于数据孤岛问题,无法直接访问外部工具和数据源。MCP协议应运而生,作为标准化接口解决这一核心挑战。该协议采用客户端-服务端架构,将AI模型的智能计算能力与外部系统的专业功能解耦,形成可扩展的协作生态。MCP客户端作为架构的关键组件,使得AI应用能够像使用"万能遥控器"一样,通过MCP客户端安全调用各类专业工具,而无需关心底层实现细节。其设计充分体现了AI系统与外部环境交互的三个基本原则:
  • 标准化:通过统一协议消除工具集成中的适配成本。
  • 安全性:在保持模型隔离的同时实现受控的外部访问。
  • 灵活性:支持多样化的传输机制和运行时环境。
MCP客户端是MCP架构中的关键组件,负责与MCP服务端进行交互,以利用MCP服务端提供的工具、资源及能力。MCP客户端实现协议的客户端部分,通过遵循MCP协议的结构化方式,发送请求并接收来自MCP服务端的响应。MCP客户端能够在不同的环境中灵活运行,利用MCP服务端提供的多种传输机制,确保与MCP服务端的稳定、高效通信。通过与MCP服务端的协同工作,MCP客户端能够扩展AI模型的功能,实现与外部工具和资源的无缝集成。
  • 核心职责包括:
    • 协议版本协商 :确保与服务器的兼容性。
    • 能力协商 :确定可用功能(如工具支持范围)。
    • 消息传输与JSON-RPC通信 :实现结构化数据交互。
    • 工具发现与执行 :动态识别并调用外部工具。
    • 资源访问与管理 :协调模型与外部数据源的交互。
    • 提示系统交互 :支持与模型提示(Prompt)系统的集成。
  • 可选功能 :
    • 根管理(Roots Management)。
    • 采样支持(如模型输出概率控制)。
    • 同步与异步操作模式。
  • 传输选项 :
    • 基于标准输入/输出的传输(适用于进程间通信)。
    • 基于Java HttpClient的SSE客户端传输(支持事件流)。
    • 基于WebFlux的SSE客户端传输(用于响应式HTTP流处理)。
MCP客户端简单示例
  • 项目依赖

    xml 复制代码
    <dependencies>
        <!-- SpringBootStarterWeb依赖包 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>3.4.5</version>
        </dependency>
    
        <!-- JavaxServlet依赖包 -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
            <version>1.0.0-M6</version>
        </dependency>
    
        <!-- SpringAI依赖包 -->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-spring-boot-autoconfigure</artifactId>
            <version>1.0.0-M6</version>
        </dependency>
    </dependencies>
  • 项目配置

    • 这里主要配置MCP服务端的SSE连接。
    yaml 复制代码
    spring:
      profiles:
        active: dev
      application:
        name: ai-demo-mcp-client
      main:
        allow-bean-definition-overriding: true
      ai:
        mcp:
          client:
            enabled: true
            name: ai-demo-mcp-client
            type: sync
            version: 1.0.0
            sse:
              connections:
                ai-demo-platform-mcp-server:
                  url: http://localhost:10102
    
    server:
      port: 10103
  • 项目代码

    • Spring AI中通过SyncMcpToolCallback适配MCP工具到统一接口。通过SyncMcpToolCallbackProvider将McpSyncClient列表转换为Spring AI标准的ToolCallback数组。SyncMcpToolCallbackProvider作为适配器,实现了MCP协议工具到Spring AI工具接口的桥接。
    • ToolCallback中通过ToolDefinition实现MCP协议的能力声明,返回工具的结构化定义。ToolDefinition获取工具的名称(name)、描述(description)和输入模式(inputSchema)等。所有工具通过统一的call()方法执行,符合MCP的JSON-RPC规范。
    java 复制代码
    @RestController("aiDemoClient")
    @RequestMapping("ai/demo/client")
    public class AiDemoClientRest {
    
        private static final Map<String, ToolCallback> TOOL_CACHE = new HashMap<>();
    
        public AiDemoClientRest(List<McpSyncClient> mcpSyncClientList) {
            SyncMcpToolCallbackProvider syncMcpToolCallbackProvider = new SyncMcpToolCallbackProvider(mcpSyncClientList);
            ToolCallback[] toolCallbacks = syncMcpToolCallbackProvider.getToolCallbacks();
            for (ToolCallback toolCallback : toolCallbacks) {
                TOOL_CACHE.put(toolCallback.getToolDefinition().name(), toolCallback);
            }
            StringBuilder stringBuilder = new StringBuilder();
    
            TOOL_CACHE.values().forEach(toolCallback -> {
                ToolDefinition toolDefinition = toolCallback.getToolDefinition();
                stringBuilder.append(String.format("name %s desc %s input %s",
                    toolDefinition.name(), toolDefinition.description(), toolDefinition.inputSchema())).append("\n");
            });
    
            System.out.println(stringBuilder);
        }
    
        @GetMapping("001")
        public String demo001() {
            return TOOL_CACHE.get("addInteger").call("{\"arg0\":2,\"arg1\":6}");
        }
    
        @GetMapping("002")
        public String demo002() {
            return TOOL_CACHE.get("addDouble").call("{\"arg0\":2.0,\"arg1\":6.0}");
        }
    
    }
  • 通过上述配置和代码,即可与MCP服务器交互。

相关推荐
兩尛6 分钟前
Spring面试
java·spring·面试
Java中文社群13 分钟前
服务器被攻击!原因竟然是他?真没想到...
java·后端
Full Stack Developme24 分钟前
java.nio 包详解
java·python·nio
零千叶40 分钟前
【面试】Java JVM 调优面试手册
java·开发语言·jvm
代码充电宝1 小时前
LeetCode 算法题【简单】290. 单词规律
java·算法·leetcode·职场和发展·哈希表
li3714908901 小时前
nginx报400bad request 请求头过大异常处理
java·运维·nginx
摇滚侠1 小时前
Spring Boot 项目, idea 控制台日志设置彩色
java·spring boot·intellij-idea
万俟淋曦1 小时前
【论文速递】2025年第30周(Jul-20-26)(Robotics/Embodied AI/LLM)
人工智能·深度学习·ai·机器人·论文·robotics·具身智能
Aevget2 小时前
「Java EE开发指南」用MyEclipse开发的EJB开发工具(二)
java·ide·java-ee·eclipse·myeclipse
黄昏晓x2 小时前
C++----多态
java·jvm·c++