@berthojoris/mcp-mysql-server 1.9.3 → 1.10.1

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.d.ts CHANGED
@@ -21,9 +21,10 @@ export declare class MySQLMCP {
21
21
  private backupRestoreTools;
22
22
  private migrationTools;
23
23
  private schemaVersioningTools;
24
+ private performanceTools;
24
25
  private security;
25
26
  private featureConfig;
26
- constructor(permissionsConfig?: string);
27
+ constructor(permissionsConfig?: string, categoriesConfig?: string);
27
28
  private checkToolEnabled;
28
29
  listDatabases(): Promise<{
29
30
  status: string;
@@ -587,6 +588,12 @@ export declare class MySQLMCP {
587
588
  categoryStatus: Record<import("./config/featureConfig").ToolCategory, boolean>;
588
589
  };
589
590
  };
591
+ /**
592
+ * Check if a specific tool is enabled based on current permissions and categories
593
+ * @param toolName - The tool name in camelCase (e.g., 'listDatabases')
594
+ * @returns boolean indicating if the tool is enabled
595
+ */
596
+ isToolEnabled(toolName: string): boolean;
590
597
  /**
591
598
  * Bulk insert multiple records into the specified table
592
599
  */
@@ -1093,5 +1100,80 @@ export declare class MySQLMCP {
1093
1100
  error?: string;
1094
1101
  queryLog?: string;
1095
1102
  }>;
1103
+ getPerformanceMetrics(): Promise<{
1104
+ status: string;
1105
+ data?: any;
1106
+ error?: string;
1107
+ queryLog?: string;
1108
+ }>;
1109
+ getTopQueriesByTime(params?: {
1110
+ limit?: number;
1111
+ }): Promise<{
1112
+ status: string;
1113
+ data?: any[];
1114
+ error?: string;
1115
+ queryLog?: string;
1116
+ }>;
1117
+ getTopQueriesByCount(params?: {
1118
+ limit?: number;
1119
+ }): Promise<{
1120
+ status: string;
1121
+ data?: any[];
1122
+ error?: string;
1123
+ queryLog?: string;
1124
+ }>;
1125
+ getSlowQueries(params?: {
1126
+ limit?: number;
1127
+ threshold_seconds?: number;
1128
+ }): Promise<{
1129
+ status: string;
1130
+ data?: any[];
1131
+ error?: string;
1132
+ queryLog?: string;
1133
+ }>;
1134
+ getTableIOStats(params?: {
1135
+ limit?: number;
1136
+ table_schema?: string;
1137
+ }): Promise<{
1138
+ status: string;
1139
+ data?: any[];
1140
+ error?: string;
1141
+ queryLog?: string;
1142
+ }>;
1143
+ getIndexUsageStats(params?: {
1144
+ limit?: number;
1145
+ table_schema?: string;
1146
+ }): Promise<{
1147
+ status: string;
1148
+ data?: any[];
1149
+ error?: string;
1150
+ queryLog?: string;
1151
+ }>;
1152
+ getUnusedIndexes(params?: {
1153
+ table_schema?: string;
1154
+ }): Promise<{
1155
+ status: string;
1156
+ data?: any[];
1157
+ error?: string;
1158
+ queryLog?: string;
1159
+ }>;
1160
+ getConnectionPoolStats(): Promise<{
1161
+ status: string;
1162
+ data?: any;
1163
+ error?: string;
1164
+ queryLog?: string;
1165
+ }>;
1166
+ getDatabaseHealthCheck(): Promise<{
1167
+ status: string;
1168
+ data?: any;
1169
+ error?: string;
1170
+ queryLog?: string;
1171
+ }>;
1172
+ resetPerformanceStats(): Promise<{
1173
+ status: string;
1174
+ message?: string;
1175
+ error?: string;
1176
+ queryLog?: string;
1177
+ }>;
1096
1178
  }
1097
1179
  export default MySQLMCP;
package/dist/index.js CHANGED
@@ -22,6 +22,7 @@ const processTools_1 = require("./tools/processTools");
22
22
  const backupRestoreTools_1 = require("./tools/backupRestoreTools");
23
23
  const migrationTools_1 = require("./tools/migrationTools");
24
24
  const schemaVersioningTools_1 = require("./tools/schemaVersioningTools");
