@berthojoris/mcp-mysql-server 1.6.2 → 1.7.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.
package/dist/index.js CHANGED
@@ -19,6 +19,7 @@ const indexTools_1 = require("./tools/indexTools");
19
19
  const constraintTools_1 = require("./tools/constraintTools");
20
20
  const maintenanceTools_1 = require("./tools/maintenanceTools");
21
21
  const processTools_1 = require("./tools/processTools");
22
+ const backupRestoreTools_1 = require("./tools/backupRestoreTools");
22
23
  const securityLayer_1 = __importDefault(require("./security/securityLayer"));
23
24
  const connection_1 = __importDefault(require("./db/connection"));
24
25
  const featureConfig_1 = require("./config/featureConfig");
@@ -45,6 +46,7 @@ class MySQLMCP {
45
46
  this.constraintTools = new constraintTools_1.ConstraintTools(this.security);
46
47
  this.maintenanceTools = new maintenanceTools_1.MaintenanceTools(this.security);
47
48
  this.processTools = new processTools_1.ProcessTools(this.security);
49
+ this.backupRestoreTools = new backupRestoreTools_1.BackupRestoreTools(this.security);
48
50
  }
49
51
  // Helper method to check if tool is enabled
50
52
  checkToolEnabled(toolName) {
@@ -284,6 +286,79 @@ class MySQLMCP {
284
286
  }
285
287
  return await this.dataExportTools.exportQueryToCSV(params);
286
288
  }
289
+ // Extended Data Export Tools (JSON, SQL)
290
+ async exportTableToJSON(params) {
291
+ const check = this.checkToolEnabled("exportTableToJSON");
292
+ if (!check.enabled) {
293
+ return { status: "error", error: check.error };
294
+ }
295
+ return await this.dataExportTools.exportTableToJSON(params);
296
+ }
297
+ async exportQueryToJSON(params) {
298
+ const check = this.checkToolEnabled("exportQueryToJSON");
299
+ if (!check.enabled) {
300
+ return { status: "error", error: check.error };
301
+ }
302
+ return await this.dataExportTools.exportQueryToJSON(params);
303
+ }
304
+ async exportTableToSql(params) {
305
+ const check = this.checkToolEnabled("exportTableToSql");
306
+ if (!check.enabled) {
307
+ return { status: "error", error: check.error };
308
+ }
309
+ return await this.dataExportTools.exportTableToSql(params);
310
+ }
311
+ // Data Import Tools
312
+ async importFromCSV(params) {
313
+ const check = this.checkToolEnabled("importFromCSV");
314
+ if (!check.enabled) {
315
+ return { status: "error", error: check.error };
316
+ }
317
+ return await this.dataExportTools.importFromCSV(params);
318
+ }
319
+ async importFromJSON(params) {
320
+ const check = this.checkToolEnabled("importFromJSON");
321
+ if (!check.enabled) {
322
+ return { status: "error", error: check.error };
323
+ }
324
+ return await this.dataExportTools.importFromJSON(params);
325
+ }
326
+ // Backup and Restore Tools
327
+ async backupTable(params) {
328
+ const check = this.checkToolEnabled("backupTable");
329
+ if (!check.enabled) {
330
+ return { status: "error", error: check.error };
331
+ }
332
+ return await this.backupRestoreTools.backupTable(params);
333
+ }
334
+ async backupDatabase(params) {
335
+ const check = this.checkToolEnabled("backupDatabase");
336
+ if (!check.enabled) {
337
+ return { status: "error", error: check.error };
338
+ }
339
+ return await this.backupRestoreTools.backupDatabase(params);
340
+ }
341
+ async restoreFromSql(params) {
342
+ const check = this.checkToolEnabled("restoreFromSql");
343
+ if (!check.enabled) {
344
+ return { status: "error", error: check.error };
345
+ }
346
+ return await this.backupRestoreTools.restoreFromSql(params);
347
+ }
348
+ async getCreateTableStatement(params) {
349
+ const check = this.checkToolEnabled("getCreateTableStatement");
350
+ if (!check.enabled) {
351
+ return { status: "error", error: check.error };
352
+ }
353
+ return await this.backupRestoreTools.getCreateTableStatement(params);
354
+ }
355
+ async getDatabaseSchema(params) {
356
+ const check = this.checkToolEnabled("getDatabaseSchema");
357
+ if (!check.enabled) {
358
+ return { status: "error", error: check.error };
359
+ }
360
+ return await this.backupRestoreTools.getDatabaseSchema(params);
361
+ }
287
362
  // Get feature configuration status
