@berthojoris/mcp-mysql-server 1.9.3 → 1.10.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.
@@ -25,14 +25,14 @@ class UtilityTools {
25
25
  // Exclude password for security
26
26
  };
27
27
  return {
28
- status: 'success',
29
- data: connectionInfo
28
+ status: "success",
29
+ data: connectionInfo,
30
30
  };
31
31
  }
32
32
  catch (error) {
33
33
  return {
34
- status: 'error',
35
- error: error.message
34
+ status: "error",
35
+ error: error.message,
36
36
  };
37
37
  }
38
38
  }
@@ -42,18 +42,104 @@ class UtilityTools {
42
42
  async testConnection() {
43
43
  try {
44
44
  const result = await this.db.testConnection();
45
+ if (!result.connected) {
46
+ // Provide detailed diagnostics based on error code
47
+ const errorCode = result.errorCode || "UNKNOWN";
48
+ const errorMessage = result.error || "Unknown connection error";
49
+ let diagnosticMessage = "āŒ Database Connection Failed\n\n";
50
+ diagnosticMessage += `Error: ${errorMessage}\n`;
51
+ diagnosticMessage += `Error Code: ${errorCode}\n\n`;
52
+ // Provide specific guidance based on error code
53
+ if (errorCode === "ECONNREFUSED" ||
54
+ errorCode === "ER_CONNECTION_REFUSED") {
55
+ diagnosticMessage +=
56
+ "šŸ” Diagnosis: MySQL server is not accepting connections\n\n";
57
+ diagnosticMessage += "āœ… Troubleshooting Steps:\n";
58
+ diagnosticMessage += "1. Check if MySQL server is running:\n";
59
+ diagnosticMessage +=
60
+ ' • Windows: Open Services and look for "MySQL" service\n';
61
+ diagnosticMessage +=
62
+ " • Linux/Mac: Run `sudo systemctl status mysql` or `brew services list`\n";
63
+ diagnosticMessage += "2. Start MySQL server if it's stopped:\n";
64
+ diagnosticMessage +=
65
+ " • Windows: Start the MySQL service from Services panel\n";
66
+ diagnosticMessage += " • Linux: `sudo systemctl start mysql`\n";
67
+ diagnosticMessage += " • Mac: `brew services start mysql`\n";
68
+ diagnosticMessage +=
69
+ "3. Verify server is listening on the correct port (default: 3306)\n";
70
+ }
71
+ else if (errorCode === "ENOTFOUND" || errorCode === "EAI_AGAIN") {
72
+ diagnosticMessage += "šŸ” Diagnosis: Cannot resolve database host\n\n";
73
+ diagnosticMessage += "āœ… Troubleshooting Steps:\n";
74
+ diagnosticMessage += "1. Check your DB_HOST configuration\n";
75
+ diagnosticMessage += "2. Verify network connectivity\n";
76
+ diagnosticMessage +=
77
+ '3. If using "localhost", try "127.0.0.1" instead\n';
78
+ }
79
+ else if (errorCode === "ER_ACCESS_DENIED_ERROR") {
80
+ diagnosticMessage += "šŸ” Diagnosis: Authentication failed\n\n";
81
+ diagnosticMessage += "āœ… Troubleshooting Steps:\n";
82
+ diagnosticMessage +=
83
+ "1. Verify DB_USER and DB_PASSWORD in your configuration\n";
84
+ diagnosticMessage += "2. Check MySQL user permissions\n";
85
+ diagnosticMessage += "3. Ensure user has access from your host\n";
86
+ }
87
+ else if (errorCode === "ER_BAD_DB_ERROR") {
88
+ diagnosticMessage += "šŸ” Diagnosis: Database does not exist\n\n";
89
+ diagnosticMessage += "āœ… Troubleshooting Steps:\n";
90
+ diagnosticMessage += "1. Verify DB_NAME in your configuration\n";
91
+ diagnosticMessage += "2. Create the database if it doesn't exist\n";
92
+ diagnosticMessage +=
93
+ "3. Check database name spelling and case sensitivity\n";
94
+ }
95
+ else if (errorCode === "ETIMEDOUT" || errorCode === "ECONNABORTED") {
96
+ diagnosticMessage += "šŸ” Diagnosis: Connection timeout\n\n";
97
+ diagnosticMessage += "āœ… Troubleshooting Steps:\n";
98
+ diagnosticMessage +=
99
+ "1. Check if firewall is blocking MySQL port (3306)\n";
100
+ diagnosticMessage +=
101
+ "2. Verify MySQL is configured to accept remote connections\n";
102
+ diagnosticMessage +=
103
+ "3. Check network connectivity to database server\n";
104
+ }
105
+ else {
106
+ diagnosticMessage += "āœ… General Troubleshooting Steps:\n";
107
+ diagnosticMessage += "1. Verify MySQL server is running\n";
108
+ diagnosticMessage +=
109
+ "2. Check connection settings in your .env file:\n";
110
+ diagnosticMessage +=
111
+ " • DB_HOST, DB_PORT, DB_USER, DB_PASSWORD, DB_NAME\n";
112
+ diagnosticMessage += "3. Review MySQL server logs for details\n";
113
+ }
114
+ diagnosticMessage += "\nšŸ“‹ Current Configuration:\n";
115
+ diagnosticMessage += ` Host: ${this.db.pool.pool.config.connectionConfig.host}\n`;
116
+ diagnosticMessage += ` Port: ${this.db.pool.pool.config.connectionConfig.port}\n`;
117
+ diagnosticMessage += ` User: ${this.db.pool.pool.config.connectionConfig.user}\n`;
118
+ diagnosticMessage += ` Database: ${this.db.pool.pool.config.connectionConfig.database}\n`;
119
+ return {
120
+ status: "error",
121
+ error: diagnosticMessage,
122
+ data: {
123
+ connected: false,
124
+ latency: -1,
125
+ errorCode: errorCode,
126
+ rawError: errorMessage,
127
+ },
128
+ };
129
+ }
45
130
  return {
46
- status: result.connected ? 'success' : 'error',
131
+ status: "success",
47
132
  data: {
48
133
  connected: result.connected,
49
- latency: result.latency
50
- }
134
+ latency: result.latency,
135
+ message: `āœ… Successfully connected to database in ${result.latency}ms`,
136
+ },
51
137
  };
52
138
  }
53
139
  catch (error) {
54
140
  return {
55
- status: 'error',
56
- error: error.message
141
+ status: "error",
142
+ error: `āŒ Unexpected error while testing connection: ${error?.message || "Unknown error"}`,
57
143
  };
58
144
  }
59
145
  }
