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服务器交互。

相关推荐
大模型码小白17 小时前
企业级检索增强后端集成:Java 服务如何管理知识库版本
java·服务器·开发语言·人工智能·python·microsoft
AI多Agent协作实战派18 小时前
AI多Agent协作系统实战(二十二):从6列到12列——任务监控报告的进化之路
java·人工智能·uni-app·bug
千桐科技18 小时前
DataX 执行引擎正式加入:qData 开源版 v1.6.0 新增 Quartz + DataX 轻量运行模式!
java·大数据·开源·数据治理·数据中台·qdata
Irene199118 小时前
Oracle PL/SQL Developer 版本差异(11g、14)实战总结
java·开发语言
AI人工智能+电脑小能手18 小时前
【大白话说Java面试题 第191题】【08_Kafka篇】第7题:消息队列的优缺点
java·消息队列·系统设计·分布式架构·技术选型
用户4461394302718 小时前
Spring Boot 接入大模型:从配置到实战的完整指南
java
青石路18 小时前
如果写Redis序列化与读Redis序列化不一致,你觉得会发生什么
java·redis
煎饼学大模型18 小时前
架构决定上限:Skill 知识架构的三次重构实践
java·重构·架构·skill
王同学的AI学习日记18 小时前
Qwen-Image-3.0技术实测:文字渲染、长上下文与多场景能力深度评测
大数据·人工智能·ai·开源
llwszx18 小时前
【Java/Go后端手撸原生Agent(第五篇):多工具并行调用 + BashTool执行引擎 + Judge证据链升级】
java·后端·golang·状态机·pydantic·agnet·llm-as-judge