288
363
  getFeatureStatus() {
289
364
  return {
@@ -1866,6 +1866,321 @@ const TOOLS = [
1866
1866
  },
1867
1867
  },
1868
1868
  },
1869
+ // Backup and Restore Tools
1870
+ {
1871
+ name: "backup_table",
1872
+ description: "Backup a single table to SQL dump format including structure and optionally data.",
1873
+ inputSchema: {
1874
+ type: "object",
1875
+ properties: {
1876
+ table_name: {
1877
+ type: "string",
1878
+ description: "Name of the table to backup",
1879
+ },
1880
+ include_data: {
1881
+ type: "boolean",
1882
+ description: "Include table data in the backup (default: true)",
1883
+ },
1884
+ include_drop: {
1885
+ type: "boolean",
1886
+ description: "Include DROP TABLE IF EXISTS statement (default: true)",
1887
+ },
1888
+ database: {
1889
+ type: "string",
1890
+ description: "Optional: specific database name",
1891
+ },
1892
+ },
1893
+ required: ["table_name"],
1894
+ },
1895
+ },
1896
+ {
1897
+ name: "backup_database",
1898
+ description: "Backup entire database or selected tables to SQL dump format.",
1899
+ inputSchema: {
1900
+ type: "object",
1901
+ properties: {
1902
+ include_data: {
1903
+ type: "boolean",
1904
+ description: "Include table data in the backup (default: true)",
1905
+ },
1906
+ include_drop: {
1907
+ type: "boolean",
1908
+ description: "Include DROP TABLE IF EXISTS statements (default: true)",
1909
+ },
1910
+ tables: {
1911
+ type: "array",
1912
+ items: { type: "string" },
1913
+ description: "Optional: specific tables to backup (default: all tables)",
1914
+ },
1915
+ database: {
1916
+ type: "string",
1917
+ description: "Optional: specific database name",
1918
+ },
1919
+ },
1920
+ },
1921
+ },
1922
+ {
1923
+ name: "restore_from_sql",
1924
+ description: "Restore database from SQL dump content. Executes SQL statements from the provided dump. Requires 'ddl' permission.",
1925
+ inputSchema: {
1926
+ type: "object",
1927
+ properties: {
1928
+ sql_dump: {
1929
+ type: "string",
1930
+ description: "SQL dump content to restore",
1931
+ },
1932
+ stop_on_error: {
1933
+ type: "boolean",
1934
+ description: "Stop execution on first error (default: true)",
1935
+ },
1936
+ database: {
1937
+ type: "string",
1938
+ description: "Optional: specific database name",
1939
+ },
1940
+ },
1941
+ required: ["sql_dump"],
1942
+ },
1943
+ },
1944
+ {
1945
+ name: "get_create_table_statement",
1946
+ description: "Get the CREATE TABLE statement for a specific table.",
1947
+ inputSchema: {
1948
+ type: "object",
1949
+ properties: {
1950
+ table_name: {
1951
+ type: "string",
1952
+ description: "Name of the table",
1953
+ },
1954
+ database: {
1955
+ type: "string",
1956
+ description: "Optional: specific database name",
1957
+ },
1958
+ },
1959
+ required: ["table_name"],
1960
+ },
1961
+ },
1962
+ {
1963
+ name: "get_database_schema",
1964
+ description: "Get complete database schema including tables, views, procedures, functions, and triggers.",
1965
+ inputSchema: {
1966
+ type: "object",
1967
+ properties: {
1968
+ database: {
1969
+ type: "string",
1970
+ description: "Optional: specific database name",
1971
+ },
1972
+ include_views: {
1973
+ type: "boolean",
1974
+ description: "Include views in schema (default: true)",
1975
+ },
1976
+ include_procedures: {
1977
+ type: "boolean",
1978
+ description: "Include stored procedures in schema (default: true)",
1979
+ },
1980
+ include_functions: {
1981
+ type: "boolean",
1982
+ description: "Include functions in schema (default: true)",
1983
+ },
1984
+ include_triggers: {
1985
+ type: "boolean",
1986
+ description: "Include triggers in schema (default: true)",
1987
+ },
1988
+ },
1989
+ },
1990
+ },
1991
+ // Extended Data Export Tools (JSON, SQL)
1992
+ {
1993
+ name: "export_table_to_json",
1994
+ description: "Export table data to JSON format with optional filtering, pagination, and sorting.",
1995
+ inputSchema: {
1996
+ type: "object",
1997
+ properties: {
1998
+ table_name: {
1999
+ type: "string",
2000
+ description: "Name of the table to export",
2001
+ },
2002
+ filters: {
2003
+ type: "array",
2004
+ description: "Array of filter conditions",
2005
+ items: {
2006
+ type: "object",
2007
+ properties: {
2008
+ field: { type: "string" },
2009
+ operator: {
2010
+ type: "string",
2011
+ enum: ["eq", "neq", "gt", "gte", "lt", "lte", "like", "in"],
2012
+ },
2013
+ value: {},
2014
+ },
2015
+ required: ["field", "operator", "value"],
2016
+ },
2017
+ },
2018
+ pagination: {
2019
+ type: "object",
2020
+ properties: {
2021
+ page: { type: "number" },
2022
+ limit: { type: "number" },
2023
+ },
2024
+ },
2025
+ sorting: {
2026
+ type: "object",
2027
+ properties: {
2028
+ field: { type: "string" },
2029
+ direction: { type: "string", enum: ["asc", "desc"] },
2030
+ },
2031
+ },
2032
+ pretty: {
2033
+ type: "boolean",
2034
+ description: "Pretty print JSON output (default: true)",
2035
+ },
2036
+ database: {
2037
+ type: "string",
2038
+ description: "Optional: specific database name",
2039
+ },
2040
+ },
2041
+ required: ["table_name"],
2042
+ },
2043
+ },
2044
+ {
2045
+ name: "export_query_to_json",
2046
+ description: "Export the results of a SELECT query to JSON format.",
2047
+ inputSchema: {
2048
+ type: "object",
2049
+ properties: {
2050
+ query: {
2051
+ type: "string",
2052
+ description: "SQL SELECT query to execute and export",
2053
+ },
2054
+ params: {
2055
+ type: "array",
2056
+ description: "Optional array of parameters for parameterized queries",
2057
+ items: {},
2058
+ },
2059
+ pretty: {
2060
+ type: "boolean",
2061
+ description: "Pretty print JSON output (default: true)",
2062
+ },
2063
+ },
2064
+ required: ["query"],
2065
+ },
2066
+ },
2067
+ {
2068
+ name: "export_table_to_sql",
2069
+ description: "Export table data to SQL INSERT statements with optional CREATE TABLE.",
2070
+ inputSchema: {
2071
+ type: "object",
2072
+ properties: {
2073
+ table_name: {
2074
+ type: "string",
2075
+ description: "Name of the table to export",
2076
+ },
2077
+ filters: {
2078
+ type: "array",
2079
+ description: "Array of filter conditions",
2080
+ items: {
2081
+ type: "object",
2082
+ properties: {
2083
+ field: { type: "string" },
2084
+ operator: {
2085
+ type: "string",
2086
+ enum: ["eq", "neq", "gt", "gte", "lt", "lte", "like", "in"],
2087
+ },
2088
+ value: {},
2089
+ },
2090
+ required: ["field", "operator", "value"],
2091
+ },
2092
+ },
2093
+ include_create_table: {
2094
+ type: "boolean",
2095
+ description: "Include CREATE TABLE statement (default: false)",
2096
+ },
2097
+ batch_size: {
2098
+ type: "number",
2099
+ description: "Number of rows per INSERT statement (default: 100)",
2100
+ },
2101
+ database: {
2102
+ type: "string",
2103
+ description: "Optional: specific database name",
2104
+ },
2105
+ },
2106
+ required: ["table_name"],
2107
+ },
2108
+ },
2109
+ // Data Import Tools
2110
+ {
2111
+ name: "import_from_csv",
2112
+ description: "Import data from CSV string into a table. Requires 'create' permission.",
2113
+ inputSchema: {
2114
+ type: "object",
2115
+ properties: {
2116
+ table_name: {
2117
+ type: "string",
2118
+ description: "Name of the table to import into",
2119
+ },
2120
+ csv_data: {
2121
+ type: "string",
2122
+ description: "CSV data as a string",
2123
+ },
2124
+ has_headers: {
2125
+ type: "boolean",
2126
+ description: "CSV has header row (default: true)",
2127
+ },
2128
+ column_mapping: {
2129
+ type: "object",
2130
+ description: "Optional: map CSV columns to table columns {csv_col: table_col}",
2131
+ additionalProperties: { type: "string" },
2132
+ },
2133
+ skip_errors: {
2134
+ type: "boolean",
2135
+ description: "Continue on row errors (default: false)",
2136
+ },
2137
+ batch_size: {
2138
+ type: "number",
2139
+ description: "Number of rows per batch insert (default: 100)",
2140
+ },
2141
+ database: {
2142
+ type: "string",
2143
+ description: "Optional: specific database name",
2144
+ },
2145
+ },
2146
+ required: ["table_name", "csv_data"],
2147
+ },
2148
+ },
2149
+ {
2150
+ name: "import_from_json",
2151
+ description: "Import data from JSON array string into a table. Requires 'create' permission.",
2152
+ inputSchema: {
2153
+ type: "object",
2154
+ properties: {
2155
+ table_name: {
2156
+ type: "string",
2157
+ description: "Name of the table to import into",
2158
+ },
2159
+ json_data: {
2160
+ type: "string",
2161
+ description: "JSON array of objects as a string",
2162
+ },
2163
+ column_mapping: {
2164
+ type: "object",
2165
+ description: "Optional: map JSON keys to table columns {json_key: table_col}",
2166
+ additionalProperties: { type: "string" },
2167
+ },
2168
+ skip_errors: {
2169
+ type: "boolean",
2170
+ description: "Continue on row errors (default: false)",
2171
+ },
2172
+ batch_size: {
2173
+ type: "number",
2174
+ description: "Number of rows per batch insert (default: 100)",
2175
+ },
2176
+ database: {
2177
+ type: "string",
2178
+ description: "Optional: specific database name",
2179
+ },
2180
+ },
2181
+ required: ["table_name", "json_data"],
2182
+ },
2183
+ },
1869
2184
  ];