25
+ const performanceTools_1 = require("./tools/performanceTools");
25
26
  const securityLayer_1 = __importDefault(require("./security/securityLayer"));
26
27
  const connection_1 = __importDefault(require("./db/connection"));
27
28
  const featureConfig_1 = require("./config/featureConfig");
@@ -30,8 +31,8 @@ const featureConfig_1 = require("./config/featureConfig");
30
31
  * A secure interface for AI models to interact with MySQL databases
31
32
  */
32
33
  class MySQLMCP {
33
- constructor(permissionsConfig) {
34
- this.featureConfig = new featureConfig_1.FeatureConfig(permissionsConfig);
34
+ constructor(permissionsConfig, categoriesConfig) {
35
+ this.featureConfig = new featureConfig_1.FeatureConfig(permissionsConfig, categoriesConfig);
35
36
  this.security = new securityLayer_1.default(this.featureConfig);
36
37
  this.dbTools = new databaseTools_1.DatabaseTools();
37
38
  this.crudTools = new crudTools_1.CrudTools(this.security);
@@ -51,6 +52,7 @@ class MySQLMCP {
51
52
  this.backupRestoreTools = new backupRestoreTools_1.BackupRestoreTools(this.security);
52
53
  this.migrationTools = new migrationTools_1.MigrationTools(this.security);
53
54
  this.schemaVersioningTools = new schemaVersioningTools_1.SchemaVersioningTools(this.security);
55
+ this.performanceTools = new performanceTools_1.PerformanceTools(this.security);
54
56
  }
55
57
  // Helper method to check if tool is enabled
56
58
  checkToolEnabled(toolName) {
@@ -502,6 +504,14 @@ class MySQLMCP {
502
504
  },
503
505
  };
504
506
  }
507
+ /**
508
+ * Check if a specific tool is enabled based on current permissions and categories
509
+ * @param toolName - The tool name in camelCase (e.g., 'listDatabases')
510
+ * @returns boolean indicating if the tool is enabled
511
+ */
512
+ isToolEnabled(toolName) {
513
+ return this.featureConfig.isToolEnabled(toolName);
514
+ }
505
515
  /**
506
516
  * Bulk insert multiple records into the specified table
507
517
  */
@@ -925,6 +935,69 @@ class MySQLMCP {
925
935
  return { status: "error", error: check.error };
926
936
  return await this.processTools.showReplicationStatus(params);
927
937
  }
938
+ // ==========================================
939
+ // Performance Monitoring Tools
940
+ // ==========================================
941
+ async getPerformanceMetrics() {
942
+ const check = this.checkToolEnabled("getPerformanceMetrics");
943
+ if (!check.enabled)
944
+ return { status: "error", error: check.error };
945
+ return await this.performanceTools.getPerformanceMetrics();
946
+ }
947
+ async getTopQueriesByTime(params) {
948
+ const check = this.checkToolEnabled("getTopQueriesByTime");
949
+ if (!check.enabled)
950
+ return { status: "error", error: check.error };
951
+ return await this.performanceTools.getTopQueriesByTime(params);
952
+ }
953
+ async getTopQueriesByCount(params) {
954
+ const check = this.checkToolEnabled("getTopQueriesByCount");
955
+ if (!check.enabled)
956
+ return { status: "error", error: check.error };
957
+ return await this.performanceTools.getTopQueriesByCount(params);
958
+ }
959
+ async getSlowQueries(params) {
960
+ const check = this.checkToolEnabled("getSlowQueries");
961
+ if (!check.enabled)
962
+ return { status: "error", error: check.error };
963
+ return await this.performanceTools.getSlowQueries(params);
964
+ }
965
+ async getTableIOStats(params) {
966
+ const check = this.checkToolEnabled("getTableIOStats");
967
+ if (!check.enabled)
968
+ return { status: "error", error: check.error };
969
+ return await this.performanceTools.getTableIOStats(params);
970
+ }
971
+ async getIndexUsageStats(params) {
972
+ const check = this.checkToolEnabled("getIndexUsageStats");
973
+ if (!check.enabled)
974
+ return { status: "error", error: check.error };
975
+ return await this.performanceTools.getIndexUsageStats(params);
976
+ }
977
+ async getUnusedIndexes(params) {
978
+ const check = this.checkToolEnabled("getUnusedIndexes");
979
+ if (!check.enabled)
980
+ return { status: "error", error: check.error };
981
+ return await this.performanceTools.getUnusedIndexes(params);
982
+ }
983
+ async getConnectionPoolStats() {
984
+ const check = this.checkToolEnabled("getConnectionPoolStats");
985
+ if (!check.enabled)
986
+ return { status: "error", error: check.error };
987
+ return await this.performanceTools.getConnectionPoolStats();
988
+ }
989
+ async getDatabaseHealthCheck() {
990
+ const check = this.checkToolEnabled("getDatabaseHealthCheck");
991
+ if (!check.enabled)
992
+ return { status: "error", error: check.error };
993
+ return await this.performanceTools.getDatabaseHealthCheck();
994
+ }
995
+ async resetPerformanceStats() {
996
+ const check = this.checkToolEnabled("resetPerformanceStats");
997
+ if (!check.enabled)
998
+ return { status: "error", error: check.error };
999
+ return await this.performanceTools.resetPerformanceStats();
1000
+ }
928
1001
  }
929
1002
  exports.MySQLMCP = MySQLMCP;
930
1003
  exports.default = MySQLMCP;
@@ -5,9 +5,11 @@ const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
5
5
  const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
6
6
  const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
7
7
  const index_js_2 = require("./index.js");
8
- // Get permissions from environment variable (set by bin/mcp-mysql.js)
9
- // Priority: MCP_PERMISSIONS (from command line) > MCP_CONFIG (from .env) > all permissions
8
+ // Get permissions and categories from environment variables (set by bin/mcp-mysql.js)
9
+ // Layer 1 (Permissions): MCP_PERMISSIONS or MCP_CONFIG (backward compatible)
10
+ // Layer 2 (Categories): MCP_CATEGORIES (optional, for fine-grained control)
10
11
  const permissions = process.env.MCP_PERMISSIONS || process.env.MCP_CONFIG || "";
12
+ const categories = process.env.MCP_CATEGORIES || "";
11
13
  // Declare the MySQL MCP instance (will be initialized in main())
12
14
  let mysqlMCP;
13
15
  // Define all available tools with their schemas
@@ -2558,6 +2560,129 @@ const TOOLS = [
2558
2560
  required: ["table1", "table2", "migration_name"],
2559
2561
  },
2560
2562
  },
