使用Spring AI构建MCP服务器的完整指南

本文详细介绍了如何使用Spring AI构建模型上下文协议(MCP)服务器,包括创建工具服务、配置MCP服务器以及使用DevoxxGenie进行测试的完整流程,展示了如何为LLM添加自定义功能。

构建基于Spring AI的MCP服务器

引言

模型上下文协议(MCP)提供了一种标准化方式,将大型语言模型(LLM)连接到不同类型的数据源和工具。这里的"标准化"一词非常重要,这意味着与数据源和工具的集成变得比以往更加容易。此外,MCP服务器通过额外的知识或功能增强您的LLM,使其成为更强大的助手。

构建MCP服务器

您将构建的MCP服务器具有以下功能:

  • 返回我最喜爱艺术家的列表
  • 返回我最喜爱歌曲的列表

项目设置

导航到Spring Initializr并添加"Model Context Protocol Server"依赖。这将在pom中添加以下依赖:

1
2
3
4
<dependency>
  <groupId>org.springframework.ai</groupId>
  <artifactId>spring-ai-starter-mcp-server</artifactId>
</dependency>

数据模型

创建Artist的数据模型:

1
2
public record Artist(String name) {
}

创建Song的数据模型:

1
2
public record Song(Artist artist, String title) {
}

服务实现

创建ArtistService。该服务将包含我最喜爱艺术家的列表,但在实际应用中,这将存储在数据库中。通过使用@Tool注解定义工具get_artists:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@Service
public class ArtistService {

    private final List<Artist> artists = new ArrayList<>();

    @Tool(name = "get_artists", description = "获取Gunter最喜爱艺术家的完整列表")
    public List<Artist> getArtists() {
        return artists;
    }

    @PostConstruct
    public void init() {
        artists.addAll(List.of(
                new Artist("Bruce Springsteen"),
                new Artist("JJ Johnson")
        ));
    }
}

以类似的方式创建SongService:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
@Service
public class SongService {

    private final List<Song> songs = new ArrayList<>();

    @Tool(name = "get_songs", description = "获取Gunter最喜爱歌曲的完整列表")
    public List<Song> getSongs() {
        return songs;
    }

    @PostConstruct
    public void init() {
        songs.addAll((List.of(
                new Song(new Artist("Bruce Springsteen"), "My Hometown"),
                new Song(new Artist("JJ Johnson"), "Lament")
        )));
    }
}

工具注册

通过Bean注册工具:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
@SpringBootApplication
public class MyMcpServerPlanetApplication {

	public static void main(String[] args) {
		SpringApplication.run(MyMcpServerPlanetApplication.class, args);
	}

	@Bean
	public ToolCallbackProvider mcpServices(ArtistService artistService, SongService songService) {
		return MethodToolCallbackProvider.builder()
				.toolObjects(artistService, songService)
				.build();
	}
}

应用配置

添加以下application.properties:

1
2
3
4
5
spring.main.web-application-type=none
spring.ai.mcp.server.name=mcp-server
spring.ai.mcp.server.version=0.0.1
spring.main.banner-mode=off
logging.pattern.console=

此配置执行几个重要操作:

  • 禁用Web应用程序:由于MCP使用STDIO传输,不需要Web服务器
  • 设置服务器名称和版本:这向客户端标识MCP服务器
  • 禁用横幅和控制台日志记录:这对于STDIO传输正常工作至关重要

构建jar文件:

1
mvn clean verify

测试MCP服务器

配置DevoxxGenie

将MCP服务器添加到DevoxxGenie MCP设置中:

  • 名称:MyMcpServerPlanet
  • 传输类型:STDIO
  • 命令:/<java安装目录>/bin/java
  • 参数:-jar /home/<项目目录>/mymcpserverplanet/server/target/mymcpserverplanet-0.0.1-SNAPSHOT.jar

点击"Test Connection & Fetch Tools"按钮,按钮标题应变为"Connection Successful! 2 tools found"。

测试功能

使用提示:“Give me a list of Gunter’s favorite artists”

LLM将意识到它无法自行回答这个问题,但会识别出有一个可用工具可以回答这个问题。因此,LLM将要求客户端调用MCP工具。DevoxxGenie具有内置的人工干预机制,将请求您的批准。

MCP服务器将执行get_artists工具,响应将发送回LLM。LLM将使用此响应来给出适当的答案。

添加搜索功能

为两个MCP工具添加基本的搜索功能。

在ArtistService中添加search_artist工具:

1
2
3
4
5
6
7
@Tool(name = "search_artist", description = "从Gunter最喜爱的艺术家中搜索单个艺术家")
public Artist getArtist(String name) {
    return artists.stream()
            .filter(artist -> artist.name().equalsIgnoreCase(name))
            .findFirst()
            .orElse(null);
}

在SongService中添加search_song工具:

1
2
3
4
5
6
7
@Tool(name = "search_song", description = "从Gunter最喜爱的歌曲中搜索单首歌曲")
public Song getSong(String title) {
    return songs.stream()
            .filter(song -> song.title().equalsIgnoreCase(title))
            .findFirst()
            .orElse(null);
}

构建jar并使用DevoxxGenie获取新工具。

使用提示测试搜索功能:“Is Bruce Springsteen one of Gunter’s favorite artists?”

这次将调用search_artist工具,响应再次正确。

结论

在本教程中,您学习了如何使用Spring Boot和Spring AI创建MCP服务器。创建MCP服务器和添加工具非常容易。您可以专注于工具的功能,这正是您想要的。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计