@berthojoris/mcp-mysql-server 1.9.3 → 1.10.1

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.
@@ -3,12 +3,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.featureConfig = exports.FeatureConfig = exports.toolCategoryMap = exports.ToolCategory = void 0;
6
+ exports.featureConfig = exports.FeatureConfig = exports.toolDocCategoryMap = exports.toolCategoryMap = exports.DocCategory = exports.ToolCategory = void 0;
7
7
  const dotenv_1 = __importDefault(require("dotenv"));
8
8
  // Load environment variables
9
9
  dotenv_1.default.config();
10
10
  /**
11
- * Available MCP tool categories
11
+ * Available MCP tool categories (Legacy - for backward compatibility)
12
12
  */
13
13
  var ToolCategory;
14
14
  (function (ToolCategory) {
@@ -24,7 +24,36 @@ var ToolCategory;
24
24
  ToolCategory["PROCEDURE"] = "procedure";
25
25
  })(ToolCategory || (exports.ToolCategory = ToolCategory = {}));
26
26
  /**
27
- * Map of tool names to their categories
27
+ * Documentation categories from README (21 categories)
28
+ * More intuitive and matches user mental model
29
+ */
30
+ var DocCategory;
31
+ (function (DocCategory) {
32
+ DocCategory["DATABASE_DISCOVERY"] = "database_discovery";
33
+ DocCategory["CRUD_OPERATIONS"] = "crud_operations";
34
+ DocCategory["BULK_OPERATIONS"] = "bulk_operations";
35
+ DocCategory["CUSTOM_QUERIES"] = "custom_queries";
36
+ DocCategory["SCHEMA_MANAGEMENT"] = "schema_management";
37
+ DocCategory["UTILITIES"] = "utilities";
38
+ DocCategory["TRANSACTION_MANAGEMENT"] = "transaction_management";
39
+ DocCategory["STORED_PROCEDURES"] = "stored_procedures";
40
+ DocCategory["VIEWS_MANAGEMENT"] = "views_management";
41
+ DocCategory["TRIGGERS_MANAGEMENT"] = "triggers_management";
42
+ DocCategory["FUNCTIONS_MANAGEMENT"] = "functions_management";
43
+ DocCategory["INDEX_MANAGEMENT"] = "index_management";
44
+ DocCategory["CONSTRAINT_MANAGEMENT"] = "constraint_management";
45
+ DocCategory["TABLE_MAINTENANCE"] = "table_maintenance";
46
+ DocCategory["SERVER_MANAGEMENT"] = "server_management";
47
+ DocCategory["PERFORMANCE_MONITORING"] = "performance_monitoring";
48
+ DocCategory["CACHE_MANAGEMENT"] = "cache_management";
49
+ DocCategory["QUERY_OPTIMIZATION"] = "query_optimization";
50
+ DocCategory["BACKUP_RESTORE"] = "backup_restore";
51
+ DocCategory["IMPORT_EXPORT"] = "import_export";
52
+ DocCategory["DATA_MIGRATION"] = "data_migration";
53
+ DocCategory["SCHEMA_MIGRATIONS"] = "schema_migrations";
54
+ })(DocCategory || (exports.DocCategory = DocCategory = {}));
55
+ /**
56
+ * Map of tool names to their legacy categories
28
57
  */