2563
+ // Performance Monitoring Tools
2564
+ {
2565
+ name: "get_performance_metrics",
2566
+ description: "Get comprehensive performance metrics including query performance, connection stats, buffer pool metrics, and InnoDB statistics.",
2567
+ inputSchema: {
2568
+ type: "object",
2569
+ properties: {},
2570
+ },
2571
+ },
2572
+ {
2573
+ name: "get_top_queries_by_time",
2574
+ description: "Get the top queries ordered by total execution time. Useful for identifying slow queries.",
2575
+ inputSchema: {
2576
+ type: "object",
2577
+ properties: {
2578
+ limit: {
2579
+ type: "number",
2580
+ description: "Maximum number of queries to return (default: 10, max: 100)",
2581
+ },
2582
+ },
2583
+ },
2584
+ },
2585
+ {
2586
+ name: "get_top_queries_by_count",
2587
+ description: "Get the top queries ordered by execution count. Useful for identifying frequently executed queries.",
2588
+ inputSchema: {
2589
+ type: "object",
2590
+ properties: {
2591
+ limit: {
2592
+ type: "number",
2593
+ description: "Maximum number of queries to return (default: 10, max: 100)",
2594
+ },
2595
+ },
2596
+ },
2597
+ },
2598
+ {
2599
+ name: "get_slow_queries",
2600
+ description: "Get queries that exceed a specified execution time threshold.",
2601
+ inputSchema: {
2602
+ type: "object",
2603
+ properties: {
2604
+ limit: {
2605
+ type: "number",
2606
+ description: "Maximum number of queries to return (default: 10, max: 100)",
2607
+ },
2608
+ threshold_seconds: {
2609
+ type: "number",
2610
+ description: "Execution time threshold in seconds (default: 1)",
2611
+ },
2612
+ },
2613
+ },
2614
+ },
2615
+ {
2616
+ name: "get_table_io_stats",
2617
+ description: "Get I/O statistics for tables including read/write operations and timings.",
2618
+ inputSchema: {
2619
+ type: "object",
2620
+ properties: {
2621
+ limit: {
2622
+ type: "number",
2623
+ description: "Maximum number of tables to return (default: 20, max: 100)",
2624
+ },
2625
+ table_schema: {
2626
+ type: "string",
2627
+ description: "Filter by specific database schema",
2628
+ },
2629
+ },
2630
+ },
2631
+ },
2632
+ {
2633
+ name: "get_index_usage_stats",
2634
+ description: "Get index usage statistics showing how often each index is used.",
2635
+ inputSchema: {
2636
+ type: "object",
2637
+ properties: {
2638
+ limit: {
2639
+ type: "number",
2640
+ description: "Maximum number of indexes to return (default: 20, max: 100)",
2641
+ },
2642
+ table_schema: {
2643
+ type: "string",
2644
+ description: "Filter by specific database schema",
2645
+ },
2646
+ },
2647
+ },
2648
+ },
2649
+ {
2650
+ name: "get_unused_indexes",
2651
+ description: "Identify indexes that are not being used by queries. These may be candidates for removal to improve write performance.",
2652
+ inputSchema: {
2653
+ type: "object",
2654
+ properties: {
2655
+ table_schema: {
2656
+ type: "string",
2657
+ description: "Filter by specific database schema",
2658
+ },
2659
+ },
2660
+ },
2661
+ },
2662
+ {
2663
+ name: "get_connection_pool_stats",
2664
+ description: "Get connection pool statistics including current connections, max usage, configuration, and health indicators.",
2665
+ inputSchema: {
2666
+ type: "object",
2667
+ properties: {},
2668
+ },
2669
+ },
2670
+ {
2671
+ name: "get_database_health_check",
2672
+ description: "Perform a comprehensive health check of the database including connection usage, buffer pool efficiency, aborted connections, and slow queries.",
2673
+ inputSchema: {
2674
+ type: "object",
2675
+ properties: {},
2676
+ },
2677
+ },
2678
+ {
2679
+ name: "reset_performance_stats",
2680
+ description: "Reset performance schema statistics. This clears query digest statistics, table I/O stats, and index usage stats. Requires 'utility' permission.",
2681
+ inputSchema: {
2682
+ type: "object",
2683
+ properties: {},
2684
+ },
2685
+ },
2561
2686
  ];
