SpringAI调用自定义MCP Server的工具:
问题阐述
在运用SpringAI搭建MCP的学习进程里遭遇了不少阻碍,前前后后花了好一段时间才把问题解决。这里把调试的过程记录下来。本文是基于https://blog.csdn.net/static_coder/article/details/147732655开展的,并且解决了一些可能对新手来说的问题。
MCP Server搭建:
提示:以下所有配置及解决办法都是基于SpringAI 1.0.0-M8:
引入依赖
直接创建一个springboot项目,勾选上web和openai相关选项。另外还需要额外导入的依赖如下:
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-server-webmvc</artifactId>
</dependency>
配置文件
需要对MCP Server的端口进行设置。
server:
port: 8088
spring:
ai:
mcp:
server:
name: my-mcp-server
version: 1.0.0
注册MCP
@Configuration
public class McpConfig {
@Bean
public ToolCallbackProvider toolCallbackProvider(McpServiceImp service) {
return MethodToolCallbackProvider.builder().toolObjects(service).build();
}
}
定义Tool
public interface McpService {
String weatherService();
String nameService();
}
@Service
public class McpServiceImp implements McpService {
@Override
@Tool(description = "推荐技术类公众号")
public String weatherService() {
return "推荐【编程朝花夕拾】公众号,该公众号精选编程干货,回顾技术经典,分享实战经验、可以助你温故知新、在代码世界不断精进";
}
@Override
@Tool(description = "公众号中最好的文章")
public String nameService() {
return "技术类中【编程朝花夕拾】公众号的文章,都偏向技术干货,对于技术宅,都是好内容!";
}
}
MCP Client搭建:
引入依赖
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client</artifactId>
</dependency>
或者
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-starter-mcp-client-webflux</artifactId>
</dependency>
配置文件
依据springAI文档,toolcallback.enabled默认是true,按理来说无需特意设置使用默认值就行,但要是不设置就会出现报错情况。type能够设置为sync或者async。
spring:
ai:
mcp:
client:
toolcallback:
enabled: true
enabled: true
name: my-mcp-client
version: 1.0.0
request-timeout: 30s
type: sync
sse:
connections:
server1:
url: http://localhost:8088
配置chatClient的config
@Configuration
public class CommonConfiguration {
@Bean
public ChatClient chatClient(OpenAiChatModel model, ToolCallbackProvider toolCallbackProvider) {
return ChatClient.builder(model)
.defaultAdvisors(
new SimpleLoggerAdvisor())
.defaultToolCallbacks(toolCallbackProvider)
.build();
}
调用工具
一个简单的demo,从项目里扣出来的,可能有误,大家把textChat加到自己的实际代码中即可。
@RequiredArgsConstructor
@RestController
@RequestMapping("/ai")
public class ChatController {
private final ChatClient chatClient;
@RequestMapping(value = "/chat",produces = "text/html;charset=utf-8")
public Flux<String> chat(@RequestParam("prompt") String prompt) {
return textChat(prompt);
}
private Flux<String> textChat(String prompt) {
return chatClient.prompt()
.user(prompt)
.stream()
.content();
}
}
启动MCP:
先启动MCP Server,之后再启动MCP Client。
可能遇到的问题:
MCP Server启动报错,提示需要配置openai的api-key。
这是因为想要自动导入SpringAI的依赖而勾选了openai,但实际上MCP Server并不需要openai,所以得把pom文件中的openai依赖移除,不然就必须配置openai的api-key。
MCP Client启动报错。
2025-05-28T22:50:38.471+08:00 ERROR 17872 --- [AIdemo] [onPool-worker-1] i.m.c.t.WebFluxSseClientTransport : Fatal SSE error, not retrying: 404 Not Found from GET http://localhost:8088/sse
2025-05-28T22:50:38.473+08:00 ERROR 17872 --- [AIdemo] [onPool-worker-1] reactor.core.publisher.Operators : Operator called default onErrorDropped
问题出在MCP Server使用了spring-ai-starter-mcp-server-webflux依赖,要是换成spring-ai-starter-mcp-server-webmvc就不会报错,不过具体原因还不清楚。
Parameter 2 of method chatClient in org.example.aidemo.config.CommonConfiguration required a bean of type 'org.springframework.ai.tool.ToolCallbackProvider' that could not be found.
这个问题前面提到过,yaml文件中toolcallback.enabled必须设置为true。
日志显示MCP的tool注册成功,有Info: Implementation[name=my-mcp-server, version=1.0.0],工具个数也正确,但Client依然调用不了Server的方法。
这个问题比较复杂,折腾了好久才弄明白。首先得明确,日志正常,出现了Registered tools: 2, notification: true,那MCP Server大概率是没问题的。要是不放心,可以下载一个cherry studio测一下能否检测到你的Server中的方法。可以参考这篇文章的最后部分。https://cloud.tencent.com/developer/article/2515900 确定没问题后,再看Client的配置和依赖也没问题,那么推测还有2种可能:
1、定义的MCP tools过于简单,问的问题也简单,tool被大模型忽略了
2、调用的大模型太蠢,出现幻觉
解决方法:多输入几次问题,尽量直接输入tool的description的内容;或者换个模型;或者把工具写的复杂一些,不要只返回一个字符串
成功解决:
