vmoo-mcp-database-server 1.2.0 → 1.2.2

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.
@@ -1,297 +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);
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);
@@ -1,25 +1,25 @@
1
- {
2
- "database": {
3
- "host": "118.25.190.11",
4
- "port": 3306,
5
- "user": "ceshi_v_moo_com",
6
- "password": "F4ytKxBB4x",
7
- "database": "ceshi_v_moo_com",
8
- "charset": "utf8mb4"
9
- },
10
- "security": {
11
- "level": "development",
12
- "description": "开发环境:允许查询、插入、更新,禁止删除操作",
13
- "features": [
14
- "SELECT、INSERT、UPDATE、ALTER TABLE、CREATE TABLE",
15
- "禁止DELETE、DROP TABLE、DROP DATABASE",
16
- "自动LIMIT限制",
17
- "时区自动转换"
18
- ]
19
- },
20
- "server": {
21
- "name": "vmoo-database-dev-server",
22
- "version": "1.0.0",
23
- "description": "开发环境数据库服务器"
24
- }
25
- }
1
+ {
2
+ "database": {
3
+ "host": "118.25.190.11",
4
+ "port": 3306,
5
+ "user": "ceshi_v_moo_com",
6
+ "password": "${V_MOO_PASSWORD}",
7
+ "database": "ceshi_v_moo_com",
8
+ "charset": "utf8mb4"
9
+ },
10
+ "security": {
11
+ "level": "development",
12
+ "description": "开发环境:允许查询、插入、更新,禁止删除操作",
13
+ "features": [
14
+ "SELECT、INSERT、UPDATE、ALTER TABLE、CREATE TABLE",
15
+ "禁止DELETE、DROP TABLE、DROP DATABASE",
16
+ "自动LIMIT限制",
17
+ "时区自动转换"
18
+ ]
19
+ },
20
+ "server": {
21
+ "name": "vmoo-database-dev-server",
22
+ "version": "1.0.0",
23
+ "description": "开发环境数据库服务器"
24
+ }
25
+ }