@berthojoris/mcp-mysql-server 1.1.0 → 1.2.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/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.1.0",
3
+ "version": "1.2.1",
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",
@@ -71,10 +71,12 @@
71
71
  "devDependencies": {
72
72
  "@types/cors": "^2.8.17",
73
73
  "@types/express": "^4.17.21",
74
+ "@types/helmet": "^0.0.48",
74
75
  "@types/jest": "^29.5.4",
75
76
  "@types/jsonwebtoken": "^9.0.5",
76
77
  "@types/morgan": "^1.9.9",
77
78
  "@types/node": "^20.6.0",
79
+ "@types/winston": "^2.4.4",
78
80
  "jest": "^29.6.4",
79
81
  "ts-jest": "^29.1.1",
80
82
  "ts-node": "^10.9.1",
@@ -1,29 +0,0 @@
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;
@@ -1,114 +0,0 @@
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();