打造一个支持MySQL查询的MCP同步插件:Java实现

打造一个支持MySQL查询的MCP同步插件:Java实现

用Java实现一个MCP本地插件,直接通过JDBC操作本地MySQL,并通过STDIO与上层MCP客户端(例如Cursor)通信。插件注册一个名为mysql
的同步工具,接收连接参数及SQL查询,执行后将结果以JSON返回。目录结构、完整代码及在Cursor中的示例配置如下。

摘要

我们基于 Model Context Protocol Java SDK 实现了一个简单的 MCP Server 插件,它:

  1. 在 Server 启动时注册一个名为 mysql 的工具(SyncToolSpecification),其参数定义包括 hostuserpassword
    databasequery 等字段。

  2. 在工具处理器中利用 MySQL 官方 JDBC 驱动(mysql-connector-java)连接数据库,执行查询,并将每行结果封装为 JSON 数组返回。

  3. 打包为可执行 JAR 后,通过命令行启动,Cursor 中配置类似于:

    {"mcpServers": {"mysql": {"command": "java","args": ["-jar", "/Users/changmeng.yuan.o/Desktop/mysql-server-mcp-java-demo/target/mysql-server-mcp-java-demo-1.0.0.jar"],"env": {"MYSQL_HOST": "localhost","MYSQL_USER": "root","MYSQL_PASSWORD": "875213MenG...","MYSQL_DATABASE": "test"}}}
    

}


即可在对话中直接调用 `mysql` 工具执行任意查询并获取结果。## 依赖在 `pom.xml` 中声明以下关键依赖:* **MCP 核心 SDK**(包含 STDIO Server 传输实现)```xml
<dependency><groupId>io.modelcontextprotocol.sdk</groupId><artifactId>mcp</artifactId><version>0.9.0</version>
</dependency>
  • MySQL JDBC 驱动
    可以用新版的 mysql-connector-j

     <dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.2.0</version></dependency>
    

    (来自 MySQL 官方 Maven 中心)

  • Jackson 用于 JSON 序列化(可选,STDIO Transport 已自带,但我们手动构造 JSON)

    <dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.15.2</version>
    </dependency>
    

目录结构

mcp-mysql-plugin/
├── pom.xml
└── src└── main├── java│   └── com│       └── example│           └── mcpmysql│               ├── Main.java│               └── MysqlTool.java└── resources└── application.properties

pom.xml


