@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.
@@ -0,0 +1,236 @@
1
+ /**
2
+ * MySQL Model Context Protocol (MCP)
3
+ * A secure interface for AI models to interact with MySQL databases
4
+ */
5
+ export declare class MySQLMCP {
6
+ private dbTools;
7
+ private crudTools;
8
+ private queryTools;
9
+ private utilityTools;
10
+ private ddlTools;
11
+ private transactionTools;
12
+ private storedProcedureTools;
13
+ private security;
14
+ private featureConfig;
15
+ constructor(permissionsConfig?: string);
16
+ private checkToolEnabled;
17
+ listDatabases(): Promise<{
18
+ status: string;
19
+ data?: string[];
20
+ error?: string;
21
+ }>;
22
+ listTables(params: {
23
+ database?: string;
24
+ }): Promise<{
25
+ status: string;
26
+ data?: import("./validation/schemas").TableInfo[];
27
+ error?: string;
28
+ }>;
29
+ readTableSchema(params: {
30
+ table_name: string;
31
+ }): Promise<{
32
+ status: string;
33
+ data?: import("./validation/schemas").ColumnInfo[];
34
+ error?: string;
35
+ }>;
36
+ createRecord(params: {
37
+ table_name: string;
38
+ data: Record<string, any>;
39
+ }): Promise<{
40
+ status: string;
41
+ data?: any;
42
+ error?: string;
43
+ }>;
44
+ readRecords(params: {
45
+ table_name: string;
46
+ filters?: any[];
47
+ pagination?: {
48
+ page: number;
49
+ limit: number;
50
+ };
51
+ sorting?: {
52
+ field: string;
53
+ direction: 'asc' | 'desc';
54
+ };
55
+ }): Promise<{
56
+ status: string;
57
+ data?: any[];
58
+ total?: number;
59
+ error?: string;
60
+ }>;
61
+ updateRecord(params: {
62
+ table_name: string;
63
+ data: Record<string, any>;
64
+ conditions: any[];
65
+ }): Promise<{
66
+ status: string;
67
+ data?: {
68
+ affectedRows: number;
69
+ };
70
+ error?: string;
71
+ }>;
72
+ deleteRecord(params: {
73
+ table_name: string;
74
+ conditions: any[];
75
+ }): Promise<{
76
+ status: string;
77
+ data?: {
78
+ affectedRows: number;
79
+ };
80
+ error?: string;
81
+ }>;
82
+ runQuery(params: {
83
+ query: string;
84
+ params?: any[];
85
+ }): Promise<{
86
+ status: string;
87
+ data?: any[];
88
+ error?: string;
89
+ }>;
90
+ executeSql(params: {
91
+ query: string;
92
+ params?: any[];
93
+ }): Promise<{
94
+ status: string;
95
+ data?: any;
96
+ error?: string;
97
+ }>;
98
+ createTable(params: any): Promise<{
99
+ status: string;
100
+ data?: any;
101
+ error?: string;
102
+ }>;
103
+ alterTable(params: any): Promise<{
104
+ status: string;
105
+ data?: any;
106
+ error?: string;
107
+ }>;
108
+ dropTable(params: any): Promise<{
109
+ status: string;
110
+ data?: any;
111
+ error?: string;
112
+ }>;
113
+ executeDdl(params: {
114
+ query: string;
115
+ }): Promise<{
116
+ status: string;
117
+ data?: any;
118
+ error?: string;
119
+ }>;
120
+ describeConnection(): Promise<{
121
+ status: string;
122
+ data?: any;
123
+ error?: string;
124
+ }>;
125
+ testConnection(): Promise<{
126
+ status: string;
127
+ data?: any;
128
+ error?: string;
129
+ }>;
130
+ getTableRelationships(params: {
131
+ table_name: string;
132
+ }): Promise<{
133
+ status: string;
134
+ data?: any;
135
+ error?: string;
136
+ }>;
137
+ beginTransaction(params?: {
138
+ transactionId?: string;
139
+ }): Promise<import("./tools/transactionTools").TransactionResult | {
140
+ status: string;
141
+ error: string | undefined;
142
+ }>;
143
+ commitTransaction(params: {
144
+ transactionId: string;
145
+ }): Promise<import("./tools/transactionTools").TransactionResult | {
146
+ status: string;
147
+ error: string | undefined;
148
+ }>;
149
+ rollbackTransaction(params: {
150
+ transactionId: string;
151
+ }): Promise<import("./tools/transactionTools").TransactionResult | {
152
+ status: string;
153
+ error: string | undefined;
154
+ }>;
155
+ getTransactionStatus(): Promise<import("./tools/transactionTools").TransactionResult | {
156
+ status: string;
157
+ error: string | undefined;
158
+ }>;
159
+ executeInTransaction(params: {
160
+ transactionId: string;
161
+ query: string;
162
+ params?: any[];
163
+ }): Promise<{
164
+ status: "success" | "error";
165
+ data?: any;
166
+ error?: string;
167
+ } | {
168
+ status: string;
169
+ error: string | undefined;
170
+ }>;
171
+ listStoredProcedures(params: {
172
+ database?: string;
173
+ }): Promise<{
174
+ status: string;
175
+ data?: any[];
176
+ error?: string;
177
+ }>;
178
+ getStoredProcedureInfo(params: {
179
+ procedure_name: string;
180
+ database?: string;
181
+ }): Promise<{
182
+ status: string;
183
+ data?: any;
184
+ error?: string;
185
+ }>;
186
+ executeStoredProcedure(params: {
187
+ procedure_name: string;
188
+ parameters?: any[];
189
+ database?: string;
190
+ }): Promise<{
191
+ status: string;
192
+ data?: any;
193
+ error?: string;
194
+ }>;
195
+ createStoredProcedure(params: {
196
+ procedure_name: string;
197
+ parameters?: Array<{
198
+ name: string;
199
+ mode: 'IN' | 'OUT' | 'INOUT';
200
+ data_type: string;
201
+ }>;
202
+ body: string;
203
+ comment?: string;
204
+ database?: string;
205
+ }): Promise<{
206
+ status: string;
207
+ data?: any;
208
+ error?: string;
209
+ }>;
210
+ dropStoredProcedure(params: {
211
+ procedure_name: string;
212
+ if_exists?: boolean;
213
+ database?: string;
214
+ }): Promise<{
215
+ status: string;
216
+ message?: string;
217
+ error?: string;
218
+ }>;
219
+ showCreateProcedure(params: {
220
+ procedure_name: string;
221
+ database?: string;
222
+ }): Promise<{
223
+ status: string;
224
+ data?: any;
225
+ error?: string;
226
+ }>;
227
+ getFeatureStatus(): {
228
+ status: string;
229
+ data: {
230
+ enabledCategories: import("./config/featureConfig").ToolCategory[];
231
+ categoryStatus: Record<import("./config/featureConfig").ToolCategory, boolean>;
232
+ };
233
+ };
234
+ close(): Promise<void>;
235
+ }
236
+ export default MySQLMCP;
package/dist/index.js ADDED
@@ -0,0 +1,273 @@
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.MySQLMCP = void 0;
7
+ const databaseTools_1 = require("./tools/databaseTools");
8
+ const crudTools_1 = require("./tools/crudTools");
9
+ const queryTools_1 = require("./tools/queryTools");
10
+ const utilityTools_1 = require("./tools/utilityTools");
11
+ const ddlTools_1 = require("./tools/ddlTools");
12
+ const transactionTools_1 = require("./tools/transactionTools");
13
+ const storedProcedureTools_1 = require("./tools/storedProcedureTools");
14
+ const securityLayer_1 = __importDefault(require("./security/securityLayer"));
15
+ const connection_1 = __importDefault(require("./db/connection"));
16
+ const featureConfig_1 = require("./config/featureConfig");
17
+ /**
18
+ * MySQL Model Context Protocol (MCP)
19
+ * A secure interface for AI models to interact with MySQL databases
20
+ */
21
+ class MySQLMCP {
22
+ constructor(permissionsConfig) {
23
+ this.featureConfig = new featureConfig_1.FeatureConfig(permissionsConfig);
24
+ this.security = new securityLayer_1.default(this.featureConfig);
25
+ this.dbTools = new databaseTools_1.DatabaseTools();
26
+ this.crudTools = new crudTools_1.CrudTools(this.security);
27
+ this.queryTools = new queryTools_1.QueryTools(this.security);
28
+ this.utilityTools = new utilityTools_1.UtilityTools();
29
+ this.ddlTools = new ddlTools_1.DdlTools();
30
+ this.transactionTools = new transactionTools_1.TransactionTools();
31
+ this.storedProcedureTools = new storedProcedureTools_1.StoredProcedureTools(this.security);
32
+ }
33
+ // Helper method to check if tool is enabled
34
+ checkToolEnabled(toolName) {
35
+ if (!this.featureConfig.isToolEnabled(toolName)) {
36
+ return {
37
+ enabled: false,
38
+ error: `Tool '${toolName}' is disabled in the current configuration. Enabled categories: ${this.featureConfig.getEnabledCategories().join(', ')}`
39
+ };
40
+ }
41
+ return { enabled: true };
42
+ }
43
+ // Database Tools
44
+ async listDatabases() {
45
+ const check = this.checkToolEnabled('listDatabases');
46
+ if (!check.enabled) {
47
+ return { status: 'error', error: check.error };
48
+ }
49
+ return await this.dbTools.listDatabases();
50
+ }
51
+ async listTables(params) {
52
+ const check = this.checkToolEnabled('listTables');
53
+ if (!check.enabled) {
54
+ return { status: 'error', error: check.error };
55
+ }
56
+ return await this.dbTools.listTables(params);
57
+ }
58
+ async readTableSchema(params) {
59
+ const check = this.checkToolEnabled('readTableSchema');
60
+ if (!check.enabled) {
61
+ return { status: 'error', error: check.error };
62
+ }
63
+ return await this.dbTools.readTableSchema(params);
64
+ }
65
+ // CRUD Tools
66
+ async createRecord(params) {
67
+ const check = this.checkToolEnabled('createRecord');
68
+ if (!check.enabled) {
69
+ return { status: 'error', error: check.error };
70
+ }
71
+ return await this.crudTools.createRecord(params);
72
+ }
73
+ async readRecords(params) {
74
+ const check = this.checkToolEnabled('readRecords');
75
+ if (!check.enabled) {
76
+ return { status: 'error', error: check.error };
77
+ }
78
+ return await this.crudTools.readRecords(params);
79
+ }
80
+ async updateRecord(params) {
81
+ const check = this.checkToolEnabled('updateRecord');
82
+ if (!check.enabled) {
83
+ return { status: 'error', error: check.error };
84
+ }
85
+ return await this.crudTools.updateRecord(params);
86
+ }
87
+ async deleteRecord(params) {
88
+ const check = this.checkToolEnabled('deleteRecord');
89
+ if (!check.enabled) {
90
+ return { status: 'error', error: check.error };
91
+ }
92
+ return await this.crudTools.deleteRecord(params);
93
+ }
94
+ // Query Tools
95
+ async runQuery(params) {
96
+ const check = this.checkToolEnabled('runQuery');
97
+ if (!check.enabled) {
98
+ return { status: 'error', error: check.error };
99
+ }
100
+ // Additional security check
101
+ if (!this.security.isReadOnlyQuery(params.query)) {
102
+ return {
103
+ status: 'error',
104
+ error: 'Only SELECT queries are allowed with runQuery. Use executeSql for other operations.'
105
+ };
106
+ }
107
+ return await this.queryTools.runQuery(params);
108
+ }
109
+ async executeSql(params) {
110
+ const check = this.checkToolEnabled('executeSql');
111
+ if (!check.enabled) {
112
+ return { status: 'error', error: check.error };
113
+ }
114
+ // Additional security check - block DDL unless DDL permission is enabled
115
+ if (this.security.hasDangerousOperations(params.query)) {
116
+ // Check if DDL permission is enabled
117
+ if (!this.featureConfig.isCategoryEnabled('ddl')) {
118
+ return {
119
+ status: 'error',
120
+ error: 'DDL operations (DROP, TRUNCATE, ALTER, CREATE) require the "ddl" permission. Use executeDdl tool or add "ddl" to permissions.'
121
+ };
122
+ }
123
+ }
124
+ return await this.queryTools.executeSql(params);
125
+ }
126
+ // DDL Tools
127
+ async createTable(params) {
128
+ const check = this.checkToolEnabled('createTable');
129
+ if (!check.enabled) {
130
+ return { status: 'error', error: check.error };
131
+ }
132
+ return await this.ddlTools.createTable(params);
133
+ }
134
+ async alterTable(params) {
135
+ const check = this.checkToolEnabled('alterTable');
136
+ if (!check.enabled) {
137
+ return { status: 'error', error: check.error };
138
+ }
139
+ return await this.ddlTools.alterTable(params);
140
+ }
141
+ async dropTable(params) {
142
+ const check = this.checkToolEnabled('dropTable');
143
+ if (!check.enabled) {
144
+ return { status: 'error', error: check.error };
145
+ }
146
+ return await this.ddlTools.dropTable(params);
147
+ }
148
+ async executeDdl(params) {
149
+ const check = this.checkToolEnabled('executeDdl');
150
+ if (!check.enabled) {
151
+ return { status: 'error', error: check.error };
152
+ }
153
+ return await this.ddlTools.executeDdl(params);
154
+ }
155
+ // Utility Tools
156
+ async describeConnection() {
157
+ const check = this.checkToolEnabled('describeConnection');
158
+ if (!check.enabled) {
159
+ return { status: 'error', error: check.error };
160
+ }
161
+ return await this.utilityTools.describeConnection();
162
+ }
163
+ async testConnection() {
164
+ const check = this.checkToolEnabled('testConnection');
165
+ if (!check.enabled) {
166
+ return { status: 'error', error: check.error };
167
+ }
168
+ return await this.utilityTools.testConnection();
169
+ }
170
+ async getTableRelationships(params) {
171
+ const check = this.checkToolEnabled('getTableRelationships');
172
+ if (!check.enabled) {
173
+ return { status: 'error', error: check.error };
174
+ }
175
+ return await this.utilityTools.getTableRelationships(params);
176
+ }
177
+ // Transaction Tools
178
+ async beginTransaction(params) {
179
+ const check = this.checkToolEnabled('beginTransaction');
180
+ if (!check.enabled) {
181
+ return { status: 'error', error: check.error };
182
+ }
183
+ return await this.transactionTools.beginTransaction(params);
184
+ }
185
+ async commitTransaction(params) {
186
+ const check = this.checkToolEnabled('commitTransaction');
187
+ if (!check.enabled) {
188
+ return { status: 'error', error: check.error };
189
+ }
190
+ return await this.transactionTools.commitTransaction(params);
191
+ }
192
+ async rollbackTransaction(params) {
193
+ const check = this.checkToolEnabled('rollbackTransaction');
194
+ if (!check.enabled) {
195
+ return { status: 'error', error: check.error };
196
+ }
197
+ return await this.transactionTools.rollbackTransaction(params);
198
+ }
199
+ async getTransactionStatus() {
200
+ const check = this.checkToolEnabled('getTransactionStatus');
201
+ if (!check.enabled) {
202
+ return { status: 'error', error: check.error };
203
+ }
204
+ return await this.transactionTools.getTransactionStatus();
205
+ }
206
+ async executeInTransaction(params) {
207
+ const check = this.checkToolEnabled('executeSql'); // Use executeSql permission for transaction queries
208
+ if (!check.enabled) {
209
+ return { status: 'error', error: check.error };
210
+ }
211
+ return await this.transactionTools.executeInTransaction(params);
212
+ }
213
+ // Stored Procedure Tools
214
+ async listStoredProcedures(params) {
215
+ const check = this.checkToolEnabled('listStoredProcedures');
216
+ if (!check.enabled) {
217
+ return { status: 'error', error: check.error };
218
+ }
219
+ return await this.storedProcedureTools.listStoredProcedures(params);
220
+ }
221
+ async getStoredProcedureInfo(params) {
222
+ const check = this.checkToolEnabled('getStoredProcedureInfo');
223
+ if (!check.enabled) {
224
+ return { status: 'error', error: check.error };
225
+ }
226
+ return await this.storedProcedureTools.getStoredProcedureInfo(params);
227
+ }
228
+ async executeStoredProcedure(params) {
229
+ const check = this.checkToolEnabled('executeStoredProcedure');
230
+ if (!check.enabled) {
231
+ return { status: 'error', error: check.error };
232
+ }
233
+ return await this.storedProcedureTools.executeStoredProcedure(params);
234
+ }
235
+ async createStoredProcedure(params) {
236
+ const check = this.checkToolEnabled('createStoredProcedure');
237
+ if (!check.enabled) {
238
+ return { status: 'error', error: check.error };
239
+ }
240
+ return await this.storedProcedureTools.createStoredProcedure(params);
241
+ }
242
+ async dropStoredProcedure(params) {
243
+ const check = this.checkToolEnabled('dropStoredProcedure');
244
+ if (!check.enabled) {
245
+ return { status: 'error', error: check.error };
246
+ }
247
+ return await this.storedProcedureTools.dropStoredProcedure(params);
248
+ }
249
+ async showCreateProcedure(params) {
250
+ const check = this.checkToolEnabled('showCreateProcedure');
251
+ if (!check.enabled) {
252
+ return { status: 'error', error: check.error };
253
+ }
254
+ return await this.storedProcedureTools.showCreateProcedure(params);
255
+ }
256
+ // Get feature configuration status
257
+ getFeatureStatus() {
258
+ return {
259
+ status: 'success',
260
+ data: {
261
+ enabledCategories: this.featureConfig.getEnabledCategories(),
262
+ categoryStatus: this.featureConfig.getCategoryStatus()
263
+ }
264
+ };
265
+ }
266
+ // Close database connection
267
+ async close() {
268
+ const db = connection_1.default.getInstance();
269
+ await db.closePool();
270
+ }
271
+ }
272
+ exports.MySQLMCP = MySQLMCP;
273
+ exports.default = MySQLMCP;
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};