@berthojoris/mcp-mysql-server 1.2.5 → 1.4.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/LICENSE CHANGED
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2025
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2025
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -157,12 +157,14 @@ The MCP server provides **30 powerful tools**:
157
157
  | `drop_table` | Delete tables | `ddl` permission |
158
158
  | `execute_ddl` | Execute raw DDL SQL (CREATE, ALTER, DROP, TRUNCATE, RENAME) | `ddl` permission |
159
159
 
160
- ### Utilities (2 tools)
160
+ ### Utilities (4 tools)
161
161
 
162
162
  | Tool | Description |
163
163
  |------|-------------|
164
164
  | `test_connection` | Test database connectivity and measure latency |
165
165
  | `describe_connection` | Get current connection information |
166
+ | `export_table_to_csv` | Export table data to CSV format with optional filtering, pagination, and sorting |
167
+ | `export_query_to_csv` | Export the results of a SELECT query to CSV format |
166
168
 
167
169
  ### Transaction Management (5 tools)
168
170
 
@@ -281,6 +283,120 @@ You can have different databases with different permissions in the same AI agent
281
283
 
282
284
  ---
283
285
 
286
+ ## 🚫 Permission Error Handling
287
+
288
+ The MySQL MCP Server provides clear, user-friendly error messages when operations are attempted without proper permissions. This helps users understand exactly what permissions are needed and how to enable them.
289
+
290
+ ### Error Message Format
291
+
292
+ When a tool is called without the required permission, you'll receive a detailed error message like:
293
+
294
+ ```
295
+ ❌ Permission denied: Cannot use tool 'create_table'. This tool requires 'ddl' permission.
296
+
297
+ Current permissions: list,read,utility
298
+ To enable this tool, add 'ddl' to your permissions configuration.
299
+
300
+ Example configuration:
301
+ "args": ["mysql://user:pass@host:3306/db", "list,read,utility,ddl"]
302
+
303
+ Tool description: Create new tables with columns and indexes
304
+ ```
305
+
306
+ ### Common Permission Error Examples
307
+
308
+ #### Creating Tables Without DDL Permission
309
+
310
+ **User prompt:** *"Create a new table called 'products'"*
311
+
312
+ **Error response when DDL not enabled:**
313
+ ```
314
+ ❌ Permission denied: Cannot use tool 'create_table'. This tool requires 'ddl' permission.
315
+
316
+ Current permissions: list,read,utility
317
+ To enable this tool, add 'ddl' to your permissions configuration.
318
+
319
+ Example configuration:
320
+ "args": ["mysql://user:pass@host:3306/db", "list,read,utility,ddl"]
321
+
322
+ Tool description: Create new tables with columns and indexes
323
+ ```
324
+
325
+ #### Inserting Data Without Create Permission
326
+
327
+ **User prompt:** *"Add a new user to the users table"*
328
+
329
+ **Error response when CREATE not enabled:**
330
+ ```
331
+ ❌ Permission denied: Cannot use tool 'create_record'. This tool requires 'create' permission.
332
+
333
+ Current permissions: list,read,utility
334
+ To enable this tool, add 'create' to your permissions configuration.
335
+
336
+ Example configuration:
337
+ "args": ["mysql://user:pass@host:3306/db", "list,read,utility,create"]
338
+
339
+ Tool description: Insert new records with automatic SQL generation
340
+ ```
341
+
342
+ #### Updating Data Without Update Permission
343
+
344
+ **User prompt:** *"Update the email for user ID 123"*
345
+
346
+ **Error response when UPDATE not enabled:**
347
+ ```
348
+ ❌ Permission denied: Cannot use tool 'update_record'. This tool requires 'update' permission.
349
+
350
+ Current permissions: list,read,utility
351
+ To enable this tool, add 'update' to your permissions configuration.
352
+
353
+ Example configuration:
354
+ "args": ["mysql://user:pass@host:3306/db", "list,read,utility,update"]
355
+
356
+ Tool description: Update existing records based on conditions
357
+ ```
358
+
359
+ ### Permission Error Benefits
360
+
361
+ 1. **🎯 Clear Guidance** - Exact permission needed and how to add it
362
+ 2. **📋 Current State** - Shows what permissions are currently active
363
+ 3. **💡 Example Configuration** - Ready-to-use configuration example
364
+ 4. **📖 Tool Context** - Explains what the tool does
365
+ 5. **🔒 Security** - Prevents unauthorized operations while being helpful
366
+
367
+ ### Troubleshooting Permission Errors
368
+
369
+ If you encounter permission errors:
370
+
371
+ 1. **Check your configuration** - Verify the permissions string in your MCP configuration
372
+ 2. **Add required permission** - Add the missing permission to your configuration
373
+ 3. **Restart your AI agent** - Changes require a restart to take effect
374
+ 4. **Test with a simple operation** - Verify the permission is working
375
+
376
+ **Example fix for DDL operations:**
377
+
378
+ Before (DDL disabled):
379
+ ```json
380
+ {
381
+ "args": [
382
+ "mysql://user:pass@localhost:3306/db",
383
+ "list,read,utility"
384
+ ]
385
+ }
386
+ ```
387
+
388
+ After (DDL enabled):
389
+ ```json
390
+ {
391
+ "args": [
392
+ "mysql://user:pass@localhost:3306/db",
393
+ "list,read,utility,ddl"
394
+ ]
395
+ }
396
+ ```
397
+
398
+ ---
399
+
284
400
  ## 🏗️ DDL Operations
