@berthojoris/mcp-mysql-server 1.10.3 → 1.10.5

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.
Files changed (43) hide show
  1. package/CHANGELOG.md +25 -7
  2. package/DOCUMENTATIONS.md +2 -2
  3. package/dist/index.d.ts +0 -99
  4. package/dist/mcp-server.js +0 -21
  5. package/dist/tools/backupRestoreTools.d.ts +1 -6
  6. package/dist/tools/backupRestoreTools.js +99 -97
  7. package/dist/tools/constraintTools.d.ts +4 -11
  8. package/dist/tools/constraintTools.js +114 -115
  9. package/dist/tools/crudTools.d.ts +2 -6
  10. package/dist/tools/crudTools.js +186 -189
  11. package/dist/tools/dataExportTools.d.ts +0 -7
  12. package/dist/tools/dataExportTools.js +0 -15
  13. package/dist/tools/databaseTools.d.ts +1 -4
  14. package/dist/tools/databaseTools.js +29 -33
  15. package/dist/tools/ddlTools.d.ts +1 -5
  16. package/dist/tools/ddlTools.js +68 -53
  17. package/dist/tools/functionTools.d.ts +3 -9
  18. package/dist/tools/functionTools.js +111 -104
  19. package/dist/tools/indexTools.d.ts +3 -8
  20. package/dist/tools/indexTools.js +99 -95
  21. package/dist/tools/maintenanceTools.d.ts +2 -10
  22. package/dist/tools/maintenanceTools.js +66 -80
  23. package/dist/tools/migrationTools.d.ts +0 -5
  24. package/dist/tools/migrationTools.js +56 -24
  25. package/dist/tools/performanceTools.d.ts +1 -11
  26. package/dist/tools/performanceTools.js +278 -267
  27. package/dist/tools/processTools.d.ts +4 -13
  28. package/dist/tools/processTools.js +78 -80
  29. package/dist/tools/queryTools.d.ts +0 -2
  30. package/dist/tools/queryTools.js +0 -4
  31. package/dist/tools/schemaVersioningTools.d.ts +0 -9
  32. package/dist/tools/schemaVersioningTools.js +167 -166
  33. package/dist/tools/storedProcedureTools.d.ts +2 -4
  34. package/dist/tools/storedProcedureTools.js +143 -134
  35. package/dist/tools/transactionTools.d.ts +2 -3
  36. package/dist/tools/transactionTools.js +28 -29
  37. package/dist/tools/triggerTools.d.ts +3 -8
  38. package/dist/tools/triggerTools.js +98 -85
  39. package/dist/tools/utilityTools.d.ts +0 -1
  40. package/dist/tools/utilityTools.js +0 -2
  41. package/dist/tools/viewTools.d.ts +7 -13
  42. package/dist/tools/viewTools.js +100 -93
  43. package/package.json +1 -1
