@berthojoris/mcp-mysql-server 1.10.2 → 1.10.4

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 (44) hide show
  1. package/CHANGELOG.md +25 -7
  2. package/DOCUMENTATIONS.md +2 -2
  3. package/README.md +1 -1
  4. package/dist/index.d.ts +0 -99
  5. package/dist/mcp-server.js +0 -21
  6. package/dist/tools/backupRestoreTools.d.ts +1 -6
  7. package/dist/tools/backupRestoreTools.js +99 -97
  8. package/dist/tools/constraintTools.d.ts +4 -11
  9. package/dist/tools/constraintTools.js +114 -115
  10. package/dist/tools/crudTools.d.ts +2 -6
  11. package/dist/tools/crudTools.js +186 -189
  12. package/dist/tools/dataExportTools.d.ts +0 -7
  13. package/dist/tools/dataExportTools.js +0 -15
  14. package/dist/tools/databaseTools.d.ts +1 -4
  15. package/dist/tools/databaseTools.js +29 -33
  16. package/dist/tools/ddlTools.d.ts +1 -5
  17. package/dist/tools/ddlTools.js +68 -53
  18. package/dist/tools/functionTools.d.ts +3 -9
  19. package/dist/tools/functionTools.js +111 -104
  20. package/dist/tools/indexTools.d.ts +3 -8
  21. package/dist/tools/indexTools.js +99 -95
  22. package/dist/tools/maintenanceTools.d.ts +2 -10
  23. package/dist/tools/maintenanceTools.js +66 -80
  24. package/dist/tools/migrationTools.d.ts +0 -5
  25. package/dist/tools/migrationTools.js +56 -24
  26. package/dist/tools/performanceTools.d.ts +1 -11
  27. package/dist/tools/performanceTools.js +278 -267
  28. package/dist/tools/processTools.d.ts +4 -13
  29. package/dist/tools/processTools.js +78 -80
  30. package/dist/tools/queryTools.d.ts +0 -2
  31. package/dist/tools/queryTools.js +0 -4
  32. package/dist/tools/schemaVersioningTools.d.ts +0 -9
  33. package/dist/tools/schemaVersioningTools.js +167 -166
  34. package/dist/tools/storedProcedureTools.d.ts +2 -4
  35. package/dist/tools/storedProcedureTools.js +143 -134
  36. package/dist/tools/transactionTools.d.ts +2 -3
  37. package/dist/tools/transactionTools.js +28 -29
  38. package/dist/tools/triggerTools.d.ts +3 -8
  39. package/dist/tools/triggerTools.js +98 -85
  40. package/dist/tools/utilityTools.d.ts +0 -1
  41. package/dist/tools/utilityTools.js +0 -2
  42. package/dist/tools/viewTools.d.ts +7 -13
  43. package/dist/tools/viewTools.js +100 -93
  44. package/package.json +1 -1
@@ -1,4 +1,4 @@
1
- import { SecurityLayer } from '../security/securityLayer';
1
+ import { SecurityLayer } from "../security/securityLayer";
2
2
  export declare class FunctionTools {
3
3
  private db;
4
4
  private security;
@@ -16,7 +16,6 @@ export declare class FunctionTools {
16
16
  status: string;
17
17
  data?: any[];
18
18
  error?: string;
19
- queryLog?: string;
20
19
  }>;
21
20
  /**
22
21
  * Get detailed information about a specific function
@@ -28,7 +27,6 @@ export declare class FunctionTools {
28
27
  status: string;
29
28
  data?: any;
30
29
  error?: string;
31
- queryLog?: string;
32
30
  }>;
33
31
  /**
34
32
  * Create a new function
@@ -42,15 +40,14 @@ export declare class FunctionTools {
42
40
  returns: string;
43
41
  body: string;
44
42
  deterministic?: boolean;
45
- data_access?: 'CONTAINS SQL' | 'NO SQL' | 'READS SQL DATA' | 'MODIFIES SQL DATA';
46
- security?: 'DEFINER' | 'INVOKER';
43
+ data_access?: "CONTAINS SQL" | "NO SQL" | "READS SQL DATA" | "MODIFIES SQL DATA";
44
+ security?: "DEFINER" | "INVOKER";
47
45
  comment?: string;
48
46
  database?: string;
49
47
  }): Promise<{
50
48
  status: string;
51
49
  data?: any;
52
50
  error?: string;
53
- queryLog?: string;
54
51
  }>;
55
52
  /**
56
53
  * Drop a function
@@ -63,7 +60,6 @@ export declare class FunctionTools {
63
60
  status: string;
64
61
  message?: string;
65
62
  error?: string;
66
- queryLog?: string;
67
63
  }>;
68
64
  /**
69
65
  * Show the CREATE statement for a function
@@ -75,7 +71,6 @@ export declare class FunctionTools {
75
71
  status: string;
76
72
  data?: any;
77
73
  error?: string;
78
- queryLog?: string;
79
74
  }>;
80
75
  /**
81
76
  * Execute a function and return its result
@@ -88,6 +83,5 @@ export declare class FunctionTools {
88
83
  status: string;
89
84
  data?: any;
90
85
  error?: string;
91
- queryLog?: string;
92
86
  }>;
93
87
  }
@@ -19,26 +19,26 @@ class FunctionTools {
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,38 +48,36 @@ class FunctionTools {
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 database = dbValidation.database;
54
- const query = `
55
- SELECT
56
- ROUTINE_NAME as function_name,
57
- DATA_TYPE as return_type,
58
- DTD_IDENTIFIER as return_type_full,
59
- ROUTINE_DEFINITION as definition,
60
- IS_DETERMINISTIC as is_deterministic,
61
- SQL_DATA_ACCESS as data_access,
62
- SECURITY_TYPE as security_type,
63
- DEFINER as definer,
64
- CREATED as created,
65
- LAST_ALTERED as last_altered,
66
- ROUTINE_COMMENT as comment
67
- FROM INFORMATION_SCHEMA.ROUTINES
68
- WHERE ROUTINE_SCHEMA = ? AND ROUTINE_TYPE = 'FUNCTION'
69
- ORDER BY ROUTINE_NAME
54
+ const query = `
55
+ SELECT
56
+ ROUTINE_NAME as function_name,
57
+ DATA_TYPE as return_type,
58
+ DTD_IDENTIFIER as return_type_full,
59
+ ROUTINE_DEFINITION as definition,
60
+ IS_DETERMINISTIC as is_deterministic,
61
+ SQL_DATA_ACCESS as data_access,
62
+ SECURITY_TYPE as security_type,
63
+ DEFINER as definer,
64
+ CREATED as created,
65
+ LAST_ALTERED as last_altered,
66
+ ROUTINE_COMMENT as comment
67
+ FROM INFORMATION_SCHEMA.ROUTINES
68
+ WHERE ROUTINE_SCHEMA = ? AND ROUTINE_TYPE = 'FUNCTION'
69
+ ORDER BY ROUTINE_NAME
70
70
  `;
71
71
  const results = await this.db.query(query, [database]);
72
72
  return {
73
- status: 'success',
73
+ status: "success",
74
74
  data: results,
75
- queryLog: this.db.getFormattedQueryLogs(1)
76
75
  };
77
76
  }
78
77
  catch (error) {
79
78
  return {
80
- status: 'error',
79
+ status: "error",
81
80
  error: error.message,
82
- queryLog: this.db.getFormattedQueryLogs(1)
83
81
  };
84
82
  }
85
83
  }
@@ -90,75 +88,75 @@ class FunctionTools {
90
88
  try {
91
89
  const dbValidation = this.validateDatabaseAccess(params?.database);
92
90
  if (!dbValidation.valid) {
93
- return { status: 'error', error: dbValidation.error };
91
+ return { status: "error", error: dbValidation.error };
94
92
  }
95
93
  const { function_name } = params;
96
94
  const database = dbValidation.database;
97
95
  // Validate function name
98
96
  const identifierValidation = this.security.validateIdentifier(function_name);
99
97
  if (!identifierValidation.valid) {
100
- return { status: 'error', error: identifierValidation.error || 'Invalid function name' };
98
+ return {
99
+ status: "error",
100
+ error: identifierValidation.error || "Invalid function name",
101
+ };
101
102
  }
102
103
  // Get function information
103
- const functionQuery = `
104
- SELECT
105
- ROUTINE_NAME as function_name,
106
- DATA_TYPE as return_type,
107
- DTD_IDENTIFIER as return_type_full,
108
- ROUTINE_DEFINITION as definition,
109
- IS_DETERMINISTIC as is_deterministic,
110
- SQL_DATA_ACCESS as data_access,
111
- SECURITY_TYPE as security_type,
112
- DEFINER as definer,
113
- CREATED as created,
114
- LAST_ALTERED as last_altered,
115
- ROUTINE_COMMENT as comment,
116
- SQL_MODE as sql_mode,
117
- CHARACTER_SET_CLIENT as charset,
118
- COLLATION_CONNECTION as collation,
119
- DATABASE_COLLATION as db_collation
120
- FROM INFORMATION_SCHEMA.ROUTINES
121
- WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ? AND ROUTINE_TYPE = 'FUNCTION'
104
+ const functionQuery = `
105
+ SELECT
106
+ ROUTINE_NAME as function_name,
107
+ DATA_TYPE as return_type,
108
+ DTD_IDENTIFIER as return_type_full,
109
+ ROUTINE_DEFINITION as definition,
110
+ IS_DETERMINISTIC as is_deterministic,
111
+ SQL_DATA_ACCESS as data_access,
112
+ SECURITY_TYPE as security_type,
113
+ DEFINER as definer,
114
+ CREATED as created,
115
+ LAST_ALTERED as last_altered,
116
+ ROUTINE_COMMENT as comment,
117
+ SQL_MODE as sql_mode,
118
+ CHARACTER_SET_CLIENT as charset,
119
+ COLLATION_CONNECTION as collation,
120
+ DATABASE_COLLATION as db_collation
121
+ FROM INFORMATION_SCHEMA.ROUTINES
122
+ WHERE ROUTINE_SCHEMA = ? AND ROUTINE_NAME = ? AND ROUTINE_TYPE = 'FUNCTION'
122
123
  `;
123
124
  // Get function parameters
124
- const parametersQuery = `
125
- SELECT
126
- PARAMETER_NAME as name,
127
- DATA_TYPE as data_type,
128
- DTD_IDENTIFIER as data_type_full,
129
- CHARACTER_MAXIMUM_LENGTH as max_length,
130
- NUMERIC_PRECISION as numeric_precision,
131
- NUMERIC_SCALE as numeric_scale,
132
- ORDINAL_POSITION as position
133
- FROM INFORMATION_SCHEMA.PARAMETERS
134
- WHERE SPECIFIC_SCHEMA = ? AND SPECIFIC_NAME = ? AND PARAMETER_MODE IS NOT NULL
135
- ORDER BY ORDINAL_POSITION
125
+ const parametersQuery = `
126
+ SELECT
127
+ PARAMETER_NAME as name,
128
+ DATA_TYPE as data_type,
129
+ DTD_IDENTIFIER as data_type_full,
130
+ CHARACTER_MAXIMUM_LENGTH as max_length,
131
+ NUMERIC_PRECISION as numeric_precision,
132
+ NUMERIC_SCALE as numeric_scale,
133
+ ORDINAL_POSITION as position
134
+ FROM INFORMATION_SCHEMA.PARAMETERS
135
+ WHERE SPECIFIC_SCHEMA = ? AND SPECIFIC_NAME = ? AND PARAMETER_MODE IS NOT NULL
136
+ ORDER BY ORDINAL_POSITION
136
137
  `;
137
138
  const [functionInfo, parameters] = await Promise.all([
138
139
  this.db.query(functionQuery, [database, function_name]),
139
- this.db.query(parametersQuery, [database, function_name])
140
+ this.db.query(parametersQuery, [database, function_name]),
140
141
  ]);
141
142
  if (functionInfo.length === 0) {
142
143
  return {
143
- status: 'error',
144
+ status: "error",
144
145
  error: `Function '${function_name}' not found in database '${database}'`,
145
- queryLog: this.db.getFormattedQueryLogs(2)
146
146
  };
147
147
  }
148
148
  return {
149
- status: 'success',
149
+ status: "success",
150
150
  data: {
151
151
  ...functionInfo[0],
152
- parameters: parameters
152
+ parameters: parameters,
153
153
  },
154
- queryLog: this.db.getFormattedQueryLogs(2)
155
154
  };
156
155
  }
157
156
  catch (error) {
158
157
  return {
159
- status: 'error',
158
+ status: "error",
160
159
  error: error.message,
161
- queryLog: this.db.getFormattedQueryLogs(2)
162
160
  };
163
161
  }
164
162
  }
@@ -169,22 +167,27 @@ class FunctionTools {
169
167
  try {
170
168
  const dbValidation = this.validateDatabaseAccess(params?.database);
171
169
  if (!dbValidation.valid) {
172
- return { status: 'error', error: dbValidation.error };
170
+ return { status: "error", error: dbValidation.error };
173
171
  }
174
- const { function_name, parameters = [], returns, body, deterministic = false, data_access, security, comment } = params;
172
+ const { function_name, parameters = [], returns, body, deterministic = false, data_access, security, comment, } = params;
175
173
  const database = dbValidation.database;
176
174
  // Validate function name
177
175
  const identifierValidation = this.security.validateIdentifier(function_name);
178
176
  if (!identifierValidation.valid) {
179
- return { status: 'error', error: identifierValidation.error || 'Invalid function name' };
177
+ return {
178
+ status: "error",
179
+ error: identifierValidation.error || "Invalid function name",
180
+ };
180
181
  }
181
182
  // Build parameter list
182
- const parameterList = parameters.map(param => {
183
+ const parameterList = parameters
184
+ .map((param) => {
183
185
  if (!this.security.validateIdentifier(param.name).valid) {
184
186
  throw new Error(`Invalid parameter name: ${param.name}`);
185
187
  }
186
188
  return `\`${param.name}\` ${param.data_type}`;
187
- }).join(', ');
189
+ })
190
+ .join(", ");
188
191
  // Build CREATE FUNCTION statement
189
192
  let createQuery = `CREATE FUNCTION \`${database}\`.\`${function_name}\`(${parameterList})\n`;
190
193
  createQuery += `RETURNS ${returns}\n`;
@@ -205,10 +208,11 @@ class FunctionTools {
205
208
  }
206
209
  // Check if body already contains BEGIN/END
207
210
  const trimmedBody = body.trim();
208
- if (trimmedBody.toUpperCase().startsWith('BEGIN') && trimmedBody.toUpperCase().endsWith('END')) {
211
+ if (trimmedBody.toUpperCase().startsWith("BEGIN") &&
212
+ trimmedBody.toUpperCase().endsWith("END")) {
209
213
  createQuery += body;
210
214
  }
211
- else if (trimmedBody.toUpperCase().startsWith('RETURN')) {
215
+ else if (trimmedBody.toUpperCase().startsWith("RETURN")) {
212
216
  // Simple one-liner function
213
217
  createQuery += body;
214
218
  }
@@ -217,20 +221,18 @@ class FunctionTools {
217
221
  }
218
222
  await this.db.query(createQuery);
219
223
  return {
220
- status: 'success',
224
+ status: "success",
221
225
  data: {
222
226
  message: `Function '${function_name}' created successfully`,
223
227
  function_name,
224
- database
228
+ database,
225
229
  },
226
- queryLog: this.db.getFormattedQueryLogs(1)
227
230
  };
228
231
  }
229
232
  catch (error) {
230
233
  return {
231
- status: 'error',
234
+ status: "error",
232
235
  error: error.message,
233
- queryLog: this.db.getFormattedQueryLogs(1)
234
236
  };
235
237
  }
236
238
  }
@@ -241,28 +243,29 @@ class FunctionTools {
241
243
  try {
242
244
  const dbValidation = this.validateDatabaseAccess(params?.database);
243
245
  if (!dbValidation.valid) {
244
- return { status: 'error', error: dbValidation.error };
246
+ return { status: "error", error: dbValidation.error };
245
247
  }
246
248
  const { function_name, if_exists = false } = params;
247
249
  const database = dbValidation.database;
248
250
  // Validate function name
249
251
  const identifierValidation = this.security.validateIdentifier(function_name);
250
252
  if (!identifierValidation.valid) {
251
- return { status: 'error', error: identifierValidation.error || 'Invalid function name' };
253
+ return {
254
+ status: "error",
255
+ error: identifierValidation.error || "Invalid function name",
256
+ };
252
257
  }
253
- const dropQuery = `DROP FUNCTION ${if_exists ? 'IF EXISTS' : ''} \`${database}\`.\`${function_name}\``;
258
+ const dropQuery = `DROP FUNCTION ${if_exists ? "IF EXISTS" : ""} \`${database}\`.\`${function_name}\``;
254
259
  await this.db.query(dropQuery);
255
260
  return {
256
- status: 'success',
261
+ status: "success",
257
262
  message: `Function '${function_name}' dropped successfully`,
258
- queryLog: this.db.getFormattedQueryLogs(1)
259
263
  };
260
264
  }
261
265
  catch (error) {
262
266
  return {
263
- status: 'error',
267
+ status: "error",
264
268
  error: error.message,
265
- queryLog: this.db.getFormattedQueryLogs(1)
266
269
  };
267
270
  }
268
271
  }
@@ -273,35 +276,35 @@ class FunctionTools {
273
276
  try {
274
277
  const dbValidation = this.validateDatabaseAccess(params?.database);
275
278
  if (!dbValidation.valid) {
276
- return { status: 'error', error: dbValidation.error };
279
+ return { status: "error", error: dbValidation.error };
277
280
  }
278
281
  const { function_name } = params;
279
282
  const database = dbValidation.database;
280
283
  // Validate function name
281
284
  const identifierValidation = this.security.validateIdentifier(function_name);
282
285
  if (!identifierValidation.valid) {
283
- return { status: 'error', error: identifierValidation.error || 'Invalid function name' };
286
+ return {
287
+ status: "error",
288
+ error: identifierValidation.error || "Invalid function name",
289
+ };
284
290
  }
285
291
  const query = `SHOW CREATE FUNCTION \`${database}\`.\`${function_name}\``;
286
292
  const results = await this.db.query(query);
287
293
  if (results.length === 0) {
288
294
  return {
289
- status: 'error',
295
+ status: "error",
290
296
  error: `Function '${function_name}' not found`,
291
- queryLog: this.db.getFormattedQueryLogs(1)
292
297
  };
293
298
  }
294
299
  return {
295
- status: 'success',
300
+ status: "success",
296
301
  data: results[0],
297
- queryLog: this.db.getFormattedQueryLogs(1)
298
302
  };
299
303
  }
300
304
  catch (error) {
301
305
  return {
302
- status: 'error',
306
+ status: "error",
303
307
  error: error.message,
304
- queryLog: this.db.getFormattedQueryLogs(1)
305
308
  };
306
309
  }
307
310
  }
@@ -312,38 +315,42 @@ class FunctionTools {
312
315
  try {
313
316
  const dbValidation = this.validateDatabaseAccess(params?.database);
314
317
  if (!dbValidation.valid) {
315
- return { status: 'error', error: dbValidation.error };
318
+ return { status: "error", error: dbValidation.error };
316
319
  }
317
320
  const { function_name, parameters = [] } = params;
318
321
  const database = dbValidation.database;
319
322
  // Validate function name
320
323
  const identifierValidation = this.security.validateIdentifier(function_name);
321
324
  if (!identifierValidation.valid) {
322
- return { status: 'error', error: identifierValidation.error || 'Invalid function name' };
325
+ return {
326
+ status: "error",
327
+ error: identifierValidation.error || "Invalid function name",
328
+ };
323
329
  }
324
330
  // Validate parameters
325
331
  const paramValidation = this.security.validateParameters(parameters);
326
332
  if (!paramValidation.valid) {
327
- return { status: 'error', error: `Parameter validation failed: ${paramValidation.error}` };
333
+ return {
334
+ status: "error",
335
+ error: `Parameter validation failed: ${paramValidation.error}`,
336
+ };
328
337
  }
329
338
  // Build SELECT query to call the function
330
- const placeholders = parameters.map(() => '?').join(', ');
339
+ const placeholders = parameters.map(() => "?").join(", ");
331
340
  const selectQuery = `SELECT \`${database}\`.\`${function_name}\`(${placeholders}) AS result`;
332
341
  const results = await this.db.query(selectQuery, paramValidation.sanitizedParams);
333
342
  return {
334
- status: 'success',
343
+ status: "success",
335
344
  data: {
336
345
  function_name,
337
- result: results[0]?.result
346
+ result: results[0]?.result,
338
347
  },
339
- queryLog: this.db.getFormattedQueryLogs(1)
340
348
  };
341
349
  }
342
350
  catch (error) {
343
351
  return {
344
- status: 'error',
352
+ status: "error",
345
353
  error: error.message,
346
- queryLog: this.db.getFormattedQueryLogs(1)
347
354
  };
348
355
  }
349
356
  }
@@ -1,4 +1,4 @@
1
- import { SecurityLayer } from '../security/securityLayer';
1
+ import { SecurityLayer } from "../security/securityLayer";
2
2
  export declare class IndexTools {
3
3
  private db;
4
4
  private security;
@@ -17,7 +17,6 @@ export declare class IndexTools {
17
17
  status: string;
18
18
  data?: any[];
19
19
  error?: string;
20
- queryLog?: string;
21
20
  }>;
22
21
  /**
23
22
  * Get detailed information about a specific index
@@ -30,7 +29,6 @@ export declare class IndexTools {
30
29
  status: string;
31
30
  data?: any;
32
31
  error?: string;
33
- queryLog?: string;
34
32
  }>;
35
33
  /**
36
34
  * Create a new index
@@ -41,17 +39,16 @@ export declare class IndexTools {
41
39
  columns: Array<string | {
42
40
  column: string;
43
41
  length?: number;
44
- order?: 'ASC' | 'DESC';
42
+ order?: "ASC" | "DESC";
45
43
  }>;
46
44
  unique?: boolean;
47
- index_type?: 'BTREE' | 'HASH' | 'FULLTEXT' | 'SPATIAL';
45
+ index_type?: "BTREE" | "HASH" | "FULLTEXT" | "SPATIAL";
48
46
  comment?: string;
49
47
  database?: string;
50
48
  }): Promise<{
51
49
  status: string;
52
50
  data?: any;
53
51
  error?: string;
54
- queryLog?: string;
55
52
  }>;
56
53
  /**
57
54
  * Drop an index
@@ -64,7 +61,6 @@ export declare class IndexTools {
64
61
  status: string;
65
62
  message?: string;
66
63
  error?: string;
67
- queryLog?: string;
68
64
  }>;
69
65
  /**
70
66
  * Analyze index usage and statistics
@@ -76,6 +72,5 @@ export declare class IndexTools {
76
72
  status: string;
77
73
  data?: any;
78
74
  error?: string;
79
- queryLog?: string;
80
75
  }>;
81
76
  }