285
401
 
286
402
  DDL (Data Definition Language) operations allow AI to create, modify, and delete tables.
@@ -366,6 +482,140 @@ DDL operations are **disabled by default** for safety. Add `ddl` to permissions
366
482
 
367
483
  ---
368
484
 
485
+ ## 📤 Data Export Tools
486
+
487
+ The MySQL MCP Server provides powerful data export capabilities, allowing AI agents to export database content in CSV format for analysis, reporting, and data sharing.
488
+
489
+ ### Data Export Tools Overview
490
+
491
+ - **`export_table_to_csv`** - Export all or filtered data from a table to CSV format
492
+ - **`export_query_to_csv`** - Export the results of a custom SELECT query to CSV format
493
+
494
+ Both tools support:
495
+ - Filtering data with conditions
496
+ - Pagination for large datasets
497
+ - Sorting results
498
+ - Optional column headers
499
+ - Proper CSV escaping for special characters
500
+
501
+ ### Data Export Tool Examples
502
+
503
+ #### Export Table to CSV
504
+
505
+ **User prompt:** *"Export the first 100 users ordered by registration date to CSV"*
506
+
507
+ **AI will execute:**
508
+ ```json
509
+ {
510
+ "tool": "export_table_to_csv",
511
+ "arguments": {
512
+ "table_name": "users",
513
+ "sorting": {
514
+ "field": "registration_date",
515
+ "direction": "desc"
516
+ },
517
+ "pagination": {
518
+ "page": 1,
519
+ "limit": 100
520
+ },
521
+ "include_headers": true
522
+ }
523
+ }
524
+ ```
525
+
526
+ #### Export Filtered Data to CSV
527
+
528
+ **User prompt:** *"Export all users from the marketing department to CSV"*
529
+
530
+ **AI will execute:**
531
+ ```json
532
+ {
533
+ "tool": "export_table_to_csv",
534
+ "arguments": {
535
+ "table_name": "users",
536
+ "filters": [
537
+ {
538
+ "field": "department",
539
+ "operator": "eq",
540
+ "value": "marketing"
541
+ }
542
+ ],
543
+ "include_headers": true
544
+ }
545
+ }
546
+ ```
547
+
548
+ #### Export Query Results to CSV
549
+
550
+ **User prompt:** *"Export a report of total sales by product category to CSV"*
551
+
552
+ **AI will execute:**
553
+ ```json
554
+ {
555
+ "tool": "export_query_to_csv",
556
+ "arguments": {
557
+ "query": "SELECT category, SUM(sales_amount) as total_sales FROM sales GROUP BY category ORDER BY total_sales DESC",
558
+ "include_headers": true
559
+ }
560
+ }
561
+ ```
562
+
563
+ ### Data Export Best Practices
564
+
565
+ 1. ✅ **Use filtering** - Export only the data you need to reduce file size
566
+ 2. ✅ **Implement pagination** - For large datasets, use pagination to avoid memory issues
567
+ 3. ✅ **Include headers** - Make CSV files more understandable with column headers
568
+ 4. ✅ **Test with small datasets first** - Verify export format before processing large amounts of data
569
+ 5. ✅ **Use proper permissions** - Data export tools require `utility` permission
570
+
571
+ ### Common Data Export Patterns
572
+
573
+ **Pattern 1: Simple Table Export**
574
+ ```json
575
+ {
576
+ "tool": "export_table_to_csv",
577
+ "arguments": {
578
+ "table_name": "products",
579
+ "include_headers": true
580
+ }
581
+ }
582
+ ```
583
+
584
+ **Pattern 2: Filtered and Sorted Export**
585
+ ```json
586
+ {
587
+ "tool": "export_table_to_csv",
588
+ "arguments": {
589
+ "table_name": "orders",
590
+ "filters": [
591
+ {
592
+ "field": "order_date",
593
+ "operator": "gte",
594
+ "value": "2023-01-01"
595
+ }
596
+ ],
597
+ "sorting": {
598
+ "field": "order_date",
599
+ "direction": "desc"
600
+ },
601
+ "include_headers": true
602
+ }
603
+ }
604
+ ```
605
+
606
+ **Pattern 3: Complex Query Export**
607
+ ```json
608
+ {
609
+ "tool": "export_query_to_csv",
610
+ "arguments": {
611
+ "query": "SELECT u.name, u.email, COUNT(o.id) as order_count FROM users u LEFT JOIN orders o ON u.id = o.user_id GROUP BY u.id HAVING order_count > 5",
612
+ "include_headers": true
613
+ }
614
+ }
615
+ ```
616
+
617
+ ---
618
+
369
619
  ## 💰 Transaction Management