@@ -19,26 +19,26 @@ class IndexTools {
19
19
  if (!connectedDatabase) {
20
20
  return {
21
21
  valid: false,
22
- database: '',
23
- error: 'No database specified in connection string. Cannot access any database.'
22
+ database: "",
23
+ error: "No database specified in connection string. Cannot access any database.",
24
24
  };
25
25
  }
26
26
  if (!requestedDatabase) {
27
27
  return {
28
28
  valid: true,
29
- database: connectedDatabase
29
+ database: connectedDatabase,
30
30
  };
31
31
  }
32
32
  if (requestedDatabase !== connectedDatabase) {
33
33
  return {
34
34
  valid: false,
35
- database: '',
36
- error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed.`
35
+ database: "",
36
+ error: `Access denied. You can only access the connected database '${connectedDatabase}'. Requested database '${requestedDatabase}' is not allowed.`,
37
37
  };
38
38
  }
39
39
  return {
40
40
  valid: true,
41
- database: connectedDatabase
41
+ database: connectedDatabase,
42
42
  };
43
43
  }
44
44
  /**
@@ -48,14 +48,17 @@ class IndexTools {
48
48
  try {
49
49
  const dbValidation = this.validateDatabaseAccess(params?.database);
50
50
  if (!dbValidation.valid) {
51
- return { status: 'error', error: dbValidation.error };
51
+ return { status: "error", error: dbValidation.error };
52
52
  }
53
53
  const { table_name } = params;
54
54
  const database = dbValidation.database;
55
55
  // Validate table name
56
56
  const identifierValidation = this.security.validateIdentifier(table_name);
57
57
  if (!identifierValidation.valid) {
58
- return { status: 'error', error: identifierValidation.error || 'Invalid table name' };
58
+ return {
59
+ status: "error",
60
+ error: identifierValidation.error || "Invalid table name",
61
+ };
59
62
  }
60
63
  const query = `SHOW INDEX FROM \`${database}\`.\`${table_name}\``;
61
64
  const results = await this.db.query(query);
@@ -68,13 +71,13 @@ class IndexTools {
68
71
  index_name: indexName,
69
72
  table_name: row.Table,
70
73
  is_unique: !row.Non_unique,
71
- is_primary: indexName === 'PRIMARY',
74
+ is_primary: indexName === "PRIMARY",
72
75
  index_type: row.Index_type,
73
76
  columns: [],
74
77
  cardinality: row.Cardinality,
75
- nullable: row.Null === 'YES',
78
+ nullable: row.Null === "YES",
76
79
  comment: row.Index_comment || null,
77
- visible: row.Visible === 'YES'
80
+ visible: row.Visible === "YES",
78
81
  });
79
82
  }
80
83
  indexMap.get(indexName).columns.push({
@@ -82,20 +85,18 @@ class IndexTools {
82
85
  seq_in_index: row.Seq_in_index,
83
86
  collation: row.Collation,
84
87
  sub_part: row.Sub_part,
85
- expression: row.Expression || null
88
+ expression: row.Expression || null,
86
89
  });
87
90
  }
88
91
  return {
89
- status: 'success',
92
+ status: "success",
90
93
  data: Array.from(indexMap.values()),
91
- queryLog: this.db.getFormattedQueryLogs(1)
92
94
  };
93
95
  }
94
96
  catch (error) {
95
97
  return {
96
- status: 'error',
98
+ status: "error",
97
99
  error: error.message,
98
- queryLog: this.db.getFormattedQueryLogs(1)
99
100
  };
100
101
  }
101
102
  }
