@berthojoris/mcp-mysql-server 1.14.1 → 1.16.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.
@@ -52,6 +52,7 @@ var DocCategory;
52
52
  DocCategory["DATA_MIGRATION"] = "data_migration";
53
53
  DocCategory["SCHEMA_MIGRATIONS"] = "schema_migrations";
54
54
  DocCategory["ANALYSIS"] = "analysis";
55
+ DocCategory["AI_ENHANCEMENT"] = "ai_enhancement";
55
56
  })(DocCategory || (exports.DocCategory = DocCategory = {}));
56
57
  const normalizePresetName = (value) => (value || "").toLowerCase().replace(/[\s_-]/g, "");
57
58
  const permissionPresets = {
@@ -84,6 +85,7 @@ const permissionPresets = {
84
85
  DocCategory.QUERY_OPTIMIZATION,
85
86
  DocCategory.CACHE_MANAGEMENT,
86
87
  DocCategory.SERVER_MANAGEMENT,
88
+ DocCategory.AI_ENHANCEMENT,
87
89
  ],
88
90
  },
89
91
  dbalite: {
@@ -115,6 +117,58 @@ const permissionPresets = {
115
117
  DocCategory.STORED_PROCEDURES,
116
118
  ],
117
119
  },
120
+ dev: {
121
+ name: "dev",
122
+ description: "Development profile with full access to all tools",
123
+ permissions: Object.values(ToolCategory),
124
+ categories: Object.values(DocCategory),
125
+ deniedTools: [], // Explicitly allow everything
126
+ },
127
+ stage: {
128
+ name: "stage",
129
+ description: "Staging profile with data modification but no destructive DDL",
130
+ permissions: [
131
+ ToolCategory.LIST,
132
+ ToolCategory.READ,
133
+ ToolCategory.CREATE,
134
+ ToolCategory.UPDATE,
135
+ ToolCategory.DELETE,
136
+ ToolCategory.UTILITY,
137
+ ToolCategory.TRANSACTION,
138
+ ],
139
+ categories: [
140
+ DocCategory.DATABASE_DISCOVERY,
141
+ DocCategory.CRUD_OPERATIONS,
142
+ DocCategory.BULK_OPERATIONS,
143
+ DocCategory.CUSTOM_QUERIES,
144
+ DocCategory.UTILITIES,
145
+ DocCategory.TRANSACTION_MANAGEMENT,
146
+ DocCategory.IMPORT_EXPORT,
147
+ DocCategory.DATA_MIGRATION,
148
+ DocCategory.PERFORMANCE_MONITORING,
149
+ DocCategory.ANALYSIS,
150
+ ],
151
+ deniedTools: ["drop_table", "truncate_table", "drop_database"],
152
+ },
153
+ prod: {
154
+ name: "prod",
155
+ description: "Production profile with strict read-only access and safety checks",
156
+ permissions: [ToolCategory.LIST, ToolCategory.READ, ToolCategory.UTILITY],
157
+ categories: [
158
+ DocCategory.DATABASE_DISCOVERY,
159
+ DocCategory.CRUD_OPERATIONS, // Read only via permissions
160
+ DocCategory.CUSTOM_QUERIES,
161
+ DocCategory.UTILITIES,
162
+ DocCategory.PERFORMANCE_MONITORING,
163
+ DocCategory.ANALYSIS,
164
+ ],
165
+ deniedTools: [
166
+ "create_table", "alter_table", "drop_table", "truncate_table",
167
+ "create_record", "update_record", "delete_record",
168
+ "bulk_insert", "bulk_update", "bulk_delete",
169
+ "execute_sql", "execute_ddl"
170
+ ],
171
+ },
118
172
  };