370
620
 
371
621
  The MySQL MCP Server provides full ACID transaction support, allowing you to group multiple database operations into atomic units.
@@ -1116,92 +1366,12 @@ FLUSH PRIVILEGES;
1116
1366
 
1117
1367
  ---
1118
1368
 
1119
- ## 📚 Development
1120
-
1121
- ### Project Structure
1122
-
1123
- ```
1124
- mysql-mcp/
1125
- ├── src/
1126
- │ ├── config/ # Configuration and permissions
1127
- │ ├── db/ # Database connection
1128
- │ ├── security/ # Security layer
1129
- │ ├── tools/ # Tool implementations
1130
- │ │ ├── databaseTools.ts # Database discovery
1131
- │ │ ├── crudTools.ts # CRUD operations
1132
- │ │ ├── queryTools.ts # Query execution
1133
- │ │ ├── ddlTools.ts # DDL operations
1134
- │ │ └── utilityTools.ts # Utilities
1135
- │ ├── validation/ # Input validation schemas
1136
- │ ├── index.ts # MySQLMCP class
1137
- │ ├── mcp-server.ts # MCP protocol server
1138
- │ └── server.ts # REST API server
1139
- ├── bin/
1140
- │ └── mcp-mysql.js # CLI entry point
1141
- ├── dist/ # Compiled JavaScript
1142
- ├── .env # Local environment config
1143
- ├── package.json
1144
- ├── tsconfig.json
1145
- └── README.md
1146
- ```
1147
-
1148
- ### Development Commands
1149
-
1150
- ```bash
1151
- # Install dependencies
1152
- npm install
1153
-
1154
- # Build TypeScript
1155
- npm run build
1156
-
1157
- # Run in development mode (MCP)
1158
- npm run dev:mcp
1159
-
1160
- # Run in development mode (API)
1161
- npm run dev:api
1162
-
1163
- # Run tests
1164
- npm test
1165
- ```
1166
-
1167
- ---
1168
-
1169
- ## 🤝 Contributing
1170
-
1171
- Contributions are welcome!
1172
-
1173
- 1. Fork the repository
1174
- 2. Create a feature branch: `git checkout -b feature/my-feature`
1175
- 3. Make your changes
1176
- 4. Build and test: `npm run build`
1177
- 5. Commit: `git commit -m "Add my feature"`
1178
- 6. Push: `git push origin feature/my-feature`
1179
- 7. Submit a pull request
1180
-
1181
- ---
1182
-
1183
1369
  ## 📄 License
1184
1370
 
1185
1371
  MIT License - see [LICENSE](LICENSE) file for details.
1186
1372
 
1187
1373
  ---
1188
1374
 
