@berthojoris/mcp-mysql-server 1.17.0 → 1.18.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/README.md CHANGED
@@ -78,7 +78,6 @@ DB_USER=root
78
78
  DB_PASSWORD=yourpassword
79
79
  DB_NAME=yourdatabase
80
80
  MCP_CONFIG=list,read,utility
81
- MCP_MASKING_PROFILE=partial
82
81
  ```
83
82
 
84
83
  ### 2. Build Project (If Cloned Locally)
@@ -194,40 +193,14 @@ Alternative approach using environment variables instead of connection string:
194
193
  "DB_PASSWORD": "your_password",
195
194
  "DB_NAME": "your_database",
196
195
  "MCP_PERMISSIONS": "list,read,utility",
197
- "MCP_CATEGORIES": "database_discovery,performance_monitoring",
198
- "MCP_MASKING_PROFILE": "partial"
196
+ "MCP_CATEGORIES": "database_discovery,performance_monitoring"
199
197
  }
200
198
  }
201
199
  }
202
200
  }
203
201
  ```
204
202
 
205
- **Option 3: Adaptive Preset (Merges with Overrides)**
206
-
207
- ```json
208
- {
209
- "mcpServers": {
210
- "mysql": {
211
- "command": "npx",
212
- "args": ["-y", "@berthojoris/mysql-mcp"],
213
- "env": {
214
- "DB_HOST": "localhost",
215
- "DB_PORT": "3306",
216
- "DB_USER": "root",
217
- "DB_PASSWORD": "your_password",
218
- "DB_NAME": "your_database",
219
- "MCP_PRESET": "readonly",
220
- "MCP_PERMISSIONS": "list,read,utility",
221
- "MCP_CATEGORIES": "performance_monitoring"
222
- }
223
- }
224
- }
225
- }
226
- ```
227
-
228
- Add `MCP_PRESET` for the base bundle and optionally layer on `MCP_PERMISSIONS` / `MCP_CATEGORIES` for project-specific overrides.
229
-
230
- For more environment-variable patterns (presets/profiles, client-specific env blocks), see **[DOCUMENTATIONS.md → Setup & Configuration](DOCUMENTATIONS.md#setup--configuration-extended)**.
203
+ For more client-specific config snippets, see **[DOCUMENTATIONS.md Setup & Configuration](DOCUMENTATIONS.md#setup--configuration-extended)**.
231
204
 
232
205
  ---
233
206
 
@@ -244,16 +217,64 @@ Control database access with a **dual-layer filtering system** that provides bot
244
217
 
245
218
  Use documentation categories to fine-tune which tools are exposed (Layer 2):
246
219
 
220
+ <table>
221
+ <thead>
222
+ <tr>
223
+ <th align="left">Category A</th>
224
+ <th align="left">Category B</th>
225
+ <th align="left">Category C</th>
226
+ <th align="left">Category D</th>
227
+ </tr>
228
+ </thead>
229
+ <tbody>
230
+ <tr>
231
+ <td><code>database_discovery</code></td>
232
+ <td><code>crud_operations</code></td>
233
+ <td><code>bulk_operations</code></td>
234
+ <td><code>custom_queries</code></td>
235
+ </tr>
236
+ <tr>
237
+ <td><code>schema_management</code></td>
238
+ <td><code>utilities</code></td>
239
+ <td><code>transaction_management</code></td>
240
+ <td><code>stored_procedures</code></td>
241
+ </tr>
242
+ <tr>
243
+ <td><code>views_management</code></td>
244
+ <td><code>triggers_management</code></td>
245
+ <td><code>functions_management</code></td>
246
+ <td><code>index_management</code></td>
247
+ </tr>
248
+ <tr>
249
+ <td><code>constraint_management</code></td>
250
+ <td><code>table_maintenance</code></td>
251
+ <td><code>server_management</code></td>
252
+ <td><code>performance_monitoring</code></td>
253
+ </tr>
254
+ <tr>
255
+ <td><code>cache_management</code></td>
256
+ <td><code>query_optimization</code></td>
257
+ <td><code>backup_restore</code></td>
258
+ <td><code>import_export</code></td>
259
+ </tr>
260
+ <tr>
261
+ <td><code>data_migration</code></td>
262
+ <td><code>schema_migrations</code></td>
263
+ <td><code>analysis</code></td>
264
+ <td><code>ai_enhancement</code></td>
265
+ </tr>
266
+ </tbody>
267
+ </table>
268
+
269
+ <details>
270
+ <summary>Copy/paste list (comma-separated, no spaces)</summary>
271
+
247
272
  ```text
248
- database_discovery,crud_operations,bulk_operations,custom_queries,
249
- schema_management,utilities,transaction_management,stored_procedures,
250
- views_management,triggers_management,functions_management,index_management,
251
- constraint_management,table_maintenance,server_management,
252
- performance_monitoring,cache_management,query_optimization,
253
- backup_restore,import_export,data_migration,schema_migrations,
254
- analysis,ai_enhancement
273
+ database_discovery,crud_operations,bulk_operations,custom_queries,schema_management,utilities,transaction_management,stored_procedures,views_management,triggers_management,functions_management,index_management,constraint_management,table_maintenance,server_management,performance_monitoring,cache_management,query_optimization,backup_restore,import_export,data_migration,schema_migrations,analysis,ai_enhancement
255
274
  ```
256
275
 
276
+ </details>
277
+
257
278
  Full category → tool mapping (and examples) lives in **[DOCUMENTATIONS.md → Category Filtering System](DOCUMENTATIONS.md#🆕-category-filtering-system)**.
258
279
 
259
280
  ### Legacy Categories (Backward Compatible)
@@ -271,7 +292,7 @@ Full category → tool mapping (and examples) lives in **[DOCUMENTATIONS.md →
271
292
  | `transaction` | BEGIN, COMMIT, ROLLBACK | ACID operations |
272
293
  | `utility` | Connection testing, diagnostics | Troubleshooting |
273
294
 
274
- Common presets, environment bundles, and multi-environment examples are documented in **[DOCUMENTATIONS.md → Category Filtering System](DOCUMENTATIONS.md#🆕-category-filtering-system)**.
295
+ Common configuration examples are documented in **[DOCUMENTATIONS.md → Category Filtering System](DOCUMENTATIONS.md#🆕-category-filtering-system)**.
275
296
 
276
297
  ---
277
298
 
package/bin/mcp-mysql.js CHANGED
@@ -10,55 +10,32 @@ const path = require("path");
10
10
  const { spawn } = require("child_process");
11
11
  require("dotenv").config();
12
12
 
13
- // Get MySQL connection string, permissions, categories, and optional preset
14
- const args = process.argv.slice(2);
15
- const mysqlUrl = args.shift();
16
-
17
- let permissions;
18
- let categories;
19
- let preset;
20
-
21
- for (let i = 0; i < args.length; i++) {
22
- const arg = args[i];
23
- const normalized = (arg || "").toLowerCase();
24
-
25
- if (normalized === "--preset") {
26
- preset = args[i + 1];
27
- i++;
28
- continue;
29
- }
30
-
31
- if (normalized.startsWith("--preset=")) {
32
- preset = arg.split("=")[1];
33
- continue;
34
- }
35
-
36
- if (normalized.startsWith("preset:")) {
37
- preset = arg.split(":")[1];
38
- continue;
39
- }
40
-
41
- if (["readonly", "analyst", "dba-lite", "dba_lite", "dba lite"].includes(normalized)) {
42
- preset = arg;
43
- continue;
44
- }
45
-
46
- if (permissions === undefined) {
47
- permissions = arg;
48
- continue;
49
- }
50
-
51
- if (categories === undefined) {
52
- categories = arg;
53
- continue;
54
- }
55
- }
13
+ // Get MySQL connection string, permissions, and optional categories
14
+ const args = process.argv.slice(2);
15
+ const mysqlUrl = args.shift();
16
+
17
+ let permissions;
18
+ let categories;
19
+
20
+ for (let i = 0; i < args.length; i++) {
21
+ const arg = args[i];
22
+
23
+ if (permissions === undefined) {
24
+ permissions = arg;
25
+ continue;
26
+ }
27
+
28
+ if (categories === undefined) {
29
+ categories = arg;
30
+ continue;
31
+ }
32
+ }
56
33
 
57
34
  if (!mysqlUrl) {
58
35
  console.error("Error: MySQL connection URL is required");
59
- console.error(
60
- "Usage: mcp-mysql mysql://user:password@host:port/dbname [permissions] [categories] [--preset <name>]",
61
- );
36
+ console.error(
37
+ "Usage: mcp-mysql mysql://user:password@host:port/dbname [permissions] [categories]",
38
+ );
62
39
  console.error("");
63
40
  console.error("Examples:");
64
41
  console.error(" # All tools enabled (no filtering)");
@@ -72,17 +49,9 @@ if (!mysqlUrl) {
72
49
  console.error(
73
50
  " # Dual-layer: Permissions + Categories (fine-grained control)",
74
51
  );
75
- console.error(
76
- ' mcp-mysql mysql://root:pass@localhost:3306/mydb "list,read,utility" "database_discovery,performance_monitoring"',
77
- );
78
- console.error("");
79
- console.error(" # Adaptive presets (auto-merge with overrides)");
80
- console.error(
81
- ' mcp-mysql mysql://root:pass@localhost:3306/mydb --preset readonly',
82
- );
83
- console.error(
84
- ' mcp-mysql mysql://root:pass@localhost:3306/mydb --preset analyst "performance_monitoring"',
85
- );
52
+ console.error(
53
+ ' mcp-mysql mysql://root:pass@localhost:3306/mydb "list,read,utility" "database_discovery,performance_monitoring"',
54
+ );
86
55
  console.error("");
87
56
  console.error("Permissions (Layer 1 - Broad Control):");
88
57
  console.error(
@@ -105,26 +74,20 @@ if (!mysqlUrl) {
105
74
  console.error(
106
75
  " performance_monitoring, cache_management, query_optimization,",
107
76
  );
108
- console.error(
109
- " backup_restore, import_export, data_migration, schema_migrations",
110
- );
111
- console.error("");
112
- console.error("Filtering Logic:");
77
+ console.error(
78
+ " backup_restore, import_export, data_migration, schema_migrations",
79
+ );
80
+ console.error("");
81
+ console.error("Filtering Logic:");
113
82
  console.error(
114
83
  " - If only permissions: All tools within those permissions enabled",
115
84
  );
116
- console.error(
117
- " - If permissions + categories: Only tools matching BOTH layers enabled",
118
- );
119
- console.error(" - If nothing specified: All 119 tools enabled");
120
- console.error("");
121
- console.error("Presets:");
122
- console.error(" readonly, analyst, dba-lite");
123
- console.error(
124
- " Presets merge with provided permissions/categories so you can add project-specific overrides.",
125
- );
126
- process.exit(1);
127
- }
85
+ console.error(
86
+ " - If permissions + categories: Only tools matching BOTH layers enabled",
87
+ );
88
+ console.error(" - If nothing specified: All tools enabled");
89
+ process.exit(1);
90
+ }
128
91
 
129
92
  // Parse the MySQL URL to extract connection details
130
93
  let connectionConfig;
@@ -168,39 +131,26 @@ const dbMessage = database
168
131
  ? `${connectionConfig.host}:${connectionConfig.port}/${database}`
169
132
  : `${connectionConfig.host}:${connectionConfig.port} (no specific database selected)`;
170
133
 
171
- // Set permissions/categories/preset as environment variables if provided
172
- if (permissions) {
173
- process.env.MCP_PERMISSIONS = permissions;
174
- console.error(`Permissions (Layer 1): ${permissions}`);
175
- }
176
-
177
- if (categories) {
178
- process.env.MCP_CATEGORIES = categories;
179
- console.error(`Categories (Layer 2): ${categories}`);
180
- }
181
-
182
- if (preset) {
183
- process.env.MCP_PRESET = preset;
184
- console.error(`Permission preset: ${preset}`);
185
- }
186
-
187
- if (!permissions && !categories && !preset) {
188
- console.error("Access Control: All tools enabled (no filtering)");
189
- } else if (preset && !permissions && !categories) {
190
- console.error("Filtering Mode: Preset-based (auto permissions + categories)");
191
- } else if (permissions && categories) {
192
- console.error(
193
- `Filtering Mode: Dual-layer (Permissions + Categories${preset ? ", preset merged" : ""})`,
194
- );
195
- } else if (permissions && !categories) {
196
- console.error(
197
- `Filtering Mode: Permission-based only${preset ? " (preset merged)" : ""}`,
198
- );
199
- } else if (!permissions && categories) {
200
- console.error(
201
- `Filtering Mode: Category-only${preset ? " (preset merged)" : ""}`,
202
- );
203
- }
134
+ // Set permissions/categories as environment variables if provided
135
+ if (permissions) {
136
+ process.env.MCP_PERMISSIONS = permissions;
137
+ console.error(`Permissions (Layer 1): ${permissions}`);
138
+ }
139
+
140
+ if (categories) {
141
+ process.env.MCP_CATEGORIES = categories;
142
+ console.error(`Categories (Layer 2): ${categories}`);
143
+ }
144
+
145
+ if (!permissions && !categories) {
146
+ console.error("Access Control: All tools enabled (no filtering)");
147
+ } else if (permissions && categories) {
148
+ console.error("Filtering Mode: Dual-layer (Permissions + Categories)");
149
+ } else if (permissions && !categories) {
150
+ console.error("Filtering Mode: Permission-based only");
151
+ } else if (!permissions && categories) {
152
+ console.error("Filtering Mode: Category-only");
153
+ }
204
154
 
205
155
  // Log to stderr (not stdout, which is used for MCP protocol)
206
156
  console.error(`Starting MySQL MCP server with connection to ${dbMessage}`);
@@ -43,17 +43,6 @@ export declare enum DocCategory {
43
43
  ANALYSIS = "analysis",
44
44
  AI_ENHANCEMENT = "ai_enhancement"
45
45
  }
46
- /**
47
- * Permission preset bundles for faster, safer configuration
48
- */
49
- export interface PermissionPreset {
50
- name: string;
51
- description: string;
52
- permissions: ToolCategory[];
53
- categories: DocCategory[];
54
- allowedTools?: string[];
55
- deniedTools?: string[];
56
- }
57
46
  /**
58
47
  * Map of tool names to their legacy categories
59
48
  */
@@ -71,22 +60,14 @@ export declare const toolDocCategoryMap: Record<string, DocCategory>;
71
60
  export declare class FeatureConfig {
72
61
  private enabledLegacyCategories;
73
62
  private enabledDocCategories;
74
- private allowedTools;
75
- private deniedTools;
76
63
  private originalPermissionsString;
77
64
  private originalCategoriesString;
78
65
  private useDualLayer;
79
- private activePreset?;
80
- private presetName?;
81
- constructor(permissionsStr?: string, categoriesStr?: string, presetName?: string);
66
+ constructor(permissionsStr?: string, categoriesStr?: string);
82
67
  /**
83
68
  * Normalize and merge preset + user-supplied configuration lists
84
69
  */
85
70
  private mergeConfigStrings;
86
- /**
87
- * Resolve a preset name to its configuration
88
- */
89
- private resolvePreset;
90
71
  /**
91
72
  * Parse permissions and categories for dual-layer filtering
92
73
  * Layer 1 (permissions): Broad control using legacy categories
@@ -96,7 +77,7 @@ export declare class FeatureConfig {
96
77
  /**
97
78
  * Update configuration at runtime
98
79
  */
99
- setConfig(permissionsStr: string, categoriesStr?: string, presetName?: string): void;
80
+ setConfig(permissionsStr: string, categoriesStr?: string): void;
100
81
  /**
101
82
  * Check if a specific tool is enabled
102
83
  * Dual-layer logic:
@@ -136,18 +117,10 @@ export declare class FeatureConfig {
136
117
  * Check if using dual-layer filtering mode
137
118
  */
138
119
  isUsingDualLayer(): boolean;
139
- /**
140
- * Get the active preset (if any)
141
- */
142
- getActivePreset(): PermissionPreset | undefined;
143
120
  /**
144
121
  * Snapshot of the resolved configuration for logging/telemetry
145
122
  */
146
123
  getConfigSnapshot(): {
147
- preset?: {
148
- name: string;
149
- description: string;
150
- };
151
124
  permissions: string;
152
125
  categories: string;
153
126
  filteringMode: string;
@@ -54,122 +54,6 @@ var DocCategory;
54
54
  DocCategory["ANALYSIS"] = "analysis";
55
55
  DocCategory["AI_ENHANCEMENT"] = "ai_enhancement";
56
56
  })(DocCategory || (exports.DocCategory = DocCategory = {}));
57
- const normalizePresetName = (value) => (value || "").toLowerCase().replace(/[\s_-]/g, "");
58
- const permissionPresets = {
59
- readonly: {
60
- name: "readonly",
61
- description: "Safe read-only profile with discovery, querying, exports, and diagnostics",
62
- permissions: [ToolCategory.LIST, ToolCategory.READ, ToolCategory.UTILITY],
63
- categories: [
64
- DocCategory.DATABASE_DISCOVERY,
65
- DocCategory.CRUD_OPERATIONS,
66
- DocCategory.CUSTOM_QUERIES,
67
- DocCategory.UTILITIES,
68
- DocCategory.IMPORT_EXPORT,
69
- DocCategory.PERFORMANCE_MONITORING,
70
- DocCategory.ANALYSIS,
71
- ],
72
- },
73
- analyst: {
74
- name: "analyst",
75
- description: "Exploratory analytics profile with query insights and safe exports",
76
- permissions: [ToolCategory.LIST, ToolCategory.READ, ToolCategory.UTILITY],
77
- categories: [
78
- DocCategory.DATABASE_DISCOVERY,
79
- DocCategory.CRUD_OPERATIONS,
80
- DocCategory.CUSTOM_QUERIES,
81
- DocCategory.UTILITIES,
82
- DocCategory.IMPORT_EXPORT,
83
- DocCategory.PERFORMANCE_MONITORING,
84
- DocCategory.ANALYSIS,
85
- DocCategory.QUERY_OPTIMIZATION,
86
- DocCategory.CACHE_MANAGEMENT,
87
- DocCategory.SERVER_MANAGEMENT,
88
- DocCategory.AI_ENHANCEMENT,
89
- ],
90
- },
91
- dbalite: {
92
- name: "dba-lite",
93
- description: "Admin-lite profile for schema care, migrations, and maintenance",
94
- permissions: [
95
- ToolCategory.LIST,
96
- ToolCategory.READ,
97
- ToolCategory.UTILITY,
98
- ToolCategory.DDL,
99
- ToolCategory.TRANSACTION,
100
- ToolCategory.PROCEDURE,
101
- ],
102
- categories: [
103
- DocCategory.DATABASE_DISCOVERY,
104
- DocCategory.CUSTOM_QUERIES,
105
- DocCategory.UTILITIES,
106
- DocCategory.SERVER_MANAGEMENT,
107
- DocCategory.SCHEMA_MANAGEMENT,
108
- DocCategory.TABLE_MAINTENANCE,
109
- DocCategory.INDEX_MANAGEMENT,
110
- DocCategory.CONSTRAINT_MANAGEMENT,
111
- DocCategory.BACKUP_RESTORE,
112
- DocCategory.SCHEMA_MIGRATIONS,
113
- DocCategory.PERFORMANCE_MONITORING,
114
- DocCategory.VIEWS_MANAGEMENT,
115
- DocCategory.TRIGGERS_MANAGEMENT,
116
- DocCategory.FUNCTIONS_MANAGEMENT,
117
- DocCategory.STORED_PROCEDURES,
118
- ],
119
- },
120
- dev: {
121
- name: "dev",
122
- description: "Development profile with full access to all tools",
123
- permissions: Object.values(ToolCategory),
124
- categories: Object.values(DocCategory),
125
- deniedTools: [], // Explicitly allow everything
126
- },
127
- stage: {
128
- name: "stage",
129
- description: "Staging profile with data modification but no destructive DDL",
130
- permissions: [
131
- ToolCategory.LIST,
132
- ToolCategory.READ,
133
- ToolCategory.CREATE,
134
- ToolCategory.UPDATE,
135
- ToolCategory.DELETE,
136
- ToolCategory.UTILITY,
137
- ToolCategory.TRANSACTION,
138
- ],
139
- categories: [
140
- DocCategory.DATABASE_DISCOVERY,
141
- DocCategory.CRUD_OPERATIONS,
142
- DocCategory.BULK_OPERATIONS,
143
- DocCategory.CUSTOM_QUERIES,
144
- DocCategory.UTILITIES,
145
- DocCategory.TRANSACTION_MANAGEMENT,
146
- DocCategory.IMPORT_EXPORT,
147
- DocCategory.DATA_MIGRATION,
148
- DocCategory.PERFORMANCE_MONITORING,
149
- DocCategory.ANALYSIS,
150
- ],
151
- deniedTools: ["drop_table", "truncate_table", "drop_database"],
152
- },
153
- prod: {
154
- name: "prod",
155
- description: "Production profile with strict read-only access and safety checks",
156
- permissions: [ToolCategory.LIST, ToolCategory.READ, ToolCategory.UTILITY],
157
- categories: [
158
- DocCategory.DATABASE_DISCOVERY,
159
- DocCategory.CRUD_OPERATIONS, // Read only via permissions
160
- DocCategory.CUSTOM_QUERIES,
161
- DocCategory.UTILITIES,
162
- DocCategory.PERFORMANCE_MONITORING,
163
- DocCategory.ANALYSIS,
164
- ],
165
- deniedTools: [
166
- "create_table", "alter_table", "drop_table", "truncate_table",
167
- "create_record", "update_record", "delete_record",
168
- "bulk_insert", "bulk_update", "bulk_delete",
169
- "execute_sql", "execute_ddl"
170
- ],
171
- },
172
- };
173
57
  /**
174
58
  * Map of tool names to their legacy categories
175
59
  */
@@ -570,52 +454,21 @@ const legacyToDocCategoryMap = {
570
454
  * - Layer 2 (Categories): Documentation categories (fine-grained control, optional)
571
455
  */
572
456
  class FeatureConfig {
573
- constructor(permissionsStr, categoriesStr, presetName) {
574
- const presetInput = presetName ||
575
- process.env.MCP_PERMISSION_PRESET ||
576
- process.env.MCP_PRESET ||
577
- "";
578
- this.activePreset = this.resolvePreset(presetInput);
579
- this.presetName = this.activePreset?.name;
580
- const presetRequested = !!presetInput.trim();
457
+ constructor(permissionsStr, categoriesStr) {
581
458
  // Support both old single-parameter and new dual-parameter signatures
582
459
  const permissionsInput = permissionsStr ||
583
460
  process.env.MCP_PERMISSIONS ||
584
461
  process.env.MCP_CONFIG ||
585
462
  "";
586
463
  const categoriesInput = categoriesStr || process.env.MCP_CATEGORIES || "";
587
- // Use preset values when available, otherwise fall back to user input
588
- // If an unknown preset is requested without explicit permissions/categories,
589
- // default to a safe read-only baseline rather than enabling everything.
590
- const basePermissions = this.activePreset
591
- ? this.activePreset.permissions.join(",")
592
- : presetRequested && !permissionsInput
593
- ? [ToolCategory.LIST, ToolCategory.READ, ToolCategory.UTILITY].join(",")
594
- : "";
595
- const baseCategories = this.activePreset
596
- ? this.activePreset.categories.join(",")
597
- : presetRequested && !categoriesInput
598
- ? [
599
- DocCategory.DATABASE_DISCOVERY,
600
- DocCategory.CRUD_OPERATIONS,
601
- DocCategory.CUSTOM_QUERIES,
602
- DocCategory.UTILITIES,
603
- ].join(",")
604
- : "";
605
- if (presetRequested && !this.activePreset) {
606
- console.warn(`Preset '${presetInput}' not recognized. Falling back to safe read-only defaults.`);
607
- }
608
- const mergedPermissions = this.mergeConfigStrings(basePermissions, permissionsInput);
609
- const mergedCategories = this.mergeConfigStrings(baseCategories, categoriesInput);
464
+ const mergedPermissions = this.mergeConfigStrings("", permissionsInput);
465
+ const mergedCategories = this.mergeConfigStrings("", categoriesInput);
610
466
  this.originalPermissionsString = mergedPermissions;
611
467
  this.originalCategoriesString = mergedCategories;
612
468
  this.useDualLayer = !!mergedCategories.trim();
613
469
  const parsed = this.parseConfig(mergedPermissions, mergedCategories);
614
470
  this.enabledLegacyCategories = parsed.legacy;
615
471
  this.enabledDocCategories = parsed.doc;
616
- // Initialize Allow/Deny Lists
617
- this.allowedTools = new Set(this.activePreset?.allowedTools || []);
618
- this.deniedTools = new Set(this.activePreset?.deniedTools || []);
619
472
  }
620
473
  /**
621
474
  * Normalize and merge preset + user-supplied configuration lists
@@ -626,13 +479,6 @@ class FeatureConfig {
626
479
  .filter(Boolean);
627
480
  return Array.from(new Set(items)).join(",");
628
481
  }
629
- /**
630
- * Resolve a preset name to its configuration
631
- */
632
- resolvePreset(name) {
633
- const normalized = normalizePresetName(name);
634
- return normalized ? permissionPresets[normalized] : undefined;
635
- }
636
482
  /**
637
483
  * Parse permissions and categories for dual-layer filtering
638
484
  * Layer 1 (permissions): Broad control using legacy categories
@@ -674,9 +520,6 @@ class FeatureConfig {
674
520
  docCats.forEach((dc) => docSet.add(dc));
675
521
  });
676
522
  }
677
- // Re-initialize Allow/Deny Lists if preset changed
678
- this.allowedTools = new Set(this.activePreset?.allowedTools || []);
679
- this.deniedTools = new Set(this.activePreset?.deniedTools || []);
680
523
  return {
681
524
  legacy: legacySet,
682
525
  doc: docSet,
@@ -685,33 +528,9 @@ class FeatureConfig {
685
528
  /**
686
529
  * Update configuration at runtime
687
530
  */
688
- setConfig(permissionsStr, categoriesStr, presetName) {
689
- const presetRequested = presetName !== undefined ? !!presetName.trim() : !!this.presetName;
690
- this.activePreset =
691
- presetName === ""
692
- ? undefined
693
- : this.resolvePreset(presetName || this.presetName);
694
- this.presetName = this.activePreset?.name;
695
- const basePermissions = this.activePreset
696
- ? this.activePreset.permissions.join(",")
697
- : presetRequested && !permissionsStr
698
- ? [ToolCategory.LIST, ToolCategory.READ, ToolCategory.UTILITY].join(",")
699
- : "";
700
- const baseCategories = this.activePreset
701
- ? this.activePreset.categories.join(",")
702
- : presetRequested && !categoriesStr
703
- ? [
704
- DocCategory.DATABASE_DISCOVERY,
705
- DocCategory.CRUD_OPERATIONS,
706
- DocCategory.CUSTOM_QUERIES,
707
- DocCategory.UTILITIES,
708
- ].join(",")
709
- : "";
710
- if (presetRequested && !this.activePreset) {
711
- console.warn(`Preset '${presetName}' not recognized. Falling back to safe read-only defaults.`);
712
- }
713
- const mergedPermissions = this.mergeConfigStrings(basePermissions, permissionsStr);
714
- const mergedCategories = this.mergeConfigStrings(baseCategories, categoriesStr || "");
531
+ setConfig(permissionsStr, categoriesStr) {
532
+ const mergedPermissions = this.mergeConfigStrings("", permissionsStr);
533
+ const mergedCategories = this.mergeConfigStrings("", categoriesStr || "");
715
534
  this.originalPermissionsString = mergedPermissions;
716
535
  this.originalCategoriesString = mergedCategories;
717
536
  this.useDualLayer = !!(mergedCategories && mergedCategories.trim());
@@ -733,15 +552,6 @@ class FeatureConfig {
733
552
  console.warn(`Unknown tool: ${toolName}`);
734
553
  return false;
735
554
  }
736
- // Layer 0: Check explicit Deny/Allow lists
737
- // Deny takes precedence
738
- if (this.deniedTools.has(toolName)) {
739
- return false;
740
- }
741
- // Allow overrides other checks
742
- if (this.allowedTools.has(toolName)) {
743
- return true;
744
- }
745
555
  // Layer 1: Check permission (legacy category)
746
556
  const hasPermission = legacyCategory
747
557
  ? this.enabledLegacyCategories.has(legacyCategory)
@@ -768,9 +578,6 @@ class FeatureConfig {
768
578
  if (!docCategory && !legacyCategory) {
769
579
  return `Unknown tool '${toolName}'. This tool is not recognized by the MCP server.`;
770
580
  }
771
- if (this.deniedTools.has(toolName)) {
772
- return `Permission denied: Tool '${toolName}' is explicitly denied by the current profile ('${this.presetName}').`;
773
- }
774
581
  const isAllEnabled = !this.originalPermissionsString.trim() &&
775
582
  !this.originalCategoriesString.trim();
776
583
  if (isAllEnabled) {
@@ -853,23 +660,11 @@ class FeatureConfig {
853
660
  isUsingDualLayer() {
854
661
  return this.useDualLayer;
855
662
  }
856
- /**
857
- * Get the active preset (if any)
858
- */
859
- getActivePreset() {
860
- return this.activePreset;
861
- }
862
663
  /**
863
664
  * Snapshot of the resolved configuration for logging/telemetry
864
665
  */
865
666
  getConfigSnapshot() {
866
667
  return {
867
- preset: this.activePreset
868
- ? {
869
- name: this.activePreset.name,
870
- description: this.activePreset.description,
871
- }
872
- : undefined,
873
668
  permissions: this.originalPermissionsString || "all",
874
669
  categories: this.originalCategoriesString ||
875
670
  (this.useDualLayer ? "" : "derived from permissions"),