1870
2185
  // Create the MCP server
1871
2186
  const server = new index_js_1.Server({
@@ -2155,6 +2470,39 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
2155
2470
  case "show_replication_status":
2156
2471
  result = await mysqlMCP.showReplicationStatus((args || {}));
2157
2472
  break;
2473
+ // Backup and Restore Tools
2474
+ case "backup_table":
2475
+ result = await mysqlMCP.backupTable((args || {}));
2476
+ break;
2477
+ case "backup_database":
2478
+ result = await mysqlMCP.backupDatabase((args || {}));
2479
+ break;
2480
+ case "restore_from_sql":
2481
+ result = await mysqlMCP.restoreFromSql((args || {}));
2482
+ break;
2483
+ case "get_create_table_statement":
2484
+ result = await mysqlMCP.getCreateTableStatement((args || {}));
2485
+ break;
2486
+ case "get_database_schema":
2487
+ result = await mysqlMCP.getDatabaseSchema((args || {}));
2488
+ break;
2489
+ // Extended Data Export Tools
2490
+ case "export_table_to_json":
2491
+ result = await mysqlMCP.exportTableToJSON((args || {}));
2492
+ break;
2493
+ case "export_query_to_json":
2494
+ result = await mysqlMCP.exportQueryToJSON((args || {}));
2495
+ break;
2496
+ case "export_table_to_sql":
2497
+ result = await mysqlMCP.exportTableToSql((args || {}));
2498
+ break;
2499
+ // Data Import Tools
2500
+ case "import_from_csv":
2501
+ result = await mysqlMCP.importFromCSV((args || {}));
2502
+ break;
2503
+ case "import_from_json":
2504
+ result = await mysqlMCP.importFromJSON((args || {}));
2505
+ break;
2158
2506
  default:
2159
2507
  throw new Error(`Unknown tool: ${name}`);
2160
2508
  }
@@ -12,17 +12,22 @@ class SecurityLayer {
12
12
  this.featureConfig = featureConfig || new featureConfig_js_1.FeatureConfig();
13
13
  // Define dangerous SQL keywords that should ALWAYS be blocked (critical security threats)
14
14
  // These are blocked even with 'execute' permission
15
+ // Note: Avoid blocking common table/column names like "user" or "password"
15
16
  this.dangerousKeywords = [
16
17
  "GRANT",
17
18
  "REVOKE",
18
19
  "INTO OUTFILE",
19
20
  "INTO DUMPFILE",
20
21
  "LOAD DATA",
21
- "MYSQL",
22
+ "LOAD_FILE",
23
+ "INFORMATION_SCHEMA.USER_PRIVILEGES",
24
+ "MYSQL.USER",
25
+ "MYSQL.DB",
22
26
  "PERFORMANCE_SCHEMA",
23
- "SYS",
24
- "USER",
25
- "PASSWORD",
27
+ "CREATE USER",
28
+ "DROP USER",
29
+ "ALTER USER",
30
+ "SET PASSWORD",
26
31
  ];
27
32
  // Define basic allowed SQL operations
28
33
  this.allowedOperations = ["SELECT", "INSERT", "UPDATE", "DELETE"];
@@ -0,0 +1,91 @@
1
+ import SecurityLayer from '../security/securityLayer';
2
+ /**
3
+ * Backup and Restore Tools for MySQL MCP Server
4
+ * Provides database backup (SQL dump generation) and restore functionality
5
+ */
6
+ export declare class BackupRestoreTools {
7
+ private db;
8
+ private security;
9
+ constructor(security: SecurityLayer);
10
+ /**
11
+ * Validate database access
12
+ */
13
+ private validateDatabaseAccess;
14
+ /**
15
+ * Escape string value for SQL
16
+ */
17
+ private escapeValue;
18
+ /**
19
+ * Get CREATE TABLE statement for a table
20
+ */
21
+ getCreateTableStatement(params: {
22
+ table_name: string;
23
+ database?: string;
24
+ }): Promise<{
25
+ status: string;
26
+ data?: any;
27
+ error?: string;
28
+ queryLog?: string;
29
+ }>;
30
+ /**
31
+ * Backup a single table to SQL dump format
32
+ */
33
+ backupTable(params: {
34
+ table_name: string;
35
+ include_data?: boolean;
36
+ include_drop?: boolean;
37
+ database?: string;
38
+ }): Promise<{
39
+ status: string;
40
+ data?: any;
41
+ error?: string;
42
+ queryLog?: string;
43
+ }>;
44
+ /**
45
+ * Backup entire database schema and optionally data
46
+ */
47
+ backupDatabase(params: {
48
+ include_data?: boolean;
49
+ include_drop?: boolean;
50
+ tables?: string[];
51
+ database?: string;
52
+ }): Promise<{
53
+ status: string;
54
+ data?: any;
55
+ error?: string;
56
+ queryLog?: string;
57
+ }>;
58
+ /**
59
+ * Restore database from SQL dump
60
+ * Executes SQL statements from the provided SQL dump string
61
+ */
62
+ restoreFromSql(params: {
63
+ sql_dump: string;
64
+ stop_on_error?: boolean;
65
+ database?: string;
66
+ }): Promise<{
67
+ status: string;
68
+ data?: any;
69
+ error?: string;
70
+ queryLog?: string;
71
+ }>;
72
+ /**
73
+ * Parse SQL dump into individual statements
74
+ */
75
+ private parseSqlStatements;
76
+ /**
77
+ * Get database schema overview (all CREATE statements)
78
+ */
79
+ getDatabaseSchema(params: {
80
+ database?: string;
81
+ include_views?: boolean;
82
+ include_procedures?: boolean;
83
+ include_functions?: boolean;
84
+ include_triggers?: boolean;
85
+ }): Promise<{
86
+ status: string;
87
+ data?: any;
88
+ error?: string;
89
+ queryLog?: string;
90
+ }>;
91
+ }