2562
2687
  // Create the MCP server
2563
2688
  const server = new index_js_1.Server({
@@ -2568,10 +2693,20 @@ const server = new index_js_1.Server({
2568
2693
  tools: {},
2569
2694
  },
2570
2695
  });
2571
- // Handle list tools request
2696
+ // Handle list tools request - filter tools based on permissions and categories
2572
2697
  server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
2698
+ // Filter tools to only return those that are enabled based on current config
2699
+ const enabledTools = TOOLS.filter((tool) => {
2700
+ // Convert tool name from snake_case to camelCase for checking
2701
+ // e.g., "list_databases" -> "listDatabases"
2702
+ const toolNameCamelCase = tool.name.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
2703
+ // Check if tool is enabled based on permissions and categories
2704
+ return mysqlMCP.isToolEnabled(toolNameCamelCase);
2705
+ });
2706
+ // Log the filtering results
2707
+ console.error(`Tools available: ${enabledTools.length} of ${TOOLS.length} total tools`);
2573
2708
  return {
2574
- tools: TOOLS,
2709
+ tools: enabledTools,
2575
2710
  };
2576
2711
  });
2577
2712
  // Handle tool call requests
@@ -2924,6 +3059,37 @@ server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
2924
3059
  case "generate_migration_from_diff":
2925
3060
  result = await mysqlMCP.generateMigrationFromDiff((args || {}));
2926
3061
  break;
