本篇文章将手把手教你如何基于 Spring AI 搭建支持 SSE模式的 MCP、服务,并成功将其集成至百炼大模型平台。相较于传统 HTTP 请求-响应模式,SSE 实现了服务器端实时、连续的数据推送,显著提升了交互效率与用户体验。
mcp从0到Agent,需要以下4步:
关于Spring AI MCP,您可以查看Spring AI MCP官方文档,了解更多详情。
1. 快速搭建SpringBoot项目,引入Spring AI
1.1 开发环境准备:
- JDK 17 或以上版本。
- Maven 3.8.6 或以上版本。
- Spring AI 1.0.0-M6。
- 通义千问 API Key(用于模型调用)。
1、创建名为springboot-bailian-mcp-workflow-server的项目。
2、在pom.xml当中引入SpringAI的依赖。
<dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-bom</artifactId> <version>1.0.0-M6</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp-server-webmvc-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.ai</groupId> <artifactId>spring-ai-mcp</artifactId> </dependency>
<dependency> <groupId>com.openai</groupId> <artifactId>openai-java</artifactId> <version>0.32.0</version> </dependency>
3、修改resources目录下的application.yml。
如果没有application.yml将application.properties删除以后创建application.yml。
server: port: 8088 spring: application: name: springboot-bailian-mcp-workflow-server ai: mcp: server: name: bailian-mcp-workflow-server version: 1.0.0 type: SYNC sse-message-endpoint: /mcp/messages
2. 创建两个MCP tool工具【将大模型封装为MCP tool】
1、创建ToolServer.java。
在SpringbootBailianMcpWorkflowServerApplication相同层级的目录下,首先创建一个名为server的文件夹。接着,在该server文件夹内新建一个名为ToolServer.java的文件。
在此文件中,我们将构建两个工具功能:【批量生成标题】和【文章润色】。
完善ToolServer.java当中的代码,代码当中的提示词均来自阿里云百炼大模型提示词生成器。
package com.alibaba.springbootbailianmcpworkflowserver.server; import com.openai.client.OpenAIClient; import com.openai.client.okhttp.OpenAIOkHttpClient; import com.openai.models.ChatCompletion; import com.openai.models.ChatCompletionCreateParams; import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Service; import java.util.Arrays; import java.util.List; /** * @author zhengxujie * 2025/05/07/上午9:31 */ @Service public class ToolServer { @Tool(description = "批量生成标题") public List<String> BatchGenerateTitles(String title) { String SystemPrompt = "# 角色\n" + "你是一位专业的批量生成标题助手,擅长根据用户提供的提示快速生成高质量的标题。\n" + "\n" + "## 技能\n" + "### 技能1:理解用户需求\n" + "- 仔细阅读并理解用户提供的提示和要求。\n" + "- 根据用户的输入,确定标题的主题、风格和目标受众。\n" + "\n" + "### 技能2:创意标题生成\n" + "- 能够在短时间内生成多个具有吸引力和多样性的标题。\n" + "- 确保每个标题都符合用户的需求,并且能够吸引目标受众的注意力。\n" + "\n" + "### 技能3:标题优化\n" + "- 对生成的标题进行优化,确保它们简洁明了、易于理解。\n" + "- 考虑到SEO优化,合理嵌入关键词以提高标题的可发现性。\n" + "\n" + "### 技能4:多样化风格\n" + "- 能够生成不同风格的标题,如新闻报道式、故事叙述式、疑问式等。\n" + "- 根据不同的使用场景(如博客文章、社交媒体帖子、新闻报道等)调整标题的风格和长度。\n" + "\n" + "## 限制\n" + "- 生成的标题数量为20个。\n" + "- 每个标题应简洁明了,不超过20个字。\n" + "- 所有标题必须与用户提供的提示和要求一致。\n" + "- 避免使用过于复杂或难以理解的语言。\n" + "- 如果需要特定领域的专业知识,可以通过调用搜索工具或查询知识库来获取相关信息。"; String UserPrompt = "用户输入内容如下:"+title; String reTitle = null; try{ reTitle = callWithMessage(SystemPrompt,UserPrompt); }catch (Exception e){ return List.of("错误:"+e.getMessage()); } if (reTitle == null){ return List.of("错误:生成标题失败"); } return List.of(reTitle); } @Tool(description = "文章润色") public List<String> polishTheArticle(String content) { String SystemPrompt = "# 角色\n" + "你是一位专业的文章润色助手,擅长提升文章的语言表达、逻辑结构和整体流畅性。你的任务是根据用户提供的原始文本,进行细致的润色,使文章更加清晰、生动和有说服力。\n" + "\n" + "## 技能\n" + "### 技能 1: 语言润色\n" + "- 优化文章中的词汇选择,使其更加精准和生动。\n" + "- 调整句子结构,使文章更加流畅自然。\n" + "- 修正语法错误和拼写错误,确保文章的专业性和准确性。\n" + "\n" + "### 技能 2: 逻辑结构优化\n" + "- 重新组织段落顺序,使文章的逻辑更加清晰。\n" + "- 添加或删除内容,以增强文章的连贯性和一致性。\n" + "- 提供适当的过渡句,使各部分之间的衔接更加自然。\n" + "\n" + "### 技能 3: 内容丰富与精简\n" + "- 根据需要添加更多细节,使文章内容更加丰富和具体。\n" + "- 删除冗余信息,使文章更加简洁明了。\n" + "- 保持文章的主题和核心思想不变,同时提升其吸引力和可读性。\n" + "\n" + "### 技能 4: 风格调整\n" + "- 根据用户的指示调整文章的风格,如正式、幽默、轻松等。\n" + "- 确保文章的风格与目标受众相匹配。\n" + "- 保持一致的语气和语调,增强文章的整体效果。\n" + "\n" + "## 限制\n" + "- 只对用户提供的一篇文章进行润色,不涉及其他文档。\n" + "- 润色过程中保持原文的核心内容和意图不变。\n" + "- 不得添加或删除与文章主题无关的内容。\n" + "- 如果用户提供了特定的风格要求,请严格遵循这些要求进行润色。\n" + "- 在润色时,注意保留用户的个人风格和声音,避免过度修改。"; String UserPrompt = "原始文本内容如下:"+content; String ReContent = null; try{ ReContent = callWithMessage(SystemPrompt,UserPrompt); }catch (Exception e){ return List.of("错误:"+e.getMessage()); } if (ReContent == null){ return List.of("错误:文章润色失败"); } return List.of(ReContent); } public String callWithMessage(String SystemPrompt,String UserPrompt) throws Exception { OpenAIClient client = OpenAIOkHttpClient.builder() .apiKey(System.getenv("DASHSCOPE_API_KEY")) .baseUrl("https://dashscope.aliyuncs.com/compatible-mode/v1") .build(); ChatCompletionCreateParams params = ChatCompletionCreateParams.builder() // 添加system消息来设定对话的基调或指示 .addSystemMessage(SystemPrompt) // 添加user消息作为实际的询问或命令 .addUserMessage(UserPrompt) .model("qwen-plus") .build(); ChatCompletion chatCompletion = client.chat().completions().create(params); return chatCompletion.choices().get(0).message().content().orElse("无返回内容"); } }
2、大致解释一下上述代码。
@Tool(description = "文章润色")
和 @Tool(description = "批量生成标题")
是 Spring AI 提供的注解,用于将方法标记为可被外部调用的工具(Tool),并提供描述信息,其中 DASHSCOPE_API_KEY 为百炼的API-KEY。
3. 将上述创建的tool注册为SpringAI 的 MCP SSE服务,并创建测试类。
1、在McpServerApplication的同级目录下创建config目录。
2、在config目录下创建McpServerConfig.java 将工具。
package com.alibaba.springbootbailianmcpworkflowserver.config; import com.alibaba.springbootbailianmcpworkflowserver.server.ToolServer; import org.springframework.ai.tool.ToolCallbackProvider; import org.springframework.ai.tool.method.MethodToolCallbackProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; /** * @author zhengxujie * 2025/05/07/上午9:31 */ @Configuration @EnableWebMvc public class McpServerConfig implements WebMvcConfigurer { @Bean public ToolCallbackProvider openLibraryTools(ToolServer toolServer) { return MethodToolCallbackProvider.builder().toolObjects(toolServer).build(); } }
3、在src/test/java/com/alibaba/springbootbailianmcpworkflowserver的测试目录下创建SampleClient.java 创建一个简单的客户端用于调用对应的MCP服务。
package com.alibaba.springbootbailianmcpworkflowserver; import io.modelcontextprotocol.client.McpClient; import io.modelcontextprotocol.spec.ClientMcpTransport; import io.modelcontextprotocol.spec.McpSchema.*; import java.util.Map; /** * @author zhengxujie * 2025/05/07/上午9:31 */ public class SampleClient { private final ClientMcpTransport transport; public SampleClient(ClientMcpTransport transport) { this.transport = transport; } public void run() { var client = McpClient.sync(this.transport).build(); client.initialize(); client.ping(); // List and demonstrate tools ListToolsResult toolsList = client.listTools(); System.out.println("Available Tools = " + toolsList); CallToolResult books = client.callTool(new CallToolRequest("BatchGenerateTitles", Map.of("title", "人工智能"))); System.out.println("Title Response = " + books); client.closeGracefully(); } }
4、在同级目录下的SpringbootBailianMcpWorkflowServerApplicationTests使用工具。
package com.alibaba.springbootbailianmcpworkflowserver; import io.modelcontextprotocol.client.transport.HttpClientSseClientTransport; import org.junit.jupiter.api.Test; import org.springframework.boot.test.context.SpringBootTest; /** * @author zhengxujie * 2025/05/07/上午9:31 */ @SpringBootTest class SpringbootBailianMcpWorkflowServerApplicationTests { @Test void contextLoads() { var transport = new HttpClientSseClientTransport("http://localhost:8088"); new SampleClient(transport).run(); } }
4. 运行测试
1、在SpringbootBailianMcpWorkflowServerApplication当中启动项目。
启动成功。
2、在SpringbootBailianMcpWorkflowServerApplicationTests当中使用客户端调用。
测试成功。
3、在cline当中运行测试
{ "mcpServers": { "bailian-mcp-workflow-server": { "url": "http://localhost:8088/sse" } } }
/sse则是调用SSE MCP服务入口,下面测试一下,都没有问题。
5. 项目打包并部署到阿里云函数当中
1、将上述SpringBoot项目进行打包。
在target目录下成功生成对应的jar。
2、将项目部署到阿里云的函数当中。
进入函数计算:点击购买或者进入管理控制台。
点击创建函数。
选择对应的Web函数,在将 jar 文件上传至函数计算之前,需先将其放置在一个单独的文件夹内。此文件夹中仅包含该 jar 文件,而我这里所用的文件夹名称为 "java"。请确保遵循此步骤以满足上传要求。
上传好对应的jar文件后,填写完上述表单信息,然后点击创建按钮即可。
点击部署代码,部署成功以后。
在配置的触发器中,可以找到对应的公网IP地址。
复制上述公网地址。
6. 将上述的部署好的SSE MCP 集成到百炼当中
1、打开百炼的自定义MCP服务。
打开链接点击创建MCP服务,在SSE模式当中填写如下内容。
{ "mcpServers": { "bailian-mcp-workflow-server": { "url": "https://sse-*******.cn-*******.fcapp.run/sse" } } }
其中 https://sse-*******.cn-*******.fcapp.run 为函数计算的公网IP地址。
/sse则是调用SSE MCP服务入口。
接下来点击提交部署。
随后,返回到自定义MCP的列表页面。
此时,可以看到服务已经成功部署。
工具也没有问题。
2、创建智能体应用集成自定义SSE MCP服务。
访问https://bailian.console.aliyun.com/,创建智能体应用。
在智能体应用中设置MCP时,选择刚刚创建的自定义MCP服务。
在集成好相应的MCP服务后,我们来进行运行测试。
现在就测试成功啦,是不是很详细呢。好了,别光看呀,跟着教程操作起来吧~~🤗
🌴注意注意:
可直接点击阿里云百炼 MCP服务使用教程合集链接跳转回合集文章页面。
可直接点击下面链接直接进控制台创建:
👉阿里云百炼详情了解可点击此官网链接:阿里云百炼官网介绍
👉阿里云百炼控制台页面可点击此链接直接进入:阿里云百炼控制台
如果在创建过程中有任何的疑问都可以在评论区中留言探讨或是加入我们的官方支持群(群号:120480015429)进行交流反馈!