29
58
  exports.toolCategoryMap = {
30
59
  // Database tools
@@ -157,125 +186,395 @@ exports.toolCategoryMap = {
157
186
  validateMigrations: ToolCategory.LIST,
158
187
  resetFailedMigration: ToolCategory.DDL,
159
188
  generateMigrationFromDiff: ToolCategory.DDL,
189
+ // Performance monitoring tools
190
+ getPerformanceMetrics: ToolCategory.UTILITY,
191
+ getTopQueriesByTime: ToolCategory.UTILITY,
192
+ getTopQueriesByCount: ToolCategory.UTILITY,
193
+ getSlowQueries: ToolCategory.UTILITY,
194
+ getTableIOStats: ToolCategory.UTILITY,
195
+ getIndexUsageStats: ToolCategory.UTILITY,
196
+ getUnusedIndexes: ToolCategory.UTILITY,
197
+ getConnectionPoolStats: ToolCategory.UTILITY,
198
+ getDatabaseHealthCheck: ToolCategory.UTILITY,
199
+ resetPerformanceStats: ToolCategory.UTILITY,
200
+ };
201
+ /**
202
+ * Map of tool names to their documentation categories (New Enhanced System)
203
+ */
204
+ exports.toolDocCategoryMap = {
205
+ // Database Discovery
206
+ listDatabases: DocCategory.DATABASE_DISCOVERY,
207
+ listTables: DocCategory.DATABASE_DISCOVERY,
208
+ readTableSchema: DocCategory.DATABASE_DISCOVERY,
209
+ getTableRelationships: DocCategory.DATABASE_DISCOVERY,
210
+ // CRUD Operations
211
+ createRecord: DocCategory.CRUD_OPERATIONS,
212
+ readRecords: DocCategory.CRUD_OPERATIONS,
213
+ updateRecord: DocCategory.CRUD_OPERATIONS,
214
+ deleteRecord: DocCategory.CRUD_OPERATIONS,
215
+ // Bulk Operations
216
+ bulkInsert: DocCategory.BULK_OPERATIONS,
217
+ bulkUpdate: DocCategory.BULK_OPERATIONS,
218
+ bulkDelete: DocCategory.BULK_OPERATIONS,
219
+ // Custom Queries
220
+ runQuery: DocCategory.CUSTOM_QUERIES,
221
+ executeSql: DocCategory.CUSTOM_QUERIES,
222
+ // Schema Management (DDL)
223
+ createTable: DocCategory.SCHEMA_MANAGEMENT,
224
+ alterTable: DocCategory.SCHEMA_MANAGEMENT,
225
+ dropTable: DocCategory.SCHEMA_MANAGEMENT,
226
+ executeDdl: DocCategory.SCHEMA_MANAGEMENT,
227
+ // Utilities
228
+ testConnection: DocCategory.UTILITIES,
229
+ describeConnection: DocCategory.UTILITIES,
230
+ exportTableToCSV: DocCategory.UTILITIES,
231
+ exportQueryToCSV: DocCategory.UTILITIES,
232
+ // Transaction Management
233
+ beginTransaction: DocCategory.TRANSACTION_MANAGEMENT,
234
+ commitTransaction: DocCategory.TRANSACTION_MANAGEMENT,
235
+ rollbackTransaction: DocCategory.TRANSACTION_MANAGEMENT,
236
+ getTransactionStatus: DocCategory.TRANSACTION_MANAGEMENT,
237
+ executeInTransaction: DocCategory.TRANSACTION_MANAGEMENT,
238
+ // Stored Procedures
239
+ listStoredProcedures: DocCategory.STORED_PROCEDURES,
240
+ getStoredProcedureInfo: DocCategory.STORED_PROCEDURES,
241
+ executeStoredProcedure: DocCategory.STORED_PROCEDURES,
242
+ createStoredProcedure: DocCategory.STORED_PROCEDURES,
243
+ dropStoredProcedure: DocCategory.STORED_PROCEDURES,
244
+ showCreateProcedure: DocCategory.STORED_PROCEDURES,
245
+ // Views Management
246
+ listViews: DocCategory.VIEWS_MANAGEMENT,
247
+ getViewInfo: DocCategory.VIEWS_MANAGEMENT,
248
+ createView: DocCategory.VIEWS_MANAGEMENT,
249
+ alterView: DocCategory.VIEWS_MANAGEMENT,
250
+ dropView: DocCategory.VIEWS_MANAGEMENT,
251
+ showCreateView: DocCategory.VIEWS_MANAGEMENT,
252
+ // Triggers Management
253
+ listTriggers: DocCategory.TRIGGERS_MANAGEMENT,
254
+ getTriggerInfo: DocCategory.TRIGGERS_MANAGEMENT,
255
+ createTrigger: DocCategory.TRIGGERS_MANAGEMENT,
256
+ dropTrigger: DocCategory.TRIGGERS_MANAGEMENT,
257
+ showCreateTrigger: DocCategory.TRIGGERS_MANAGEMENT,
258
+ // Functions Management
259
+ listFunctions: DocCategory.FUNCTIONS_MANAGEMENT,
260
+ getFunctionInfo: DocCategory.FUNCTIONS_MANAGEMENT,
261
+ createFunction: DocCategory.FUNCTIONS_MANAGEMENT,
262
+ dropFunction: DocCategory.FUNCTIONS_MANAGEMENT,
263
+ showCreateFunction: DocCategory.FUNCTIONS_MANAGEMENT,
264
+ executeFunction: DocCategory.FUNCTIONS_MANAGEMENT,
265
+ // Index Management
266
+ listIndexes: DocCategory.INDEX_MANAGEMENT,
267
+ getIndexInfo: DocCategory.INDEX_MANAGEMENT,
268
+ createIndex: DocCategory.INDEX_MANAGEMENT,
269
+ dropIndex: DocCategory.INDEX_MANAGEMENT,
270
+ analyzeIndex: DocCategory.INDEX_MANAGEMENT,
271
+ // Constraint Management
272
+ listForeignKeys: DocCategory.CONSTRAINT_MANAGEMENT,
273
+ listConstraints: DocCategory.CONSTRAINT_MANAGEMENT,
274
+ addForeignKey: DocCategory.CONSTRAINT_MANAGEMENT,
275
+ dropForeignKey: DocCategory.CONSTRAINT_MANAGEMENT,
276
+ addUniqueConstraint: DocCategory.CONSTRAINT_MANAGEMENT,
277
+ dropConstraint: DocCategory.CONSTRAINT_MANAGEMENT,
278
+ addCheckConstraint: DocCategory.CONSTRAINT_MANAGEMENT,
279
+ // Table Maintenance
280
+ analyzeTable: DocCategory.TABLE_MAINTENANCE,
281
+ optimizeTable: DocCategory.TABLE_MAINTENANCE,
282
+ checkTable: DocCategory.TABLE_MAINTENANCE,
283
+ repairTable: DocCategory.TABLE_MAINTENANCE,
284
+ truncateTable: DocCategory.TABLE_MAINTENANCE,
285
+ getTableStatus: DocCategory.TABLE_MAINTENANCE,
286
+ flushTable: DocCategory.TABLE_MAINTENANCE,
287
+ getTableSize: DocCategory.TABLE_MAINTENANCE,
288
+ // Server Management
289
+ showProcessList: DocCategory.SERVER_MANAGEMENT,
290
+ killProcess: DocCategory.SERVER_MANAGEMENT,
291
+ showStatus: DocCategory.SERVER_MANAGEMENT,
292
+ showVariables: DocCategory.SERVER_MANAGEMENT,
293
+ explainQuery: DocCategory.SERVER_MANAGEMENT,
294
+ showEngineStatus: DocCategory.SERVER_MANAGEMENT,
295
+ getServerInfo: DocCategory.SERVER_MANAGEMENT,
296
+ showBinaryLogs: DocCategory.SERVER_MANAGEMENT,
297
+ showReplicationStatus: DocCategory.SERVER_MANAGEMENT,
298
+ // Performance Monitoring
299
+ getPerformanceMetrics: DocCategory.PERFORMANCE_MONITORING,
300
+ getTopQueriesByTime: DocCategory.PERFORMANCE_MONITORING,
301
+ getTopQueriesByCount: DocCategory.PERFORMANCE_MONITORING,
302
+ getSlowQueries: DocCategory.PERFORMANCE_MONITORING,
303
+ getTableIOStats: DocCategory.PERFORMANCE_MONITORING,
304
+ getIndexUsageStats: DocCategory.PERFORMANCE_MONITORING,
305
+ getUnusedIndexes: DocCategory.PERFORMANCE_MONITORING,
306
+ getConnectionPoolStats: DocCategory.PERFORMANCE_MONITORING,
307
+ getDatabaseHealthCheck: DocCategory.PERFORMANCE_MONITORING,
308
+ resetPerformanceStats: DocCategory.PERFORMANCE_MONITORING,
309
+ // Cache Management
310
+ getCacheStats: DocCategory.CACHE_MANAGEMENT,
311
+ getCacheConfig: DocCategory.CACHE_MANAGEMENT,
312
+ configureCacheSettings: DocCategory.CACHE_MANAGEMENT,
313
+ clearCache: DocCategory.CACHE_MANAGEMENT,
314
+ invalidateCacheForTable: DocCategory.CACHE_MANAGEMENT,
315
+ // Query Optimization
316
+ analyzeQuery: DocCategory.QUERY_OPTIMIZATION,
317
+ getOptimizationHints: DocCategory.QUERY_OPTIMIZATION,
318
+ // Backup & Restore
319
+ backupTable: DocCategory.BACKUP_RESTORE,
320
+ backupDatabase: DocCategory.BACKUP_RESTORE,
321
+ restoreFromSql: DocCategory.BACKUP_RESTORE,
322
+ getCreateTableStatement: DocCategory.BACKUP_RESTORE,
323
+ getDatabaseSchema: DocCategory.BACKUP_RESTORE,
324
+ // Import/Export
325
+ exportTableToJSON: DocCategory.IMPORT_EXPORT,
326
+ exportQueryToJSON: DocCategory.IMPORT_EXPORT,
327
+ exportTableToSql: DocCategory.IMPORT_EXPORT,
328
+ importFromCSV: DocCategory.IMPORT_EXPORT,
329
+ importFromJSON: DocCategory.IMPORT_EXPORT,
330
+ // Data Migration
331
+ copyTableData: DocCategory.DATA_MIGRATION,
332
+ moveTableData: DocCategory.DATA_MIGRATION,
333
+ cloneTable: DocCategory.DATA_MIGRATION,
334
+ compareTableStructure: DocCategory.DATA_MIGRATION,
335
+ syncTableData: DocCategory.DATA_MIGRATION,
336
+ // Schema Migrations
337
+ initMigrationsTable: DocCategory.SCHEMA_MIGRATIONS,
338
+ createMigration: DocCategory.SCHEMA_MIGRATIONS,
339
+ applyMigrations: DocCategory.SCHEMA_MIGRATIONS,
340
+ rollbackMigration: DocCategory.SCHEMA_MIGRATIONS,
341
+ getMigrationStatus: DocCategory.SCHEMA_MIGRATIONS,
342
+ getSchemaVersion: DocCategory.SCHEMA_MIGRATIONS,
343
+ validateMigrations: DocCategory.SCHEMA_MIGRATIONS,
344
+ resetFailedMigration: DocCategory.SCHEMA_MIGRATIONS,
345
+ generateMigrationFromDiff: DocCategory.SCHEMA_MIGRATIONS,
346
+ };
347
+ /**
348
+ * Mapping between legacy categories and documentation categories
349
+ * This allows backward compatibility
350
+ */
351
+ const legacyToDocCategoryMap = {
352
+ list: [
353
+ DocCategory.DATABASE_DISCOVERY,
354
+ DocCategory.STORED_PROCEDURES,
355
+ DocCategory.VIEWS_MANAGEMENT,
356
+ DocCategory.TRIGGERS_MANAGEMENT,
357
+ DocCategory.FUNCTIONS_MANAGEMENT,
358
+ DocCategory.INDEX_MANAGEMENT,
359
+ DocCategory.CONSTRAINT_MANAGEMENT,
360
+ DocCategory.TABLE_MAINTENANCE,
361
+ DocCategory.SERVER_MANAGEMENT,
362
+ DocCategory.SCHEMA_MIGRATIONS,
363
+ ],
364
+ read: [DocCategory.CRUD_OPERATIONS, DocCategory.CUSTOM_QUERIES],
365
+ create: [
366
+ DocCategory.CRUD_OPERATIONS,
367
+ DocCategory.BULK_OPERATIONS,
368
+ DocCategory.IMPORT_EXPORT,
369
+ DocCategory.DATA_MIGRATION,
370
+ ],
371
+ update: [
372
+ DocCategory.CRUD_OPERATIONS,
373
+ DocCategory.BULK_OPERATIONS,
374
+ DocCategory.DATA_MIGRATION,
375
+ ],
376
+ delete: [
377
+ DocCategory.CRUD_OPERATIONS,
378
+ DocCategory.BULK_OPERATIONS,
379
+ DocCategory.DATA_MIGRATION,
380
+ ],
381
+ execute: [DocCategory.CUSTOM_QUERIES, DocCategory.SERVER_MANAGEMENT],
382
+ ddl: [
383
+ DocCategory.SCHEMA_MANAGEMENT,
384
+ DocCategory.VIEWS_MANAGEMENT,
385
+ DocCategory.TRIGGERS_MANAGEMENT,
386
+ DocCategory.INDEX_MANAGEMENT,
387
+ DocCategory.CONSTRAINT_MANAGEMENT,
388
+ DocCategory.TABLE_MAINTENANCE,
389
+ DocCategory.BACKUP_RESTORE,
390
+ DocCategory.DATA_MIGRATION,
391
+ DocCategory.SCHEMA_MIGRATIONS,
392
+ ],
393
+ utility: [
394
+ DocCategory.UTILITIES,
395
+ DocCategory.TABLE_MAINTENANCE,
396
+ DocCategory.PERFORMANCE_MONITORING,
397
+ DocCategory.CACHE_MANAGEMENT,
398
+ DocCategory.QUERY_OPTIMIZATION,
399
+ DocCategory.BACKUP_RESTORE,
400
+ DocCategory.IMPORT_EXPORT,
401
+ ],
402
+ transaction: [DocCategory.TRANSACTION_MANAGEMENT],
403
+ procedure: [DocCategory.STORED_PROCEDURES, DocCategory.FUNCTIONS_MANAGEMENT],
160
404
  };
161
405
  /**
162
406
  * Class to manage feature configuration based on runtime or environment variables
407
+ * Supports dual-layer filtering:
408
+ * - Layer 1 (Permissions): Legacy categories (broad control)
409
+ * - Layer 2 (Categories): Documentation categories (fine-grained control, optional)
163
410
  */
164
411
  class FeatureConfig {
165
- constructor(configStr) {
166
- this.originalConfigString = configStr || process.env.MCP_CONFIG || "";
167
- this.enabledCategories = this.parseConfig(configStr);
412
+ constructor(permissionsStr, categoriesStr) {
413
+ // Support both old single-parameter and new dual-parameter signatures
414
+ const permissions = permissionsStr ||
415
+ process.env.MCP_PERMISSIONS ||
416
+ process.env.MCP_CONFIG ||
417
+ "";
418
+ const categories = categoriesStr || process.env.MCP_CATEGORIES || "";
419
+ this.originalPermissionsString = permissions;
420
+ this.originalCategoriesString = categories;
421
+ this.useDualLayer = !!categories.trim();
422
+ const parsed = this.parseConfig(permissions, categories);
423
+ this.enabledLegacyCategories = parsed.legacy;
424
+ this.enabledDocCategories = parsed.doc;
168
425
  }
169
426
  /**
170
- * Parse MCP_CONFIG from provided string or environment variables
427
+ * Parse permissions and categories for dual-layer filtering
428
+ * Layer 1 (permissions): Broad control using legacy categories
429
+ * Layer 2 (categories): Fine-grained control using documentation categories (optional)
171
430
  */
172
- parseConfig(configStr) {
173
- // Priority: 1. Provided config, 2. Environment variable, 3. Enable all
174
- const config = configStr || process.env.MCP_CONFIG || "";
175
- // If config is empty, enable all features
176
- if (!config.trim()) {
177
- return new Set(Object.values(ToolCategory));
431
+ parseConfig(permissionsStr, categoriesStr) {
432
+ // If both are empty, enable all features
433
+ if (!permissionsStr.trim() && !categoriesStr.trim()) {
434
+ return {
435
+ legacy: new Set(Object.values(ToolCategory)),
436
+ doc: new Set(Object.values(DocCategory)),
437
+ };
438
+ }
439
+ // Parse Layer 1: Permissions (legacy categories)
440
+ let legacySet = new Set();
441
+ if (permissionsStr.trim()) {
442
+ const items = permissionsStr
443
+ .split(",")
444
+ .map((c) => c.trim().toLowerCase());
445
+ const validLegacyCategories = items.filter((c) => Object.values(ToolCategory).includes(c));
446
+ legacySet = new Set(validLegacyCategories);
447
+ }
448
+ else {
449
+ // If no permissions specified but categories are, allow all permissions
450
+ legacySet = new Set(Object.values(ToolCategory));
451
+ }
452
+ // Parse Layer 2: Categories (documentation categories)
453
+ let docSet = new Set();
454
+ if (categoriesStr.trim()) {
455
+ // Categories specified - use them for fine-grained filtering
456
+ const items = categoriesStr.split(",").map((c) => c.trim().toLowerCase());
457
+ const validDocCategories = items.filter((c) => Object.values(DocCategory).includes(c));
458
+ docSet = new Set(validDocCategories);
178
459
  }
179
- // Parse comma-separated list
180
- const categories = config.split(",").map((c) => c.trim().toLowerCase());
181
- const validCategories = categories.filter((c) => Object.values(ToolCategory).includes(c));
182
- return new Set(validCategories);
460
+ else {
461
+ // No categories specified - derive from permissions
462
+ legacySet.forEach((legacyCat) => {
463
+ const docCats = legacyToDocCategoryMap[legacyCat] || [];
464
+ docCats.forEach((dc) => docSet.add(dc));
465
+ });
466
+ }
467
+ return {
468
+ legacy: legacySet,
469
+ doc: docSet,
470
+ };
183
471
  }
184
472
  /**
185
473
  * Update configuration at runtime
186
474
  */
187
- setConfig(configStr) {
188
- this.originalConfigString = configStr;
189
- this.enabledCategories = this.parseConfig(configStr);
475
+ setConfig(permissionsStr, categoriesStr) {
476
+ this.originalPermissionsString = permissionsStr;
477
+ this.originalCategoriesString = categoriesStr || "";
478
+ this.useDualLayer = !!(categoriesStr && categoriesStr.trim());
479
+ const parsed = this.parseConfig(permissionsStr, categoriesStr || "");
480
+ this.enabledLegacyCategories = parsed.legacy;
481
+ this.enabledDocCategories = parsed.doc;
190
482
  }
191
483
  /**
192
484
  * Check if a specific tool is enabled
485
+ * Dual-layer logic:
486
+ * - Layer 1 (Permission): Tool must be allowed by its legacy category
487
+ * - Layer 2 (Category): If categories specified, tool must also be in allowed doc category
193
488
  */
194
489
  isToolEnabled(toolName) {
195
- const category = exports.toolCategoryMap[toolName];
196
- // If tool is not in the map, default to disabled
197
- if (!category) {
490
+ const docCategory = exports.toolDocCategoryMap[toolName];
491
+ const legacyCategory = exports.toolCategoryMap[toolName];
492
+ // If tool is not in either map, default to disabled
493
+ if (!docCategory && !legacyCategory) {
198
494
  console.warn(`Unknown tool: ${toolName}`);
199
495
  return false;
200
496
  }
201
- return this.enabledCategories.has(category);
497
+ // Layer 1: Check permission (legacy category)
498
+ const hasPermission = legacyCategory
499
+ ? this.enabledLegacyCategories.has(legacyCategory)
500
+ : false;
501
+ if (!hasPermission) {
502
+ return false;
503
+ }
504
+ // Layer 2: Check category (documentation category) if dual-layer mode
505
+ if (this.useDualLayer) {
506
+ const hasCategory = docCategory
507
+ ? this.enabledDocCategories.has(docCategory)
508
+ : false;
509
+ return hasCategory;
510
+ }
511
+ // Single-layer mode: permission is sufficient
512
+ return true;
202
513
  }
203
514
  /**
204
515
  * Get detailed permission error message for a specific tool
205
516
  */
206
517
  getPermissionError(toolName) {
207
- const category = exports.toolCategoryMap[toolName];
208
- if (!category) {
518
+ const docCategory = exports.toolDocCategoryMap[toolName];
519
+ const legacyCategory = exports.toolCategoryMap[toolName];
520
+ if (!docCategory && !legacyCategory) {
209
521
  return `Unknown tool '${toolName}'. This tool is not recognized by the MCP server.`;
210
522
  }
211
- const isAllPermissions = !this.originalConfigString.trim();
212
- const currentPermissions = isAllPermissions
213
- ? "all"
214
- : this.originalConfigString;
215
- const actionDescriptions = {
216
- [ToolCategory.LIST]: "list databases and tables",
217
- [ToolCategory.READ]: "read data from tables",
218
- [ToolCategory.CREATE]: "create new records",
219
- [ToolCategory.UPDATE]: "update existing records",
220
- [ToolCategory.DELETE]: "delete records",
221
- [ToolCategory.EXECUTE]: "execute custom SQL queries",
222
- [ToolCategory.DDL]: "create, alter, or drop tables (schema changes)",
223
- [ToolCategory.UTILITY]: "use utility functions",
224
- [ToolCategory.TRANSACTION]: "manage database transactions",
225
- [ToolCategory.PROCEDURE]: "manage stored procedures",
226
- };
227
- const toolDescriptions = {
228
- createTable: "create new tables",
229
- alterTable: "modify table structure",
230
- dropTable: "delete tables",
231
- executeDdl: "execute DDL statements",
232
- createRecord: "insert new records",
233
- updateRecord: "update existing records",
234
- deleteRecord: "delete records",
235
- bulkInsert: "insert multiple records in batches",
236
- bulkUpdate: "update multiple records in batches",
237
- bulkDelete: "delete multiple records in batches",
238
- executeSql: "execute custom SQL statements",
239
- runQuery: "run SELECT queries",
240
- beginTransaction: "start database transactions",
241
- commitTransaction: "commit database transactions",
242
- rollbackTransaction: "rollback database transactions",
243
- executeInTransaction: "execute queries within transactions",
244
- createStoredProcedure: "create stored procedures",
245
- dropStoredProcedure: "delete stored procedures",
246
- executeStoredProcedure: "execute stored procedures",
247
- exportTableToCSV: "export table data to CSV",
248
- exportQueryToCSV: "export query results to CSV",
249
- // Backup and restore
250
- backupTable: "backup table to SQL dump",
251
- backupDatabase: "backup database to SQL dump",
252
- restoreFromSql: "restore database from SQL dump",
253
- getCreateTableStatement: "get CREATE TABLE statement",
254
- getDatabaseSchema: "get database schema overview",
255
- // Extended export/import
256
- exportTableToJSON: "export table data to JSON",
257
- exportQueryToJSON: "export query results to JSON",
258
- exportTableToSql: "export table data to SQL INSERT statements",
259
- importFromCSV: "import data from CSV",
260
- importFromJSON: "import data from JSON",
261
- };
262
- const toolDescription = toolDescriptions[toolName] || actionDescriptions[category];
263
- const requiredPermission = category;
264
- return (`Permission denied: Cannot ${toolDescription}. ` +
265
- `This action requires '${requiredPermission}' permission, but your current MCP configuration only allows: ${currentPermissions}. ` +
266
- `To enable this feature, update your MCP server configuration to include '${requiredPermission}' in the permissions list.`);
523
+ const isAllEnabled = !this.originalPermissionsString.trim() &&
524
+ !this.originalCategoriesString.trim();
525
+ if (isAllEnabled) {
526
+ return `Unknown error: All tools should be enabled but '${toolName}' was blocked.`;
527
+ }
528
+ // Build error message based on dual-layer or single-layer mode
529
+ if (this.useDualLayer) {
530
+ const hasPermission = legacyCategory
531
+ ? this.enabledLegacyCategories.has(legacyCategory)
532
+ : false;
533
+ const hasCategory = docCategory
534
+ ? this.enabledDocCategories.has(docCategory)
535
+ : false;
536
+ if (!hasPermission) {
537
+ return (`Permission denied: This tool requires '${legacyCategory}' permission (Layer 1). ` +
538
+ `Your current permissions: ${this.originalPermissionsString || "none"}. ` +
539
+ `Add '${legacyCategory}' to the permissions argument.`);
540
+ }
541
+ if (!hasCategory) {
542
+ return (`Permission denied: This tool requires '${docCategory}' category (Layer 2). ` +
543
+ `Your current categories: ${this.originalCategoriesString || "none"}. ` +
544
+ `Add '${docCategory}' to the categories argument.`);
545
+ }
546
+ }
547
+ else {
548
+ // Single-layer mode
549
+ return (`Permission denied: This tool requires '${legacyCategory}' permission. ` +
550
+ `Your current configuration allows: ${this.originalPermissionsString || "all"}. ` +
551
+ `Add '${legacyCategory}' to enable this tool.`);
552
+ }
553
+ return `Permission denied for tool '${toolName}'.`;
267
554
  }
268
555
  /**
269
- * Check if a category is enabled
556
+ * Check if a legacy category is enabled
270
557
  */
271
558
  isCategoryEnabled(category) {
272
- return this.enabledCategories.has(category);
559
+ return this.enabledLegacyCategories.has(category);
273
560
  }
274
561
  /**
275
- * Get all enabled categories
562
+ * Check if a documentation category is enabled
563
+ */
564
+ isDocCategoryEnabled(category) {
565
+ return this.enabledDocCategories.has(category);
566
+ }
567
+ /**
568
+ * Get all enabled legacy categories
276
569
  */
277
570
  getEnabledCategories() {
278
- return Array.from(this.enabledCategories);
571
+ return Array.from(this.enabledLegacyCategories);
572
+ }
573
+ /**
574
+ * Get all enabled documentation categories
575
+ */
576
+ getEnabledDocCategories() {
577
+ return Array.from(this.enabledDocCategories);
279
578
  }
280
579
  /**
281
580
  * Get all available categories with their status
@@ -283,10 +582,39 @@ class FeatureConfig {
283
582
  getCategoryStatus() {
284
583
  const result = {};
285
584
  for (const category of Object.values(ToolCategory)) {
286
- result[category] = this.enabledCategories.has(category);
585
+ result[category] = this.enabledLegacyCategories.has(category);
586
+ }
587
+ return result;
588
+ }
589
+ /**
590
+ * Get all available documentation categories with their status
591
+ */
592
+ getDocCategoryStatus() {
593
+ const result = {};
594
+ for (const category of Object.values(DocCategory)) {
595
+ result[category] = this.enabledDocCategories.has(category);
287
596
  }
288
597
  return result;
289
598
  }
599
+ /**
600
+ * Check if using dual-layer filtering mode
601
+ */
602
+ isUsingDualLayer() {
603
+ return this.useDualLayer;
604
+ }
605
+ /**
606
+ * Get filtering mode description
607
+ */
608
+ getFilteringMode() {
609
+ if (!this.originalPermissionsString.trim() &&
610
+ !this.originalCategoriesString.trim()) {
611
+ return "No filtering (all tools enabled)";
612
+ }
613
+ if (this.useDualLayer) {
614
+ return "Dual-layer (Permissions + Categories)";
615
+ }
616
+ return "Single-layer (Permissions only)";
617
+ }
290
618
  }
291
619
  exports.FeatureConfig = FeatureConfig;
292
620
  // Export singleton instance
@@ -15,6 +15,8 @@ declare class DatabaseConnection {
15
15
  testConnection(): Promise<{
16
16
  connected: boolean;
17
17
  latency: number;
18
+ error?: string;
19
+ errorCode?: string;
18
20
  }>;
19
21
  closePool(): Promise<void>;
20
22
  beginTransaction(transactionId: string): Promise<void>;
@@ -93,7 +93,13 @@ class DatabaseConnection {
93
93
  return { connected: true, latency: endTime - startTime };
94
94
  }
95
95
  catch (error) {
96
- return { connected: false, latency: -1 };
96
+ // Return detailed error information for diagnostics
97
+ return {
98
+ connected: false,
99
+ latency: -1,
100
+ error: error?.message || "Unknown connection error",
101
+ errorCode: error?.code || error?.errno || "UNKNOWN",
102
+ };
97
103
  }
98
104
  }
99
105
  async closePool() {