@cmd233/mcp-database-server 1.1.7 → 1.3.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.
@@ -1,7 +1,7 @@
1
1
  import { formatErrorResponse } from '../utils/formatUtils.js';
2
2
  // 导入所有工具实现
3
3
  import { readQuery, writeQuery, exportQuery } from '../tools/queryTools.js';
4
- import { createTable, alterTable, dropTable, listTables, describeTable } from '../tools/schemaTools.js';
4
+ import { createTable, alterTable, dropTable, listTables, describeTable, listViews, describeView, getViewDefinition, listProcedures, describeProcedure, getProcedureDefinition } from '../tools/schemaTools.js';
5
5
  import { appendInsight, listInsights } from '../tools/insightTools.js';
6
6
  /**
7
7
  * 处理列出可用工具的请求
@@ -12,109 +12,597 @@ export function handleListTools() {
12
12
  tools: [
13
13
  {
14
14
  name: "read_query",
15
- description: "执行 SELECT 查询以从数据库读取数据",
15
+ title: "Read Query",
16
+ description: "Execute a SELECT query to read data from the database. " +
17
+ "Returns the complete result set with all matching rows and columns. " +
18
+ "Only SELECT statements are allowed - use write_query for data modifications. " +
19
+ "Supports all database types: SQLite, SQL Server, PostgreSQL, MySQL.",
16
20
  inputSchema: {
17
21
  type: "object",
18
22
  properties: {
19
- query: { type: "string" },
23
+ query: {
24
+ type: "string",
25
+ description: "The SQL SELECT query to execute (e.g., 'SELECT * FROM users WHERE active = 1')"
26
+ },
20
27
  },
21
28
  required: ["query"],
22
29
  },
30
+ outputSchema: {
31
+ type: "object",
32
+ properties: {
33
+ rows: {
34
+ type: "array",
35
+ description: "Array of result rows from the query"
36
+ },
37
+ columns: {
38
+ type: "array",
39
+ description: "Array of column names in the result set"
40
+ }
41
+ }
42
+ },
43
+ annotations: {
44
+ readOnlyHint: true,
45
+ idempotentHint: true
46
+ }
23
47
  },
24
48
  {
25
49
  name: "write_query",
26
- description: "执行 INSERT、UPDATE 或 DELETE 查询",
50
+ title: "Write Query",
51
+ description: "Execute INSERT, UPDATE, or DELETE queries to modify database data. " +
52
+ "Returns the number of affected rows. " +
53
+ "Cannot be used for SELECT queries - use read_query instead. " +
54
+ "Supports all database types: SQLite, SQL Server, PostgreSQL, MySQL. " +
55
+ "Requires confirm=true as a safety measure to prevent accidental data modification.",
27
56
  inputSchema: {
28
57
  type: "object",
29
58
  properties: {
30
- query: { type: "string" },
59
+ query: {
60
+ type: "string",
61
+ description: "The SQL INSERT/UPDATE/DELETE query to execute"
62
+ },
63
+ confirm: {
64
+ type: "boolean",
65
+ description: "Must be set to true to confirm data modification"
66
+ },
31
67
  },
32
68
  required: ["query"],
33
69
  },
70
+ outputSchema: {
71
+ type: "object",
72
+ properties: {
73
+ affected_rows: {
74
+ type: "number",
75
+ description: "Number of rows affected by the operation"
76
+ },
77
+ last_id: {
78
+ type: "number",
79
+ description: "ID of the last inserted row (for INSERT operations)"
80
+ }
81
+ }
82
+ },
83
+ annotations: {
84
+ readOnlyHint: false,
85
+ destructiveHint: true
86
+ }
34
87
  },
35
88
  {
36
89
  name: "create_table",
37
- description: "在数据库中创建新表",
90
+ title: "Create Table",
91
+ description: "Create a new table in the database using a CREATE TABLE statement. " +
92
+ "Supports all standard SQL table creation syntax including column definitions, " +
93
+ "constraints, indexes, and relationships. " +
94
+ "Works with SQLite, SQL Server, PostgreSQL, and MySQL. " +
95
+ "Requires confirm=true as a safety measure to prevent accidental table creation.",
38
96
  inputSchema: {
39
97
  type: "object",
40
98
  properties: {
41
- query: { type: "string" },
99
+ query: {
100
+ type: "string",
101
+ description: "The complete CREATE TABLE SQL statement"
102
+ },
103
+ confirm: {
104
+ type: "boolean",
105
+ description: "Must be set to true to confirm table creation"
106
+ },
42
107
  },
43
108
  required: ["query"],
44
109
  },
110
+ outputSchema: {
111
+ type: "object",
112
+ properties: {
113
+ success: {
114
+ type: "boolean",
115
+ description: "True if the table was created successfully"
116
+ },
117
+ message: {
118
+ type: "string",
119
+ description: "Success message with table name"
120
+ }
121
+ }
122
+ },
123
+ annotations: {
124
+ readOnlyHint: false,
125
+ destructiveHint: true
126
+ }
45
127
  },
46
128
  {
47
129
  name: "alter_table",
48
- description: "修改现有表结构(添加列、重命名表等)",
130
+ title: "Alter Table",
131
+ description: "Modify an existing table's structure using ALTER TABLE statements. " +
132
+ "Supports adding columns, dropping columns, renaming columns, changing data types, " +
133
+ "and other table modifications. " +
134
+ "The table must exist before alterations can be made. " +
135
+ "Requires confirm=true as a safety measure to prevent accidental schema changes.",
49
136
  inputSchema: {
50
137
  type: "object",
51
138
  properties: {
52
- query: { type: "string" },
139
+ query: {
140
+ type: "string",
141
+ description: "The ALTER TABLE SQL statement to modify table structure"
142
+ },
143
+ confirm: {
144
+ type: "boolean",
145
+ description: "Must be set to true to confirm table alteration"
146
+ },
53
147
  },
54
148
  required: ["query"],
55
149
  },
150
+ outputSchema: {
151
+ type: "object",
152
+ properties: {
153
+ success: {
154
+ type: "boolean",
155
+ description: "True if the table was altered successfully"
156
+ },
157
+ message: {
158
+ type: "string",
159
+ description: "Success message confirming the alteration"
160
+ }
161
+ }
162
+ },
163
+ annotations: {
164
+ readOnlyHint: false,
165
+ destructiveHint: true
166
+ }
56
167
  },
57
168
  {
58
169
  name: "drop_table",
59
- description: "从数据库中删除表(需要安全确认)",
170
+ title: "Drop Table",
171
+ description: "Permanently delete a table from the database. " +
172
+ "This operation has been DISABLED for security reasons. " +
173
+ "DROP operations should be handled by DBA at the database level. " +
174
+ "Contact your database administrator if you need to delete a table.",
60
175
  inputSchema: {
61
176
  type: "object",
62
177
  properties: {
63
- table_name: { type: "string" },
64
- confirm: { type: "boolean" },
178
+ table_name: {
179
+ type: "string",
180
+ description: "Name of the table to delete"
181
+ },
182
+ confirm: {
183
+ type: "boolean",
184
+ description: "Must be set to true to confirm table deletion"
185
+ },
65
186
  },
66
187
  required: ["table_name", "confirm"],
67
188
  },
189
+ outputSchema: {
190
+ type: "object",
191
+ properties: {
192
+ success: {
193
+ type: "boolean",
194
+ description: "True if the table was dropped successfully"
195
+ },
196
+ message: {
197
+ type: "string",
198
+ description: "Success message with the dropped table name"
199
+ }
200
+ }
201
+ },
202
+ annotations: {
203
+ readOnlyHint: false,
204
+ destructiveHint: true
205
+ }
68
206
  },
69
207
  {
70
208
  name: "export_query",
71
- description: "将查询结果导出为各种格式(CSV、JSON)",
209
+ title: "Export Query",
210
+ description: "Execute a SELECT query and export the results in CSV or JSON format. " +
211
+ "Only SELECT queries are allowed. " +
212
+ "CSV format returns comma-separated values with headers. " +
213
+ "JSON format returns the raw result array. " +
214
+ "Useful for data analysis, reporting, or data transfer.",
72
215
  inputSchema: {
73
216
  type: "object",
74
217
  properties: {
75
- query: { type: "string" },
76
- format: { type: "string", enum: ["csv", "json"] },
218
+ query: {
219
+ type: "string",
220
+ description: "The SQL SELECT query to execute and export"
221
+ },
222
+ format: {
223
+ type: "string",
224
+ enum: ["csv", "json"],
225
+ description: "Output format: 'csv' for comma-separated values, 'json' for raw JSON array"
226
+ },
77
227
  },
78
228
  required: ["query", "format"],
79
229
  },
230
+ outputSchema: {
231
+ type: "object",
232
+ properties: {
233
+ data: {
234
+ type: "string",
235
+ description: "Exported data in the requested format"
236
+ },
237
+ format: {
238
+ type: "string",
239
+ description: "The format of the exported data"
240
+ }
241
+ }
242
+ },
243
+ annotations: {
244
+ readOnlyHint: true,
245
+ idempotentHint: true
246
+ }
80
247
  },
81
248
  {
82
249
  name: "list_tables",
83
- description: "获取数据库中所有表的列表",
250
+ title: "List Tables",
251
+ description: "Retrieve a list of all table names in the current database. " +
252
+ "Returns only table names without structure details. " +
253
+ "Use describe_table to get detailed column information for a specific table. " +
254
+ "Set include_views=true to also include database views (SQL Server only).",
84
255
  inputSchema: {
85
256
  type: "object",
86
- properties: {},
257
+ properties: {
258
+ include_views: {
259
+ type: "boolean",
260
+ description: "Set to true to include views in the result (SQL Server only)"
261
+ },
262
+ },
263
+ },
264
+ outputSchema: {
265
+ type: "object",
266
+ properties: {
267
+ tables: {
268
+ type: "array",
269
+ items: {
270
+ type: "object",
271
+ properties: {
272
+ name: { type: "string", description: "Table or view name" },
273
+ type: { type: "string", enum: ["table", "view"], description: "Object type" }
274
+ }
275
+ },
276
+ description: "Array of table/view names and types in the database"
277
+ }
278
+ }
87
279
  },
280
+ annotations: {
281
+ readOnlyHint: true,
282
+ idempotentHint: true
283
+ }
88
284
  },
89
285
  {
90
286
  name: "describe_table",
91
- description: "查看特定表的结构信息",
287
+ title: "Describe Table",
288
+ description: "Get detailed structural information about a specific table or view. " +
289
+ "Returns column name, data type, nullable status, default value, " +
290
+ "primary key status, and column comment (if supported). " +
291
+ "Supports both tables and views (SQL Server only for views). " +
292
+ "The table or view must exist in the database.",
92
293
  inputSchema: {
93
294
  type: "object",
94
295
  properties: {
95
- table_name: { type: "string" },
296
+ table_name: {
297
+ type: "string",
298
+ description: "Name of the table or view to describe"
299
+ },
96
300
  },
97
301
  required: ["table_name"],
98
302
  },
303
+ outputSchema: {
304
+ type: "object",
305
+ properties: {
306
+ name: { type: "string", description: "Table or view name" },
307
+ type: { type: "string", enum: ["table", "view"], description: "Object type" },
308
+ columns: {
309
+ type: "array",
310
+ description: "Array of column definitions",
311
+ items: {
312
+ type: "object",
313
+ properties: {
314
+ name: { type: "string", description: "Column name" },
315
+ type: { type: "string", description: "Data type" },
316
+ notnull: { type: "boolean", description: "Whether the column is NOT NULL" },
317
+ default_value: { type: "string", description: "Default value" },
318
+ primary_key: { type: "boolean", description: "Whether the column is a primary key" },
319
+ comment: { type: "string", description: "Column comment" }
320
+ }
321
+ }
322
+ }
323
+ }
324
+ },
325
+ annotations: {
326
+ readOnlyHint: true,
327
+ idempotentHint: true
328
+ }
329
+ },
330
+ {
331
+ name: "list_views",
332
+ title: "List Views",
333
+ description: "Retrieve a list of all view names in the current database. " +
334
+ "Only works with SQL Server databases. " +
335
+ "Returns only view names without structure details. " +
336
+ "Use describe_view to get detailed column information for a specific view.",
337
+ inputSchema: {
338
+ type: "object",
339
+ properties: {},
340
+ },
341
+ outputSchema: {
342
+ type: "object",
343
+ properties: {
344
+ views: {
345
+ type: "array",
346
+ items: { type: "string" },
347
+ description: "Array of view names in the database"
348
+ }
349
+ }
350
+ },
351
+ annotations: {
352
+ readOnlyHint: true,
353
+ idempotentHint: true
354
+ }
355
+ },
356
+ {
357
+ name: "describe_view",
358
+ title: "Describe View",
359
+ description: "Get detailed structural information about a specific view. " +
360
+ "Only works with SQL Server databases. " +
361
+ "Returns column name, data type, nullable status, default value, " +
362
+ "primary key status, and column comment (if available). " +
363
+ "The view must exist in the database.",
364
+ inputSchema: {
365
+ type: "object",
366
+ properties: {
367
+ view_name: {
368
+ type: "string",
369
+ description: "Name of the view to describe"
370
+ },
371
+ },
372
+ required: ["view_name"],
373
+ },
374
+ outputSchema: {
375
+ type: "object",
376
+ properties: {
377
+ name: { type: "string", description: "View name" },
378
+ type: { type: "string", description: "Always 'view'" },
379
+ columns: {
380
+ type: "array",
381
+ description: "Array of column definitions",
382
+ items: {
383
+ type: "object",
384
+ properties: {
385
+ name: { type: "string", description: "Column name" },
386
+ type: { type: "string", description: "Data type" },
387
+ notnull: { type: "boolean", description: "Whether the column is NOT NULL" },
388
+ default_value: { type: "string", description: "Default value" },
389
+ primary_key: { type: "boolean", description: "Whether the column is a primary key" },
390
+ comment: { type: "string", description: "Column comment" }
391
+ }
392
+ }
393
+ }
394
+ }
395
+ },
396
+ annotations: {
397
+ readOnlyHint: true,
398
+ idempotentHint: true
399
+ }
400
+ },
401
+ {
402
+ name: "get_view_definition",
403
+ title: "Get View Definition",
404
+ description: "Retrieve the SQL definition (CREATE VIEW statement) of a specific view. " +
405
+ "Only works with SQL Server databases. " +
406
+ "Returns the complete CREATE VIEW SQL statement. " +
407
+ "Note: Views created WITH ENCRYPTION cannot have their definition retrieved.",
408
+ inputSchema: {
409
+ type: "object",
410
+ properties: {
411
+ view_name: {
412
+ type: "string",
413
+ description: "Name of the view to get definition for"
414
+ },
415
+ },
416
+ required: ["view_name"],
417
+ },
418
+ outputSchema: {
419
+ type: "object",
420
+ properties: {
421
+ name: { type: "string", description: "View name" },
422
+ definition: { type: "string", description: "CREATE VIEW SQL statement" },
423
+ message: { type: "string", description: "Additional information if definition is unavailable" }
424
+ }
425
+ },
426
+ annotations: {
427
+ readOnlyHint: true,
428
+ idempotentHint: true
429
+ }
99
430
  },
100
431
  {
101
432
  name: "append_insight",
102
- description: "添加业务洞察到备忘录",
433
+ title: "Append Insight",
434
+ description: "Add a business insight to the SQLite insights memo. " +
435
+ "Only works with SQLite databases - creates and uses an mcp_insights table. " +
436
+ "Each insight is stored with a timestamp for tracking. " +
437
+ "Useful for maintaining notes during analysis sessions. " +
438
+ "Requires confirm=true as a safety measure to prevent accidental data insertion.",
103
439
  inputSchema: {
104
440
  type: "object",
105
441
  properties: {
106
- insight: { type: "string" },
442
+ insight: {
443
+ type: "string",
444
+ description: "The business insight text to store in the memo"
445
+ },
446
+ confirm: {
447
+ type: "boolean",
448
+ description: "Must be set to true to confirm adding the insight"
449
+ },
107
450
  },
108
451
  required: ["insight"],
109
452
  },
453
+ outputSchema: {
454
+ type: "object",
455
+ properties: {
456
+ success: {
457
+ type: "boolean",
458
+ description: "True if the insight was added successfully"
459
+ },
460
+ id: {
461
+ type: "number",
462
+ description: "ID of the newly created insight entry"
463
+ },
464
+ message: {
465
+ type: "string",
466
+ description: "Success message"
467
+ }
468
+ }
469
+ },
470
+ annotations: {
471
+ readOnlyHint: false,
472
+ destructiveHint: false
473
+ }
110
474
  },
111
475
  {
112
476
  name: "list_insights",
113
- description: "列出备忘录中的所有业务洞察",
477
+ title: "List Insights",
478
+ description: "Retrieve all stored business insights from the SQLite insights memo. " +
479
+ "Only works with SQLite databases. " +
480
+ "Returns insights in descending order by creation time (newest first). " +
481
+ "Returns an empty list if no insights have been stored yet.",
114
482
  inputSchema: {
115
483
  type: "object",
116
484
  properties: {},
117
485
  },
486
+ outputSchema: {
487
+ type: "object",
488
+ properties: {
489
+ insights: {
490
+ type: "array",
491
+ description: "Array of insight entries",
492
+ items: {
493
+ type: "object",
494
+ properties: {
495
+ id: { type: "number", description: "Insight ID" },
496
+ insight: { type: "string", description: "Insight text" },
497
+ created_at: { type: "string", description: "Creation timestamp" }
498
+ }
499
+ }
500
+ }
501
+ }
502
+ },
503
+ annotations: {
504
+ readOnlyHint: true,
505
+ idempotentHint: true
506
+ }
507
+ },
508
+ {
509
+ name: "list_procedures",
510
+ title: "List Procedures",
511
+ description: "Retrieve a list of all stored procedure names in the current database. " +
512
+ "Only works with SQL Server databases. " +
513
+ "Returns only procedure names without parameter details. " +
514
+ "Use describe_procedure to get detailed parameter information for a specific procedure.",
515
+ inputSchema: {
516
+ type: "object",
517
+ properties: {},
518
+ },
519
+ outputSchema: {
520
+ type: "object",
521
+ properties: {
522
+ procedures: {
523
+ type: "array",
524
+ items: { type: "string" },
525
+ description: "Array of stored procedure names in the database"
526
+ }
527
+ }
528
+ },
529
+ annotations: {
530
+ readOnlyHint: true,
531
+ idempotentHint: true
532
+ }
533
+ },
534
+ {
535
+ name: "describe_procedure",
536
+ title: "Describe Procedure",
537
+ description: "Get detailed parameter information about a specific stored procedure. " +
538
+ "Only works with SQL Server databases. " +
539
+ "Returns parameter name, data type, direction (IN/OUT/INOUT), and default value. " +
540
+ "The procedure must exist in the database.",
541
+ inputSchema: {
542
+ type: "object",
543
+ properties: {
544
+ procedure_name: {
545
+ type: "string",
546
+ description: "Name of the stored procedure to describe"
547
+ },
548
+ },
549
+ required: ["procedure_name"],
550
+ },
551
+ outputSchema: {
552
+ type: "object",
553
+ properties: {
554
+ name: { type: "string", description: "Procedure name" },
555
+ type: { type: "string", description: "Always 'procedure'" },
556
+ parameters: {
557
+ type: "array",
558
+ description: "Array of parameter definitions",
559
+ items: {
560
+ type: "object",
561
+ properties: {
562
+ name: { type: "string", description: "Parameter name" },
563
+ type: { type: "string", description: "Data type" },
564
+ direction: { type: "string", enum: ["IN", "OUT", "INOUT"], description: "Parameter direction" },
565
+ default_value: { type: "string", description: "Default value" },
566
+ is_output: { type: "boolean", description: "Whether this is an output parameter" }
567
+ }
568
+ }
569
+ }
570
+ }
571
+ },
572
+ annotations: {
573
+ readOnlyHint: true,
574
+ idempotentHint: true
575
+ }
576
+ },
577
+ {
578
+ name: "get_procedure_definition",
579
+ title: "Get Procedure Definition",
580
+ description: "Retrieve the SQL definition (CREATE PROCEDURE statement) of a specific stored procedure. " +
581
+ "Only works with SQL Server databases. " +
582
+ "Returns the complete CREATE PROCEDURE SQL statement. " +
583
+ "Note: Procedures created WITH ENCRYPTION cannot have their definition retrieved.",
584
+ inputSchema: {
585
+ type: "object",
586
+ properties: {
587
+ procedure_name: {
588
+ type: "string",
589
+ description: "Name of the stored procedure to get definition for"
590
+ },
591
+ },
592
+ required: ["procedure_name"],
593
+ },
594
+ outputSchema: {
595
+ type: "object",
596
+ properties: {
597
+ name: { type: "string", description: "Procedure name" },
598
+ definition: { type: "string", description: "CREATE PROCEDURE SQL statement" },
599
+ message: { type: "string", description: "Additional information if definition is unavailable" }
600
+ }
601
+ },
602
+ annotations: {
603
+ readOnlyHint: true,
604
+ idempotentHint: true
605
+ }
118
606
  },
119
607
  ],
120
608
  };
@@ -131,21 +619,33 @@ export async function handleToolCall(name, args) {
131
619
  case "read_query":
132
620
  return await readQuery(args.query);
133
621
  case "write_query":
134
- return await writeQuery(args.query);
622
+ return await writeQuery(args.query, args.confirm);
135
623
  case "create_table":
136
- return await createTable(args.query);
624
+ return await createTable(args.query, args.confirm);
137
625
  case "alter_table":
138
- return await alterTable(args.query);
626
+ return await alterTable(args.query, args.confirm);
139
627
  case "drop_table":
140
628
  return await dropTable(args.table_name, args.confirm);
141
629
  case "export_query":
142
630
  return await exportQuery(args.query, args.format);
143
631
  case "list_tables":
144
- return await listTables();
632
+ return await listTables(args.include_views);
145
633
  case "describe_table":
146
634
  return await describeTable(args.table_name);
635
+ case "list_views":
636
+ return await listViews();
637
+ case "describe_view":
638
+ return await describeView(args.view_name);
639
+ case "get_view_definition":
640
+ return await getViewDefinition(args.view_name);
641
+ case "list_procedures":
642
+ return await listProcedures();
643
+ case "describe_procedure":
644
+ return await describeProcedure(args.procedure_name);
645
+ case "get_procedure_definition":
646
+ return await getProcedureDefinition(args.procedure_name);
147
647
  case "append_insight":
148
- return await appendInsight(args.insight);
648
+ return await appendInsight(args.insight, args.confirm);
149
649
  case "list_insights":
150
650
  return await listInsights();
151
651
  default: