@berthojoris/mcp-mysql-server 1.10.3 → 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 (43) hide show
  1. package/CHANGELOG.md +18 -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 ViewTools {
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,35 +48,33 @@ class ViewTools {
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
- TABLE_NAME as view_name,
57
- VIEW_DEFINITION as definition,
58
- CHECK_OPTION as check_option,
59
- IS_UPDATABLE as is_updatable,
60
- DEFINER as definer,
61
- SECURITY_TYPE as security_type,
62
- CHARACTER_SET_CLIENT as charset,
63
- COLLATION_CONNECTION as collation
64
- FROM INFORMATION_SCHEMA.VIEWS
65
- WHERE TABLE_SCHEMA = ?
66
- ORDER BY TABLE_NAME
54
+ const query = `
55
+ SELECT
56
+ TABLE_NAME as view_name,
57
+ VIEW_DEFINITION as definition,
58
+ CHECK_OPTION as check_option,
59
+ IS_UPDATABLE as is_updatable,
60
+ DEFINER as definer,
61
+ SECURITY_TYPE as security_type,
62
+ CHARACTER_SET_CLIENT as charset,
63
+ COLLATION_CONNECTION as collation
64
+ FROM INFORMATION_SCHEMA.VIEWS
65
+ WHERE TABLE_SCHEMA = ?
66
+ ORDER BY TABLE_NAME
67
67
  `;
68
68
  const results = await this.db.query(query, [database]);
69
69
  return {
70
- status: 'success',
70
+ status: "success",
71
71
  data: results,
72
- queryLog: this.db.getFormattedQueryLogs(1)
73
72
  };
74
73
  }
75
74
  catch (error) {
76
75
  return {
77
- status: 'error',
76
+ status: "error",
78
77
  error: error.message,
79
- queryLog: this.db.getFormattedQueryLogs(1)
80
78
  };
81
79
  }
82
80
  }
@@ -87,67 +85,67 @@ class ViewTools {
87
85
  try {
88
86
  const dbValidation = this.validateDatabaseAccess(params?.database);
89
87
  if (!dbValidation.valid) {
90
- return { status: 'error', error: dbValidation.error };
88
+ return { status: "error", error: dbValidation.error };
91
89
  }
92
90
  const { view_name } = params;
93
91
  const database = dbValidation.database;
94
92
  // Validate view name
95
93
  const identifierValidation = this.security.validateIdentifier(view_name);
96
94
  if (!identifierValidation.valid) {
97
- return { status: 'error', error: identifierValidation.error || 'Invalid view name' };
95
+ return {
96
+ status: "error",
97
+ error: identifierValidation.error || "Invalid view name",
98
+ };
98
99
  }
99
100
  // Get view information
100
- const viewQuery = `
101
- SELECT
102
- TABLE_NAME as view_name,
103
- VIEW_DEFINITION as definition,
104
- CHECK_OPTION as check_option,
105
- IS_UPDATABLE as is_updatable,
106
- DEFINER as definer,
107
- SECURITY_TYPE as security_type,
108
- CHARACTER_SET_CLIENT as charset,
109
- COLLATION_CONNECTION as collation
110
- FROM INFORMATION_SCHEMA.VIEWS
111
- WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
101
+ const viewQuery = `
102
+ SELECT
103
+ TABLE_NAME as view_name,
104
+ VIEW_DEFINITION as definition,
105
+ CHECK_OPTION as check_option,
106
+ IS_UPDATABLE as is_updatable,
107
+ DEFINER as definer,
108
+ SECURITY_TYPE as security_type,
109
+ CHARACTER_SET_CLIENT as charset,
110
+ COLLATION_CONNECTION as collation
111
+ FROM INFORMATION_SCHEMA.VIEWS
112
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
112
113
  `;
113
114
  // Get view columns
114
- const columnsQuery = `
115
- SELECT
116
- COLUMN_NAME as column_name,
117
- DATA_TYPE as data_type,
118
- COLUMN_TYPE as column_type,
119
- IS_NULLABLE as is_nullable,
120
- COLUMN_DEFAULT as column_default,
121
- ORDINAL_POSITION as position
122
- FROM INFORMATION_SCHEMA.COLUMNS
123
- WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
124
- ORDER BY ORDINAL_POSITION
115
+ const columnsQuery = `
116
+ SELECT
117
+ COLUMN_NAME as column_name,
118
+ DATA_TYPE as data_type,
119
+ COLUMN_TYPE as column_type,
120
+ IS_NULLABLE as is_nullable,
121
+ COLUMN_DEFAULT as column_default,
122
+ ORDINAL_POSITION as position
123
+ FROM INFORMATION_SCHEMA.COLUMNS
124
+ WHERE TABLE_SCHEMA = ? AND TABLE_NAME = ?
125
+ ORDER BY ORDINAL_POSITION
125
126
  `;
126
127
  const [viewInfo, columns] = await Promise.all([
127
128
  this.db.query(viewQuery, [database, view_name]),
128
- this.db.query(columnsQuery, [database, view_name])
129
+ this.db.query(columnsQuery, [database, view_name]),
129
130
  ]);
130
131
  if (viewInfo.length === 0) {
131
132
  return {
132
- status: 'error',
133
+ status: "error",
133
134
  error: `View '${view_name}' not found in database '${database}'`,
134
- queryLog: this.db.getFormattedQueryLogs(2)
135
135
  };
136
136
  }
137
137
  return {
138
- status: 'success',
138
+ status: "success",
139
139
  data: {
140
140
  ...viewInfo[0],
141
- columns: columns
141
+ columns: columns,
142
142
  },
143
- queryLog: this.db.getFormattedQueryLogs(2)
144
143
  };
145
144
  }
146
145
  catch (error) {
147
146
  return {
148
- status: 'error',
147
+ status: "error",
149
148
  error: error.message,
150
- queryLog: this.db.getFormattedQueryLogs(2)
151
149
  };
152
150
  }
153
151
  }
@@ -158,22 +156,28 @@ class ViewTools {
158
156
  try {
159
157
  const dbValidation = this.validateDatabaseAccess(params?.database);
160
158
  if (!dbValidation.valid) {
161
- return { status: 'error', error: dbValidation.error };
159
+ return { status: "error", error: dbValidation.error };
162
160
  }
163
- const { view_name, definition, or_replace = false, algorithm, security, check_option } = params;
161
+ const { view_name, definition, or_replace = false, algorithm, security, check_option, } = params;
164
162
  const database = dbValidation.database;
165
163
  // Validate view name
166
164
  const identifierValidation = this.security.validateIdentifier(view_name);
167
165
  if (!identifierValidation.valid) {
168
- return { status: 'error', error: identifierValidation.error || 'Invalid view name' };
166
+ return {
167
+ status: "error",
168
+ error: identifierValidation.error || "Invalid view name",
169
+ };
169
170
  }
170
171
  // Validate that definition is a SELECT statement
171
172
  const trimmedDef = definition.trim().toUpperCase();
172
- if (!trimmedDef.startsWith('SELECT')) {
173
- return { status: 'error', error: 'View definition must be a SELECT statement' };
173
+ if (!trimmedDef.startsWith("SELECT")) {
174
+ return {
175
+ status: "error",
176
+ error: "View definition must be a SELECT statement",
177
+ };
174
178
  }
175
179
  // Build CREATE VIEW statement
176
- let createQuery = or_replace ? 'CREATE OR REPLACE ' : 'CREATE ';
180
+ let createQuery = or_replace ? "CREATE OR REPLACE " : "CREATE ";
177
181
  if (algorithm) {
178
182
  createQuery += `ALGORITHM = ${algorithm} `;
179
183
  }
@@ -186,20 +190,18 @@ class ViewTools {
186
190
  }
187
191
  await this.db.query(createQuery);
188
192
  return {
189
- status: 'success',
193
+ status: "success",
190
194
  data: {
191
195
  message: `View '${view_name}' created successfully`,
192
196
  view_name,
193
- database
197
+ database,
194
198
  },
195
- queryLog: this.db.getFormattedQueryLogs(1)
196
199
  };
197
200
  }
198
201
  catch (error) {
199
202
  return {
200
- status: 'error',
203
+ status: "error",
201
204
  error: error.message,
202
- queryLog: this.db.getFormattedQueryLogs(1)
203
205
  };
204
206
  }
205
207
  }
@@ -210,22 +212,28 @@ class ViewTools {
210
212
  try {
211
213
  const dbValidation = this.validateDatabaseAccess(params?.database);
212
214
  if (!dbValidation.valid) {
213
- return { status: 'error', error: dbValidation.error };
215
+ return { status: "error", error: dbValidation.error };
214
216
  }
215
217
  const { view_name, definition, algorithm, security, check_option } = params;
216
218
  const database = dbValidation.database;
217
219
  // Validate view name
218
220
  const identifierValidation = this.security.validateIdentifier(view_name);
219
221
  if (!identifierValidation.valid) {
220
- return { status: 'error', error: identifierValidation.error || 'Invalid view name' };
222
+ return {
223
+ status: "error",
224
+ error: identifierValidation.error || "Invalid view name",
225
+ };
221
226
  }
222
227
  // Validate that definition is a SELECT statement
223
228
  const trimmedDef = definition.trim().toUpperCase();
224
- if (!trimmedDef.startsWith('SELECT')) {
225
- return { status: 'error', error: 'View definition must be a SELECT statement' };
229
+ if (!trimmedDef.startsWith("SELECT")) {
230
+ return {
231
+ status: "error",
232
+ error: "View definition must be a SELECT statement",
233
+ };
226
234
  }
227
235
  // Build ALTER VIEW statement
228
- let alterQuery = 'ALTER ';
236
+ let alterQuery = "ALTER ";
229
237
  if (algorithm) {
230
238
  alterQuery += `ALGORITHM = ${algorithm} `;
231
239
  }
@@ -238,20 +246,18 @@ class ViewTools {
238
246
  }
239
247
  await this.db.query(alterQuery);
240
248
  return {
241
- status: 'success',
249
+ status: "success",
242
250
  data: {
243
251
  message: `View '${view_name}' altered successfully`,
244
252
  view_name,
245
- database
253
+ database,
246
254
  },
247
- queryLog: this.db.getFormattedQueryLogs(1)
248
255
  };
249
256
  }
250
257
  catch (error) {
251
258
  return {
252
- status: 'error',
259
+ status: "error",
253
260
  error: error.message,
254
- queryLog: this.db.getFormattedQueryLogs(1)
255
261
  };
256
262
  }
257
263
  }
@@ -262,28 +268,29 @@ class ViewTools {
262
268
  try {
263
269
  const dbValidation = this.validateDatabaseAccess(params?.database);
264
270
  if (!dbValidation.valid) {
265
- return { status: 'error', error: dbValidation.error };
271
+ return { status: "error", error: dbValidation.error };
266
272
  }
267
273
  const { view_name, if_exists = false } = params;
268
274
  const database = dbValidation.database;
269
275
  // Validate view name
270
276
  const identifierValidation = this.security.validateIdentifier(view_name);
271
277
  if (!identifierValidation.valid) {
272
- return { status: 'error', error: identifierValidation.error || 'Invalid view name' };
278
+ return {
279
+ status: "error",
280
+ error: identifierValidation.error || "Invalid view name",
281
+ };
273
282
  }
274
- const dropQuery = `DROP VIEW ${if_exists ? 'IF EXISTS' : ''} \`${database}\`.\`${view_name}\``;
283
+ const dropQuery = `DROP VIEW ${if_exists ? "IF EXISTS" : ""} \`${database}\`.\`${view_name}\``;
275
284
  await this.db.query(dropQuery);
276
285
  return {
277
- status: 'success',
286
+ status: "success",
278
287
  message: `View '${view_name}' dropped successfully`,
279
- queryLog: this.db.getFormattedQueryLogs(1)
280
288
  };
281
289
  }
282
290
  catch (error) {
283
291
  return {
284
- status: 'error',
292
+ status: "error",
285
293
  error: error.message,
286
- queryLog: this.db.getFormattedQueryLogs(1)
287
294
  };
288
295
  }
289
296
  }
@@ -294,35 +301,35 @@ class ViewTools {
294
301
  try {
295
302
  const dbValidation = this.validateDatabaseAccess(params?.database);
296
303
  if (!dbValidation.valid) {
297
- return { status: 'error', error: dbValidation.error };
304
+ return { status: "error", error: dbValidation.error };
298
305
  }
299
306
  const { view_name } = params;
300
307
  const database = dbValidation.database;
301
308
  // Validate view name
302
309
  const identifierValidation = this.security.validateIdentifier(view_name);
303
310
  if (!identifierValidation.valid) {
304
- return { status: 'error', error: identifierValidation.error || 'Invalid view name' };
311
+ return {
312
+ status: "error",
313
+ error: identifierValidation.error || "Invalid view name",
314
+ };
305
315
  }
306
316
  const query = `SHOW CREATE VIEW \`${database}\`.\`${view_name}\``;
307
317
  const results = await this.db.query(query);
308
318
  if (results.length === 0) {
309
319
  return {
310
- status: 'error',
320
+ status: "error",
311
321
  error: `View '${view_name}' not found`,
312
- queryLog: this.db.getFormattedQueryLogs(1)
313
322
  };
314
323
  }
315
324
  return {
316
- status: 'success',
325
+ status: "success",
317
326
  data: results[0],
318
- queryLog: this.db.getFormattedQueryLogs(1)
319
327
  };
320
328
  }
321
329
  catch (error) {
322
330
  return {
323
- status: 'error',
331
+ status: "error",
324
332
  error: error.message,
325
- queryLog: this.db.getFormattedQueryLogs(1)
326
333
  };
327
334
  }
328
335
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@berthojoris/mcp-mysql-server",
3
- "version": "1.10.3",
3
+ "version": "1.10.4",
4
4
  "description": "Model Context Protocol server for MySQL database integration with dynamic per-project permissions, backup/restore, data import/export, and data migration capabilities",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",