vmoo-mcp-database-server 1.0.1 → 1.1.0
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 +7 -0
- package/bin/vmoo-mcp-deliver.js +45 -0
- package/bin/vmoo-mcp-server.js +28 -12
- package/package.json +4 -2
- package/vmoo-database-deliver/config.json +35 -0
- package/vmoo-database-deliver/package.json +28 -0
- package/vmoo-database-deliver/server.js +297 -0
package/README.md
CHANGED
|
@@ -15,6 +15,9 @@ npx vmoo-mcp-database-server@latest --env=dev
|
|
|
15
15
|
|
|
16
16
|
# 生产环境
|
|
17
17
|
npx vmoo-mcp-database-server@latest --env=prod
|
|
18
|
+
|
|
19
|
+
# 配送测试站
|
|
20
|
+
npx vmoo-mcp-database-server@latest --env=deliver
|
|
18
21
|
```
|
|
19
22
|
|
|
20
23
|
### 在Augment中配置
|
|
@@ -29,6 +32,10 @@ npx vmoo-mcp-database-server@latest --env=prod
|
|
|
29
32
|
"vmoo-database-prod": {
|
|
30
33
|
"command": "npx",
|
|
31
34
|
"args": ["vmoo-mcp-database-server@latest", "--env=prod"]
|
|
35
|
+
},
|
|
36
|
+
"vmoo-database-deliver": {
|
|
37
|
+
"command": "npx",
|
|
38
|
+
"args": ["vmoo-mcp-database-server@latest", "--env=deliver"]
|
|
32
39
|
}
|
|
33
40
|
}
|
|
34
41
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// VMOO配送测试站MCP服务器启动器
|
|
4
|
+
|
|
5
|
+
import { spawn } from 'child_process';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
|
|
9
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
+
const __dirname = path.dirname(__filename);
|
|
11
|
+
|
|
12
|
+
// 解析命令行参数
|
|
13
|
+
const args = process.argv.slice(2);
|
|
14
|
+
const configPath = args.find(arg => arg.startsWith('--config='))?.split('=')[1];
|
|
15
|
+
|
|
16
|
+
console.log('🚚 启动VMOO配送测试站MCP服务器...');
|
|
17
|
+
|
|
18
|
+
// 服务器文件路径
|
|
19
|
+
const serverPath = path.join(__dirname, '../vmoo-database-deliver/server.js');
|
|
20
|
+
|
|
21
|
+
// 启动服务器
|
|
22
|
+
const serverProcess = spawn('node', [serverPath], {
|
|
23
|
+
stdio: 'inherit',
|
|
24
|
+
env: {
|
|
25
|
+
...process.env,
|
|
26
|
+
...(configPath && { CONFIG_PATH: configPath })
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// 处理进程退出
|
|
31
|
+
serverProcess.on('close', (code) => {
|
|
32
|
+
console.log(`🚚 配送测试站MCP服务器已退出,退出码: ${code}`);
|
|
33
|
+
process.exit(code);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
// 处理中断信号
|
|
37
|
+
process.on('SIGINT', () => {
|
|
38
|
+
console.log('\n🛑 正在关闭配送测试站MCP服务器...');
|
|
39
|
+
serverProcess.kill('SIGINT');
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
process.on('SIGTERM', () => {
|
|
43
|
+
console.log('\n🛑 正在关闭配送测试站MCP服务器...');
|
|
44
|
+
serverProcess.kill('SIGTERM');
|
|
45
|
+
});
|
package/bin/vmoo-mcp-server.js
CHANGED
|
@@ -15,12 +15,26 @@ const envArg = args.find(arg => arg.startsWith('--env='));
|
|
|
15
15
|
const environment = envArg ? envArg.split('=')[1] : 'dev';
|
|
16
16
|
const configPath = args.find(arg => arg.startsWith('--config='))?.split('=')[1];
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
const envNames = {
|
|
19
|
+
'dev': '开发',
|
|
20
|
+
'prod': '生产',
|
|
21
|
+
'deliver': '配送测试'
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
console.log(`🚀 启动VMOO ${envNames[environment] || '开发'}环境MCP服务器...`);
|
|
19
25
|
|
|
20
26
|
// 根据环境选择服务器文件路径
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
27
|
+
let serverPath;
|
|
28
|
+
switch (environment) {
|
|
29
|
+
case 'prod':
|
|
30
|
+
serverPath = path.join(__dirname, '../vmoo-database-prod/server.js');
|
|
31
|
+
break;
|
|
32
|
+
case 'deliver':
|
|
33
|
+
serverPath = path.join(__dirname, '../vmoo-database-deliver/server.js');
|
|
34
|
+
break;
|
|
35
|
+
default:
|
|
36
|
+
serverPath = path.join(__dirname, '../vmoo-database-dev/server.js');
|
|
37
|
+
}
|
|
24
38
|
|
|
25
39
|
// 启动服务器
|
|
26
40
|
const serverProcess = spawn('node', [serverPath], {
|
|
@@ -33,18 +47,18 @@ const serverProcess = spawn('node', [serverPath], {
|
|
|
33
47
|
|
|
34
48
|
// 处理进程退出
|
|
35
49
|
serverProcess.on('close', (code) => {
|
|
36
|
-
console.log(`🛑 ${environment
|
|
50
|
+
console.log(`🛑 ${envNames[environment] || '开发'}环境MCP服务器已退出,退出码: ${code}`);
|
|
37
51
|
process.exit(code);
|
|
38
52
|
});
|
|
39
53
|
|
|
40
54
|
// 处理中断信号
|
|
41
55
|
process.on('SIGINT', () => {
|
|
42
|
-
console.log(`\n🛑 正在关闭${environment
|
|
56
|
+
console.log(`\n🛑 正在关闭${envNames[environment] || '开发'}环境MCP服务器...`);
|
|
43
57
|
serverProcess.kill('SIGINT');
|
|
44
58
|
});
|
|
45
59
|
|
|
46
60
|
process.on('SIGTERM', () => {
|
|
47
|
-
console.log(`\n🛑 正在关闭${environment
|
|
61
|
+
console.log(`\n🛑 正在关闭${envNames[environment] || '开发'}环境MCP服务器...`);
|
|
48
62
|
serverProcess.kill('SIGTERM');
|
|
49
63
|
});
|
|
50
64
|
|
|
@@ -52,12 +66,14 @@ process.on('SIGTERM', () => {
|
|
|
52
66
|
if (!envArg) {
|
|
53
67
|
console.log(`
|
|
54
68
|
📋 使用方法:
|
|
55
|
-
npx vmoo-mcp-database-server --env=dev
|
|
56
|
-
npx vmoo-mcp-database-server --env=prod
|
|
57
|
-
|
|
69
|
+
npx vmoo-mcp-database-server --env=dev # 开发环境
|
|
70
|
+
npx vmoo-mcp-database-server --env=prod # 生产环境
|
|
71
|
+
npx vmoo-mcp-database-server --env=deliver # 配送测试站
|
|
72
|
+
|
|
58
73
|
或者直接使用:
|
|
59
|
-
npx vmoo-mcp-dev
|
|
60
|
-
npx vmoo-mcp-prod
|
|
74
|
+
npx vmoo-mcp-dev # 开发环境
|
|
75
|
+
npx vmoo-mcp-prod # 生产环境
|
|
76
|
+
npx vmoo-mcp-deliver # 配送测试站
|
|
61
77
|
|
|
62
78
|
配置选项:
|
|
63
79
|
--config=path/to/config.json # 自定义配置文件路径
|
package/package.json
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "vmoo-mcp-database-server",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "VMOO数据库MCP服务器集合 - 支持开发和生产环境的安全数据库访问",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"bin": {
|
|
8
8
|
"vmoo-mcp-database-server": "./bin/vmoo-mcp-server.js",
|
|
9
9
|
"vmoo-mcp-dev": "./bin/vmoo-mcp-dev.js",
|
|
10
|
-
"vmoo-mcp-prod": "./bin/vmoo-mcp-prod.js"
|
|
10
|
+
"vmoo-mcp-prod": "./bin/vmoo-mcp-prod.js",
|
|
11
|
+
"vmoo-mcp-deliver": "./bin/vmoo-mcp-deliver.js"
|
|
11
12
|
},
|
|
12
13
|
"scripts": {
|
|
13
14
|
"start:prod": "cd vmoo-database-prod && npm start",
|
|
@@ -45,6 +46,7 @@
|
|
|
45
46
|
"shared/",
|
|
46
47
|
"vmoo-database-dev/",
|
|
47
48
|
"vmoo-database-prod/",
|
|
49
|
+
"vmoo-database-deliver/",
|
|
48
50
|
"index.js",
|
|
49
51
|
"README.md"
|
|
50
52
|
],
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"server": {
|
|
3
|
+
"name": "vmoo-database-deliver-server",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "VMOO配送测试站MCP服务器 - 支持配送系统的数据库访问和管理"
|
|
6
|
+
},
|
|
7
|
+
"database": {
|
|
8
|
+
"host": "118.25.190.11",
|
|
9
|
+
"port": 3306,
|
|
10
|
+
"user": "ceshi_deliver",
|
|
11
|
+
"password": "Gf8G3pEnm7pjRMGE",
|
|
12
|
+
"database": "ceshi_deliver",
|
|
13
|
+
"charset": "utf8mb4",
|
|
14
|
+
"timezone": "+08:00",
|
|
15
|
+
"acquireTimeout": 60000,
|
|
16
|
+
"timeout": 60000,
|
|
17
|
+
"reconnect": true,
|
|
18
|
+
"connectionLimit": 10
|
|
19
|
+
},
|
|
20
|
+
"security": {
|
|
21
|
+
"level": "development",
|
|
22
|
+
"allowedOperations": ["SELECT", "INSERT", "UPDATE", "SHOW", "DESCRIBE", "EXPLAIN"],
|
|
23
|
+
"blockedOperations": ["DELETE", "DROP", "TRUNCATE", "ALTER TABLE DROP"],
|
|
24
|
+
"queryTimeout": 30000,
|
|
25
|
+
"maxQueryLength": 10000,
|
|
26
|
+
"autoLimit": true,
|
|
27
|
+
"defaultLimit": 100
|
|
28
|
+
},
|
|
29
|
+
"features": {
|
|
30
|
+
"timeZoneConversion": true,
|
|
31
|
+
"autoAnonymization": false,
|
|
32
|
+
"queryLogging": true,
|
|
33
|
+
"performanceMonitoring": true
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "vmoo-database-deliver-server",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "VMOO配送测试站MCP服务器",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "server.js",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"start": "node server.js",
|
|
9
|
+
"dev": "node server.js",
|
|
10
|
+
"test": "echo \"配送测试站MCP服务器测试通过\" && exit 0"
|
|
11
|
+
},
|
|
12
|
+
"dependencies": {
|
|
13
|
+
"@modelcontextprotocol/sdk": "^1.17.2",
|
|
14
|
+
"mysql2": "^3.6.5"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"mcp",
|
|
18
|
+
"database",
|
|
19
|
+
"mysql",
|
|
20
|
+
"vmoo",
|
|
21
|
+
"deliver",
|
|
22
|
+
"delivery",
|
|
23
|
+
"配送",
|
|
24
|
+
"测试站"
|
|
25
|
+
],
|
|
26
|
+
"author": "VMOO Team",
|
|
27
|
+
"license": "MIT"
|
|
28
|
+
}
|
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
4
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
|
+
import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
|
|
6
|
+
import mysql from 'mysql2/promise';
|
|
7
|
+
import fs from 'fs';
|
|
8
|
+
import path from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
13
|
+
|
|
14
|
+
// 导入共享模块
|
|
15
|
+
const { createConnectionPool, executeQuery, normalizeTableName, getTableStructure, getTableCount, getTableSampleData, listTables } = await import('../shared/database-utils.js');
|
|
16
|
+
const { SECURITY_LEVELS, performSecurityCheck, applyQueryLimits } = await import('../shared/security-utils.js');
|
|
17
|
+
const { processTimeFields } = await import('../shared/time-utils.js');
|
|
18
|
+
|
|
19
|
+
// 读取配置文件
|
|
20
|
+
const config = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json'), 'utf8'));
|
|
21
|
+
|
|
22
|
+
console.log('🚚 VMOO配送测试站MCP服务器已启动 - vmoo-database-deliver-server v1.0.0');
|
|
23
|
+
console.log('🔒 安全级别: development - 配送测试站:允许查询、插入、更新,禁止删除操作');
|
|
24
|
+
|
|
25
|
+
// 创建数据库连接池
|
|
26
|
+
const pool = createConnectionPool(config.database);
|
|
27
|
+
|
|
28
|
+
// 创建MCP服务器
|
|
29
|
+
const server = new Server(
|
|
30
|
+
{
|
|
31
|
+
name: config.server.name,
|
|
32
|
+
version: config.server.version,
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
capabilities: {
|
|
36
|
+
tools: {},
|
|
37
|
+
},
|
|
38
|
+
}
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
// 注册工具
|
|
42
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
43
|
+
return {
|
|
44
|
+
tools: [
|
|
45
|
+
{
|
|
46
|
+
name: 'query_database',
|
|
47
|
+
description: '执行SQL查询语句(开发环境:支持增删改查,禁止删除操作)',
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: 'object',
|
|
50
|
+
properties: {
|
|
51
|
+
query: {
|
|
52
|
+
type: 'string',
|
|
53
|
+
description: 'SQL查询语句'
|
|
54
|
+
},
|
|
55
|
+
limit: {
|
|
56
|
+
type: 'number',
|
|
57
|
+
description: '限制返回结果数量,默认100',
|
|
58
|
+
default: 100
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
required: ['query']
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'query_with_time_format',
|
|
66
|
+
description: '执行SQL查询并自动格式化时间字段(推荐用于包含时间的查询)',
|
|
67
|
+
inputSchema: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
properties: {
|
|
70
|
+
query: {
|
|
71
|
+
type: 'string',
|
|
72
|
+
description: 'SQL查询语句,时间字段会自动转换为北京时间'
|
|
73
|
+
},
|
|
74
|
+
limit: {
|
|
75
|
+
type: 'number',
|
|
76
|
+
description: '限制返回结果数量,默认100',
|
|
77
|
+
default: 100
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
required: ['query']
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
name: 'describe_table',
|
|
85
|
+
description: '获取表结构信息',
|
|
86
|
+
inputSchema: {
|
|
87
|
+
type: 'object',
|
|
88
|
+
properties: {
|
|
89
|
+
table_name: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: '表名(可以包含或不包含fanwe_前缀)'
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
required: ['table_name']
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
name: 'list_tables',
|
|
99
|
+
description: '列出数据库中所有表',
|
|
100
|
+
inputSchema: {
|
|
101
|
+
type: 'object',
|
|
102
|
+
properties: {
|
|
103
|
+
pattern: {
|
|
104
|
+
type: 'string',
|
|
105
|
+
description: '表名匹配模式(可选)'
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
name: 'table_sample_data',
|
|
112
|
+
description: '获取表的示例数据',
|
|
113
|
+
inputSchema: {
|
|
114
|
+
type: 'object',
|
|
115
|
+
properties: {
|
|
116
|
+
table_name: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
description: '表名'
|
|
119
|
+
},
|
|
120
|
+
limit: {
|
|
121
|
+
type: 'number',
|
|
122
|
+
description: '返回记录数量,默认10',
|
|
123
|
+
default: 10
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
required: ['table_name']
|
|
127
|
+
}
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
name: 'table_count',
|
|
131
|
+
description: '获取表的记录总数',
|
|
132
|
+
inputSchema: {
|
|
133
|
+
type: 'object',
|
|
134
|
+
properties: {
|
|
135
|
+
table_name: {
|
|
136
|
+
type: 'string',
|
|
137
|
+
description: '表名'
|
|
138
|
+
}
|
|
139
|
+
},
|
|
140
|
+
required: ['table_name']
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
]
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// 处理工具调用
|
|
148
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
149
|
+
const { name, arguments: args } = request.params;
|
|
150
|
+
|
|
151
|
+
try {
|
|
152
|
+
switch (name) {
|
|
153
|
+
case 'query_database':
|
|
154
|
+
return await handleQueryDatabase(args);
|
|
155
|
+
case 'query_with_time_format':
|
|
156
|
+
return await handleQueryWithTimeFormat(args);
|
|
157
|
+
case 'describe_table':
|
|
158
|
+
return await handleDescribeTable(args);
|
|
159
|
+
case 'list_tables':
|
|
160
|
+
return await handleListTables(args);
|
|
161
|
+
case 'table_sample_data':
|
|
162
|
+
return await handleTableSampleData(args);
|
|
163
|
+
case 'table_count':
|
|
164
|
+
return await handleTableCount(args);
|
|
165
|
+
default:
|
|
166
|
+
throw new Error(`未知工具: ${name}`);
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
return {
|
|
170
|
+
content: [
|
|
171
|
+
{
|
|
172
|
+
type: 'text',
|
|
173
|
+
text: `错误: ${error.message}`
|
|
174
|
+
}
|
|
175
|
+
]
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// 查询数据库
|
|
181
|
+
async function handleQueryDatabase(args) {
|
|
182
|
+
const { query, limit = 100 } = args;
|
|
183
|
+
|
|
184
|
+
// 安全检查
|
|
185
|
+
const securityCheck = performSecurityCheck(query, SECURITY_LEVELS.DEVELOPMENT);
|
|
186
|
+
if (!securityCheck.allowed) {
|
|
187
|
+
throw new Error(securityCheck.reason);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// 应用查询限制
|
|
191
|
+
const finalQuery = applyQueryLimits(query, limit);
|
|
192
|
+
|
|
193
|
+
const rows = await executeQuery(pool, finalQuery);
|
|
194
|
+
|
|
195
|
+
return {
|
|
196
|
+
content: [
|
|
197
|
+
{
|
|
198
|
+
type: 'text',
|
|
199
|
+
text: `🟡 开发环境查询结果 (${Array.isArray(rows) ? rows.length : 0} 条记录):\n\n${JSON.stringify(rows, null, 2)}`
|
|
200
|
+
}
|
|
201
|
+
]
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// 带时间格式化的查询
|
|
206
|
+
async function handleQueryWithTimeFormat(args) {
|
|
207
|
+
const { query, limit = 100 } = args;
|
|
208
|
+
|
|
209
|
+
// 安全检查
|
|
210
|
+
const securityCheck = performSecurityCheck(query, SECURITY_LEVELS.DEVELOPMENT);
|
|
211
|
+
if (!securityCheck.allowed) {
|
|
212
|
+
throw new Error(securityCheck.reason);
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
// 应用查询限制
|
|
216
|
+
const finalQuery = applyQueryLimits(query, limit);
|
|
217
|
+
|
|
218
|
+
const rows = await executeQuery(pool, finalQuery);
|
|
219
|
+
const processedRows = processTimeFields(rows);
|
|
220
|
+
|
|
221
|
+
return {
|
|
222
|
+
content: [
|
|
223
|
+
{
|
|
224
|
+
type: 'text',
|
|
225
|
+
text: `🟡 开发环境查询结果 (${Array.isArray(processedRows) ? processedRows.length : 0} 条记录):\n📅 时间字段已自动转换为北京时间\n\n${JSON.stringify(processedRows, null, 2)}`
|
|
226
|
+
}
|
|
227
|
+
]
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 其他处理函数...
|
|
232
|
+
async function handleDescribeTable(args) {
|
|
233
|
+
const { table_name } = args;
|
|
234
|
+
const rows = await getTableStructure(pool, table_name);
|
|
235
|
+
|
|
236
|
+
return {
|
|
237
|
+
content: [
|
|
238
|
+
{
|
|
239
|
+
type: 'text',
|
|
240
|
+
text: `表 ${normalizeTableName(table_name)} 的结构:\n\n${JSON.stringify(rows, null, 2)}`
|
|
241
|
+
}
|
|
242
|
+
]
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
async function handleListTables(args) {
|
|
247
|
+
const { pattern } = args;
|
|
248
|
+
const rows = await listTables(pool, pattern);
|
|
249
|
+
|
|
250
|
+
return {
|
|
251
|
+
content: [
|
|
252
|
+
{
|
|
253
|
+
type: 'text',
|
|
254
|
+
text: `数据库表列表:\n\n${JSON.stringify(rows, null, 2)}`
|
|
255
|
+
}
|
|
256
|
+
]
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
async function handleTableSampleData(args) {
|
|
261
|
+
const { table_name, limit = 10 } = args;
|
|
262
|
+
const rows = await getTableSampleData(pool, table_name, limit);
|
|
263
|
+
const processedRows = processTimeFields(rows);
|
|
264
|
+
|
|
265
|
+
return {
|
|
266
|
+
content: [
|
|
267
|
+
{
|
|
268
|
+
type: 'text',
|
|
269
|
+
text: `表 ${normalizeTableName(table_name)} 的示例数据 (前${limit}条):\n\n${JSON.stringify(processedRows, null, 2)}`
|
|
270
|
+
}
|
|
271
|
+
]
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
async function handleTableCount(args) {
|
|
276
|
+
const { table_name } = args;
|
|
277
|
+
const count = await getTableCount(pool, table_name);
|
|
278
|
+
|
|
279
|
+
return {
|
|
280
|
+
content: [
|
|
281
|
+
{
|
|
282
|
+
type: 'text',
|
|
283
|
+
text: `表 ${normalizeTableName(table_name)} 共有 ${count} 条记录`
|
|
284
|
+
}
|
|
285
|
+
]
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
// 启动服务器
|
|
290
|
+
async function main() {
|
|
291
|
+
const transport = new StdioServerTransport();
|
|
292
|
+
await server.connect(transport);
|
|
293
|
+
console.error(`🟡 VMOO开发环境MCP服务器已启动 - ${config.server.name} v${config.server.version}`);
|
|
294
|
+
console.error(`🔒 安全级别: ${config.security.level} - ${config.security.description}`);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
main().catch(console.error);
|