1189
- ## 🙏 Acknowledgments
1190
-
1191
- - Built with [@modelcontextprotocol/sdk](https://github.com/modelcontextprotocol/typescript-sdk)
1192
- - Compatible with [Claude Desktop](https://claude.ai/), [Cline](https://github.com/cline/cline), [Windsurf](https://codeium.com/windsurf), and other MCP-compatible tools
1193
- - Inspired by the Model Context Protocol specification
1194
-
1195
- ---
1196
-
1197
- ## 💬 Support
1198
-
1199
- - **Issues:** [GitHub Issues](https://github.com/berthojoris/mysql-mcp/issues)
1200
- - **Discussions:** [GitHub Discussions](https://github.com/berthojoris/mysql-mcp/discussions)
1201
- - **Documentation:** This README
1202
-
1203
- ---
1204
-
1205
1375
  ## 🗺️ Roadmap
1206
1376
 
1207
1377
  ### Core Features
@@ -1228,6 +1398,45 @@ MIT License - see [LICENSE](LICENSE) file for details.
1228
1398
  - [ ] Oracle Database adapter
1229
1399
  - [ ] SQL Server adapter
1230
1400
 
1401
+ ### Recommended Implementation Order
1402
+
1403
+ #### **Phase 1: Performance & Monitoring** 🚀
1404
+ - [ ] **Query result caching** - Dramatically improve response times for repeated queries
1405
+ - [ ] **Performance metrics** - Track query execution times and database performance
1406
+ - [ ] **Connection pool monitoring** - Monitor database connection health and usage
1407
+ - [ ] **Database health checks** - Comprehensive system health monitoring
1408
+
1409
+ #### **Phase 2: Data Management** 📊
1410
+ - [ ] **Database backup and restore tools** - Essential for production data safety
1411
+ - [ ] **Data migration utilities** - Move data between databases and environments
1412
+ - [ ] **Enhanced export/import** - Support for JSON, XML, Excel formats
1413
+ - [ ] **Query history & analytics** - Track and analyze database usage patterns
1414
+
1415
+ #### **Phase 3: Enterprise Features** 🏢
1416
+ - [ ] **Audit logging and compliance** - Track all database operations for security
1417
+ - [ ] **Schema versioning and migrations** - Version control for database schema changes
1418
+ - [ ] **Query optimization** - Automatic query analysis and optimization suggestions
1419
+ - [ ] **Advanced security features** - Enhanced access control and monitoring
1420
+
1421
+ #### **Phase 4: Multi-Database Support** 🌐
1422
+ - [ ] **PostgreSQL adapter** - Extend support to PostgreSQL databases
1423
+ - [ ] **MongoDB adapter** - Add NoSQL document database support
1424
+ - [ ] **SQLite adapter** - Support for lightweight embedded databases
1425
+ - [ ] **Database-agnostic operations** - Unified API across different database types
1426
+
1427
+ #### **Implementation Priority Matrix**
1428
+
1429
+ | Feature | Impact | Effort | Priority |
1430
+ |---------|--------|--------|----------|
1431
+ | Query Result Caching | High | Medium | 1 |
1432
+ | Database Backup/Restore | High | High | 2 |
1433
+ | Performance Monitoring | High | Medium | 3 |
1434
+ | Data Migration | High | High | 4 |
1435
+ | Query Optimization | Medium | Medium | 5 |
1436
+ | PostgreSQL Adapter | High | High | 6 |
1437
+ | Audit Logging | Medium | Low | 7 |
1438
+ | Schema Versioning | Medium | Medium | 8 |
1439
+
1231
1440
  ---
1232
1441
 
1233
1442
  **Made with ❤️ for the AI community**
@@ -0,0 +1,29 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ export interface User {
3
+ id: string;
4
+ username: string;
5
+ role: string;
6
+ }
7
+ export declare class AuthService {
8
+ /**
9
+ * Generate a JWT token for a user
10
+ */
11
+ generateToken(user: User): string;
12
+ /**
13
+ * Verify a JWT token
14
+ */
15
+ verifyToken(token: string): User;
16
+ /**
17
+ * Middleware to authenticate using JWT
18
+ */
19
+ authenticateJWT(req: Request, res: Response, next: NextFunction): void;
20
+ /**
21
+ * Middleware to authenticate using API key
22
+ */
23
+ authenticateApiKey(req: Request, res: Response, next: NextFunction): void;
24
+ /**
25
+ * Login endpoint handler
26
+ */
27
+ login(req: Request, res: Response): void;
28
+ }
29
+ export declare const authService: AuthService;
@@ -0,0 +1,114 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.authService = exports.AuthService = void 0;
7
+ const jsonwebtoken_1 = __importDefault(require("jsonwebtoken"));
8
+ // Environment variables
9
+ const JWT_SECRET = process.env.JWT_SECRET || 'default_secret_change_in_production';
10
+ const JWT_EXPIRES_IN = process.env.JWT_EXPIRES_IN || '24h';
11
+ const API_KEY = process.env.API_KEY;
12
+ class AuthService {
13
+ /**
14
+ * Generate a JWT token for a user
15
+ */
16
+ generateToken(user) {
17
+ // Cast to any to bypass TypeScript's strict type checking for JWT
18
+ return jsonwebtoken_1.default.sign(user, JWT_SECRET, { expiresIn: JWT_EXPIRES_IN });
19
+ }
20
+ /**
21
+ * Verify a JWT token
22
+ */
23
+ verifyToken(token) {
24
+ // Cast to any to bypass TypeScript's strict type checking for JWT
25
+ return jsonwebtoken_1.default.verify(token, JWT_SECRET);
26
+ }
27
+ /**
28
+ * Middleware to authenticate using JWT
29
+ */
30
+ authenticateJWT(req, res, next) {
31
+ const authHeader = req.headers['authorization'];
32
+ const token = authHeader && authHeader.split(' ')[1];
33
+ if (!token) {
34
+ res.status(401).json({
35
+ error: {
36
+ code: 'AUTH_TOKEN_MISSING',
37
+ message: 'Authentication token is required',
38
+ details: 'Please provide a valid JWT token in the Authorization header'
39
+ }
40
+ });
41
+ return;
42
+ }
43
+ try {
44
+ const user = this.verifyToken(token);
45
+ req.user = user;
46
+ next();
47
+ }
48
+ catch (error) {
49
+ res.status(403).json({
50
+ error: {
51
+ code: 'AUTH_TOKEN_INVALID',
52
+ message: 'Invalid or expired token',
53
+ details: 'Please provide a valid JWT token'
54
+ }
55
+ });
56
+ }
57
+ }
58
+ /**
59
+ * Middleware to authenticate using API key
60
+ */
61
+ authenticateApiKey(req, res, next) {
62
+ const providedApiKey = req.headers['x-api-key'];
63
+ if (!API_KEY) {
64
+ console.warn('API_KEY environment variable is not set');
65
+ res.status(500).json({
66
+ error: {
67
+ code: 'SERVER_CONFIG_ERROR',
68
+ message: 'Server configuration error',
69
+ details: 'API key authentication is not properly configured'
70
+ }
71
+ });
72
+ return;
73
+ }
74
+ if (!providedApiKey || providedApiKey !== API_KEY) {
75
+ res.status(401).json({
76
+ error: {
77
+ code: 'INVALID_API_KEY',
78
+ message: 'Invalid API key',
79
+ details: 'Please provide a valid API key in the X-API-Key header'
80
+ }
81
+ });
82
+ return;
83
+ }
84
+ next();
85
+ }
86
+ /**
87
+ * Login endpoint handler
88
+ */
89
+ login(req, res) {
90
+ const { username, password } = req.body;
91
+ // In a real application, you would validate credentials against a database
92
+ // This is a simplified example for demonstration purposes
93
+ if (username === 'admin' && password === 'password') {
94
+ const user = {
95
+ id: '1',
96
+ username: 'admin',
97
+ role: 'admin'
98
+ };
99
+ const token = this.generateToken(user);
100
+ res.json({ token });
101
+ }
102
+ else {
103
+ res.status(401).json({
104
+ error: {
105
+ code: 'INVALID_CREDENTIALS',
106
+ message: 'Invalid username or password',
107
+ details: 'Please check your credentials and try again'
108
+ }
109
+ });
110
+ }
111
+ }
112
+ }
113
+ exports.AuthService = AuthService;
114
+ exports.authService = new AuthService();
@@ -22,6 +22,7 @@ export declare const toolCategoryMap: Record<string, ToolCategory>;
22
22
  */
23
23
  export declare class FeatureConfig {
24
24
  private enabledCategories;
25
+ private originalConfigString;
25
26
  constructor(configStr?: string);
26
27
  /**
27
28
  * Parse MCP_CONFIG from provided string or environment variables
@@ -35,6 +36,10 @@ export declare class FeatureConfig {
35
36
  * Check if a specific tool is enabled
36
37
  */
37
38
  isToolEnabled(toolName: string): boolean;
39
+ /**
40
+ * Get detailed permission error message for a specific tool
41
+ */
42
+ getPermissionError(toolName: string): string;
38
43
  /**
39
44
  * Check if a category is enabled
40
45
  */