IT评测·应用市场-qidao123.com技术社区

标题: Spring AI MCP Server + Cline 快速搭建一个数据库 ChatBi 助手 [打印本页]

作者: 种地    时间: 2025-4-9 12:20
标题: Spring AI MCP Server + Cline 快速搭建一个数据库 ChatBi 助手
一、Spring AI MCP

MCP 由 Anthropic 推出的一种开放标准协议,旨在统一大模型(LLM)与外部数据源和工具之间的通讯方式。通过 MCP 协议,开发者可以更高效地实现 AI 模型与外部资源的集成,从而提拔应用的智能化和上下文感知本领。现在关于MCP的先容文章也非常多,这里就不过多先容了。
而 Spring AI MCP 则是基于 Spring AI 集成扩展了 MCP Java SDK,让开发者在 Spring 体系下可以快速开发 MCP Server 端或 MCP Client 端。别的官方将 Function Calling 模式给标记 Deprecated 了,说实话动作确实快:

MCP 官方文档:
   https://modelcontextprotocol.io/introduction
  Spring AI MCP 文档
   https://docs.spring.io/spring-ai/reference/api/mcp/mcp-overview.html
  本文基于 Spring AI MCP 实现 MCP Server 端包括三个 MCP Tool ,分别是 获取全部可用的表名、根据表名获取Schema、实行SQL。MCP Client 端利用 Cline 工具进行集成,以及和大模型的交互。
MCP调用实行结果如下所示(实验表结构后面内容中已提供):
首先发起标题:现在的用户数是多少
大模型首先调用 MCP Server 获取全部可用的表名:

根据表名判断出必要利用的表后,主动再次调用 MCP Server 获取表的 Schema :

根据 Schema 天生 SQL ,再次调用 MCP Server 实行 SQL。

根据拿到的实行结果天生答复:

下面开始上述结果的实现过程。
二、准备MySQL表结构及测试数据

用户表

  1. CREATE TABLE `user` (
  2.   `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  3.   `name` varchar(255) DEFAULT NULL COMMENT '姓名',
  4.   `age` int DEFAULT NULL COMMENT '年龄',
  5.   PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户表';
复制代码
写入测试数据:
  1. INSERT INTO `user`(`id`, `name`, `age`) VALUES (1, 'zhangsan', 20);
  2. INSERT INTO `user`(`id`, `name`, `age`) VALUES (2, 'lisi', 60);
  3. INSERT INTO `user`(`id`, `name`, `age`) VALUES (3, 'wangwu', 30);
  4. INSERT INTO `user`(`id`, `name`, `age`) VALUES (4, 'zhaoliu', 31);
  5. INSERT INTO `user`(`id`, `name`, `age`) VALUES (5, 'xiaoming', 35);
  6. INSERT INTO `user`(`id`, `name`, `age`) VALUES (6, 'xiaohong', 25);
  7. INSERT INTO `user`(`id`, `name`, `age`) VALUES (7, 'xiaolan', 40);
复制代码
角色表

  1. CREATE TABLE `role` (
  2.   `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  3.   `role` varchar(255) DEFAULT NULL COMMENT '角色名',
  4.   PRIMARY KEY (`id`)
  5. ) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='角色表';
复制代码
写入测试数据:
  1. INSERT INTO `role`(`id`, `role`) VALUES (1, 'admin');
  2. INSERT INTO `role`(`id`, `role`) VALUES (2, 'common');
  3. INSERT INTO `role`(`id`, `role`) VALUES (3, 'role1');
  4. INSERT INTO `role`(`id`, `role`) VALUES (4, 'role2');
  5. INSERT INTO `role`(`id`, `role`) VALUES (5, 'role3');