3062
+ // Performance Monitoring Tools
3063
+ case "get_performance_metrics":
3064
+ result = await mysqlMCP.getPerformanceMetrics();
3065
+ break;
3066
+ case "get_top_queries_by_time":
3067
+ result = await mysqlMCP.getTopQueriesByTime((args || {}));
3068
+ break;
3069
+ case "get_top_queries_by_count":
3070
+ result = await mysqlMCP.getTopQueriesByCount((args || {}));
3071
+ break;
3072
+ case "get_slow_queries":
3073
+ result = await mysqlMCP.getSlowQueries((args || {}));
3074
+ break;
3075
+ case "get_table_io_stats":
3076
+ result = await mysqlMCP.getTableIOStats((args || {}));
3077
+ break;
3078
+ case "get_index_usage_stats":
3079
+ result = await mysqlMCP.getIndexUsageStats((args || {}));
3080
+ break;
3081
+ case "get_unused_indexes":
3082
+ result = await mysqlMCP.getUnusedIndexes((args || {}));
3083
+ break;
3084
+ case "get_connection_pool_stats":
3085
+ result = await mysqlMCP.getConnectionPoolStats();
3086
+ break;
3087
+ case "get_database_health_check":
3088
+ result = await mysqlMCP.getDatabaseHealthCheck();
3089
+ break;
3090
+ case "reset_performance_stats":
3091
+ result = await mysqlMCP.resetPerformanceStats();
3092
+ break;
2927
3093
  default:
2928
3094
  throw new Error(`Unknown tool: ${name}`);
2929
3095
  }
