@berthojoris/mcp-mysql-server 1.6.0 → 1.6.2

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 CHANGED
@@ -5,6 +5,37 @@ All notable changes to the MySQL MCP Server will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.6.2] - 2025-11-22
9
+
10
+ ### Fixed
11
+ - **Security keyword false positive bug** - Fixed issue where `run_query` rejected valid SELECT queries containing table names like "users"
12
+ - The dangerous keyword check was using substring matching (`includes()`) which caused "USER" to match "USERS"
13
+ - Changed to word boundary regex matching (`\bKEYWORD\b`) to only match whole words
14
+ - `SELECT * FROM users` now works correctly while `SELECT USER()` is still blocked as intended
15
+
16
+ ### Changed
17
+ - **Updated tool count in README.md** - Corrected tool count from 30/73 to 85 powerful tools
18
+ - Accurate count of all available MCP tools across all categories
19
+
20
+ ## [1.4.16] - 2025-11-22
21
+
22
+ ### Added
23
+ - **get_table_size tool** - Added get_table_size tool to manifest.json and documentation
24
+ - Tool was implemented in server code but missing from manifest causing "Unknown tool" error
25
+ - Added proper input/output schema to manifest.json
26
+ - Enhanced documentation with usage examples and parameter details
27
+ - Updated version in manifest.json to match server code (1.4.4)
28
+
29
+ ### Fixed
30
+ - **Manifest synchronization** - Fixed manifest.json to include all implemented tools
31
+ - Many tools were implemented in server code but missing from manifest.json
32
+ - get_table_size tool now properly exposed to MCP clients
33
+ - Version number synchronized between manifest and server code
34
+
35
+ ### Documentation
36
+ - Enhanced Table Maintenance section with complete get_table_size examples
37
+ - Added proper usage patterns and parameter documentation
38
+
8
39
  ## [1.4.15] - 2025-11-22
9
40
 
10
41
  ### Fixed
package/DOCUMENTATIONS.md CHANGED
@@ -838,6 +838,8 @@ Table maintenance tools help optimize performance and fix issues.
838
838
 
839
839
  ### Getting Table Size Information
840
840
 
841
+ **User:** *"Get size information for all tables in the database"*
842
+
841
843
  ```json
842
844
  {
843
845
  "tool": "get_table_size",
@@ -845,6 +847,17 @@ Table maintenance tools help optimize performance and fix issues.
845
847
  }
846
848
  ```
847
849
 
850
+ **User:** *"Get size information for a specific table"*
851
+
852
+ ```json
853
+ {
854
+ "tool": "get_table_size",
855
+ "arguments": {
856
+ "table_name": "orders"
857
+ }
858
+ }
859
+ ```
860
+
848
861
  **Returns:**
849
862
  ```json
850
863
  {
@@ -864,6 +877,11 @@ Table maintenance tools help optimize performance and fix issues.
864
877
  }
865
878
  ```
866
879
 
880
+ **Usage:**
881
+ - Get size information for all tables (no arguments)
882
+ - Get size for specific table (use `table_name` parameter)
883
+ - Optional `database` parameter to specify different database
884
+
867
885
  ---
868
886
 
869
887
  ## 📊 Process & Server Management
package/README.md CHANGED
@@ -11,7 +11,7 @@ A fully-featured **Model Context Protocol (MCP)** server for MySQL database inte
11
11
 
12
12
  - ✅ **Full MCP Protocol Support** - Works with Claude Desktop, Cline, Windsurf, and any MCP-compatible AI agent
13
13
  - 🔐 **Secure by Default** - Parameterized queries, SQL injection protection, permission-based access control
14
- - 🛠️ **30 Powerful Tools** - Complete database operations (CRUD, DDL, queries, schema inspection, transactions, stored procedures, bulk operations)
14
+ - 🛠️ **85 Powerful Tools** - Complete database operations (CRUD, DDL, queries, schema inspection, transactions, stored procedures, bulk operations)
15
15
  - 🎛️ **Dynamic Per-Project Permissions** - Each AI agent can have different access levels
16
16
  - 🗃️ **DDL Support** - Create, alter, and drop tables (when explicitly enabled)
17
17
  - 💎 **Transaction Support** - Full ACID transaction management (BEGIN, COMMIT, ROLLBACK)
@@ -463,7 +463,7 @@ After (DDL enabled):
463
463
 
