@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/CHANGELOG.md +47 -0
- package/DOCUMENTATIONS.md +3847 -3145
- package/README.md +151 -13
- package/bin/mcp-mysql.js +110 -53
- package/dist/config/featureConfig.d.ts +72 -9
- package/dist/config/featureConfig.js +415 -87
- package/dist/db/connection.d.ts +2 -0
- package/dist/db/connection.js +7 -1
- package/dist/index.d.ts +83 -1
- package/dist/index.js +75 -2
- package/dist/mcp-server.js +179 -7
- package/dist/security/securityLayer.d.ts +5 -1
- package/dist/security/securityLayer.js +18 -1
- package/dist/tools/performanceTools.d.ts +111 -0
- package/dist/tools/performanceTools.js +623 -0
- package/dist/tools/utilityTools.js +115 -24
- package/package.json +1 -1
|
@@ -25,14 +25,14 @@ class UtilityTools {
|
|
|
25
25
|
// Exclude password for security
|
|
26
26
|
};
|
|
27
27
|
return {
|
|
28
|
-
status:
|
|
29
|
-
data: connectionInfo
|
|
28
|
+
status: "success",
|
|
29
|
+
data: connectionInfo,
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
catch (error) {
|
|
33
33
|
return {
|
|
34
|
-
status:
|
|
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:
|
|
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:
|
|
56
|
-
error: error
|
|
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:
|
|
68
|
-
error:
|
|
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, [
|
|
104
|
-
|
|
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:
|
|
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:
|
|
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.
|
|
3
|
+
"version": "1.10.1",
|
|
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",
|