@berthojoris/mcp-mysql-server 1.0.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 +21 -0
- package/README.md +1142 -0
- package/bin/mcp-mysql.js +122 -0
- package/dist/auth/authService.d.ts +29 -0
- package/dist/auth/authService.js +114 -0
- package/dist/config/config.d.ts +12 -0
- package/dist/config/config.js +19 -0
- package/dist/config/featureConfig.d.ts +51 -0
- package/dist/config/featureConfig.js +130 -0
- package/dist/db/connection.d.ts +22 -0
- package/dist/db/connection.js +135 -0
- package/dist/index.d.ts +236 -0
- package/dist/index.js +273 -0
- package/dist/mcp-server.d.ts +2 -0
- package/dist/mcp-server.js +748 -0
- package/dist/security/securityLayer.d.ts +52 -0
- package/dist/security/securityLayer.js +213 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +283 -0
- package/dist/tools/crudTools.d.ts +59 -0
- package/dist/tools/crudTools.js +443 -0
- package/dist/tools/databaseTools.d.ts +33 -0
- package/dist/tools/databaseTools.js +108 -0
- package/dist/tools/ddlTools.d.ts +69 -0
- package/dist/tools/ddlTools.js +199 -0
- package/dist/tools/queryTools.d.ts +29 -0
- package/dist/tools/queryTools.js +119 -0
- package/dist/tools/storedProcedureTools.d.ts +80 -0
- package/dist/tools/storedProcedureTools.js +411 -0
- package/dist/tools/transactionTools.d.ts +45 -0
- package/dist/tools/transactionTools.js +130 -0
- package/dist/tools/utilityTools.d.ts +30 -0
- package/dist/tools/utilityTools.js +121 -0
- package/dist/validation/schemas.d.ts +423 -0
- package/dist/validation/schemas.js +287 -0
- package/manifest.json +248 -0
- package/package.json +83 -0
|
@@ -0,0 +1,748 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const index_js_1 = require("@modelcontextprotocol/sdk/server/index.js");
|
|
5
|
+
const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
6
|
+
const types_js_1 = require("@modelcontextprotocol/sdk/types.js");
|
|
7
|
+
const index_js_2 = require("./index.js");
|
|
8
|
+
// Get permissions from environment variable (set by bin/mcp-mysql.js)
|
|
9
|
+
// Priority: MCP_PERMISSIONS (from command line) > MCP_CONFIG (from .env) > all permissions
|
|
10
|
+
const permissions = process.env.MCP_PERMISSIONS || process.env.MCP_CONFIG || '';
|
|
11
|
+
// Initialize the MySQL MCP instance with permissions
|
|
12
|
+
const mysqlMCP = new index_js_2.MySQLMCP(permissions);
|
|
13
|
+
// Log the effective permissions to stderr
|
|
14
|
+
if (permissions) {
|
|
15
|
+
console.error(`Active permissions: ${permissions}`);
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
console.error('Active permissions: all (default)');
|
|
19
|
+
}
|
|
20
|
+
// Define all available tools with their schemas
|
|
21
|
+
const TOOLS = [
|
|
22
|
+
{
|
|
23
|
+
name: 'list_databases',
|
|
24
|
+
description: 'Lists all databases available on the MySQL server.',
|
|
25
|
+
inputSchema: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
properties: {},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: 'list_tables',
|
|
32
|
+
description: 'Lists all tables in the connected MySQL database.',
|
|
33
|
+
inputSchema: {
|
|
34
|
+
type: 'object',
|
|
35
|
+
properties: {
|
|
36
|
+
database: {
|
|
37
|
+
type: 'string',
|
|
38
|
+
description: 'Optional: specific database name to list tables from',
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: 'read_table_schema',
|
|
45
|
+
description: 'Reads the schema of a specified table, including columns, types, keys, and indexes.',
|
|
46
|
+
inputSchema: {
|
|
47
|
+
type: 'object',
|
|
48
|
+
properties: {
|
|
49
|
+
table_name: {
|
|
50
|
+
type: 'string',
|
|
51
|
+
description: 'Name of the table to read schema from',
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
required: ['table_name'],
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
name: 'create_record',
|
|
59
|
+
description: 'Creates a new record in the specified table.',
|
|
60
|
+
inputSchema: {
|
|
61
|
+
type: 'object',
|
|
62
|
+
properties: {
|
|
63
|
+
table_name: {
|
|
64
|
+
type: 'string',
|
|
65
|
+
description: 'Name of the table to insert into',
|
|
66
|
+
},
|
|
67
|
+
data: {
|
|
68
|
+
type: 'object',
|
|
69
|
+
description: 'Object containing column names and values to insert',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
required: ['table_name', 'data'],
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
name: 'read_records',
|
|
77
|
+
description: 'Reads records from the specified table with optional filtering, pagination, and sorting.',
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: 'object',
|
|
80
|
+
properties: {
|
|
81
|
+
table_name: {
|
|
82
|
+
type: 'string',
|
|
83
|
+
description: 'Name of the table to read from',
|
|
84
|
+
},
|
|
85
|
+
filters: {
|
|
86
|
+
type: 'array',
|
|
87
|
+
description: 'Array of filter conditions',
|
|
88
|
+
items: {
|
|
89
|
+
type: 'object',
|
|
90
|
+
properties: {
|
|
91
|
+
field: { type: 'string' },
|
|
92
|
+
operator: {
|
|
93
|
+
type: 'string',
|
|
94
|
+
enum: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'like', 'in']
|
|
95
|
+
},
|
|
96
|
+
value: {
|
|
97
|
+
description: 'Value to compare against (can be string, number, boolean, or array for "in" operator)'
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
required: ['field', 'operator', 'value'],
|
|
101
|
+
},
|
|
102
|
+
},
|
|
103
|
+
pagination: {
|
|
104
|
+
type: 'object',
|
|
105
|
+
properties: {
|
|
106
|
+
page: { type: 'number', description: 'Page number (starting from 1)' },
|
|
107
|
+
limit: { type: 'number', description: 'Number of records per page' },
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
sorting: {
|
|
111
|
+
type: 'object',
|
|
112
|
+
properties: {
|
|
113
|
+
field: { type: 'string', description: 'Field name to sort by' },
|
|
114
|
+
direction: { type: 'string', enum: ['asc', 'desc'] },
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
},
|
|
118
|
+
required: ['table_name'],
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'update_record',
|
|
123
|
+
description: 'Updates existing records in the specified table based on conditions.',
|
|
124
|
+
inputSchema: {
|
|
125
|
+
type: 'object',
|
|
126
|
+
properties: {
|
|
127
|
+
table_name: {
|
|
128
|
+
type: 'string',
|
|
129
|
+
description: 'Name of the table to update',
|
|
130
|
+
},
|
|
131
|
+
data: {
|
|
132
|
+
type: 'object',
|
|
133
|
+
description: 'Object containing column names and new values',
|
|
134
|
+
},
|
|
135
|
+
conditions: {
|
|
136
|
+
type: 'array',
|
|
137
|
+
description: 'Array of conditions to identify which records to update',
|
|
138
|
+
items: {
|
|
139
|
+
type: 'object',
|
|
140
|
+
properties: {
|
|
141
|
+
field: { type: 'string' },
|
|
142
|
+
operator: {
|
|
143
|
+
type: 'string',
|
|
144
|
+
enum: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'like', 'in']
|
|
145
|
+
},
|
|
146
|
+
value: {},
|
|
147
|
+
},
|
|
148
|
+
required: ['field', 'operator', 'value'],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
required: ['table_name', 'data', 'conditions'],
|
|
153
|
+
},
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
name: 'delete_record',
|
|
157
|
+
description: 'Deletes records from the specified table based on conditions.',
|
|
158
|
+
inputSchema: {
|
|
159
|
+
type: 'object',
|
|
160
|
+
properties: {
|
|
161
|
+
table_name: {
|
|
162
|
+
type: 'string',
|
|
163
|
+
description: 'Name of the table to delete from',
|
|
164
|
+
},
|
|
165
|
+
conditions: {
|
|
166
|
+
type: 'array',
|
|
167
|
+
description: 'Array of conditions to identify which records to delete',
|
|
168
|
+
items: {
|
|
169
|
+
type: 'object',
|
|
170
|
+
properties: {
|
|
171
|
+
field: { type: 'string' },
|
|
172
|
+
operator: {
|
|
173
|
+
type: 'string',
|
|
174
|
+
enum: ['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'like', 'in']
|
|
175
|
+
},
|
|
176
|
+
value: {},
|
|
177
|
+
},
|
|
178
|
+
required: ['field', 'operator', 'value'],
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
182
|
+
required: ['table_name', 'conditions'],
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
{
|
|
186
|
+
name: 'run_query',
|
|
187
|
+
description: 'Runs a read-only SQL SELECT query with optional parameters. Only SELECT statements are allowed.',
|
|
188
|
+
inputSchema: {
|
|
189
|
+
type: 'object',
|
|
190
|
+
properties: {
|
|
191
|
+
query: {
|
|
192
|
+
type: 'string',
|
|
193
|
+
description: 'SQL SELECT query to execute',
|
|
194
|
+
},
|
|
195
|
+
params: {
|
|
196
|
+
type: 'array',
|
|
197
|
+
description: 'Optional array of parameters for parameterized queries',
|
|
198
|
+
items: {},
|
|
199
|
+
},
|
|
200
|
+
},
|
|
201
|
+
required: ['query'],
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
{
|
|
205
|
+
name: 'execute_sql',
|
|
206
|
+
description: 'Executes a write SQL operation (INSERT, UPDATE, DELETE) with optional parameters. DDL operations require "ddl" permission.',
|
|
207
|
+
inputSchema: {
|
|
208
|
+
type: 'object',
|
|
209
|
+
properties: {
|
|
210
|
+
query: {
|
|
211
|
+
type: 'string',
|
|
212
|
+
description: 'SQL query to execute (INSERT, UPDATE, DELETE, or DDL if permitted)',
|
|
213
|
+
},
|
|
214
|
+
params: {
|
|
215
|
+
type: 'array',
|
|
216
|
+
description: 'Optional array of parameters for parameterized queries',
|
|
217
|
+
items: {},
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
required: ['query'],
|
|
221
|
+
},
|
|
222
|
+
},
|
|
223
|
+
{
|
|
224
|
+
name: 'create_table',
|
|
225
|
+
description: 'Creates a new table with the specified columns and indexes. Requires "ddl" permission.',
|
|
226
|
+
inputSchema: {
|
|
227
|
+
type: 'object',
|
|
228
|
+
properties: {
|
|
229
|
+
table_name: {
|
|
230
|
+
type: 'string',
|
|
231
|
+
description: 'Name of the table to create',
|
|
232
|
+
},
|
|
233
|
+
columns: {
|
|
234
|
+
type: 'array',
|
|
235
|
+
description: 'Array of column definitions',
|
|
236
|
+
items: {
|
|
237
|
+
type: 'object',
|
|
238
|
+
properties: {
|
|
239
|
+
name: { type: 'string', description: 'Column name' },
|
|
240
|
+
type: { type: 'string', description: 'MySQL data type (e.g., VARCHAR(255), INT, TEXT)' },
|
|
241
|
+
nullable: { type: 'boolean', description: 'Whether column can be NULL' },
|
|
242
|
+
primary_key: { type: 'boolean', description: 'Whether this is the primary key' },
|
|
243
|
+
auto_increment: { type: 'boolean', description: 'Whether column auto-increments' },
|
|
244
|
+
default: { type: 'string', description: 'Default value' },
|
|
245
|
+
},
|
|
246
|
+
required: ['name', 'type'],
|
|
247
|
+
},
|
|
248
|
+
},
|
|
249
|
+
indexes: {
|
|
250
|
+
type: 'array',
|
|
251
|
+
description: 'Optional indexes to create',
|
|
252
|
+
items: {
|
|
253
|
+
type: 'object',
|
|
254
|
+
properties: {
|
|
255
|
+
name: { type: 'string' },
|
|
256
|
+
columns: { type: 'array', items: { type: 'string' } },
|
|
257
|
+
unique: { type: 'boolean' },
|
|
258
|
+
},
|
|
259
|
+
},
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
required: ['table_name', 'columns'],
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
name: 'alter_table',
|
|
267
|
+
description: 'Alters an existing table structure (add/drop/modify columns, add/drop indexes). Requires "ddl" permission.',
|
|
268
|
+
inputSchema: {
|
|
269
|
+
type: 'object',
|
|
270
|
+
properties: {
|
|
271
|
+
table_name: {
|
|
272
|
+
type: 'string',
|
|
273
|
+
description: 'Name of the table to alter',
|
|
274
|
+
},
|
|
275
|
+
operations: {
|
|
276
|
+
type: 'array',
|
|
277
|
+
description: 'Array of alter operations to perform',
|
|
278
|
+
items: {
|
|
279
|
+
type: 'object',
|
|
280
|
+
properties: {
|
|
281
|
+
type: {
|
|
282
|
+
type: 'string',
|
|
283
|
+
enum: ['add_column', 'drop_column', 'modify_column', 'rename_column', 'add_index', 'drop_index'],
|
|
284
|
+
description: 'Type of alteration',
|
|
285
|
+
},
|
|
286
|
+
column_name: { type: 'string' },
|
|
287
|
+
new_column_name: { type: 'string' },
|
|
288
|
+
column_type: { type: 'string' },
|
|
289
|
+
nullable: { type: 'boolean' },
|
|
290
|
+
default: { type: 'string' },
|
|
291
|
+
index_name: { type: 'string' },
|
|
292
|
+
index_columns: { type: 'array', items: { type: 'string' } },
|
|
293
|
+
unique: { type: 'boolean' },
|
|
294
|
+
},
|
|
295
|
+
required: ['type'],
|
|
296
|
+
},
|
|
297
|
+
},
|
|
298
|
+
},
|
|
299
|
+
required: ['table_name', 'operations'],
|
|
300
|
+
},
|
|
301
|
+
},
|
|
302
|
+
{
|
|
303
|
+
name: 'drop_table',
|
|
304
|
+
description: 'Drops (deletes) a table and all its data. Requires "ddl" permission. WARNING: This is irreversible!',
|
|
305
|
+
inputSchema: {
|
|
306
|
+
type: 'object',
|
|
307
|
+
properties: {
|
|
308
|
+
table_name: {
|
|
309
|
+
type: 'string',
|
|
310
|
+
description: 'Name of the table to drop',
|
|
311
|
+
},
|
|
312
|
+
if_exists: {
|
|
313
|
+
type: 'boolean',
|
|
314
|
+
description: 'If true, will not error if table does not exist',
|
|
315
|
+
},
|
|
316
|
+
},
|
|
317
|
+
required: ['table_name'],
|
|
318
|
+
},
|
|
319
|
+
},
|
|
320
|
+
{
|
|
321
|
+
name: 'execute_ddl',
|
|
322
|
+
description: 'Executes raw DDL SQL (CREATE, ALTER, DROP, TRUNCATE, RENAME). Requires "ddl" permission.',
|
|
323
|
+
inputSchema: {
|
|
324
|
+
type: 'object',
|
|
325
|
+
properties: {
|
|
326
|
+
query: {
|
|
327
|
+
type: 'string',
|
|
328
|
+
description: 'DDL SQL query to execute',
|
|
329
|
+
},
|
|
330
|
+
},
|
|
331
|
+
required: ['query'],
|
|
332
|
+
},
|
|
333
|
+
},
|
|
334
|
+
{
|
|
335
|
+
name: 'describe_connection',
|
|
336
|
+
description: 'Returns information about the current database connection.',
|
|
337
|
+
inputSchema: {
|
|
338
|
+
type: 'object',
|
|
339
|
+
properties: {},
|
|
340
|
+
},
|
|
341
|
+
},
|
|
342
|
+
{
|
|
343
|
+
name: 'test_connection',
|
|
344
|
+
description: 'Tests the database connection and returns latency information.',
|
|
345
|
+
inputSchema: {
|
|
346
|
+
type: 'object',
|
|
347
|
+
properties: {},
|
|
348
|
+
},
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
name: 'get_table_relationships',
|
|
352
|
+
description: 'Returns foreign key relationships for a specified table.',
|
|
353
|
+
inputSchema: {
|
|
354
|
+
type: 'object',
|
|
355
|
+
properties: {
|
|
356
|
+
table_name: {
|
|
357
|
+
type: 'string',
|
|
358
|
+
description: 'Name of the table to get relationships for',
|
|
359
|
+
},
|
|
360
|
+
},
|
|
361
|
+
required: ['table_name'],
|
|
362
|
+
},
|
|
363
|
+
},
|
|
364
|
+
// Transaction Tools
|
|
365
|
+
{
|
|
366
|
+
name: 'begin_transaction',
|
|
367
|
+
description: 'Begins a new database transaction. Returns a transaction ID for subsequent operations.',
|
|
368
|
+
inputSchema: {
|
|
369
|
+
type: 'object',
|
|
370
|
+
properties: {
|
|
371
|
+
transactionId: {
|
|
372
|
+
type: 'string',
|
|
373
|
+
description: 'Optional custom transaction ID. If not provided, one will be generated.',
|
|
374
|
+
},
|
|
375
|
+
},
|
|
376
|
+
},
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
name: 'commit_transaction',
|
|
380
|
+
description: 'Commits a transaction and makes all changes permanent.',
|
|
381
|
+
inputSchema: {
|
|
382
|
+
type: 'object',
|
|
383
|
+
properties: {
|
|
384
|
+
transactionId: {
|
|
385
|
+
type: 'string',
|
|
386
|
+
description: 'The transaction ID to commit',
|
|
387
|
+
},
|
|
388
|
+
},
|
|
389
|
+
required: ['transactionId'],
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
{
|
|
393
|
+
name: 'rollback_transaction',
|
|
394
|
+
description: 'Rolls back a transaction and undoes all changes made within it.',
|
|
395
|
+
inputSchema: {
|
|
396
|
+
type: 'object',
|
|
397
|
+
properties: {
|
|
398
|
+
transactionId: {
|
|
399
|
+
type: 'string',
|
|
400
|
+
description: 'The transaction ID to rollback',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
required: ['transactionId'],
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
{
|
|
407
|
+
name: 'get_transaction_status',
|
|
408
|
+
description: 'Returns the status of all active transactions.',
|
|
409
|
+
inputSchema: {
|
|
410
|
+
type: 'object',
|
|
411
|
+
properties: {},
|
|
412
|
+
},
|
|
413
|
+
},
|
|
414
|
+
{
|
|
415
|
+
name: 'execute_in_transaction',
|
|
416
|
+
description: 'Executes a SQL query within an active transaction.',
|
|
417
|
+
inputSchema: {
|
|
418
|
+
type: 'object',
|
|
419
|
+
properties: {
|
|
420
|
+
transactionId: {
|
|
421
|
+
type: 'string',
|
|
422
|
+
description: 'The transaction ID to execute the query within',
|
|
423
|
+
},
|
|
424
|
+
query: {
|
|
425
|
+
type: 'string',
|
|
426
|
+
description: 'SQL query to execute within the transaction',
|
|
427
|
+
},
|
|
428
|
+
params: {
|
|
429
|
+
type: 'array',
|
|
430
|
+
description: 'Optional array of parameters for parameterized queries',
|
|
431
|
+
items: {},
|
|
432
|
+
},
|
|
433
|
+
},
|
|
434
|
+
required: ['transactionId', 'query'],
|
|
435
|
+
},
|
|
436
|
+
},
|
|
437
|
+
// Stored Procedure Tools
|
|
438
|
+
{
|
|
439
|
+
name: 'list_stored_procedures',
|
|
440
|
+
description: 'Lists all stored procedures in the specified database.',
|
|
441
|
+
inputSchema: {
|
|
442
|
+
type: 'object',
|
|
443
|
+
properties: {
|
|
444
|
+
database: {
|
|
445
|
+
type: 'string',
|
|
446
|
+
description: 'Optional: specific database name to list procedures from',
|
|
447
|
+
},
|
|
448
|
+
},
|
|
449
|
+
},
|
|
450
|
+
},
|
|
451
|
+
{
|
|
452
|
+
name: 'get_stored_procedure_info',
|
|
453
|
+
description: 'Gets detailed information about a specific stored procedure including parameters and metadata.',
|
|
454
|
+
inputSchema: {
|
|
455
|
+
type: 'object',
|
|
456
|
+
properties: {
|
|
457
|
+
procedure_name: {
|
|
458
|
+
type: 'string',
|
|
459
|
+
description: 'Name of the stored procedure to get information for',
|
|
460
|
+
},
|
|
461
|
+
database: {
|
|
462
|
+
type: 'string',
|
|
463
|
+
description: 'Optional: specific database name',
|
|
464
|
+
},
|
|
465
|
+
},
|
|
466
|
+
required: ['procedure_name'],
|
|
467
|
+
},
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
name: 'execute_stored_procedure',
|
|
471
|
+
description: 'Executes a stored procedure with optional parameters.',
|
|
472
|
+
inputSchema: {
|
|
473
|
+
type: 'object',
|
|
474
|
+
properties: {
|
|
475
|
+
procedure_name: {
|
|
476
|
+
type: 'string',
|
|
477
|
+
description: 'Name of the stored procedure to execute',
|
|
478
|
+
},
|
|
479
|
+
parameters: {
|
|
480
|
+
type: 'array',
|
|
481
|
+
description: 'Optional array of parameters to pass to the stored procedure',
|
|
482
|
+
items: {},
|
|
483
|
+
},
|
|
484
|
+
database: {
|
|
485
|
+
type: 'string',
|
|
486
|
+
description: 'Optional: specific database name',
|
|
487
|
+
},
|
|
488
|
+
},
|
|
489
|
+
required: ['procedure_name'],
|
|
490
|
+
},
|
|
491
|
+
},
|
|
492
|
+
{
|
|
493
|
+
name: 'create_stored_procedure',
|
|
494
|
+
description: 'Creates a new stored procedure with the specified parameters and body.',
|
|
495
|
+
inputSchema: {
|
|
496
|
+
type: 'object',
|
|
497
|
+
properties: {
|
|
498
|
+
procedure_name: {
|
|
499
|
+
type: 'string',
|
|
500
|
+
description: 'Name of the stored procedure to create',
|
|
501
|
+
},
|
|
502
|
+
parameters: {
|
|
503
|
+
type: 'array',
|
|
504
|
+
description: 'Optional array of parameter definitions',
|
|
505
|
+
items: {
|
|
506
|
+
type: 'object',
|
|
507
|
+
properties: {
|
|
508
|
+
name: { type: 'string', description: 'Parameter name' },
|
|
509
|
+
mode: { type: 'string', enum: ['IN', 'OUT', 'INOUT'], description: 'Parameter mode' },
|
|
510
|
+
data_type: { type: 'string', description: 'MySQL data type (e.g., VARCHAR(255), INT)' },
|
|
511
|
+
},
|
|
512
|
+
required: ['name', 'mode', 'data_type'],
|
|
513
|
+
},
|
|
514
|
+
},
|
|
515
|
+
body: {
|
|
516
|
+
type: 'string',
|
|
517
|
+
description: 'SQL body of the stored procedure',
|
|
518
|
+
},
|
|
519
|
+
comment: {
|
|
520
|
+
type: 'string',
|
|
521
|
+
description: 'Optional comment for the stored procedure',
|
|
522
|
+
},
|
|
523
|
+
database: {
|
|
524
|
+
type: 'string',
|
|
525
|
+
description: 'Optional: specific database name',
|
|
526
|
+
},
|
|
527
|
+
},
|
|
528
|
+
required: ['procedure_name', 'body'],
|
|
529
|
+
},
|
|
530
|
+
},
|
|
531
|
+
{
|
|
532
|
+
name: 'drop_stored_procedure',
|
|
533
|
+
description: 'Drops (deletes) a stored procedure. WARNING: This is irreversible!',
|
|
534
|
+
inputSchema: {
|
|
535
|
+
type: 'object',
|
|
536
|
+
properties: {
|
|
537
|
+
procedure_name: {
|
|
538
|
+
type: 'string',
|
|
539
|
+
description: 'Name of the stored procedure to drop',
|
|
540
|
+
},
|
|
541
|
+
if_exists: {
|
|
542
|
+
type: 'boolean',
|
|
543
|
+
description: 'If true, will not error if procedure does not exist',
|
|
544
|
+
},
|
|
545
|
+
database: {
|
|
546
|
+
type: 'string',
|
|
547
|
+
description: 'Optional: specific database name',
|
|
548
|
+
},
|
|
549
|
+
},
|
|
550
|
+
required: ['procedure_name'],
|
|
551
|
+
},
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
name: 'show_create_procedure',
|
|
555
|
+
description: 'Shows the CREATE statement for a stored procedure.',
|
|
556
|
+
inputSchema: {
|
|
557
|
+
type: 'object',
|
|
558
|
+
properties: {
|
|
559
|
+
procedure_name: {
|
|
560
|
+
type: 'string',
|
|
561
|
+
description: 'Name of the stored procedure to show CREATE statement for',
|
|
562
|
+
},
|
|
563
|
+
database: {
|
|
564
|
+
type: 'string',
|
|
565
|
+
description: 'Optional: specific database name',
|
|
566
|
+
},
|
|
567
|
+
},
|
|
568
|
+
required: ['procedure_name'],
|
|
569
|
+
},
|
|
570
|
+
},
|
|
571
|
+
];
|
|
572
|
+
// Create the MCP server
|
|
573
|
+
const server = new index_js_1.Server({
|
|
574
|
+
name: 'mysql-mcp-server',
|
|
575
|
+
version: '1.0.0',
|
|
576
|
+
}, {
|
|
577
|
+
capabilities: {
|
|
578
|
+
tools: {},
|
|
579
|
+
},
|
|
580
|
+
});
|
|
581
|
+
// Handle list tools request
|
|
582
|
+
server.setRequestHandler(types_js_1.ListToolsRequestSchema, async () => {
|
|
583
|
+
return {
|
|
584
|
+
tools: TOOLS,
|
|
585
|
+
};
|
|
586
|
+
});
|
|
587
|
+
// Handle tool call requests
|
|
588
|
+
server.setRequestHandler(types_js_1.CallToolRequestSchema, async (request) => {
|
|
589
|
+
const { name, arguments: args } = request.params;
|
|
590
|
+
try {
|
|
591
|
+
let result;
|
|
592
|
+
switch (name) {
|
|
593
|
+
case 'list_databases':
|
|
594
|
+
result = await mysqlMCP.listDatabases();
|
|
595
|
+
break;
|
|
596
|
+
case 'list_tables':
|
|
597
|
+
result = await mysqlMCP.listTables(args);
|
|
598
|
+
break;
|
|
599
|
+
case 'read_table_schema':
|
|
600
|
+
result = await mysqlMCP.readTableSchema(args);
|
|
601
|
+
break;
|
|
602
|
+
case 'create_record':
|
|
603
|
+
result = await mysqlMCP.createRecord(args);
|
|
604
|
+
break;
|
|
605
|
+
case 'read_records':
|
|
606
|
+
result = await mysqlMCP.readRecords(args);
|
|
607
|
+
break;
|
|
608
|
+
case 'update_record':
|
|
609
|
+
result = await mysqlMCP.updateRecord(args);
|
|
610
|
+
break;
|
|
611
|
+
case 'delete_record':
|
|
612
|
+
result = await mysqlMCP.deleteRecord(args);
|
|
613
|
+
break;
|
|
614
|
+
case 'run_query':
|
|
615
|
+
result = await mysqlMCP.runQuery(args);
|
|
616
|
+
break;
|
|
617
|
+
case 'execute_sql':
|
|
618
|
+
result = await mysqlMCP.executeSql(args);
|
|
619
|
+
break;
|
|
620
|
+
case 'create_table':
|
|
621
|
+
result = await mysqlMCP.createTable(args);
|
|
622
|
+
break;
|
|
623
|
+
case 'alter_table':
|
|
624
|
+
result = await mysqlMCP.alterTable(args);
|
|
625
|
+
break;
|
|
626
|
+
case 'drop_table':
|
|
627
|
+
result = await mysqlMCP.dropTable(args);
|
|
628
|
+
break;
|
|
629
|
+
case 'execute_ddl':
|
|
630
|
+
result = await mysqlMCP.executeDdl(args);
|
|
631
|
+
break;
|
|
632
|
+
case 'describe_connection':
|
|
633
|
+
result = await mysqlMCP.describeConnection();
|
|
634
|
+
break;
|
|
635
|
+
case 'test_connection':
|
|
636
|
+
result = await mysqlMCP.testConnection();
|
|
637
|
+
break;
|
|
638
|
+
case 'get_table_relationships':
|
|
639
|
+
result = await mysqlMCP.getTableRelationships(args);
|
|
640
|
+
break;
|
|
641
|
+
// Transaction Tools
|
|
642
|
+
case 'begin_transaction':
|
|
643
|
+
result = await mysqlMCP.beginTransaction(args);
|
|
644
|
+
break;
|
|
645
|
+
case 'commit_transaction':
|
|
646
|
+
result = await mysqlMCP.commitTransaction(args);
|
|
647
|
+
break;
|
|
648
|
+
case 'rollback_transaction':
|
|
649
|
+
result = await mysqlMCP.rollbackTransaction(args);
|
|
650
|
+
break;
|
|
651
|
+
case 'get_transaction_status':
|
|
652
|
+
result = await mysqlMCP.getTransactionStatus();
|
|
653
|
+
break;
|
|
654
|
+
case 'execute_in_transaction':
|
|
655
|
+
result = await mysqlMCP.executeInTransaction(args);
|
|
656
|
+
break;
|
|
657
|
+
// Stored Procedure Tools
|
|
658
|
+
case 'list_stored_procedures':
|
|
659
|
+
result = await mysqlMCP.listStoredProcedures(args);
|
|
660
|
+
break;
|
|
661
|
+
case 'get_stored_procedure_info':
|
|
662
|
+
result = await mysqlMCP.getStoredProcedureInfo(args);
|
|
663
|
+
break;
|
|
664
|
+
case 'execute_stored_procedure':
|
|
665
|
+
result = await mysqlMCP.executeStoredProcedure(args);
|
|
666
|
+
break;
|
|
667
|
+
case 'create_stored_procedure':
|
|
668
|
+
result = await mysqlMCP.createStoredProcedure(args);
|
|
669
|
+
break;
|
|
670
|
+
case 'drop_stored_procedure':
|
|
671
|
+
result = await mysqlMCP.dropStoredProcedure(args);
|
|
672
|
+
break;
|
|
673
|
+
case 'show_create_procedure':
|
|
674
|
+
result = await mysqlMCP.showCreateProcedure(args);
|
|
675
|
+
break;
|
|
676
|
+
default:
|
|
677
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
678
|
+
}
|
|
679
|
+
// Handle the result based on status
|
|
680
|
+
if (result.status === 'error') {
|
|
681
|
+
return {
|
|
682
|
+
content: [
|
|
683
|
+
{
|
|
684
|
+
type: 'text',
|
|
685
|
+
text: `Error: ${result.error}`,
|
|
686
|
+
},
|
|
687
|
+
],
|
|
688
|
+
isError: true,
|
|
689
|
+
};
|
|
690
|
+
}
|
|
691
|
+
// Return successful result - handle different result types
|
|
692
|
+
let responseData;
|
|
693
|
+
if ('data' in result) {
|
|
694
|
+
// Standard result with data property
|
|
695
|
+
responseData = result.data;
|
|
696
|
+
}
|
|
697
|
+
else if ('transactionId' in result) {
|
|
698
|
+
// Transaction result
|
|
699
|
+
responseData = {
|
|
700
|
+
transactionId: result.transactionId
|
|
701
|
+
};
|
|
702
|
+
if ('message' in result && result.message) {
|
|
703
|
+
responseData.message = result.message;
|
|
704
|
+
}
|
|
705
|
+
if ('activeTransactions' in result && result.activeTransactions) {
|
|
706
|
+
responseData.activeTransactions = result.activeTransactions;
|
|
707
|
+
}
|
|
708
|
+
}
|
|
709
|
+
else if ('message' in result) {
|
|
710
|
+
// Simple message result
|
|
711
|
+
responseData = { message: result.message };
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
// Fallback
|
|
715
|
+
responseData = result;
|
|
716
|
+
}
|
|
717
|
+
return {
|
|
718
|
+
content: [
|
|
719
|
+
{
|
|
720
|
+
type: 'text',
|
|
721
|
+
text: JSON.stringify(responseData, null, 2),
|
|
722
|
+
},
|
|
723
|
+
],
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
catch (error) {
|
|
727
|
+
return {
|
|
728
|
+
content: [
|
|
729
|
+
{
|
|
730
|
+
type: 'text',
|
|
731
|
+
text: `Error executing tool: ${error.message}`,
|
|
732
|
+
},
|
|
733
|
+
],
|
|
734
|
+
isError: true,
|
|
735
|
+
};
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
// Start the server
|
|
739
|
+
async function main() {
|
|
740
|
+
const transport = new stdio_js_1.StdioServerTransport();
|
|
741
|
+
await server.connect(transport);
|
|
742
|
+
// Log to stderr (not stdout, which is used for MCP protocol)
|
|
743
|
+
console.error('MySQL MCP Server running on stdio');
|
|
744
|
+
}
|
|
745
|
+
main().catch((error) => {
|
|
746
|
+
console.error('Fatal error in main():', error);
|
|
747
|
+
process.exit(1);
|
|
748
|
+
});
|