119
173
  /**
120
174
  * Map of tool names to their legacy categories
@@ -153,6 +207,8 @@ exports.toolCategoryMap = {
153
207
  getTableRelationships: ToolCategory.UTILITY,
154
208
  exportTableToCSV: ToolCategory.UTILITY,
155
209
  exportQueryToCSV: ToolCategory.UTILITY,
210
+ safe_export_table: ToolCategory.UTILITY,
211
+ read_changelog: ToolCategory.UTILITY,
156
212
  // Transaction tools
157
213
  beginTransaction: ToolCategory.TRANSACTION,
158
214
  commitTransaction: ToolCategory.TRANSACTION,
@@ -256,6 +312,15 @@ exports.toolCategoryMap = {
256
312
  getConnectionPoolStats: ToolCategory.UTILITY,
257
313
  getDatabaseHealthCheck: ToolCategory.UTILITY,
258
314
  resetPerformanceStats: ToolCategory.UTILITY,
315
+ // Phase 1: AI Enhancement Tools
316
+ buildQueryFromIntent: ToolCategory.READ,
317
+ suggestQueryImprovements: ToolCategory.UTILITY,
318
+ smartSearch: ToolCategory.LIST,
319
+ findSimilarColumns: ToolCategory.LIST,
320
+ discoverDataPatterns: ToolCategory.READ,
321
+ generateDocumentation: ToolCategory.UTILITY,
322
+ generateDataDictionary: ToolCategory.UTILITY,
323
+ generateBusinessGlossary: ToolCategory.UTILITY,
259
324
  };
260
325
  /**
261
326
  * Map of tool names to their documentation categories (New Enhanced System)
@@ -288,6 +353,7 @@ exports.toolDocCategoryMap = {
288
353
  describeConnection: DocCategory.UTILITIES,
289
354
  exportTableToCSV: DocCategory.UTILITIES,
290
355
  exportQueryToCSV: DocCategory.UTILITIES,
356
+ read_changelog: DocCategory.UTILITIES,
291
357
  // Transaction Management
292
358
  beginTransaction: DocCategory.TRANSACTION_MANAGEMENT,
293
359
  commitTransaction: DocCategory.TRANSACTION_MANAGEMENT,
@@ -408,6 +474,15 @@ exports.toolDocCategoryMap = {
408
474
  getSchemaERD: DocCategory.ANALYSIS,
409
475
  getColumnStatistics: DocCategory.ANALYSIS,
410
476
  getSchemaRagContext: DocCategory.ANALYSIS,
477
+ // Phase 1: AI Enhancement
478
+ buildQueryFromIntent: DocCategory.AI_ENHANCEMENT,
479
+ suggestQueryImprovements: DocCategory.AI_ENHANCEMENT,
480
+ smartSearch: DocCategory.AI_ENHANCEMENT,
481
+ findSimilarColumns: DocCategory.AI_ENHANCEMENT,
482
+ discoverDataPatterns: DocCategory.AI_ENHANCEMENT,
483
+ generateDocumentation: DocCategory.AI_ENHANCEMENT,
484
+ generateDataDictionary: DocCategory.AI_ENHANCEMENT,
485
+ generateBusinessGlossary: DocCategory.AI_ENHANCEMENT,
411
486
  };
412
487
  /**
413
488
  * Mapping between legacy categories and documentation categories
@@ -518,6 +593,9 @@ class FeatureConfig {
518
593
  const parsed = this.parseConfig(mergedPermissions, mergedCategories);
519
594
  this.enabledLegacyCategories = parsed.legacy;
520
595
  this.enabledDocCategories = parsed.doc;
596
+ // Initialize Allow/Deny Lists
597
+ this.allowedTools = new Set(this.activePreset?.allowedTools || []);
598
+ this.deniedTools = new Set(this.activePreset?.deniedTools || []);
521
599
  }
522
600
  /**
523
601
  * Normalize and merge preset + user-supplied configuration lists
@@ -576,6 +654,9 @@ class FeatureConfig {
576
654
  docCats.forEach((dc) => docSet.add(dc));
577
655
  });
578
656
  }
657
+ // Re-initialize Allow/Deny Lists if preset changed
658
+ this.allowedTools = new Set(this.activePreset?.allowedTools || []);
659
+ this.deniedTools = new Set(this.activePreset?.deniedTools || []);
579
660
  return {
580
661
  legacy: legacySet,
581
662
  doc: docSet,
@@ -632,6 +713,15 @@ class FeatureConfig {
632
713
  console.warn(`Unknown tool: ${toolName}`);
633
714
  return false;
634
715
  }
716
+ // Layer 0: Check explicit Deny/Allow lists
717
+ // Deny takes precedence
718
+ if (this.deniedTools.has(toolName)) {
719
+ return false;
720
+ }
721
+ // Allow overrides other checks
722
+ if (this.allowedTools.has(toolName)) {
723
+ return true;
724
+ }
635
725
  // Layer 1: Check permission (legacy category)
636
726
  const hasPermission = legacyCategory
637
727
  ? this.enabledLegacyCategories.has(legacyCategory)
@@ -658,6 +748,9 @@ class FeatureConfig {
658
748
  if (!docCategory && !legacyCategory) {
659
749
  return `Unknown tool '${toolName}'. This tool is not recognized by the MCP server.`;
660
750
  }
751
+ if (this.deniedTools.has(toolName)) {
752
+ return `Permission denied: Tool '${toolName}' is explicitly denied by the current profile ('${this.presetName}').`;
753
+ }
661
754
  const isAllEnabled = !this.originalPermissionsString.trim() &&
662
755
  !this.originalCategoriesString.trim();
663
756
  if (isAllEnabled) {
package/dist/index.d.ts CHANGED
@@ -25,6 +25,9 @@ export declare class MySQLMCP {
25
25
  private analysisTools;
26
26
  private aiTools;
27
27
  private macroTools;
28
+ private intelligentQueryTools;
29
+ private smartDiscoveryTools;
30
+ private documentationGeneratorTools;
28
31
  private security;
29
32
  private featureConfig;
30
33
  constructor(permissionsConfig?: string, categoriesConfig?: string, presetName?: string);
@@ -190,6 +193,14 @@ export declare class MySQLMCP {
190
193
  data?: any;
191
194
  error?: string;
192
195
  }>;
196
+ readChangelog(params?: {
197
+ version?: string;
198
+ limit?: number;
199
+ }): Promise<{
200
+ status: string;
201
+ data?: any;
202
+ error?: string;
203
+ }>;
193
204
  beginTransaction(params?: {
194
205
  transactionId?: string;
195
206
  }): Promise<import("./tools/transactionTools").TransactionResult | {
@@ -1167,5 +1178,227 @@ export declare class MySQLMCP {
1167
1178
  message?: string;
1168
1179
  error?: string;
1169
1180
  }>;
1181
+ buildQueryFromIntent(params: {
1182
+ natural_language: string;
1183
+ context?: "analytics" | "reporting" | "data_entry" | "schema_exploration";
1184
+ max_complexity?: "simple" | "medium" | "complex";
1185
+ safety_level?: "strict" | "moderate" | "permissive";
1186
+ database?: string;
1187
+ }): Promise<{
1188
+ status: string;
1189
+ data?: {
1190
+ generated_sql: string;
1191
+ explanation: string;
1192
+ tables_involved: string[];
1193
+ columns_involved: string[];
1194
+ estimated_complexity: string;
1195
+ safety_notes: string[];
1196
+ optimization_hints: string[];
1197
+ alternatives?: string[];
1198
+ };
1199
+ error?: string;
1200
+ }>;
1201
+ suggestQueryImprovements(params: {
1202
+ query: string;
1203
+ optimization_goal?: "speed" | "memory" | "readability";
1204
+ database?: string;
1205
+ }): Promise<{
1206
+ status: string;
1207
+ data?: {
1208
+ original_query: string;
1209
+ suggestions: Array<{
1210
+ type: string;
1211
+ description: string;
1212
+ improved_query?: string;
1213
+ }>;
1214
+ estimated_improvement: string;
1215
+ };
1216
+ error?: string;
1217
+ }>;
1218
+ smartSearch(params: {
1219
+ search_term: string;
1220
+ search_type?: "column" | "table" | "data_pattern" | "relationship" | "all";
1221
+ similarity_threshold?: number;
1222
+ include_sample_data?: boolean;
1223
+ max_results?: number;
1224
+ database?: string;
1225
+ }): Promise<{
1226
+ status: string;
1227
+ data?: {
1228
+ search_term: string;
1229
+ search_type: string;
1230
+ results: {
1231
+ tables: Array<{
1232
+ name: string;
1233
+ relevance_score: number;
1234
+ match_reason: string;
1235
+ column_count: number;
1236
+ row_estimate: number;
1237
+ matching_columns?: string[];
1238
+ }>;
1239
+ columns: Array<{
1240
+ table_name: string;
1241
+ column_name: string;
1242
+ data_type: string;
1243
+ relevance_score: number;
1244
+ match_reason: string;
1245
+ sample_values?: any[];
1246
+ }>;
1247
+ data_patterns: Array<{
1248
+ table_name: string;
1249
+ column_name: string;
1250
+ pattern_type: string;
1251
+ description: string;
1252
+ sample_matches?: any[];
1253
+ }>;
1254
+ relationships: Array<{
1255
+ from_table: string;
1256
+ from_column: string;
1257
+ to_table: string;
1258
+ to_column: string;
1259
+ relationship_type: string;
1260
+ confidence: number;
1261
+ }>;
1262
+ };
1263
+ total_matches: number;
1264
+ search_time_ms: number;
1265
+ };
1266
+ error?: string;
1267
+ }>;
1268
+ findSimilarColumns(params: {
1269
+ column_name?: string;
1270
+ table_name?: string;
1271
+ include_data_comparison?: boolean;
1272
+ max_results?: number;
1273
+ database?: string;
1274
+ }): Promise<{
1275
+ status: string;
1276
+ data?: {
1277
+ reference_column?: {
1278
+ table: string;
1279
+ column: string;
1280
+ data_type: string;
1281
+ };
1282
+ similar_columns: Array<{
1283
+ table_name: string;
1284
+ column_name: string;
1285
+ data_type: string;
1286
+ similarity_score: number;
1287
+ similarity_type: string;
1288
+ data_overlap_percentage?: number;
1289
+ }>;
1290
+ potential_joins: Array<{
1291
+ table1: string;
1292
+ column1: string;
1293
+ table2: string;
1294
+ column2: string;
1295
+ confidence: number;
1296
+ reason: string;
1297
+ }>;
1298
+ };
1299
+ error?: string;
1300
+ }>;
1301
+ discoverDataPatterns(params: {
1302
+ table_name: string;
1303
+ pattern_types?: Array<"unique" | "null" | "duplicate" | "format" | "range">;
1304
+ max_columns?: number;
1305
+ database?: string;
1306
+ }): Promise<{
1307
+ status: string;
1308
+ data?: {
1309
+ table_name: string;
1310
+ patterns: Array<{
1311
+ column_name: string;
1312
+ pattern_type: string;
1313
+ description: string;
1314
+ metrics?: Record<string, any>;
1315
+ recommendations?: string[];
1316
+ }>;
1317
+ summary: {
1318
+ columns_analyzed: number;
1319
+ patterns_found: number;
1320
+ data_quality_score: number;
1321
+ };
1322
+ };
1323
+ error?: string;
1324
+ }>;
1325
+ generateDocumentation(params: {
1326
+ scope?: "database" | "table" | "column" | "relationship";
1327
+ table_name?: string;
1328
+ include_business_glossary?: boolean;
1329
+ format?: "markdown" | "html" | "json";
1330
+ include_examples?: boolean;
1331
+ include_statistics?: boolean;
1332
+ database?: string;
1333
+ }): Promise<{
1334
+ status: string;
1335
+ data?: {
1336
+ format: string;
1337
+ scope: string;
1338
+ content: string;
1339
+ metadata: {
1340
+ generated_at: string;
1341
+ database: string;
1342
+ tables_documented: number;
1343
+ columns_documented: number;
1344
+ };
1345
+ };
1346
+ error?: string;
1347
+ }>;
1348
+ generateDataDictionary(params: {
1349
+ table_name: string;
1350
+ include_sample_values?: boolean;
1351
+ include_constraints?: boolean;
1352
+ database?: string;
1353
+ }): Promise<{
1354
+ status: string;
1355
+ data?: {
1356
+ table_name: string;
1357
+ description: string;
1358
+ columns: Array<{
1359
+ name: string;
1360
+ data_type: string;
1361
+ description: string;
1362
+ constraints: string[];
1363
+ is_nullable: boolean;
1364
+ default_value: string | null;
1365
+ sample_values?: any[];
1366
+ business_term?: string;
1367
+ }>;
1368
+ primary_key: string[];
1369
+ foreign_keys: Array<{
1370
+ column: string;
1371
+ references_table: string;
1372
+ references_column: string;
1373
+ }>;
1374
+ indexes: Array<{
1375
+ name: string;
1376
+ columns: string[];
1377
+ is_unique: boolean;
1378
+ }>;
1379
+ };
1380
+ error?: string;
1381
+ }>;
1382
+ generateBusinessGlossary(params: {
1383
+ include_descriptions?: boolean;
1384
+ group_by?: "table" | "category" | "alphabetical";
1385
+ database?: string;
1386
+ }): Promise<{
1387
+ status: string;
1388
+ data?: {
1389
+ glossary: Array<{
1390
+ term: string;
1391
+ technical_name: string;
1392
+ source_table: string;
1393
+ data_type: string;
1394
+ description: string;
1395
+ category: string;
1396
+ related_terms?: string[];
1397
+ }>;
1398
+ categories: string[];
1399
+ total_terms: number;
1400
+ };
1401
+ error?: string;
1402
+ }>;
1170
1403
  }
1171
1404
  export default MySQLMCP;
package/dist/index.js CHANGED
@@ -26,6 +26,9 @@ const performanceTools_1 = require("./tools/performanceTools");
26
26
  const analysisTools_1 = require("./tools/analysisTools");
27
27
  const aiTools_1 = require("./tools/aiTools");
28
28
  const macroTools_1 = require("./tools/macroTools");
29
+ const intelligentQueryTools_1 = require("./tools/intelligentQueryTools");
30
+ const smartDiscoveryTools_1 = require("./tools/smartDiscoveryTools");
31
+ const documentationGeneratorTools_1 = require("./tools/documentationGeneratorTools");
29
32
  const securityLayer_1 = __importDefault(require("./security/securityLayer"));
30
33
  const connection_1 = __importDefault(require("./db/connection"));
31
34
  const featureConfig_1 = require("./config/featureConfig");
@@ -60,6 +63,9 @@ class MySQLMCP {
60
63
  this.analysisTools = new analysisTools_1.AnalysisTools(this.security);
61
64
  this.aiTools = new aiTools_1.AiTools(this.security);
62
65
  this.macroTools = new macroTools_1.MacroTools(this.security);
66
+ this.intelligentQueryTools = new intelligentQueryTools_1.IntelligentQueryTools(this.security);
67
+ this.smartDiscoveryTools = new smartDiscoveryTools_1.SmartDiscoveryTools(this.security);
68
+ this.documentationGeneratorTools = new documentationGeneratorTools_1.DocumentationGeneratorTools(this.security);
63
69
  }
64
70
  // Helper method to check if tool is enabled
65
71
  checkToolEnabled(toolName) {
@@ -234,6 +240,13 @@ class MySQLMCP {
234
240
  }
235
241
  return await this.utilityTools.getTableRelationships(params);
236
242
  }
243
+ async readChangelog(params) {
244
+ const check = this.checkToolEnabled("read_changelog");
245
+ if (!check.enabled) {
246
+ return { status: "error", error: check.error };
247
+ }
248
+ return await this.utilityTools.readChangelog(params);
249
+ }
237
250
  // Transaction Tools
238
251
  async beginTransaction(params) {
239
252
  const check = this.checkToolEnabled("beginTransaction");
@@ -1061,6 +1074,60 @@ class MySQLMCP {
1061
1074
  return { status: "error", error: check.error };
1062
1075
  return await this.performanceTools.resetPerformanceStats();
1063
1076
  }
1077
+ // ==========================================
1078
+ // PHASE 1: AI Enhancement Tools
1079
+ // ==========================================
1080
+ // Intelligent Query Assistant
1081
+ async buildQueryFromIntent(params) {
1082
+ const check = this.checkToolEnabled("buildQueryFromIntent");
1083
+ if (!check.enabled)
1084
+ return { status: "error", error: check.error };
1085
+ return await this.intelligentQueryTools.buildQueryFromIntent(params);
1086
+ }
1087
+ async suggestQueryImprovements(params) {
1088
+ const check = this.checkToolEnabled("suggestQueryImprovements");
1089
+ if (!check.enabled)
1090
+ return { status: "error", error: check.error };
1091
+ return await this.intelligentQueryTools.suggestQueryImprovements(params);
1092
+ }
1093
+ // Smart Data Discovery
1094
+ async smartSearch(params) {
1095
+ const check = this.checkToolEnabled("smartSearch");
1096
+ if (!check.enabled)
1097
+ return { status: "error", error: check.error };
1098
+ return await this.smartDiscoveryTools.smartSearch(params);
1099
+ }
1100
+ async findSimilarColumns(params) {
1101
+ const check = this.checkToolEnabled("findSimilarColumns");
1102
+ if (!check.enabled)
1103
+ return { status: "error", error: check.error };
1104
+ return await this.smartDiscoveryTools.findSimilarColumns(params);
1105
+ }
1106
+ async discoverDataPatterns(params) {
1107
+ const check = this.checkToolEnabled("discoverDataPatterns");
1108
+ if (!check.enabled)
1109
+ return { status: "error", error: check.error };
1110
+ return await this.smartDiscoveryTools.discoverDataPatterns(params);
1111
+ }
1112
+ // Documentation Generator
1113
+ async generateDocumentation(params) {
1114
+ const check = this.checkToolEnabled("generateDocumentation");
1115
+ if (!check.enabled)
1116
+ return { status: "error", error: check.error };
1117
+ return await this.documentationGeneratorTools.generateDocumentation(params);
1118
+ }
1119
+ async generateDataDictionary(params) {
1120
+ const check = this.checkToolEnabled("generateDataDictionary");
1121
+ if (!check.enabled)
1122
+ return { status: "error", error: check.error };
1123
+ return await this.documentationGeneratorTools.generateDataDictionary(params);
1124
+ }
1125
+ async generateBusinessGlossary(params) {
1126
+ const check = this.checkToolEnabled("generateBusinessGlossary");
1127
+ if (!check.enabled)
1128
+ return { status: "error", error: check.error };
1129
+ return await this.documentationGeneratorTools.generateBusinessGlossaryReport(params);
1130
+ }
1064
1131
  }
1065
1132
  exports.MySQLMCP = MySQLMCP;
1066
1133
  exports.default = MySQLMCP;