MCP实践:MCP Client 开发保姆教程(附全部代码)

1、概述

前两篇我们讲了MCP Server的开发(MCP实践:MCP Server 开发保姆教程(附全部代码))和使用(),这篇文章我们介绍下如何自己开发MCP Client来调用自己开发的MCP Server。

2、MCP Client开发

MCP Server 调用有两种方式,一种是Stdio模式,另一种是SSE模式。Stdio相当于是依赖包加载到本地进行运行,SSE模式相当于远程服务调用,这篇文章我们介绍使用SSE方式进行调用。

2.1、依赖相关

开发MCP对环境有要求,Jdk要求17+,SpringBoot要求【3.4.0+】 MCP-Client开发有两个依赖包,底层的技术一个是依赖Webmvc,另一个是依赖Webflux。Webmvc是基于Servlet的阻塞式模型,Webflux是一个异步非阻塞式的 Web 框架,它能够充分利用多核 CPU 的硬件资源去处理大量的并发请求。 具体两个依赖如下(目前最新版本【1.0.0-M6】):

xml 复制代码
<!-- stdio和webMvc是一个包-->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
    <version>${spring-ai.version}</version>
</dependency>

<!-- MCP client SSE 包-->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-mcp-client-webflux-spring-boot-starter</artifactId>
    <version>1.0.0-M6</version>
</dependency>


<!--        Spring ai 大模型的实现-->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
    <version>${spring-ai.version}</version>
</dependency>

<!--    AI基础依赖(感觉应该是SPI接口,定义接口标准)-->
<dependencyManagement>
<dependencies>
    <dependency>
        <groupId>org.springframework.ai</groupId>
        <artifactId>spring-ai-bom</artifactId>
        <version>1.0.0-SNAPSHOT</version>
        <type>pom</type>
    </dependency>
</dependencies>
</dependencyManagement>

2.2、代码开发

整体目录 代码开发比较简单,先看下整体目录,由于使用【spring-ai-openai-spring-boot-starter】包,因此许多组件在配置文件中配置完成后可以直接自动注入。

Controller

配置文件 配置文件比较简单,主要分为两部分

  • 配置大模型,这里使用火山引擎的豆包大模型,也可以使用其他,只要符合标准OpenAi格式就行
  • 配置MCP Server:这里要注意,开发的MCP Server 一定要是以SSE结尾的Endpoint,依赖里面进行强制拼接了(SSE),所以如果路由不正确的话会调不通(高德那个注释掉就是因为调不通)

下面是Client依赖包里面的源码(看网上说1.0的依赖已经修复,但是spring-mcp-client包还未更新到正式maven仓库)

3、功能验证

3.1、启动MCP Server

3.2、启动MCP Client

从MCP Client启动日志中看出订阅成功

从MCP Server启动日志中看出通信成功

3.3、调试

使用Postman进行调试

查看MCP Server发现已经被调用

MCP Server返回结果后,大模型对结果进行总结整理,输出如下

最终结果如下

4、总结

通过各个依赖组件发现,目前MCP相关发展还在初期,许多依赖不是特别完整。因此在开发过程中需要特别的注意配置及依赖版本等内容。如果遇到问题,我们可以进行源码调试,通过源码调试能让我们了解组件的原理。

5、源码

  • 依赖
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/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.young</groupId>
        <artifactId>my-agi</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>mcp-client</artifactId>
    <packaging>war</packaging>
    <name>mcp-client Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <build>
        <finalName>mcp-client</finalName>
    </build>

    <properties>
        <spring-ai.version>1.0.0-M6</spring-ai.version>
        <java.version>17</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.ai</groupId>
                <artifactId>spring-ai-bom</artifactId>
                <version>1.0.0-SNAPSHOT</version>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

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

        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-openai-spring-boot-starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

        <!--        stdio模式-->
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-mcp-client-spring-boot-starter</artifactId>
            <version>${spring-ai.version}</version>
        </dependency>

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

    <repositories>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <releases>
                <enabled>false</enabled>
            </releases>
        </repository>
        <repository>
            <id>central-portal-snapshots</id>
            <name>Central Portal Snapshots</name>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

</project>
  • McpClientController
kotlin 复制代码
package com.young.client.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.tool.ToolCallbackProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

/**
 * @author 刘子洋
 * @date 2025年05月14日 下午5:13
 * @description:mcp测试调用controller
 */
@RestController
@RequestMapping("/mcp")
public class McpClientController {

    private static final Logger log = LoggerFactory.getLogger(McpClientController.class);
    private final ChatClient chatClient;

    @Autowired
    public McpClientController(ChatClient.Builder mcpChatClientBuilder, ToolCallbackProvider tools) {
        this.chatClient = mcpChatClientBuilder.defaultTools(tools).build();
    }

    @PostMapping("/ask")
    public String ask(@RequestBody Map<String, String> question) {
        String response = chatClient.prompt(question.get("question")).call().content();
        log.info("response: {}", response);
        return "question: " + question + " <hr>"
                + response
                .replaceAll("\\*\\*(.*?)\\*\\*", "<strong>$1</strong>")
                .replaceAll("\n", "<br/>");
    }

    @GetMapping("/askModel")
    public String ask2(@RequestParam String question) {
        return chatClient.prompt().user(question).call().content();
    }
}
  • 配置文件
yaml 复制代码
spring:
  application:
    name: my-mcp-client
  ai:
    openai:
      api-key: ********
      base-url: https://ark.cn-beijing.volces.com/api
      chat:
        completions-path: /v3/chat/completions
        options:
          model: doubao-1-5-pro-256k-250115
    mcp:
      client:
        sse:
          connections:
            server1:
              url: http://localhost:8081
#            server2:
#              url: https://mcp.amap.com
#              sse-endpoint: /sse?key=********
server:
  port: 8082
相关推荐
TeamDev17 小时前
使用 MCP 自动化 JxBrowser
浏览器自动化·jxbrowser·mcp·模型上下文协议·mcp 自动化·jxbrowser 自动化·jxbrowser mcp
ChaITSimpleLove1 天前
使用 .net10 构建 AI 友好的 RSS 订阅机器人
人工智能·.net·mcp·ai bot·rss bot
妮妮分享2 天前
维智 MCP 接口服务技术支持指南
mcp·mcp server·维智 mcp·智能体接口
感谢地心引力2 天前
【AI】免费的代价?Google AI Studio 使用指南与 Cherry Studio + MCP 实战教程
人工智能·ai·google·chatgpt·gemini·mcp·cherry studio
AI架构师易筋2 天前
模型上下文协议(MCP)完全指南:从AI代理痛点到实战开发
人工智能·microsoft·语言模型·llm·mcp
qdprobot2 天前
齐护AiTall pro ESP32S3 小智AI对话 MQTT MCP 开发板Mixly Scratch Steam图形化编程创客教育
人工智能·mqtt·scratch·mixly·mcp·小智ai·齐护机器人aitall pro
路西法013 天前
Office-Word-MCP-Server在Cursor中使用方法
cursor·mcp
Light603 天前
【MCP原生时代】第2篇|前端如何舞动 MCP:新一代交互范式——从 Hook 到流式渲染,打造 AI 原生前端体验
状态模式·前端架构·mcp·react hook·流式渲染·ai交互
渣渣苏4 天前
MCP实战指南
mcp
爬点儿啥4 天前
[Ai Agent] 10 MCP基础:快速编写你自己的MCP服务器(Server)
人工智能·ai·langchain·agent·transport·mcp