@@ -64,58 +150,63 @@ class UtilityTools {
64
150
  // Validate input
65
151
  if (!(0, schemas_1.validateGetTableRelationships)(params)) {
66
152
  return {
67
- status: 'error',
68
- error: 'Invalid parameters: ' + JSON.stringify(schemas_1.validateGetTableRelationships.errors)
153
+ status: "error",
154
+ error: "Invalid parameters: " +
155
+ JSON.stringify(schemas_1.validateGetTableRelationships.errors),
69
156
  };
70
157
  }
71
158
  try {
72
159
  const { table_name } = params;
73
160
  // Query to get foreign keys where this table is the parent
74
161
  const parentQuery = `
75
- SELECT
162
+ SELECT
76
163
  TABLE_NAME as child_table,
77
164
  COLUMN_NAME as child_column,
78
165
  REFERENCED_TABLE_NAME as parent_table,
79
166
  REFERENCED_COLUMN_NAME as parent_column,
80
167
  CONSTRAINT_NAME as constraint_name
81
- FROM
168
+ FROM
82
169
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE
83
- WHERE
170
+ WHERE
84
171
  REFERENCED_TABLE_NAME = ?
85
172
  AND REFERENCED_TABLE_SCHEMA = DATABASE()
86
173
  `;
87
174
  // Query to get foreign keys where this table is the child
88
175
  const childQuery = `
89
- SELECT
176
+ SELECT
90
177
  TABLE_NAME as child_table,
91
178
  COLUMN_NAME as child_column,
92
179
  REFERENCED_TABLE_NAME as parent_table,
93
180
  REFERENCED_COLUMN_NAME as parent_column,
94
181
  CONSTRAINT_NAME as constraint_name
95
- FROM
182
+ FROM
96
183
  INFORMATION_SCHEMA.KEY_COLUMN_USAGE
97
- WHERE
184
+ WHERE
98
185
  TABLE_NAME = ?
99
186
  AND REFERENCED_TABLE_NAME IS NOT NULL
100
187
  AND TABLE_SCHEMA = DATABASE()
101
188
  `;
102
189
  // Execute both queries
103
- const parentRelationships = await this.db.query(parentQuery, [table_name]);
104
- const childRelationships = await this.db.query(childQuery, [table_name]);
190
+ const parentRelationships = await this.db.query(parentQuery, [
191
+ table_name,
192
+ ]);
193
+ const childRelationships = await this.db.query(childQuery, [
194
+ table_name,
195
+ ]);
105
196
  return {
106
- status: 'success',
197
+ status: "success",
107
198
  data: {
108
199
  as_parent: parentRelationships,
109
- as_child: childRelationships
200
+ as_child: childRelationships,
110
201
  },
111
- queryLog: this.db.getFormattedQueryLogs(2)
202
+ queryLog: this.db.getFormattedQueryLogs(2),
112
203
  };
113
204
  }
114
205
  catch (error) {
115
206
  return {
116
- status: 'error',
207
+ status: "error",
117
208
  error: error.message,
118
- queryLog: this.db.getFormattedQueryLogs(2)
209
+ queryLog: this.db.getFormattedQueryLogs(2),
119
210
  };
120
211
  }
121
212
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@berthojoris/mcp-mysql-server",
3
- "version": "1.9.3",
3
+ "version": "1.10.0",
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",