SpringAI搭建MCP Server和Client及Bug解决
SpringAI调用自定义MCP Server的工具:
问题描述
学习用SpringAI搭建MCP的过程中踩了不少坑,前后折腾了大半天才解决。
这里记录一下调试过程。
本文基于https://blog.csdn.net/static_coder/article/details/147732655
在此基础上解决了一些可能比较小白的问题。
MCP Server搭建:
提示:以下所有配置及解决方案都是基于SpringAI 1.0.0-M8:
引入依赖
直接创建一个springboot项目,勾选上web和openai选项。
然后额外需要导入的依赖就是下面这个:
org.springframework.ai spring-ai-starter-mcp-server-webmvc
配置文件
需要设置一下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搭建:
引入依赖
org.springframework.ai spring-ai-starter-mcp-client
或者
org.springframework.ai spring-ai-starter-mcp-client-webflux
都可以。
配置文件
根据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 chat(@RequestParam("prompt") String prompt) { return textChat(prompt); } private Flux 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的内容;或者换个模型;或者把工具写的复杂一些,不要只返回一个字符串