@@ -3028,10 +3194,16 @@ async function main() {
3028
3194
  await server.connect(transport);
3029
3195
  // Initialize the MySQL MCP instance AFTER transport is connected
3030
3196
  // This ensures the database connection pool is created when the server is ready
3031
- mysqlMCP = new index_js_2.MySQLMCP(permissions);
3032
- // Log the effective permissions to stderr
3033
- if (permissions) {
3197
+ mysqlMCP = new index_js_2.MySQLMCP(permissions, categories);
3198
+ // Log the effective filtering configuration to stderr
3199
+ if (permissions && categories) {
3200
+ console.error(`Active permissions (Layer 1): ${permissions}`);
3201
+ console.error(`Active categories (Layer 2): ${categories}`);
3202
+ console.error("Filtering mode: Dual-layer");
3203
+ }
3204
+ else if (permissions) {
3034
3205
  console.error(`Active permissions: ${permissions}`);
3206
+ console.error("Filtering mode: Single-layer");
3035
3207
  }
3036
3208
  else {
3037
3209
  console.error("Active permissions: all (default)");
@@ -6,6 +6,10 @@ export declare class SecurityLayer {
6
6
  private readonly ddlOperations;
7
7
  private featureConfig;
8
8
  constructor(featureConfig?: FeatureConfig);
9
+ /**
10
+ * Check if a query is a read-only information query (SHOW, DESCRIBE, EXPLAIN, etc.)
11
+ */
12
+ private isInformationQuery;
9
13
  /**
10
14
  * Validate input against a JSON schema
11
15
  */
@@ -39,7 +43,7 @@ export declare class SecurityLayer {
39
43
  sanitizedParams?: any[];
40
44
  };
41
45
  /**
42
- * Check if a query is a read-only SELECT query
46
+ * Check if a query is a read-only SELECT query or information query (SHOW, DESCRIBE, etc.)
43
47
  */
44
48
  isReadOnlyQuery(query: string): boolean;
45
49
  /**
@@ -34,6 +34,14 @@ class SecurityLayer {
34
34
  // Define DDL operations that require special permission
35
35
  this.ddlOperations = ["CREATE", "ALTER", "DROP", "TRUNCATE", "RENAME"];
36
36
  }
37
+ /**
38
+ * Check if a query is a read-only information query (SHOW, DESCRIBE, EXPLAIN, etc.)
39
+ */
40
+ isInformationQuery(query) {
41
+ const trimmedQuery = query.trim().toUpperCase();
42
+ const readOnlyCommands = ["SHOW", "DESCRIBE", "DESC", "EXPLAIN", "HELP"];
43
+ return readOnlyCommands.some((cmd) => trimmedQuery.startsWith(cmd));
44
+ }
37
45
  /**
38
46
  * Validate input against a JSON schema
39
47
  */
@@ -132,6 +140,10 @@ class SecurityLayer {
132
140
  }
133
141
  // Remove trailing semicolon for analysis
134
142
  const cleanQuery = trimmedQuery.replace(/;$/, "");
143
+ // Check if it's an information query (SHOW, DESCRIBE, EXPLAIN, etc.) - these are always allowed
144
+ if (this.isInformationQuery(trimmedQuery)) {
145
+ return { valid: true, queryType: "INFORMATION" };
146
+ }
135
147
  // Determine query type - check basic operations first
136
148
  let queryType = "";
137
149
  for (const operation of this.allowedOperations) {
@@ -257,9 +269,14 @@ class SecurityLayer {
257
269
  return { valid: true, sanitizedParams };
258
270
  }
259
271
  /**
260
- * Check if a query is a read-only SELECT query
272
+ * Check if a query is a read-only SELECT query or information query (SHOW, DESCRIBE, etc.)
261
273
  */
262
274
  isReadOnlyQuery(query) {
275
+ // Check if it's an information query first (SHOW, DESCRIBE, EXPLAIN, etc.)
276
+ if (this.isInformationQuery(query)) {
277
+ return true;
278
+ }
279
+ // Check if it's a SELECT query
263
280
  const validation = this.validateQuery(query);
264
281
  return validation.valid && validation.queryType === "SELECT";
265
282
  }
@@ -0,0 +1,111 @@
1
+ import { SecurityLayer } from '../security/securityLayer';
2
+ export declare class PerformanceTools {
3
+ private db;
4
+ private security;
5
+ constructor(security: SecurityLayer);
6
+ /**
7
+ * Get comprehensive performance metrics
8
+ */
9
+ getPerformanceMetrics(): Promise<{
10
+ status: string;
11
+ data?: any;
12
+ error?: string;
13
+ queryLog?: string;
14
+ }>;
15
+ /**
16
+ * Get top queries by execution time
17
+ */
18
+ getTopQueriesByTime(params?: {
19
+ limit?: number;
20
+ }): Promise<{
21
+ status: string;
22
+ data?: any[];
23
+ error?: string;
24
+ queryLog?: string;
25
+ }>;
26
+ /**
27
+ * Get top queries by execution count
28
+ */
29
+ getTopQueriesByCount(params?: {
30
+ limit?: number;
31
+ }): Promise<{
32
+ status: string;
33
+ data?: any[];
34
+ error?: string;
35
+ queryLog?: string;
36
+ }>;
37
+ /**
38
+ * Get slow queries
39
+ */
40
+ getSlowQueries(params?: {
41
+ limit?: number;
42
+ threshold_seconds?: number;
43
+ }): Promise<{
44
+ status: string;
45
+ data?: any[];
46
+ error?: string;
47
+ queryLog?: string;
48
+ }>;
49
+ /**
50
+ * Get table I/O statistics
51
+ */
52
+ getTableIOStats(params?: {
53
+ limit?: number;
54
+ table_schema?: string;
55
+ }): Promise<{
56
+ status: string;
57
+ data?: any[];
58
+ error?: string;
59
+ queryLog?: string;
60
+ }>;
61
+ /**
62
+ * Get index usage statistics
63
+ */
64
+ getIndexUsageStats(params?: {
65
+ limit?: number;
66
+ table_schema?: string;
67
+ }): Promise<{
68
+ status: string;
69
+ data?: any[];
70
+ error?: string;
71
+ queryLog?: string;
72
+ }>;
73
+ /**
74
+ * Get unused indexes
75
+ */
76
+ getUnusedIndexes(params?: {
77
+ table_schema?: string;
78
+ }): Promise<{
79
+ status: string;
80
+ data?: any[];
81
+ error?: string;
82
+ queryLog?: string;
83
+ }>;
84
+ /**
85
+ * Get connection pool statistics
86
+ */
87
+ getConnectionPoolStats(): Promise<{
88
+ status: string;
89
+ data?: any;
90
+ error?: string;
91
+ queryLog?: string;
92
+ }>;
93
+ /**
94
+ * Get database health check
95
+ */
96
+ getDatabaseHealthCheck(): Promise<{
97
+ status: string;
98
+ data?: any;
99
+ error?: string;
100
+ queryLog?: string;
101
+ }>;
102
+ /**
103
+ * Reset performance schema statistics
104
+ */
105
+ resetPerformanceStats(): Promise<{
106
+ status: string;
107
+ message?: string;
108
+ error?: string;
109
+ queryLog?: string;
110
+ }>;
111
+ }