<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.codeyuan.mcpmysql</groupId><artifactId>mysql-server-mcp-java-demo</artifactId><version>1.0.0</version><properties><!-- 指定 Java 版本 --><java.version>17</java.version><mcp.version>0.9.0</mcp.version><jackson.version>2.15.2</jackson.version><mysql.connector.version>8.2.0</mysql.connector.version><!-- 用于 Maven Compiler Plugin 的 release 配置 --><maven.compiler.release>${java.version}</maven.compiler.release></properties><dependencies><!-- MCP core SDK with STDIO transport --><dependency><groupId>io.modelcontextprotocol.sdk</groupId><artifactId>mcp</artifactId><version>${mcp.version}</version></dependency><!-- MySQL JDBC --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.connector.version}</version></dependency><!-- Jackson JSON --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>${jackson.version}</version></dependency></dependencies><build><plugins><!-- 1. Maven Compiler: 指定 Java 版本,支持文本块 --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><version>3.14.0</version><configuration><!-- 一次性设置 source、target 和标准库版本 --><release>${maven.compiler.release}</release></configuration></plugin><!-- 2. Maven Shade: 打包为 fat-jar --><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-shade-plugin</artifactId><version>3.5.0</version><executions><execution><phase>package</phase><goals><goal>shade</goal></goals><configuration><!-- 去除依赖中的签名文件等,避免冲突 --><filters><filter><artifact>*:*</artifact><excludes><exclude>META-INF/*.SF</exclude><exclude>META-INF/*.DSA</exclude><exclude>META-INF/*.RSA</exclude></excludes></filter></filters><!-- 指定主类 --><transformers><transformerimplementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"><mainClass>com.codeyuan.mcpmysql.Main</mainClass></transformer></transformers></configuration></execution></executions></plugin></plugins></build>
</project>

Main.java

package com.codeyuan.mcpmysql;import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpServer;
import io.modelcontextprotocol.server.McpSyncServer;
import io.modelcontextprotocol.server.transport.StdioServerTransportProvider;
import io.modelcontextprotocol.spec.McpSchema;/*** main主函数方法* @author codeyuan*/
public class Main {public static void main(String[] args) throws InterruptedException {// 1) 使用 STDIO 传输层启动服务器var transportProvider = new StdioServerTransportProvider(new ObjectMapper());// 2) 构建并启动同步 MCP Server,启用工具执行能力McpSyncServer server = McpServer.sync(transportProvider)// 配置一下  Server 信息.serverInfo("mysql-plugin", "1.0.0").capabilities(McpSchema.ServerCapabilities.builder()// 开启工具支持.tools(true).build())// build() 方法会立即启动服务器并监听输入:contentReference[oaicite:6]{index=6}.build();// 3) 注册自定义 MySQL 工具// addTool 可在运行时动态添加工具:contentReference[oaicite:7]{index=7}server.addTool(MysqlTool.specification());// 4) 在 JVM 退出时优雅关闭服务器// close() 用于关闭传输并释放资源:contentReference[oaicite:8]{index=8}Runtime.getRuntime().addShutdownHook(new Thread(server::close));// 5) 阻塞主线程,保持进程存活// join() 阻塞主线程,防止 JVM 退出:contentReference[oaicite:9]{index=9}Thread.currentThread().join();}
}

说明:基于文档示例,使用 McpServer.sync(...) 构建同步服务器,开启 tools 功能,并注册我们自定义的工具。

MysqlTool.java

package com.codeyuan.mcpmysql;import com.fasterxml.jackson.databind.ObjectMapper;
import io.modelcontextprotocol.server.McpServerFeatures;
import io.modelcontextprotocol.spec.McpSchema;import java.sql.*;
import java.util.*;/*** 执行连接操作mysql* 支持 SELECT 和非 SELECT 类型语句* @author codeyuan*/
public class MysqlTool {private static final ObjectMapper JSON = new ObjectMapper();// 定义工具规格:name、description、JSON 参数 schemapublic static McpServerFeatures.SyncToolSpecification specification() {String schema = """{"type": "object","properties": {"host":     { "type": "string" },"user":     { "type": "string" },"password": { "type": "string" },"database": { "type": "string" },"query":    { "type": "string" }},"required": ["host","user","password","database","query"]}""";McpSchema.Tool tool = new McpSchema.Tool("mysql", "Execute SQL on MySQL", schema);return new McpServerFeatures.SyncToolSpecification(tool, (exchange, arguments) -> {try {// 提取参数String host = arguments.get("host").toString();String user = arguments.get("user").toString();String pass = arguments.get("password").toString();String db   = arguments.get("database").toString();String sql  = arguments.get("query").toString().trim();String url  = String.format("jdbc:mysql://%s/%s?useSSL=false&allowMultiQueries=true", host, db);try (Connection conn = DriverManager.getConnection(url, user, pass);Statement stmt = conn.createStatement()) {if (sql.toLowerCase().startsWith("select")) {try (ResultSet rs = stmt.executeQuery(sql)) {List<Map<String, Object>> rows = new ArrayList<>();ResultSetMetaData meta = rs.getMetaData();int colCount = meta.getColumnCount();while (rs.next()) {Map<String, Object> row = new LinkedHashMap<>();for (int i = 1; i <= colCount; i++) {row.put(meta.getColumnLabel(i), rs.getObject(i));}rows.add(row);}Map<String, Object> result = Map.of("rows", rows);return new McpSchema.CallToolResult(String.valueOf(result), false);}} else {int affected = stmt.executeUpdate(sql);Map<String, Object> result = Map.of("affectedRows", affected);return new McpSchema.CallToolResult(String.valueOf(result), false);}}} catch (Exception e) {// 错误时将异常信息返回return new McpSchema.CallToolResult(String.valueOf(Map.of("error", e.getMessage())), false);}});}
}

application.properties

(可用于默认值配置,示例中未使用;所有参数均从工具调用时传入或环境变量读取。)

# 可在此预置 host, user, password, database 等默认值

打包与发布

# 编译并打包为 fat-jar
mvn clean package
# 生成目标: target/mcp-mysql-plugin-1.0.0.jar

将生成的 JAR 上传或放置在可访问路径,然后在 Cursor 等 MCP 客户端中配置:

{"mcpServers": {"mysql": {"command": "java","args": ["-jar","/absolute/path/to/mcp-mysql-plugin-1.0.0.jar"],"env": {"MYSQL_HOST": "localhost","MYSQL_USER": "root","MYSQL_PASSWORD": "secret","MYSQL_DATABASE": "testdb"}}}
}

调用示例(在对话中):

{"tool": "mysql","arguments": {"host": "localhost","user": "root","password": "secret","database": "testdb","query": "SELECT * FROM users LIMIT 10"}
}

即可返回如下 JSON 结构:

{"rows": [{"id": 1,"name": "Alice","email": "alice@example.com"}]
}

获取直接使用自然语言对话

我是用的数据库版本是8.0,给我创建一个用户表,用户表可能存在,表中有姓名、年纪、性别、地址等字段,模拟插入10条数据

cursor-mysql-mcp-test-1.jpg

cursor-mysql-mcp-test-2.jpg

参考文档:

