打造一個支持MySQL查詢的MCP同步插件:Java實現
用Java實現一個MCP本地插件,直接通過JDBC操作本地MySQL,并通過STDIO與上層MCP客戶端(例如Cursor)通信。插件注冊一個名為mysql
的同步工具,接收連接參數及SQL查詢,執行后將結果以JSON返回。目錄結構、完整代碼及在Cursor中的示例配置如下。
摘要
我們基于 Model Context Protocol Java SDK 實現了一個簡單的 MCP Server 插件,它:
-
在 Server 啟動時注冊一個名為
mysql
的工具(SyncToolSpecification
),其參數定義包括host
、user
、password
、
database
、query
等字段。 -
在工具處理器中利用 MySQL 官方 JDBC 驅動(
mysql-connector-java
)連接數據庫,執行查詢,并將每行結果封裝為 JSON 數組返回。 -
打包為可執行 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條數據
參考文檔:
- https://modelcontextprotocol.io/sdk/java/mcp-server “MCP Server - Model Context Protocol”
- https://modelcontextprotocol.io/sdk/java/mcp-overview “Overview - Model Context Protocol”
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
下面關注回復【mysql-server-mcp-java-demo】
↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