@xingyuchen/mysql-mcp-server 4.0.3 → 4.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -321,10 +321,33 @@ lsof -ti:3001 | xargs kill -9
321
321
 
322
322
  **解决:** 刷新 MCP 客户端(重新初始化)
323
323
 
324
+ ### 4. 连接已关闭错误
325
+
326
+ **错误:** `Can't add new command when connection is in closed state`
327
+
328
+ **原因:**
329
+ - 数据库连接长时间空闲,MySQL 服务器关闭了连接
330
+ - 网络中断导致连接断开
331
+
332
+ **解决方案:**
333
+ - ✅ v4.0.5+ 已使用连接池替代单连接,自动支持:
334
+ - 连接保活(Keep-Alive)机制
335
+ - 自动重连功能
336
+ - 并发查询支持
337
+ - 如果仍遇到问题,请重启 MCP 服务器
338
+
324
339
  ---
325
340
 
326
341
  ## 📦 版本历史
327
342
 
343
+ ### v4.0.5 (2025-12-09) - 连接池优化
344
+
345
+ - 🎯 使用连接池替代单连接
346
+ - 🔄 自动连接保活(Keep-Alive)
347
+ - 🔌 自动重连机制
348
+ - 🚀 支持并发查询
349
+ - 🐛 修复 "connection in closed state" 错误
350
+
328
351
  ### v4.0.0 (2025-12-09) - 全新架构
329
352
 
330
353
  - 🔥 完全重写,全新模块化架构
@@ -349,6 +372,114 @@ lsof -ti:3001 | xargs kill -9
349
372
 
350
373
  ---
351
374
 