@@ -106,42 +107,45 @@ class IndexTools {
106
107
  try {
107
108
  const dbValidation = this.validateDatabaseAccess(params?.database);
108
109
  if (!dbValidation.valid) {
109
- return { status: 'error', error: dbValidation.error };
110
+ return { status: "error", error: dbValidation.error };
110
111
  }
111
112
  const { table_name, index_name } = params;
112
113
  const database = dbValidation.database;
113
114
  // Validate names
114
115
  if (!this.security.validateIdentifier(table_name).valid) {
115
- return { status: 'error', error: 'Invalid table name' };
116
+ return { status: "error", error: "Invalid table name" };
116
117
  }
117
118
  if (!this.security.validateIdentifier(index_name).valid) {
118
- return { status: 'error', error: 'Invalid index name' };
119
+ return { status: "error", error: "Invalid index name" };
119
120
  }
120
- const query = `
121
- SELECT
122
- s.INDEX_NAME as index_name,
123
- s.TABLE_NAME as table_name,
124
- s.NON_UNIQUE as non_unique,
125
- s.SEQ_IN_INDEX as seq_in_index,
126
- s.COLUMN_NAME as column_name,
127
- s.COLLATION as collation,
128
- s.CARDINALITY as cardinality,
129
- s.SUB_PART as sub_part,
130
- s.PACKED as packed,
131
- s.NULLABLE as nullable,
132
- s.INDEX_TYPE as index_type,
133
- s.COMMENT as comment,
134
- s.INDEX_COMMENT as index_comment
135
- FROM INFORMATION_SCHEMA.STATISTICS s
136
- WHERE s.TABLE_SCHEMA = ? AND s.TABLE_NAME = ? AND s.INDEX_NAME = ?
137
- ORDER BY s.SEQ_IN_INDEX
121
+ const query = `
122
+ SELECT
123
+ s.INDEX_NAME as index_name,
124
+ s.TABLE_NAME as table_name,
125
+ s.NON_UNIQUE as non_unique,
126
+ s.SEQ_IN_INDEX as seq_in_index,
127
+ s.COLUMN_NAME as column_name,
128
+ s.COLLATION as collation,
129
+ s.CARDINALITY as cardinality,
130
+ s.SUB_PART as sub_part,
131
+ s.PACKED as packed,
132
+ s.NULLABLE as nullable,
133
+ s.INDEX_TYPE as index_type,
134
+ s.COMMENT as comment,
135
+ s.INDEX_COMMENT as index_comment
136
+ FROM INFORMATION_SCHEMA.STATISTICS s
137
+ WHERE s.TABLE_SCHEMA = ? AND s.TABLE_NAME = ? AND s.INDEX_NAME = ?
138
+ ORDER BY s.SEQ_IN_INDEX
138
139
  `;
139
- const results = await this.db.query(query, [database, table_name, index_name]);
140
+ const results = await this.db.query(query, [
141
+ database,
142
+ table_name,
143
+ index_name,
144
+ ]);
140
145
  if (results.length === 0) {
141
146
  return {
142
- status: 'error',
147
+ status: "error",
143
148
  error: `Index '${index_name}' not found on table '${table_name}'`,
144
- queryLog: this.db.getFormattedQueryLogs(1)
145
149
  };
146
150
  }
147
151
  // Compile index info
@@ -150,29 +154,27 @@ class IndexTools {
150
154
  index_name: firstRow.index_name,
151
155
  table_name: firstRow.table_name,
152
156
  is_unique: !firstRow.non_unique,
153
- is_primary: firstRow.index_name === 'PRIMARY',
157
+ is_primary: firstRow.index_name === "PRIMARY",
154
158
  index_type: firstRow.index_type,
155
159
  comment: firstRow.index_comment || null,
156
- columns: results.map(r => ({
160
+ columns: results.map((r) => ({
157
161
  column_name: r.column_name,
158
162
  seq_in_index: r.seq_in_index,
159
163
  collation: r.collation,
160
164
  cardinality: r.cardinality,
161
165
  sub_part: r.sub_part,
162
- nullable: r.nullable === 'YES'
163
- }))
166
+ nullable: r.nullable === "YES",
167
+ })),
164
168
  };
165
169
  return {
166
- status: 'success',
170
+ status: "success",
167
171
  data: indexInfo,
168
- queryLog: this.db.getFormattedQueryLogs(1)
169
172
  };
170
173
  }
171
174
  catch (error) {
172
175
  return {
173
- status: 'error',
176
+ status: "error",
174
177
  error: error.message,
175
- queryLog: this.db.getFormattedQueryLogs(1)
176
178
  };
177
179
  }
178
180
  }
@@ -183,20 +185,21 @@ class IndexTools {
183
185
  try {
184
186
  const dbValidation = this.validateDatabaseAccess(params?.database);
185
187
  if (!dbValidation.valid) {
186
- return { status: 'error', error: dbValidation.error };
188
+ return { status: "error", error: dbValidation.error };
187
189
  }
188
- const { table_name, index_name, columns, unique = false, index_type, comment } = params;
190
+ const { table_name, index_name, columns, unique = false, index_type, comment, } = params;
189
191
  const database = dbValidation.database;
190
192
  // Validate names
191
193
  if (!this.security.validateIdentifier(table_name).valid) {
192
- return { status: 'error', error: 'Invalid table name' };
194
+ return { status: "error", error: "Invalid table name" };
193
195
  }
194
196
  if (!this.security.validateIdentifier(index_name).valid) {
195
- return { status: 'error', error: 'Invalid index name' };
197
+ return { status: "error", error: "Invalid index name" };
196
198
  }
197
199
  // Build column list
198
- const columnList = columns.map(col => {
199
- if (typeof col === 'string') {
200
+ const columnList = columns
201
+ .map((col) => {
202
+ if (typeof col === "string") {
200
203
  if (!this.security.validateIdentifier(col).valid) {
201
204
  throw new Error(`Invalid column name: ${col}`);
202
205
  }
@@ -215,20 +218,21 @@ class IndexTools {
215
218
  }
216
219
  return colDef;
217
220
  }
218
- }).join(', ');
221
+ })
222
+ .join(", ");
219
223
  // Build CREATE INDEX statement
220
- let createQuery = 'CREATE ';
221
- if (index_type === 'FULLTEXT') {
222
- createQuery += 'FULLTEXT ';
224
+ let createQuery = "CREATE ";
225
+ if (index_type === "FULLTEXT") {
226
+ createQuery += "FULLTEXT ";
223
227
  }
224
- else if (index_type === 'SPATIAL') {
225
- createQuery += 'SPATIAL ';
228
+ else if (index_type === "SPATIAL") {
229
+ createQuery += "SPATIAL ";
226
230
  }
227
231
  else if (unique) {
228
- createQuery += 'UNIQUE ';
232
+ createQuery += "UNIQUE ";
229
233
  }
230
234
  createQuery += `INDEX \`${index_name}\` ON \`${database}\`.\`${table_name}\` (${columnList})`;
231
- if (index_type && index_type !== 'FULLTEXT' && index_type !== 'SPATIAL') {
235
+ if (index_type && index_type !== "FULLTEXT" && index_type !== "SPATIAL") {
232
236
  createQuery += ` USING ${index_type}`;
233
237
  }
234
238
  if (comment) {
@@ -236,21 +240,19 @@ class IndexTools {
236
240
  }
237
241
  await this.db.query(createQuery);
238
242
  return {
239
- status: 'success',
243
+ status: "success",
240
244
  data: {
241
245
  message: `Index '${index_name}' created successfully on table '${table_name}'`,
242
246
  index_name,
243
247
  table_name,
244
- database
248
+ database,
245
249
  },
246
- queryLog: this.db.getFormattedQueryLogs(1)
247
250
  };
248
251
  }
249
252
  catch (error) {
250
253
  return {
251
- status: 'error',
254
+ status: "error",
252
255
  error: error.message,
253
- queryLog: this.db.getFormattedQueryLogs(1)
254
256
  };
255
257
  }
256
258
  }
@@ -261,34 +263,35 @@ class IndexTools {
261
263
  try {
262
264
  const dbValidation = this.validateDatabaseAccess(params?.database);
263
265
  if (!dbValidation.valid) {
264
- return { status: 'error', error: dbValidation.error };
266
+ return { status: "error", error: dbValidation.error };
265
267
  }
266
268
  const { table_name, index_name } = params;
267
269
  const database = dbValidation.database;
268
270
  // Validate names
269
271
  if (!this.security.validateIdentifier(table_name).valid) {
270
- return { status: 'error', error: 'Invalid table name' };
272
+ return { status: "error", error: "Invalid table name" };
271
273
  }
272
274
  if (!this.security.validateIdentifier(index_name).valid) {
273
- return { status: 'error', error: 'Invalid index name' };
275
+ return { status: "error", error: "Invalid index name" };
274
276
  }
275
277
  // Cannot drop PRIMARY KEY with DROP INDEX
276
- if (index_name.toUpperCase() === 'PRIMARY') {
277
- return { status: 'error', error: 'Cannot drop PRIMARY KEY using drop_index. Use ALTER TABLE DROP PRIMARY KEY instead.' };
278
+ if (index_name.toUpperCase() === "PRIMARY") {
279
+ return {
280
+ status: "error",
281
+ error: "Cannot drop PRIMARY KEY using drop_index. Use ALTER TABLE DROP PRIMARY KEY instead.",
282
+ };
278
283
  }
279
284
  const dropQuery = `DROP INDEX \`${index_name}\` ON \`${database}\`.\`${table_name}\``;
280
285
  await this.db.query(dropQuery);
281
286
  return {
282
- status: 'success',
287
+ status: "success",
283
288
  message: `Index '${index_name}' dropped successfully from table '${table_name}'`,
284
- queryLog: this.db.getFormattedQueryLogs(1)
285
289
  };
286
290
  }
287
291
  catch (error) {
288
292
  return {
289
- status: 'error',
293
+ status: "error",
290
294
  error: error.message,
291
- queryLog: this.db.getFormattedQueryLogs(1)
292
295
  };
293
296
  }
294
297
  }
@@ -299,45 +302,46 @@ class IndexTools {
299
302
  try {
300
303
  const dbValidation = this.validateDatabaseAccess(params?.database);
301
304
  if (!dbValidation.valid) {
302
- return { status: 'error', error: dbValidation.error };
305
+ return { status: "error", error: dbValidation.error };
303
306
  }
304
307
  const { table_name } = params;
305
308
  const database = dbValidation.database;
306
309
  // Validate table name
307
310
  if (!this.security.validateIdentifier(table_name).valid) {
308
- return { status: 'error', error: 'Invalid table name' };
311
+ return { status: "error", error: "Invalid table name" };
309
312
  }
310
313
  // Run ANALYZE TABLE to update index statistics
311
314
  const analyzeQuery = `ANALYZE TABLE \`${database}\`.\`${table_name}\``;
312
315
  const analyzeResult = await this.db.query(analyzeQuery);
313
316
  // Get updated index statistics
314
- const statsQuery = `
315
- SELECT
316
- INDEX_NAME as index_name,
317
- COLUMN_NAME as column_name,
318
- SEQ_IN_INDEX as seq_in_index,
319
- CARDINALITY as cardinality,
320
- INDEX_TYPE as index_type,
321
- NULLABLE as nullable
322
- FROM INFORMATION_SCHEMA.STATISTICS
323
- WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
324
- ORDER BY INDEX_NAME, SEQ_IN_INDEX
317
+ const statsQuery = `
318
+ SELECT
319
+ INDEX_NAME as index_name,
320
+ COLUMN_NAME as column_name,
321
+ SEQ_IN_INDEX as seq_in_index,
322
+ CARDINALITY as cardinality,
323
+ INDEX_TYPE as index_type,
324
+ NULLABLE as nullable
325
+ FROM INFORMATION_SCHEMA.STATISTICS
326
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
327
+ ORDER BY INDEX_NAME, SEQ_IN_INDEX
325
328
  `;
326
- const stats = await this.db.query(statsQuery, [database, table_name]);
329
+ const stats = await this.db.query(statsQuery, [
330
+ database,
331
+ table_name,
332
+ ]);
327
333
  return {
328
- status: 'success',
334
+ status: "success",
329
335
  data: {
330
336
  analyze_result: analyzeResult[0],
331
- index_statistics: stats
337
+ index_statistics: stats,
332
338
  },
333
- queryLog: this.db.getFormattedQueryLogs(2)
334
339
  };
335
340
  }
336
341
  catch (error) {
337
342
  return {
338
- status: 'error',
343
+ status: "error",
339
344
  error: error.message,
340
- queryLog: this.db.getFormattedQueryLogs(2)
341
345
  };
342
346
  }
343
347
  }
@@ -1,4 +1,4 @@
1
- import { SecurityLayer } from '../security/securityLayer';
1
+ import { SecurityLayer } from "../security/securityLayer";
2
2
  export declare class MaintenanceTools {
3
3
  private db;
4
4
  private security;
@@ -17,7 +17,6 @@ export declare class MaintenanceTools {
17
17
  status: string;
18
18
  data?: any;
19
19
  error?: string;
20
- queryLog?: string;
21
20
  }>;
22
21
  /**
23
22
  * Optimize table to reclaim unused space and defragment
@@ -29,20 +28,18 @@ export declare class MaintenanceTools {
29
28
  status: string;
30
29
  data?: any;
31
30
  error?: string;
32
- queryLog?: string;
33
31
  }>;
34
32
  /**
35
33
  * Check table for errors
36
34
  */
37
35
  checkTable(params: {
38
36
  table_name: string;
39
- check_type?: 'QUICK' | 'FAST' | 'MEDIUM' | 'EXTENDED' | 'CHANGED';
37
+ check_type?: "QUICK" | "FAST" | "MEDIUM" | "EXTENDED" | "CHANGED";
40
38
  database?: string;
41
39
  }): Promise<{
42
40
  status: string;
43
41
  data?: any;
44
42
  error?: string;
45
- queryLog?: string;
46
43
  }>;
47
44
  /**
48
45
  * Repair table (MyISAM, ARCHIVE, CSV only)
@@ -57,7 +54,6 @@ export declare class MaintenanceTools {
57
54
  status: string;
58
55
  data?: any;
59
56
  error?: string;
60
- queryLog?: string;
61
57
  }>;
62
58
  /**
63
59
  * Truncate table (remove all rows quickly)
@@ -69,7 +65,6 @@ export declare class MaintenanceTools {
69
65
  status: string;
70
66
  message?: string;
71
67
  error?: string;
72
- queryLog?: string;
73
68
  }>;
74
69
  /**
75
70
  * Get table status and statistics
@@ -81,7 +76,6 @@ export declare class MaintenanceTools {
81
76
  status: string;
82
77
  data?: any;
83
78
  error?: string;
84
- queryLog?: string;
85
79
  }>;
86
80
  /**
87
81
  * Flush table (close and reopen)
@@ -94,7 +88,6 @@ export declare class MaintenanceTools {
94
88
  status: string;
95
89
  message?: string;
96
90
  error?: string;
97
- queryLog?: string;
98
91
  }>;
99
92
  /**
100
93
  * Get table size information
@@ -106,6 +99,5 @@ export declare class MaintenanceTools {
106
99
  status: string;
107
100
  data?: any;
108
101
  error?: string;
109
- queryLog?: string;
110
102
  }>;
111
103
  }