复制代码
工作组表:

  1. CREATE TABLE `work_group` (
  2.   `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  3.   `group` varchar(255) DEFAULT NULL COMMENT '工作组',
  4.   PRIMARY KEY (`id`)
  5. ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='工作组表';
复制代码
写入测试数据:
  1. INSERT INTO `work_group`(`id`, `group`) VALUES (1, 'A');
  2. INSERT INTO `work_group`(`id`, `group`) VALUES (2, 'B');
  3. INSERT INTO `work_group`(`id`, `group`) VALUES (3, 'C');
  4. INSERT INTO `work_group`(`id`, `group`) VALUES (4, 'E');
复制代码
用户角色关系表

  1. CREATE TABLE `user_role_mapping` (
  2.   `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  3.   `user_id` int DEFAULT NULL COMMENT '用户ID',
  4.   `role_id` int DEFAULT NULL COMMENT '角色ID',
  5.   PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户角色关系表';
复制代码
写入测试数据:
  1. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (1, 1, 1);
  2. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (2, 1, 2);
  3. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (3, 1, 3);
  4. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (4, 2, 4);
  5. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (5, 2, 5);
  6. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (6, 3, 2);
  7. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (7, 4, 2);
  8. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (8, 5, 2);
  9. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (9, 6, 2);
  10. INSERT INTO `user_role_mapping`(`id`, `user_id`, `role_id`) VALUES (10, 7, 5);
复制代码
用户工作组关系表

  1. CREATE TABLE `user_work_group_mapping` (
  2.   `id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
  3.   `user_id` int DEFAULT NULL COMMENT '用户ID',
  4.   `group_id` int DEFAULT NULL COMMENT '工作组ID',
  5.   PRIMARY KEY (`id`)
  6. ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='用户工作组关系表';
复制代码
写入测试数据:
  1. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (1, 1, 1);
  2. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (2, 1, 2);
  3. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (3, 1, 3);
  4. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (4, 2, 1);
  5. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (5, 2, 2);
  6. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (6, 2, 3);
  7. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (7, 3, 2);
  8. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (8, 3, 3);
  9. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (9, 4, 1);
  10. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (10, 4, 2);
  11. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (11, 5, 2);
  12. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (12, 5, 4);
  13. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (13, 6, 3);
  14. INSERT INTO `user_work_group_mapping`(`id`, `user_id`, `group_id`) VALUES (14, 7, 2);
复制代码
三、Spring AI MCP Server 搭建

首先创建 SpringBoot 项目。注意:SpringBoot 版本必要 3.x 以上,jdk 版本 17 及以上。
在 pom 中加入 spring-ai-mcp-server-spring-boot-starter 的依靠,整体 pom 如下:
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3.          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  4.     <modelVersion>4.0.0</modelVersion>
  5.     <groupId>com.example</groupId>
  6.     <artifactId>mcp-demo</artifactId>
  7.     <version>0.0.1-SNAPSHOT</version>
  8.     <name>mcp-demo</name>
  9.     <description>mcp-demo</description>
  10.     <properties>
  11.         <java.version>17</java.version>
  12.         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  13.         <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  14.         <spring-boot.version>3.4.2</spring-boot.version>
  15.         <spring-ai.version>1.0.0-SNAPSHOT</spring-ai.version>
  16.     </properties>
  17.     <dependencies>
  18.         <dependency>
  19.             <groupId>org.springframework.boot</groupId>
  20.             <artifactId>spring-boot-starter</artifactId>
  21.         </dependency>
  22.         <dependency>
  23.             <groupId>org.springframework.boot</groupId>
  24.             <artifactId>spring-boot-starter-test</artifactId>
  25.             <scope>test</scope>
  26.         </dependency>
  27.         <dependency>
  28.             <groupId>org.springframework.ai</groupId>
  29.             <artifactId>spring-ai-mcp-server-spring-boot-starter</artifactId>
  30.             <version>${spring-ai.version}</version>
  31.         </dependency>
  32.         <dependency>
  33.             <groupId>mysql</groupId>
  34.             <artifactId>mysql-connector-java</artifactId>
  35.             <version>8.0.22</version>
  36.         </dependency>
  37.         <dependency>
  38.             <groupId>com.alibaba</groupId>
  39.             <artifactId>druid</artifactId>
  40.             <version>1.1.6</version>
  41.         </dependency>
  42.         <dependency>
  43.             <groupId>org.springframework.boot</groupId>
  44.             <artifactId>spring-boot-starter-jdbc</artifactId>
  45.         </dependency>
  46.     </dependencies>
  47.     <dependencyManagement>
  48.         <dependencies>
  49.             <dependency>
  50.                 <groupId>org.springframework.boot</groupId>
  51.                 <artifactId>spring-boot-dependencies</artifactId>
  52.                 <version>${spring-boot.version}</version>
  53.                 <type>pom</type>
  54.                 <scope>import</scope>
  55.             </dependency>
  56.             <dependency>
  57.                 <groupId>org.springframework.ai</groupId>
  58.                 <artifactId>spring-ai-bom</artifactId>
  59.                 <version>${spring-ai.version}</version>
  60.                 <type>pom</type>
  61.                 <scope>import</scope>
  62.             </dependency>
  63.         </dependencies>
  64.     </dependencyManagement>
  65.     <build>
  66.         <plugins>
  67.             <plugin>
  68.                 <groupId>org.apache.maven.plugins</groupId>
  69.                 <artifactId>maven-compiler-plugin</artifactId>
  70.                 <version>3.8.1</version>
  71.                 <configuration>
  72.                     <source>17</source>
  73.                     <target>17</target>
  74.                     <encoding>UTF-8</encoding>
  75.                 </configuration>
  76.             </plugin>
  77.             <plugin>
  78.                 <groupId>org.springframework.boot</groupId>
  79.                 <artifactId>spring-boot-maven-plugin</artifactId>
  80.                 <version>${spring-boot.version}</version>
  81.                 <executions>
  82.                     <execution>
  83.                         <goals>
  84.                             <goal>repackage</goal>
  85.                         </goals>
  86.                     </execution>
  87.                 </executions>
  88.             </plugin>
  89.         </plugins>
  90.     </build>
  91.     <repositories>
  92.         <repository>
  93.             <name>Central Portal Snapshots</name>
  94.             <id>central-portal-snapshots</id>
  95.             <url>https://central.sonatype.com/repository/maven-snapshots/</url>
  96.             <releases>
  97.                 <enabled>false</enabled>
  98.             </releases>
  99.             <snapshots>
  100.                 <enabled>true</enabled>
  101.             </snapshots>
  102.         </repository>
  103.         <repository>
  104.             <id>spring-milestones</id>
  105.             <name>Spring Milestones</name>
  106.             <url>https://repo.spring.io/milestone</url>
  107.             <snapshots>
  108.                 <enabled>false</enabled>
  109.             </snapshots>
  110.         </repository>
  111.         <repository>
  112.             <id>spring-snapshots</id>
  113.             <name>Spring Snapshots</name>
  114.             <url>https://repo.spring.io/snapshot</url>
  115.             <releases>
  116.                 <enabled>false</enabled>
  117.             </releases>
  118.         </repository>
  119.     </repositories>
  120. </project>
复制代码
application.yml 中加入数据库连接配置:
  1. spring:
  2.   datasource:
  3.     url: jdbc:mysql://127.0.0.1:3306/langchain?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
  4.     type: com.alibaba.druid.pool.DruidDataSource
  5.     username: root
  6.     password: root
  7.     driver-class-name: com.mysql.cj.jdbc.Driver
复制代码
创建三个 MCP Tool ,实现 获取可用表名、根据表名获取表结构、实行SQL 三个功能:
  1. @Component
  2. public class DBTool {
  3.     @Resource
  4.     private JdbcTemplate jdbcTemplate;
  5.     private final String sql = "SELECT TABLE_NAME, TABLE_COMMENT FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'langchain'";
  6.     private final String schemaSql = "SELECT COLUMN_NAME, DATA_TYPE, COLUMN_COMMENT FROM INFORMATION_SCHEMA.COLUMNS " +
  7.             "WHERE TABLE_SCHEMA = 'langchain' AND TABLE_NAME = ?";
  8.     @Tool(description = "获取所有可用的表名")
  9.     public List<String> getTables() {
  10.         List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
  11.         return maps.stream().map(map -> {
  12.             String tableName = String.valueOf(map.get("TABLE_NAME"));
  13.             String tableComment = String.valueOf(map.get("TABLE_COMMENT"));
  14.             return tableName + " (" + tableComment + ")";
  15.         }).collect(Collectors.toList());
  16.     }
  17.     @Tool(description = "根据表名获取Schema")
  18.     public String getTableSchema(@ToolParam(description = "表名") List<String> tables) {
  19.         return tables.stream().filter(t -> !t.isBlank()).map(tableName -> {
  20.             List<Map<String, Object>> columns = jdbcTemplate.queryForList(schemaSql, tableName);
  21.             String tablePrompt = columns.stream().map(map -> {
  22.                 String name = String.valueOf(map.get("COLUMN_NAME"));
  23.                 String type = String.valueOf(map.get("DATA_TYPE"));
  24.                 String comment = String.valueOf(map.get("COLUMN_COMMENT"));
  25.                 return String.format("%s (%s) - %s", name, type, comment);
  26.             }).collect(Collectors.joining(", \n"));
  27.             return String.format("Table: %s (%s)\n", tableName, tablePrompt);
  28.         }).collect(Collectors.joining("\n"));
  29.     }
  30.     @Tool(description = "执行SQL查询结果")
  31.     public List<Map<String, Object>> runSql(@ToolParam(description = "sql") String sql) {
  32.         if (sql.contains("DELETE") || sql.contains("UPDATE") || sql.contains("INSERT")){
  33.             throw new RuntimeException("执行SQL仅限于查询语句!");
  34.         }
  35.         return jdbcTemplate.queryForList(sql);
  36.     }
  37. }
复制代码
注册 MCP Tools :
  1. @Configuration
  2. public class MCPConfig {
  3.     @Bean
  4.     public List<ToolCallback> tools(DBTool dbTool) {
  5.         return new java.util.ArrayList<>(List.of(ToolCallbacks.from(dbTool)));
  6.     }
  7. }
复制代码
到此 Java 端的开发就结束了,下面打包成 jar 包,为后续 Cline 利用:
  1. mvn clean package
复制代码
四、Cline 配置 MCP Server

利用 VsCode 打开 Cline ,点击右上角 MCP Server,然后选择 Installed ,点击 Configure MCP Server:

写入如下 json 配置,注意 jar 包的路径修改为你的真实所在:
  1. {
  2.   "mcpServers": {
  3.     "mymcp": {
  4.       "command": "java",
  5.       "args": [
  6.         "-jar",
  7.         "D:/mcp-demo/target/mcp-demo-0.0.1-SNAPSHOT.jar"
  8.       ],
  9.       "disabled": false
  10.     }
  11.   }
  12. }
复制代码
然后右侧可以看到 MCP Server 的连接状态,绿色表示连接正常,点开可以看到前面实现的 tools ,别的每个工具的 Auto-approve 建议打上勾,如果不打勾 Cline 调用 MCP Server 时会让我们手动确认一下是否实行:

别的还要在设置开启利用 MCP Server:

到此 Cline 端就配置完成了,可以在对话窗口测试结果。
五、测试

发起标题:现在的用户数,以及每个用户所属的角色和工作组
大模型首先调用 MCP Server 获取全部可用的表名:

然后根据表名判断必要利用哪些表,再次调用 MCP Server 获取表的 Schema :

根据 Schema 天生 SQL ,再次调用 MCP Server 实行 SQL。

根据拿到的查询结果天生答复:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com技术社区 (https://dis.qidao123.com/) Powered by Discuz! X3.4