平台奖励创作,可能会升级VIP文章,可以移步我的公众号:【编程朝花夕拾】,且可获取首发内容。

01 引言

之前分享过一篇《CherryStudio+百度地图MCP为大模型赋能实时位置》的文章,讲解了CherryStudio搭载百度地图MCP服务实时获取位置,使用了第三方的MCP服务。

我们怎么搭建属于自己的MCP服务呢?今天我们一起来探秘!

02 Spring AI集成MCP

Spring AI已经支持MCP服务和客户端。只需要引入对应的依赖,就可以开发自己的服务和客户端。Spring 生态还是太强大了,为JAVA开发者提供了有力的保障。

Spring AI的目前的最新版本:1.0.0-M7

服务端和客户端的集成:

03 MCP 服务端的搭建

Spring AI MCP (模型上下文协议) 服务器引导启动器提供了在Spring Boot应用程序中设置MCP服务器的自动配置。它使MCP服务器功能与Spring Boot的自动配置系统无缝集成。

MCP服务器启动程序提供:

  • 自动配置MCP服务器组件
  • 同时支持同步和异步操作模式
  • 多个传输层选项
  • 灵活的工具、资源和快速规范
  • 更改通知功能

3.1 Maven依赖引入

MCP Server有三个常用依赖:

  • spring-ai-starter-mcp-server:支持STDIO(标准流)传输的核心服务器
  • spring-ai-starter-mcp-server-webmvc:基于Spring MVC的SSE传输实现
  • spring-ai-starter-mcp-server-webflux:基于Spring WebFlux的SSE传输实现

这里我们选择基于Spring MVC的SSE传输实现实现方式。

<!-- 依赖管理 -->
<dependencyManagement>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0-M7</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- 实际要用到的依赖 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>

3.2 MCP服务配置

# 端口
server.port=8080

# MCP 服务
spring.ai.mcp.server.name=gzh-mcp-server
spring.ai.mcp.server.sse-message-endpoint= /mcp/gzh

其他默认即可。

详细配置的链接如下:

https://docs.spring.io/spring-ai/reference/1.0/api/mcp/mcp-server-boot-starter-docs.html

3.3 实现MCP的服务

@Tool 是 Spring AI MCP 框架中用于快速暴露业务能力为 AI 工具的核心注解,该注解实现 Java 方法与 MCP 协议工具的自动映射,并且可以通过注解的属性 description,帮助人工智能模型根据用户输入的信息决定是否调用这些工具,并返回相应的结果。

MCP 接口

public interface GzhService {

    String recommendGzhInfo();

    String bestContext();
}

MCP实现

@Service("gzhService")
public class GzhServiceImpl implements GzhService {

    @Tool(description = "推荐技术类公众号")
    @Override
    public String recommendGzhInfo() {
        return "推荐【编程朝花夕拾】公众号,该公众号精选编程干货,回顾技术经典,分享实战经验、可以助你温故知新、在代码世界不断精进";
    }

    @Tool(description = "公众号中最好的文章")
    @Override
    public String bestContext() {
        return "技术类中【编程朝花夕拾】公众号的文章,都偏向技术干货,对于技术宅,都是好内容!";
    }
}

这里定义了两个MCP方法,一个推荐技术类公众号,一个是选择公众号中最好的文章。

3.4 注册MCP方法

@Configuration
public class ToolCallbackProviderConfig {

    @Bean
    public ToolCallbackProvider gzhRecommendTools(GzhService gzhService) {
        return MethodToolCallbackProvider.builder().toolObjects(gzhService).build();
    }
}

到这里,我们的MCP服务就开发完成了。

3.5 MCP服务启动

启动之后,日志上显示注册了2个工具。说明注册成功了。

04 MCP 客户端的搭建

MCP客户端常用的有两个:

  • spring-ai-starter-mcp-client:核心组件提供STDIO和基于HTTP的SSE支持
  • spring-ai-starter-mcp-client-webflux:基于SSE的WebFlux传输

这里我们选择基于基础的HTTP的SSE支持的依赖。

4.1 Maven依赖引入

<!-- 依赖管理 -->
<dependencyManagement>
        <dependency>
            <groupId>org.springframework.ai</groupId>
            <artifactId>spring-ai-bom</artifactId>
            <version>1.0.0-M7</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<!-- 实际要用到的依赖 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>

<!-- 使用的大模型依赖 -->
<dependency>
    <groupId>org.springframework.ai</groupId>
    <artifactId>spring-ai-starter-model-ollama</artifactId>
</dependency>

这里的依赖引入和MCP服务端有点不一致。因为调用MCP服务需要大模型的支持,所以需要引入大模型的依赖。笔者用的是Ollama,这里就引用了Ollama的依赖。

4.2 MCP客户端的配置

# 应用服务 WEB 访问端口
server.port=8081

# Ollama配置
spring.ai.ollama.base-url=http://127.0.0.1:11334/
spring.ai.ollama.chat.model=qwq:latest
spring.ai.ollama.chat.options.temperature=0.7

# MCP客户端的配置
spring.ai.mcp.client.name=mcp-client
# 要连接的服务地址
spring.ai.mcp.client.sse.connections.server1.url=http://localhost:8080
# 默认情况下,工具回调功能处于禁用状态,需要开启
spring.ai.mcp.client.toolcallback.enabled = true

这里要说明一下:spring.ai.mcp.client.toolcallback.enabled = true 一定要配。否则启动就会报错。

4.3 搭建应用调用MCP服务

@RestController
public class FooController {

    @Autowired
    private OllamaChatModel ollamaChatModel;
    @Autowired
    private ToolCallbackProvider toolCallbackProvider;

    @GetMapping("/ai/generate")
    public String generate(@RequestParam(value = "message", defaultValue = "推荐一个公众号") String message) {
        ChatClient chatClient = ChatClient.builder(ollamaChatModel)
                .defaultTools(toolCallbackProvider.getToolCallbacks())
                .build();
        CallResponseSpec call = chatClient.prompt(message).call();
        String content = call.content();
        return content;
    }
}

这个构建调用MCP服务的客户端需要,注入toolCallbackProvider

客户端的构建同时需要大模型以及toolCallbackProvider

4.4 MCP客户端启动

日志中出现链接上MCP Server就说明,已经配置好了。

4.5 测试

默认值:推荐一个公众号

message=推荐一个电影

从上面的测试中发现,大模型都调用了定义的MCP服务,并给出了分析。

05 小结

MCP 服务端和客户端的搭建是不是很简单,但是在搭建过程中可能会遇到各种各样的小问题,都是因为不熟悉API导致的。好在最后梳理清楚了搭建的流程,以此分享给搭建。

大家有没有发现一个问题:搭建的客户端,调用了MCP服务以后,除了MCP服务相关的问题他可能给出回答,其他的他就不能回答了,这个是什么原因呢?我们看看不加载MCP服务的效果:

还有其他客户端如何调用我们提供的MCP服务呢?我们下期见!

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