375
+ ## 🔧 故障排除
376
+
377
+ ### 问题:`ERR_MODULE_NOT_FOUND` 错误
378
+
379
+ **错误信息**:
380
+ ```
381
+ Error [ERR_MODULE_NOT_FOUND]: Cannot find module '...@modelcontextprotocol/sdk...'
382
+ ```
383
+
384
+ **解决方案**:
385
+
386
+ 1. **删除并重新安装依赖**:
387
+ ```bash
388
+ # 删除旧依赖
389
+ rm -rf node_modules package-lock.json # Linux/Mac
390
+ # 或
391
+ rmdir /s /q node_modules && del package-lock.json # Windows
392
+
393
+ # 清理缓存
394
+ npm cache clean --force
395
+
396
+ # 重新安装
397
+ npm install
398
+ ```
399
+
400
+ 2. **检查 Node.js 版本**:
401
+ ```bash
402
+ node --version # 需要 >= 18.0.0
403
+ ```
404
+
405
+ 3. **使用全局安装**:
406
+ ```bash
407
+ npm install -g @xingyuchen/mysql-mcp-server@latest
408
+ ```
409
+
410
+ ### 问题:SSE 流断开
411
+
412
+ **错误信息**:
413
+ ```
414
+ SSE stream disconnected: TypeError: terminated
415
+ ```
416
+
417
+ **解决方案**:
418
+
419
+ 在 `mcp.json` 中设置更长的超时或禁用超时:
420
+ ```json
421
+ {
422
+ "mysql-mcp-http": {
423
+ "type": "streamableHttp",
424
+ "url": "http://localhost:3002/mcp",
425
+ "timeout": 0, // 0 表示无超时限制
426
+ "headers": { ... }
427
+ }
428
+ }
429
+ ```
430
+
431
+ ### 问题:安全漏洞警告
432
+
433
+ **警告信息**:
434
+ ```
435
+ npm audit: vulnerabilities found
436
+ ```
437
+
438
+ **解决方案**:
439
+ ```bash
440
+ # 自动修复
441
+ npm audit fix
442
+
443
+ # 如果还有问题,强制修复
444
+ npm audit fix --force
445
+
446
+ # 重新构建
447
+ npm run build
448
+ ```
449
+
450
+ ### 问题:端口被占用
451
+
452
+ **错误信息**:
453
+ ```
454
+ Error: listen EADDRINUSE: address already in use :::3002
455
+ ```
456
+
457
+ **解决方案**:
458
+
459
+ 1. **更改端口**(在 `.env` 文件中):
460
+ ```env
461
+ PORT=3003
462
+ ```
463
+
464
+ 2. **或者关闭占用端口的进程**:
465
+ ```bash
466
+ # Windows
467
+ netstat -ano | findstr :3002
468
+ taskkill /PID <进程ID> /F
469
+
470
+ # Linux/Mac
471
+ lsof -i :3002
472
+ kill -9 <进程ID>
473
+ ```
474
+
475
+ ### 获取更多帮助
476
+
477
+ - 🐛 [提交 Issue](https://github.com/guangxiangdebizi/MySQL_MCP/issues)
478
+ - 📖 [查看文档](https://github.com/guangxiangdebizi/MySQL_MCP#readme)
479
+ - 💬 [讨论区](https://github.com/guangxiangdebizi/MySQL_MCP/discussions)
480
+
481
+ ---
482
+
352
483
  ## 📄 License
353
484
 
354
485
  Apache 2.0 License - 详见 [LICENSE](./LICENSE) 文件
package/dist/database.js CHANGED
@@ -11,8 +11,8 @@ export class DatabaseConnectionManager {
11
11
  if (this.connections.has(config.id)) {
12
12
  await this.removeConnection(config.id);
13
13
  }
14
- // 创建连接
15
- const connection = await mysql.createConnection({
14
+ // 创建连接池
15
+ const pool = mysql.createPool({
16
16
  host: config.host,
17
17
  port: config.port,
18
18
  user: config.user,
@@ -20,11 +20,25 @@ export class DatabaseConnectionManager {
20
20
  database: config.database,
21
21
  charset: 'utf8mb4',
22
22
  timezone: '+08:00',
23
+ // 连接池配置
24
+ waitForConnections: true,
25
+ connectionLimit: 10,
26
+ queueLimit: 0,
27
+ // 连接保活配置
28
+ enableKeepAlive: true,
29
+ keepAliveInitialDelay: 0,
30
+ // 超时配置
31
+ connectTimeout: 10000,
32
+ // 自动重连
33
+ maxIdle: 10,
34
+ idleTimeout: 60000,
23
35
  });
24
36
  // 测试连接
37
+ const connection = await pool.getConnection();
25
38
  await connection.ping();
26
- // 保存连接和配置
27
- this.connections.set(config.id, connection);
39
+ connection.release();
40
+ // 保存连接池和配置
41
+ this.connections.set(config.id, pool);
28
42
  this.configs.set(config.id, {
29
43
  ...config,
30
44
  isActive: false,
@@ -40,11 +54,11 @@ export class DatabaseConnectionManager {
40
54
  * 移除连接
41
55
  */
42
56
  async removeConnection(id) {
43
- const connection = this.connections.get(id);
44
- if (!connection) {
57
+ const pool = this.connections.get(id);
58
+ if (!pool) {
45
59
  throw new Error(`连接 '${id}' 不存在`);
46
60
  }
47
- await connection.end();
61
+ await pool.end();
48
62
  this.connections.delete(id);
49
63
  this.configs.delete(id);
50
64
  // 如果移除的是活跃连接,切换到第一个可用连接
@@ -65,7 +79,7 @@ export class DatabaseConnectionManager {
65
79
  console.log(`🎯 已选择数据库: ${id}`);
66
80
  }
67
81
  /**
68
- * 获取活跃连接
82
+ * 获取活跃连接池
69
83
  */
70
84
  getActiveConnection() {
71
85
  if (!this.activeConnectionId || !this.connections.has(this.activeConnectionId)) {
@@ -80,7 +94,7 @@ export class DatabaseConnectionManager {
80
94
  return this.activeConnectionId;
81
95
  }
82
96
  /**
83
- * 获取指定连接
97
+ * 获取指定连接池
84
98
  */
85
99
  getConnection(id) {
86
100
  return this.connections.get(id);
@@ -98,23 +112,23 @@ export class DatabaseConnectionManager {
98
112
  * 执行查询
99
113
  */
100
114
  async executeQuery(sql, connectionId) {
101
- const connection = connectionId
115
+ const pool = connectionId
102
116
  ? this.getConnection(connectionId)
103
117
  : this.getActiveConnection();
104
- if (!connection) {
118
+ if (!pool) {
105
119
  throw new Error(connectionId ? `连接 '${connectionId}' 不存在` : "没有活跃连接");
106
120
  }
107
- const [results] = await connection.query(sql);
121
+ const [results] = await pool.query(sql);
108
122
  return results;
109
123
  }
110
124
  /**
111
- * 断开所有连接
125
+ * 断开所有连接池
112
126
  */
113
127
  async disconnectAll() {
114
- for (const [id, connection] of this.connections.entries()) {
128
+ for (const [id, pool] of this.connections.entries()) {
115
129
  try {
116
- await connection.end();
117
- console.log(`断开连接: ${id}`);
130
+ await pool.end();
131
+ console.log(`断开连接池: ${id}`);
118
132
  }
119
133
  catch (error) {
120
134
  console.error(`断开 ${id} 失败:`, error);
package/dist/index.js CHANGED
@@ -55,14 +55,14 @@ function extractDatabaseConfigsFromHeaders(req) {
55
55
  function createMCPServer(dbManager) {
56
56
  const server = new Server({
57
57
  name: "mysql-mcp-server",
58
- version: "4.0.3"
58
+ version: "4.0.5"
59
59
  }, {
60
60
  capabilities: {
61
61
  tools: {}
62
62
  }
63
63
  });
64
64
  // 注册工具列表处理器
65
- server.setRequestHandler(ListToolsRequestSchema, async () => {
65
+ server.setRequestHandler(ListToolsRequestSchema, async (_request) => {
66
66
  return { tools: allTools };
67
67
  });
68
68
  // 注册工具调用处理器
@@ -119,7 +119,7 @@ app.get("/health", (_req, res) => {
119
119
  status: "healthy",
120
120
  transport: "streamable-http",
121
121
  activeSessions: sessions.size,
122
- version: "4.0.0"
122
+ version: "4.0.5"
123
123
  });
124
124
  });
125
125
  // ==================== MCP Endpoint ====================
@@ -301,7 +301,7 @@ app.listen(PORT, () => {
301
301
  console.log(`
302
302
  ╔═══════════════════════════════════════════════════════════╗
303
303
  ║ ║
304
- ║ 🚀 MySQL MCP Server v4.0.3 已启动 ║
304
+ ║ 🚀 MySQL MCP Server v4.0.5 已启动 ║
305
305
  ║ ║
306
306
  ║ 📡 MCP Endpoint: http://localhost:${PORT}/mcp ║
307
307
  ║ 💚 Health Check: http://localhost:${PORT}/health ║
@@ -311,6 +311,7 @@ app.listen(PORT, () => {
311
311
  ║ • AI 动态添加连接 ║
312
312
  ║ • 多数据库管理 ║
313
313
  ║ • SQL 查询执行 ║
314
+ ║ • 连接池 + 自动重连 ║
314
315
  ║ ║
315
316
  ╚═══════════════════════════════════════════════════════════╝
316
317
  `);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xingyuchen/mysql-mcp-server",
3
- "version": "4.0.3",
3
+ "version": "4.0.5",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "bin": {