@berthojoris/mcp-mysql-server 1.2.4 → 1.2.6

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
@@ -1116,92 +1116,12 @@ FLUSH PRIVILEGES;
1116
1116
 
1117
1117
  ---
1118
1118
 
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
1119
  ## 📄 License
1184
1120
 
1185
1121
  MIT License - see [LICENSE](LICENSE) file for details.
1186
1122
 
1187
1123
  ---
1188
1124
 
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
1125
  ## 🗺️ Roadmap
1206
1126
 
1207
1127
  ### Core Features
@@ -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();
@@ -108,20 +108,20 @@ class DatabaseTools {
108
108
  };
109
109
  }
110
110
  try {
111
- const query = `
112
- SELECT
113
- COLUMN_NAME as column_name,
114
- DATA_TYPE as data_type,
115
- IS_NULLABLE as is_nullable,
116
- COLUMN_KEY as column_key,
117
- COLUMN_DEFAULT as column_default,
118
- EXTRA as extra
119
- FROM
120
- INFORMATION_SCHEMA.COLUMNS
121
- WHERE
122
- TABLE_NAME = ?
123
- ORDER BY
124
- ORDINAL_POSITION
111
+ const query = `
112
+ SELECT
113
+ COLUMN_NAME as column_name,
114
+ DATA_TYPE as data_type,
115
+ IS_NULLABLE as is_nullable,
116
+ COLUMN_KEY as column_key,
117
+ COLUMN_DEFAULT as column_default,
118
+ EXTRA as extra
119
+ FROM
120
+ INFORMATION_SCHEMA.COLUMNS
121
+ WHERE
122
+ TABLE_NAME = ?
123
+ ORDER BY
124
+ ORDINAL_POSITION
125
125
  `;
126
126
  const results = await this.db.query(query, [params.table_name]);
127
127
  return {
@@ -71,33 +71,33 @@ class UtilityTools {
71
71
  try {
72
72
  const { table_name } = params;
73
73
  // Query to get foreign keys where this table is the parent
74
- const parentQuery = `
75
- SELECT
76
- TABLE_NAME as child_table,
77
- COLUMN_NAME as child_column,
78
- REFERENCED_TABLE_NAME as parent_table,
79
- REFERENCED_COLUMN_NAME as parent_column,
80
- CONSTRAINT_NAME as constraint_name
81
- FROM
82
- INFORMATION_SCHEMA.KEY_COLUMN_USAGE
83
- WHERE
84
- REFERENCED_TABLE_NAME = ?
85
- AND REFERENCED_TABLE_SCHEMA = DATABASE()
74
+ const parentQuery = `
75
+ SELECT
76
+ TABLE_NAME as child_table,
77
+ COLUMN_NAME as child_column,
78
+ REFERENCED_TABLE_NAME as parent_table,
79
+ REFERENCED_COLUMN_NAME as parent_column,
80
+ CONSTRAINT_NAME as constraint_name
81
+ FROM
82
+ INFORMATION_SCHEMA.KEY_COLUMN_USAGE
83
+ WHERE
84
+ REFERENCED_TABLE_NAME = ?
85
+ AND REFERENCED_TABLE_SCHEMA = DATABASE()
86
86
  `;
87
87
  // Query to get foreign keys where this table is the child
88
- const childQuery = `
89
- SELECT
90
- TABLE_NAME as child_table,
91
- COLUMN_NAME as child_column,
92
- REFERENCED_TABLE_NAME as parent_table,
93
- REFERENCED_COLUMN_NAME as parent_column,
94
- CONSTRAINT_NAME as constraint_name
95
- FROM
96
- INFORMATION_SCHEMA.KEY_COLUMN_USAGE
97
- WHERE
98
- TABLE_NAME = ?
99
- AND REFERENCED_TABLE_NAME IS NOT NULL
100
- AND TABLE_SCHEMA = DATABASE()
88
+ const childQuery = `
89
+ SELECT
90
+ TABLE_NAME as child_table,
91
+ COLUMN_NAME as child_column,
92
+ REFERENCED_TABLE_NAME as parent_table,
93
+ REFERENCED_COLUMN_NAME as parent_column,
94
+ CONSTRAINT_NAME as constraint_name
95
+ FROM
96
+ INFORMATION_SCHEMA.KEY_COLUMN_USAGE
97
+ WHERE
98
+ TABLE_NAME = ?
99
+ AND REFERENCED_TABLE_NAME IS NOT NULL
100
+ AND TABLE_SCHEMA = DATABASE()
101
101
  `;
102
102
  // Execute both queries
103
103
  const parentRelationships = await this.db.query(parentQuery, [table_name]);
package/manifest.json CHANGED
@@ -1,248 +1,248 @@
1
- {
2
- "name": "mysql-mcp",
3
- "description": "A Model Context Protocol for MySQL database interaction",
4
- "version": "1.0.0",
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
- ]
1
+ {
2
+ "name": "mysql-mcp",
3
+ "description": "A Model Context Protocol for MySQL database interaction",
4
+ "version": "1.0.0",
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
248
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@berthojoris/mcp-mysql-server",
3
- "version": "1.2.4",
3
+ "version": "1.2.6",
4
4
  "description": "Model Context Protocol server for MySQL database integration with dynamic per-project permissions",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",