  1. https://modelcontextprotocol.io/sdk/java/mcp-server “MCP Server - Model Context Protocol”
  2. https://modelcontextprotocol.io/sdk/java/mcp-overview “Overview - Model Context Protocol”

↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
下面关注回复【mysql-server-mcp-java-demo】
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/web/81313.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据架构01】数据技术架构篇

✅ 9张高质量数据架构图&#xff1a;大数据平台功能架构、数据全生命周期管理图、AI技术融合架构等&#xff1b; &#x1f680;无论你是数据架构师、治理专家&#xff0c;还是数字化转型负责人&#xff0c;这份资料库都能为你提供体系化参考&#xff0c;高效解决“架构设计难、…

java三种常见设计模式,工厂、策略、责任链

设计模式实战解析 一、工厂模式&#xff08;点外卖模式&#xff09; 1. 核心思想 代替直接new对象像点外卖一样获取对象 2. 实际应用 Spring框架&#xff1a;BeanFactoryJDBC&#xff1a;DriverManager.getConnection() 3. 三种变体对比 类型特点示例场景简单工厂一个工…

jenkins使用Send build artifacts over SSH发布jar包目录配置

本测试用ruoyi-plus的代码。 1 [GitLab 自动触发 Jenkins 构建_jenkins构建触发器没有build when a change is pushed to git-CSDN博客](https://blog.csdn.net/wangyiyungw/article/details/81776972) 2 [jenkins使用Send build artifacts over SSH遇到的坑-CSDN博客](https…

vscode打开vue + element项目

好嘞&#xff0c;我帮你详细整理一个用 VS Code 来可视化开发 Vue Element UI 的完整步骤&#xff0c;让你能舒服地写代码、预览界面、调试和管理项目。 用 VS Code 可视化开发 Vue Element UI 全流程指南 一、准备工作 安装 VS Code 官网下载安装&#xff1a;https://code…

黑马程序员C++2024新版笔记 第4章 函数和结构体

目录 1.结构体的基本应用 2.结构体成员的默认值 3.结构体数组 4.结构体指针 ->操作符 5.结构体指针数组 1.引入已存在的结构体数组地址 2.通过new操作符申请指针数组空间 6.函数的概念 7.函数的基础语法 8.无返回值函数和void类型 9.空参函数 10.函数的嵌套调用…

高级前端工程师必备的 JS 设计模式入门教程,常用设计模式案例分享

目录 高级前端工程师必备的 JS 设计模式入门教程&#xff0c;常用设计模式案例分享 一、什么是设计模式&#xff1f;为什么前端也要学&#xff1f; 1、设计模式是什么 2、设计模式的产出 二、设计模式在 JS 里的分类 三、常用设计模式实战讲解 1、单例模式&#xff08;S…

Ubuntu+Docker+内网穿透:保姆级教程实现安卓开发环境远程部署

文章目录 前言1. 虚拟化环境检查2. Android 模拟器部署3. Ubuntu安装Cpolar4. 配置公网地址5. 远程访问小结 6. 固定Cpolar公网地址7. 固定地址访问 前言 本文将详细介绍一种创新性的云开发架构&#xff1a;基于Ubuntu系统构建Android仿真容器环境&#xff0c;并集成安全隧道技…

Linux Kernel调试:强大的printk(一)

引言 想了好久&#xff0c;还是觉得这个标题才配得上printk&#xff01;^_^ 我相信&#xff0c;不管做什么开发&#xff0c;使用最多的调试手段应该就是打印了&#xff0c;从我们学习编程语言第一课开始&#xff0c;写的第一段代码&#xff0c;就是打印"Hello, world&qu…

基于NLP技术的客户投诉与需求文本分类方法研究

目录 摘要 1. 引言 2. 文本分类基础 2.1 文本分类的定义与类型 2.2 文本分类的评价指标 3. 传统文本分类方法 3.1 基于TF-IDF和SVM的方法 3.2 基于主题模型和词向量的改进方法 4. 深度学习文本分类方法 4.1 TextCNN模型 4.2 BiLSTM模型 4.3 注意力机制与Transformer…

#RabbitMQ# 消息队列入门

目录 一 MQ技术选型 1 运行rabbitmq 2 基本介绍 3 快速入门 1 交换机负责路由消息给队列 2 数据隔离 二 Java客户端 1 快速入门 2 WorkQueue 3 FanOut交换机 4 Direct交换机 5 Topic交换机 *6 声明队列交换机 1 在配置类当中声明 2 使用注解的方式指定 7 消息转…

【深度学习】多目标融合算法(六):渐进式分层提取模型PLE(Progressive Layered Extraction)

目录 一、引言 二、PLE&#xff08;Progressive Layered Extraction&#xff0c;渐进式分层提取模型&#xff09; 2.1 技术原理 2.2 技术优缺点 2.3 业务代码实践 2.3.1 业务场景与建模 2.3.2 模型代码实现 2.3.3 模型训练与推理测试 2.3.4 打印模型结构 三、总结 一…

【Java开发日记】如何使用Java开发在线生成 pdf 文档

一、介绍 在实际的业务开发的时候&#xff0c;研发人员往往会碰到很多这样的一些场景&#xff0c;需要提供相关的电子凭证信息给用户&#xff0c;例如网银&#xff0f;支付宝&#xff0f;微信购物支付的电子发票、订单的库存打印单、各种电子签署合同等等&#xff0c;以方便用…

Oracle 11g 单实例使用+asm修改主机名导致ORA-29701 故障分析

解决 把服务器名修改为原来的&#xff0c;重启服务器。 故障 建表空间失败。 分析 查看告警日志 ORA-1119 signalled during: create tablespace splex datafile ‘DATA’ size 2000M… Tue May 20 18:04:28 2025 create tablespace splex datafile ‘DATA/option/dataf…

消息队列的使用

使用内存队列来处理基于内存的【生产者-消费者】场景 思考和使用Disruptor Disruptor可以实现单个或多个生产者生产消息&#xff0c;单个或多个消费者消息&#xff0c;且消费者之间可以存在消费消息的依赖关系 使用Disruptor需要结合业务特性&#xff0c;设计要灵活 什么业务…

《帝国时代1》游戏秘籍

资源类 PEPPERONI PIZZA&#xff1a;获得 1000 食物。COINAGE&#xff1a;获得 1000 金。WOODSTOCK&#xff1a;获得 1000 木头。QUARRY&#xff1a;获得 1000 石头。 建筑与生产类 STEROIDS&#xff1a;快速建筑。 地图类 REVEAL MAP&#xff1a;显示所有地图。NO FOG&#xf…

使用JSP踩过的坑

虽然说jsp已经过时了&#xff0c;但是有时维护比较老的项目还是需要的。 下面说下&#xff0c;我使用jsp踩过的坑&#xff1a; 1.关于打印输出 在jsp中输出使用 out.println("hello");而不是 System.out.println("hello");如果在定义函数部分需要打印…

redis集群创建时手动指定主从关系的方法

适用场景&#xff1a; 创建主从关系时默认参数 --cluster-replicas 1 会自动分配从节点。 为了能精确控制 Redis Cluster 的主从拓扑结构&#xff0c;我们通过 Redis Cluster 的手动分片功能来实现 一、手动指定主从关系的方法 使用 redis-cli --cluster-replicas 0 先创建纯…

ROS合集(七)SVIn2声呐模块分析

文章目录 一、整体思想二、具体误差建模流程三、总结明确&#xff08;预测值与观测值&#xff09;四、选点逻辑五、Sonar 数据处理流水线1. ROS Launch 配置&#xff08;imagenex831l.launch&#xff09;2. SonarNode 节点&#xff08;sonar_node.py&#xff09;3. Subscriber …

Python爬虫实战:研究PySpider框架相关技术

1. 引言 1.1 研究背景与意义 网络爬虫作为互联网数据采集的重要工具,在信息检索、舆情分析、市场调研等领域发挥着重要作用。随着互联网信息的爆炸式增长,如何高效、稳定地获取所需数据成为了一个关键挑战。PySpider 作为一款功能强大的 Python 爬虫框架,提供了丰富的功能…

《大模型开源与闭源的深度博弈:科技新生态下的权衡与抉择》

开源智能体大模型的核心魅力&#xff0c;在于它构建起了一个全球开发者共同参与的超级协作网络。想象一下&#xff0c;来自世界各个角落的开发者、研究者&#xff0c;无论身处繁华都市还是偏远小镇&#xff0c;只要心怀对技术的热爱与追求&#xff0c;就能加入到这场技术狂欢中…