464
464
  ## 🛠️ Available Tools
465
465
 
466
- The MCP server provides **72 powerful tools**:
466
+ The MCP server provides **85 powerful tools**:
467
467
 
468
468
  ### Database Discovery (4 tools)
469
469
 
@@ -160,7 +160,9 @@ class SecurityLayer {
160
160
  // When bypassDangerousCheck is true (user has 'execute' permission), skip this check
161
161
  if (!bypassDangerousCheck) {
162
162
  for (const keyword of this.dangerousKeywords) {
163
- if (cleanQuery.includes(keyword)) {
163
+ // Use word boundary regex to avoid false positives (e.g., "USER" matching "USERS")
164
+ const keywordRegex = new RegExp(`\\b${keyword}\\b`, "i");
165
+ if (keywordRegex.test(cleanQuery)) {
164
166
  return {
165
167
  valid: false,
166
168
  error: `Dangerous keyword detected: ${keyword}. This requires 'execute' permission.`,
package/manifest.json CHANGED
@@ -1,248 +1,290 @@
1
- {
2
- "name": "mysql-mcp",
3
- "description": "A Model Context Protocol for MySQL database interaction",
4
- "version": "1.2.6",
5
- "tools": [
6
- {
7
- "name": "list_databases",
8
- "description": "Lists all databases available on the MySQL server.",
9
- "input_schema": {},
10
- "output_schema": {
11
- "type": "array",
12
- "items": { "type": "string" }
13
- }
14
- },
15
- {
16
- "name": "list_tables",
17
- "description": "Lists all tables in the connected MySQL database.",
18
- "input_schema": {},
19
- "output_schema": {
20
- "type": "array",
21
- "items": { "type": "string" }
22
- }
23
- },
24
- {
25
- "name": "read_table_schema",
26
- "description": "Reads the schema of a specified table.",
27
- "input_schema": {
28
- "type": "object",
29
- "properties": {
30
- "table_name": { "type": "string" }
31
- },
32
- "required": ["table_name"]
33
- },
34
- "output_schema": {
35
- "type": "object",
36
- "properties": {
37
- "columns": {
38
- "type": "array",
39
- "items": {
40
- "type": "object",
41
- "properties": {
42
- "name": { "type": "string" },
43
- "type": { "type": "string" },
44
- "nullable": { "type": "boolean" },
45
- "default": { "type": ["string", "null"] },
46
- "primary_key": { "type": "boolean" }
47
- }
48
- }
49
- },
50
- "primary_key": { "type": ["string", "null"] },
51
- "indexes": {
52
- "type": "array",
53
- "items": { "type": "string" }
54
- }
55
- }
56
- }
57
- },
58
- {
59
- "name": "create_record",
60
- "description": "Creates a new record in the specified table.",
61
- "input_schema": {
62
- "type": "object",
63
- "properties": {
64
- "table_name": { "type": "string" },
65
- "data": { "type": "object" }
66
- },
67
- "required": ["table_name", "data"]
68
- },
69
- "output_schema": {
70
- "type": "object",
71
- "properties": {
72
- "success": { "type": "boolean" },
73
- "id": { "type": ["string", "number"] },
74
- "affected_rows": { "type": "number" }
75
- }
76
- }
77
- },
78
- {
79
- "name": "read_records",
80
- "description": "Reads records from the specified table with optional filtering, pagination, and sorting.",
81
- "input_schema": {
82
- "type": "object",
83
- "properties": {
84
- "table_name": { "type": "string" },
85
- "filters": { "type": "object" },
86
- "limit": { "type": "number" },
87
- "offset": { "type": "number" },
88
- "sort_by": { "type": "string" },
89
- "sort_direction": { "type": "string", "enum": ["ASC", "DESC"] }
90
- },
91
- "required": ["table_name"]
92
- },
93
- "output_schema": {
94
- "type": "object",
95
- "properties": {
96
- "records": { "type": "array" },
97
- "total": { "type": "number" }
98
- }
99
- }
100
- },
101
- {
102
- "name": "update_record",
103
- "description": "Updates an existing record in the specified table.",
104
- "input_schema": {
105
- "type": "object",
106
- "properties": {
107
- "table_name": { "type": "string" },
108
- "id_field": { "type": "string" },
109
- "id": { "type": ["string", "number"] },
110
- "data": { "type": "object" }
111
- },
112
- "required": ["table_name", "id", "data"]
113
- },
114
- "output_schema": {
115
- "type": "object",
116
- "properties": {
117
- "success": { "type": "boolean" },
118
- "affected_rows": { "type": "number" }
119
- }
120
- }
121
- },
122
- {
123
- "name": "delete_record",
124
- "description": "Deletes a record from the specified table.",
125
- "input_schema": {
126
- "type": "object",
127
- "properties": {
128
- "table_name": { "type": "string" },
129
- "id_field": { "type": "string" },
130
- "id": { "type": ["string", "number"] }
131
- },
132
- "required": ["table_name", "id"]
133
- },
134
- "output_schema": {
135
- "type": "object",
136
- "properties": {
137
- "success": { "type": "boolean" },
138
- "affected_rows": { "type": "number" }
139
- }
140
- }
141
- },
142
- {
143
- "name": "run_query",
144
- "description": "Runs a read-only SQL query with optional parameters.",
145
- "input_schema": {
146
- "type": "object",
147
- "properties": {
148
- "query": { "type": "string" },
149
- "params": { "type": "array" }
150
- },
151
- "required": ["query"]
152
- },
153
- "output_schema": {
154
- "type": "object",
155
- "properties": {
156
- "results": { "type": "array" },
157
- "fields": { "type": "array" }
158
- }
159
- }
160
- },
161
- {
162
- "name": "execute_sql",
163
- "description": "Executes a write SQL operation (INSERT, UPDATE, DELETE) with optional parameters.",
164
- "input_schema": {
165
- "type": "object",
166
- "properties": {
167
- "query": { "type": "string" },
168
- "params": { "type": "array" }
169
- },
170
- "required": ["query"]
171
- },
172
- "output_schema": {
173
- "type": "object",
174
- "properties": {
175
- "success": { "type": "boolean" },
176
- "affected_rows": { "type": "number" },
177
- "insert_id": { "type": ["number", "null"] }
178
- }
179
- }
180
- },
181
- {
182
- "name": "describe_connection",
183
- "description": "Returns information about the current database connection.",
184
- "input_schema": {},
185
- "output_schema": {
186
- "type": "object",
187
- "properties": {
188
- "host": { "type": "string" },
189
- "port": { "type": "number" },
190
- "database": { "type": "string" },
191
- "user": { "type": "string" },
192
- "connected": { "type": "boolean" }
193
- }
194
- }
195
- },
196
- {
197
- "name": "test_connection",
198
- "description": "Tests the database connection and returns latency information.",
199
- "input_schema": {},
200
- "output_schema": {
201
- "type": "object",
202
- "properties": {
203
- "success": { "type": "boolean" },
204
- "latency_ms": { "type": "number" },
205
- "message": { "type": "string" }
206
- }
207
- }
208
- },
209
- {
210
- "name": "get_table_relationships",
211
- "description": "Returns foreign key relationships for a specified table.",
212
- "input_schema": {
213
- "type": "object",
214
- "properties": {
215
- "table_name": { "type": "string" }
216
- },
217
- "required": ["table_name"]
218
- },
219
- "output_schema": {
220
- "type": "object",
221
- "properties": {
222
- "as_parent": {
223
- "type": "array",
224
- "items": {
225
- "type": "object",
226
- "properties": {
227
- "table": { "type": "string" },
228
- "column": { "type": "string" },
229
- "referenced_column": { "type": "string" }
230
- }
231
- }
232
- },
233
- "as_child": {
234
- "type": "array",
235
- "items": {
236
- "type": "object",
237
- "properties": {
238
- "table": { "type": "string" },
239
- "column": { "type": "string" },
240
- "referenced_column": { "type": "string" }
241
- }
242
- }
243
- }
244
- }
245
- }
246
- }
247
- ]
248
- }
1
+ {
2
+ "name": "mysql-mcp",
3
+ "description": "A Model Context Protocol for MySQL database interaction",
4
+ "version": "1.4.4",
5
+ "tools": [
6
+ {
7
+ "name": "list_databases",
8
+ "description": "Lists all databases available on the MySQL server.",
9
+ "input_schema": {},
10
+ "output_schema": {
11
+ "type": "array",
12
+ "items": { "type": "string" }
13
+ }
14
+ },
15
+ {
16
+ "name": "list_tables",
17
+ "description": "Lists all tables in the connected MySQL database.",
18
+ "input_schema": {},
19
+ "output_schema": {
20
+ "type": "array",
21
+ "items": { "type": "string" }
22
+ }
23
+ },
24
+ {
25
+ "name": "read_table_schema",
26
+ "description": "Reads the schema of a specified table.",
27
+ "input_schema": {
28
+ "type": "object",
29
+ "properties": {
30
+ "table_name": { "type": "string" }
31
+ },
32
+ "required": ["table_name"]
33
+ },
34
+ "output_schema": {
35
+ "type": "object",
36
+ "properties": {
37
+ "columns": {
38
+ "type": "array",
39
+ "items": {
40
+ "type": "object",
41
+ "properties": {
42
+ "name": { "type": "string" },
43
+ "type": { "type": "string" },
44
+ "nullable": { "type": "boolean" },
45
+ "default": { "type": ["string", "null"] },
46
+ "primary_key": { "type": "boolean" }
47
+ }
48
+ }
49
+ },
50
+ "primary_key": { "type": ["string", "null"] },
51
+ "indexes": {
52
+ "type": "array",
53
+ "items": { "type": "string" }
54
+ }
55
+ }
56
+ }
57
+ },
58
+ {
59
+ "name": "create_record",
60
+ "description": "Creates a new record in the specified table.",
61
+ "input_schema": {
62
+ "type": "object",
63
+ "properties": {
64
+ "table_name": { "type": "string" },
65
+ "data": { "type": "object" }
66
+ },
67
+ "required": ["table_name", "data"]
68
+ },
69
+ "output_schema": {
70
+ "type": "object",
71
+ "properties": {
72
+ "success": { "type": "boolean" },
73
+ "id": { "type": ["string", "number"] },
74
+ "affected_rows": { "type": "number" }
75
+ }
76
+ }
77
+ },
78
+ {
79
+ "name": "read_records",
80
+ "description": "Reads records from the specified table with optional filtering, pagination, and sorting.",
81
+ "input_schema": {
82
+ "type": "object",
83
+ "properties": {
84
+ "table_name": { "type": "string" },
85
+ "filters": { "type": "object" },
86
+ "limit": { "type": "number" },
87
+ "offset": { "type": "number" },
88
+ "sort_by": { "type": "string" },
89
+ "sort_direction": { "type": "string", "enum": ["ASC", "DESC"] }
90
+ },
91
+ "required": ["table_name"]
92
+ },
93
+ "output_schema": {
94
+ "type": "object",
95
+ "properties": {
96
+ "records": { "type": "array" },
97
+ "total": { "type": "number" }
98
+ }
99
+ }
100
+ },
101
+ {
102
+ "name": "update_record",
103
+ "description": "Updates an existing record in the specified table.",
104
+ "input_schema": {
105
+ "type": "object",
106
+ "properties": {
107
+ "table_name": { "type": "string" },
108
+ "id_field": { "type": "string" },
109
+ "id": { "type": ["string", "number"] },
110
+ "data": { "type": "object" }
111
+ },
112
+ "required": ["table_name", "id", "data"]
113
+ },
114
+ "output_schema": {
115
+ "type": "object",
116
+ "properties": {
117
+ "success": { "type": "boolean" },
118
+ "affected_rows": { "type": "number" }
119
+ }
120
+ }
121
+ },
122
+ {
123
+ "name": "delete_record",
124
+ "description": "Deletes a record from the specified table.",
125
+ "input_schema": {
126
+ "type": "object",
127
+ "properties": {
128
+ "table_name": { "type": "string" },
129
+ "id_field": { "type": "string" },
130
+ "id": { "type": ["string", "number"] }
131
+ },
132
+ "required": ["table_name", "id"]
133
+ },
134
+ "output_schema": {
135
+ "type": "object",
136
+ "properties": {
137
+ "success": { "type": "boolean" },
138
+ "affected_rows": { "type": "number" }
139
+ }
140
+ }
141
+ },
142
+ {
143
+ "name": "run_query",
144
+ "description": "Runs a read-only SQL query with optional parameters.",
145
+ "input_schema": {
146
+ "type": "object",
147
+ "properties": {
148
+ "query": { "type": "string" },
149
+ "params": { "type": "array" }
150
+ },
151
+ "required": ["query"]
152
+ },
153
+ "output_schema": {
154
+ "type": "object",
155
+ "properties": {
156
+ "results": { "type": "array" },
157
+ "fields": { "type": "array" }
158
+ }
159
+ }
160
+ },
161
+ {
162
+ "name": "execute_sql",
163
+ "description": "Executes a write SQL operation (INSERT, UPDATE, DELETE) with optional parameters.",
164
+ "input_schema": {
165
+ "type": "object",
166
+ "properties": {
167
+ "query": { "type": "string" },
168
+ "params": { "type": "array" }
169
+ },
170
+ "required": ["query"]
171
+ },
172
+ "output_schema": {
173
+ "type": "object",
174
+ "properties": {
175
+ "success": { "type": "boolean" },
176
+ "affected_rows": { "type": "number" },
177
+ "insert_id": { "type": ["number", "null"] }
178
+ }
179
+ }
180
+ },
181
+ {
182
+ "name": "describe_connection",
183
+ "description": "Returns information about the current database connection.",
184
+ "input_schema": {},
185
+ "output_schema": {
186
+ "type": "object",
187
+ "properties": {
188
+ "host": { "type": "string" },
189
+ "port": { "type": "number" },
190
+ "database": { "type": "string" },
191
+ "user": { "type": "string" },
192
+ "connected": { "type": "boolean" }
193
+ }
194
+ }
195
+ },
196
+ {
197
+ "name": "test_connection",
198
+ "description": "Tests the database connection and returns latency information.",
199
+ "input_schema": {},
200
+ "output_schema": {
201
+ "type": "object",
202
+ "properties": {
203
+ "success": { "type": "boolean" },
204
+ "latency_ms": { "type": "number" },
205
+ "message": { "type": "string" }
206
+ }
207
+ }
208
+ },
209
+ {
210
+ "name": "get_table_relationships",
211
+ "description": "Returns foreign key relationships for a specified table.",
212
+ "input_schema": {
213
+ "type": "object",
214
+ "properties": {
215
+ "table_name": { "type": "string" }
216
+ },
217
+ "required": ["table_name"]
218
+ },
219
+ "output_schema": {
220
+ "type": "object",
221
+ "properties": {
222
+ "as_parent": {
223
+ "type": "array",
224
+ "items": {
225
+ "type": "object",
226
+ "properties": {
227
+ "table": { "type": "string" },
228
+ "column": { "type": "string" },
229
+ "referenced_column": { "type": "string" }
230
+ }
231
+ }
232
+ },
233
+ "as_child": {
234
+ "type": "array",
235
+ "items": {
236
+ "type": "object",
237
+ "properties": {
238
+ "table": { "type": "string" },
239
+ "column": { "type": "string" },
240
+ "referenced_column": { "type": "string" }
241
+ }
242
+ }
243
+ }
244
+ }
245
+ }
246
+ },
247
+ {
248
+ "name": "get_table_size",
249
+ "description": "Gets size information for one or all tables including data and index sizes.",
250
+ "input_schema": {
251
+ "type": "object",
252
+ "properties": {
253
+ "table_name": {
254
+ "type": "string",
255
+ "description": "Optional: specific table name (omit for all tables)"
256
+ },
257
+ "database": {
258
+ "type": "string",
259
+ "description": "Optional: specific database name"
260
+ }
261
+ }
262
+ },
263
+ "output_schema": {
264
+ "type": "object",
265
+ "properties": {
266
+ "tables": {
267
+ "type": "array",
268
+ "items": {
269
+ "type": "object",
270
+ "properties": {
271
+ "table_name": { "type": "string" },
272
+ "row_count": { "type": "number" },
273
+ "data_size_bytes": { "type": "number" },
274
+ "index_size_bytes": { "type": "number" },
275
+ "total_size_mb": { "type": "string" }
276
+ }
277
+ }
278
+ },
279
+ "summary": {
280
+ "type": "object",
281
+ "properties": {
282
+ "total_tables": { "type": "number" },
283
+ "total_size_mb": { "type": "string" }
284
+ }
285
+ }
286
+ }
287
+ }
288
+ }
289
+ ]
290
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@berthojoris/mcp-mysql-server",
3
- "version": "1.6.0",
3
+ "version": "1.6.2",
4
4
  "description": "Model Context Protocol server for MySQL database integration with dynamic per-project permissions and data export capabilities",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",