@neverinfamous/mysql-mcp 2.2.0 → 2.3.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.
Files changed (213) hide show
  1. package/.github/workflows/docker-publish.yml +1 -2
  2. package/CHANGELOG.md +85 -0
  3. package/CODE_MODE.md +245 -0
  4. package/DOCKER_README.md +59 -36
  5. package/README.md +65 -42
  6. package/VERSION +1 -1
  7. package/dist/adapters/mysql/MySQLAdapter.d.ts +4 -0
  8. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  9. package/dist/adapters/mysql/MySQLAdapter.js +9 -0
  10. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  11. package/dist/adapters/mysql/prompts/index.d.ts +8 -1
  12. package/dist/adapters/mysql/prompts/index.d.ts.map +1 -1
  13. package/dist/adapters/mysql/prompts/index.js +8 -1
  14. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  15. package/dist/adapters/mysql/prompts/routerSetup.d.ts.map +1 -1
  16. package/dist/adapters/mysql/prompts/routerSetup.js +5 -0
  17. package/dist/adapters/mysql/prompts/routerSetup.js.map +1 -1
  18. package/dist/adapters/mysql/resources/capabilities.d.ts.map +1 -1
  19. package/dist/adapters/mysql/resources/capabilities.js +6 -5
  20. package/dist/adapters/mysql/resources/capabilities.js.map +1 -1
  21. package/dist/adapters/mysql/resources/index.d.ts +9 -1
  22. package/dist/adapters/mysql/resources/index.d.ts.map +1 -1
  23. package/dist/adapters/mysql/resources/index.js +9 -1
  24. package/dist/adapters/mysql/resources/index.js.map +1 -1
  25. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  26. package/dist/adapters/mysql/tools/admin/backup.js +3 -3
  27. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  28. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  29. package/dist/adapters/mysql/tools/admin/maintenance.js +5 -5
  30. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  31. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  32. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +26 -5
  33. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  34. package/dist/adapters/mysql/tools/codemode/index.d.ts +38 -0
  35. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -0
  36. package/dist/adapters/mysql/tools/codemode/index.js +203 -0
  37. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -0
  38. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  39. package/dist/adapters/mysql/tools/core.js +32 -20
  40. package/dist/adapters/mysql/tools/core.js.map +1 -1
  41. package/dist/adapters/mysql/tools/events.js +18 -6
  42. package/dist/adapters/mysql/tools/events.js.map +1 -1
  43. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  44. package/dist/adapters/mysql/tools/json/core.js +5 -5
  45. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  46. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  47. package/dist/adapters/mysql/tools/json/helpers.js +9 -3
  48. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  49. package/dist/adapters/mysql/tools/partitioning.d.ts.map +1 -1
  50. package/dist/adapters/mysql/tools/partitioning.js +38 -6
  51. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  52. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  53. package/dist/adapters/mysql/tools/performance/analysis.js +67 -20
  54. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  55. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  56. package/dist/adapters/mysql/tools/performance/optimization.js +36 -6
  57. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  58. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  59. package/dist/adapters/mysql/tools/security/data-protection.js +9 -4
  60. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  61. package/dist/adapters/mysql/tools/shell/common.d.ts.map +1 -1
  62. package/dist/adapters/mysql/tools/shell/common.js +28 -2
  63. package/dist/adapters/mysql/tools/shell/common.js.map +1 -1
  64. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  65. package/dist/adapters/mysql/tools/shell/restore.js +54 -4
  66. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  67. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  68. package/dist/adapters/mysql/tools/spatial/operations.js +10 -2
  69. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  70. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  71. package/dist/adapters/mysql/tools/spatial/setup.js +18 -0
  72. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  73. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  74. package/dist/adapters/mysql/tools/sysschema/resources.js +5 -0
  75. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  76. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  77. package/dist/adapters/mysql/tools/text/fulltext.js +6 -4
  78. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  79. package/dist/adapters/mysql/tools/text/processing.d.ts.map +1 -1
  80. package/dist/adapters/mysql/tools/text/processing.js +10 -45
  81. package/dist/adapters/mysql/tools/text/processing.js.map +1 -1
  82. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  83. package/dist/adapters/mysql/tools/transactions.js +8 -8
  84. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  85. package/dist/adapters/mysql/types.d.ts +968 -78
  86. package/dist/adapters/mysql/types.d.ts.map +1 -1
  87. package/dist/adapters/mysql/types.js +1084 -78
  88. package/dist/adapters/mysql/types.js.map +1 -1
  89. package/dist/auth/scopes.d.ts.map +1 -1
  90. package/dist/auth/scopes.js +1 -0
  91. package/dist/auth/scopes.js.map +1 -1
  92. package/dist/cli/args.d.ts.map +1 -1
  93. package/dist/cli/args.js +12 -0
  94. package/dist/cli/args.js.map +1 -1
  95. package/dist/codemode/api.d.ts +69 -0
  96. package/dist/codemode/api.d.ts.map +1 -0
  97. package/dist/codemode/api.js +1035 -0
  98. package/dist/codemode/api.js.map +1 -0
  99. package/dist/codemode/index.d.ts +13 -0
  100. package/dist/codemode/index.d.ts.map +1 -0
  101. package/dist/codemode/index.js +17 -0
  102. package/dist/codemode/index.js.map +1 -0
  103. package/dist/codemode/sandbox-factory.d.ts +72 -0
  104. package/dist/codemode/sandbox-factory.d.ts.map +1 -0
  105. package/dist/codemode/sandbox-factory.js +88 -0
  106. package/dist/codemode/sandbox-factory.js.map +1 -0
  107. package/dist/codemode/sandbox.d.ts +96 -0
  108. package/dist/codemode/sandbox.d.ts.map +1 -0
  109. package/dist/codemode/sandbox.js +345 -0
  110. package/dist/codemode/sandbox.js.map +1 -0
  111. package/dist/codemode/security.d.ts +44 -0
  112. package/dist/codemode/security.d.ts.map +1 -0
  113. package/dist/codemode/security.js +149 -0
  114. package/dist/codemode/security.js.map +1 -0
  115. package/dist/codemode/types.d.ts +137 -0
  116. package/dist/codemode/types.d.ts.map +1 -0
  117. package/dist/codemode/types.js +46 -0
  118. package/dist/codemode/types.js.map +1 -0
  119. package/dist/codemode/worker-sandbox.d.ts +82 -0
  120. package/dist/codemode/worker-sandbox.d.ts.map +1 -0
  121. package/dist/codemode/worker-sandbox.js +244 -0
  122. package/dist/codemode/worker-sandbox.js.map +1 -0
  123. package/dist/codemode/worker-script.d.ts +8 -0
  124. package/dist/codemode/worker-script.d.ts.map +1 -0
  125. package/dist/codemode/worker-script.js +113 -0
  126. package/dist/codemode/worker-script.js.map +1 -0
  127. package/dist/constants/ServerInstructions.d.ts +1 -1
  128. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  129. package/dist/constants/ServerInstructions.js +33 -9
  130. package/dist/constants/ServerInstructions.js.map +1 -1
  131. package/dist/filtering/ToolConstants.d.ts +11 -11
  132. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  133. package/dist/filtering/ToolConstants.js +37 -19
  134. package/dist/filtering/ToolConstants.js.map +1 -1
  135. package/dist/filtering/ToolFilter.d.ts.map +1 -1
  136. package/dist/filtering/ToolFilter.js +12 -0
  137. package/dist/filtering/ToolFilter.js.map +1 -1
  138. package/dist/server/McpServer.js +1 -1
  139. package/dist/server/McpServer.js.map +1 -1
  140. package/dist/types/modules/server.d.ts +2 -0
  141. package/dist/types/modules/server.d.ts.map +1 -1
  142. package/dist/types/modules/tools.d.ts +1 -1
  143. package/dist/types/modules/tools.d.ts.map +1 -1
  144. package/dist/utils/logger.d.ts +1 -1
  145. package/dist/utils/logger.d.ts.map +1 -1
  146. package/dist/utils/logger.js.map +1 -1
  147. package/package.json +12 -7
  148. package/releases/v2.2.0-release-notes.md +18 -18
  149. package/releases/v2.3.0-release-notes.md +191 -0
  150. package/src/__tests__/perf.test.ts +12 -12
  151. package/src/adapters/mysql/MySQLAdapter.ts +10 -0
  152. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
  153. package/src/adapters/mysql/prompts/index.ts +8 -1
  154. package/src/adapters/mysql/prompts/routerSetup.ts +5 -0
  155. package/src/adapters/mysql/resources/__tests__/capabilities.test.ts +50 -1
  156. package/src/adapters/mysql/resources/capabilities.ts +6 -4
  157. package/src/adapters/mysql/resources/index.ts +9 -1
  158. package/src/adapters/mysql/tools/__tests__/core.test.ts +68 -0
  159. package/src/adapters/mysql/tools/__tests__/events.test.ts +56 -2
  160. package/src/adapters/mysql/tools/__tests__/json_core.test.ts +1 -1
  161. package/src/adapters/mysql/tools/__tests__/json_helpers.test.ts +46 -4
  162. package/src/adapters/mysql/tools/__tests__/replication.test.ts +144 -42
  163. package/src/adapters/mysql/tools/__tests__/security.test.ts +39 -0
  164. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +39 -7
  165. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +35 -3
  166. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +3 -5
  167. package/src/adapters/mysql/tools/admin/backup.ts +8 -3
  168. package/src/adapters/mysql/tools/admin/maintenance.ts +8 -4
  169. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +35 -0
  170. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +26 -5
  171. package/src/adapters/mysql/tools/codemode/index.ts +249 -0
  172. package/src/adapters/mysql/tools/core.ts +44 -27
  173. package/src/adapters/mysql/tools/events.ts +23 -7
  174. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +59 -14
  175. package/src/adapters/mysql/tools/json/core.ts +8 -4
  176. package/src/adapters/mysql/tools/json/helpers.ts +13 -3
  177. package/src/adapters/mysql/tools/partitioning.ts +53 -6
  178. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +227 -4
  179. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +35 -0
  180. package/src/adapters/mysql/tools/performance/analysis.ts +75 -21
  181. package/src/adapters/mysql/tools/performance/optimization.ts +44 -6
  182. package/src/adapters/mysql/tools/security/data-protection.ts +10 -4
  183. package/src/adapters/mysql/tools/shell/__tests__/common.test.ts +46 -0
  184. package/src/adapters/mysql/tools/shell/__tests__/restore.test.ts +28 -1
  185. package/src/adapters/mysql/tools/shell/common.ts +34 -2
  186. package/src/adapters/mysql/tools/shell/restore.ts +70 -7
  187. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +29 -0
  188. package/src/adapters/mysql/tools/spatial/operations.ts +13 -2
  189. package/src/adapters/mysql/tools/spatial/setup.ts +23 -0
  190. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +21 -0
  191. package/src/adapters/mysql/tools/sysschema/resources.ts +5 -0
  192. package/src/adapters/mysql/tools/text/fulltext.ts +13 -5
  193. package/src/adapters/mysql/tools/text/processing.ts +20 -49
  194. package/src/adapters/mysql/tools/transactions.ts +11 -7
  195. package/src/adapters/mysql/types.ts +1241 -87
  196. package/src/auth/scopes.ts +1 -0
  197. package/src/cli/args.ts +14 -0
  198. package/src/codemode/api.ts +1224 -0
  199. package/src/codemode/index.ts +51 -0
  200. package/src/codemode/sandbox-factory.ts +146 -0
  201. package/src/codemode/sandbox.ts +450 -0
  202. package/src/codemode/security.ts +188 -0
  203. package/src/codemode/types.ts +194 -0
  204. package/src/codemode/worker-sandbox.ts +326 -0
  205. package/src/codemode/worker-script.ts +144 -0
  206. package/src/constants/ServerInstructions.ts +33 -9
  207. package/src/filtering/ToolConstants.ts +37 -19
  208. package/src/filtering/ToolFilter.ts +15 -0
  209. package/src/filtering/__tests__/ToolFilter.test.ts +65 -38
  210. package/src/server/McpServer.ts +1 -1
  211. package/src/types/modules/server.ts +3 -0
  212. package/src/types/modules/tools.ts +2 -1
  213. package/src/utils/logger.ts +2 -1
@@ -0,0 +1,345 @@
1
+ /**
2
+ * mysql-mcp - Code Mode Sandbox
3
+ *
4
+ * Sandboxed execution environment using Node.js vm module.
5
+ * Provides code isolation with memory/time limits for LLM-generated code.
6
+ *
7
+ * Note: This uses Node.js vm module which provides script isolation but not
8
+ * true V8 isolate separation. For production environments with untrusted code,
9
+ * consider using isolated-vm or running in a separate process/container.
10
+ */
11
+ import vm from "node:vm";
12
+ import { logger } from "../utils/logger.js";
13
+ import { DEFAULT_SANDBOX_OPTIONS, DEFAULT_POOL_OPTIONS, } from "./types.js";
14
+ /**
15
+ * A sandboxed execution context using Node.js vm module
16
+ */
17
+ export class CodeModeSandbox {
18
+ context;
19
+ options;
20
+ disposed = false;
21
+ logBuffer = [];
22
+ constructor(context, options) {
23
+ this.context = context;
24
+ this.options = options;
25
+ }
26
+ /**
27
+ * Create a new sandbox instance
28
+ */
29
+ static create(options) {
30
+ const opts = { ...DEFAULT_SANDBOX_OPTIONS, ...options };
31
+ // Create a shared log buffer that will be used by both sandbox console and instance
32
+ const sharedLogBuffer = [];
33
+ // Create a minimal sandbox context
34
+ const sandbox = {
35
+ console: {
36
+ log: (...args) => {
37
+ sharedLogBuffer.push(args
38
+ .map((a) => typeof a === "object" && a !== null
39
+ ? JSON.stringify(a)
40
+ : String(a))
41
+ .join(" "));
42
+ },
43
+ warn: (...args) => sharedLogBuffer.push("[WARN] " +
44
+ args
45
+ .map((a) => typeof a === "object" && a !== null
46
+ ? JSON.stringify(a)
47
+ : String(a))
48
+ .join(" ")),
49
+ error: (...args) => sharedLogBuffer.push("[ERROR] " +
50
+ args
51
+ .map((a) => typeof a === "object" && a !== null
52
+ ? JSON.stringify(a)
53
+ : String(a))
54
+ .join(" ")),
55
+ info: (...args) => sharedLogBuffer.push("[INFO] " +
56
+ args
57
+ .map((a) => typeof a === "object" && a !== null
58
+ ? JSON.stringify(a)
59
+ : String(a))
60
+ .join(" ")),
61
+ },
62
+ // No access to Node.js globals
63
+ require: undefined,
64
+ process: undefined,
65
+ global: undefined,
66
+ globalThis: undefined,
67
+ __dirname: undefined,
68
+ __filename: undefined,
69
+ module: undefined,
70
+ exports: undefined,
71
+ // Safe built-ins only
72
+ JSON,
73
+ Math,
74
+ Date,
75
+ Array,
76
+ Object,
77
+ String,
78
+ Number,
79
+ Boolean,
80
+ Map,
81
+ Set,
82
+ Promise,
83
+ Error,
84
+ TypeError,
85
+ RangeError,
86
+ SyntaxError,
87
+ // Async support
88
+ setTimeout: undefined, // Disabled for security
89
+ setInterval: undefined, // Disabled for security
90
+ setImmediate: undefined, // Disabled for security
91
+ };
92
+ const context = vm.createContext(sandbox);
93
+ const instance = new CodeModeSandbox(context, opts);
94
+ // Use the shared buffer directly - replace instance's buffer with the shared one
95
+ instance.logBuffer =
96
+ sharedLogBuffer;
97
+ return instance;
98
+ }
99
+ /**
100
+ * Execute code in the sandbox
101
+ * @param code - TypeScript/JavaScript code to execute
102
+ * @param apiBindings - Object with mysql.* API methods to expose
103
+ */
104
+ async execute(code, apiBindings) {
105
+ if (this.disposed) {
106
+ return {
107
+ success: false,
108
+ error: "Sandbox has been disposed",
109
+ metrics: { wallTimeMs: 0, cpuTimeMs: 0, memoryUsedMb: 0 },
110
+ };
111
+ }
112
+ const startTime = performance.now();
113
+ const startMemory = process.memoryUsage().heapUsed;
114
+ try {
115
+ // Inject mysql API bindings into the context
116
+ this.context["mysql"] = apiBindings;
117
+ // Wrap code in async IIFE to support await
118
+ const wrappedCode = `
119
+ (async () => {
120
+ ${code}
121
+ })();
122
+ `;
123
+ // Compile and run with timeout
124
+ const script = new vm.Script(wrappedCode, {
125
+ filename: "codemode-script.js",
126
+ });
127
+ const result = await script.runInContext(this.context, {
128
+ timeout: this.options.timeoutMs,
129
+ breakOnSigint: true,
130
+ });
131
+ const endTime = performance.now();
132
+ const endMemory = process.memoryUsage().heapUsed;
133
+ return {
134
+ success: true,
135
+ result,
136
+ metrics: this.calculateMetrics(startTime, endTime, startMemory, endMemory),
137
+ };
138
+ }
139
+ catch (error) {
140
+ const endTime = performance.now();
141
+ const endMemory = process.memoryUsage().heapUsed;
142
+ const errorMessage = error instanceof Error ? error.message : String(error);
143
+ const stack = error instanceof Error ? error.stack : undefined;
144
+ // Check for specific error types
145
+ if (errorMessage.includes("Script execution timed out")) {
146
+ return {
147
+ success: false,
148
+ error: `Execution timeout: exceeded ${String(this.options.timeoutMs)}ms limit`,
149
+ stack,
150
+ metrics: this.calculateMetrics(startTime, endTime, startMemory, endMemory),
151
+ };
152
+ }
153
+ return {
154
+ success: false,
155
+ error: errorMessage,
156
+ stack,
157
+ metrics: this.calculateMetrics(startTime, endTime, startMemory, endMemory),
158
+ };
159
+ }
160
+ }
161
+ /**
162
+ * Calculate execution metrics
163
+ */
164
+ calculateMetrics(startTime, endTime, startMemory, endMemory) {
165
+ return {
166
+ wallTimeMs: Math.round(endTime - startTime),
167
+ cpuTimeMs: Math.round(endTime - startTime), // Approximation
168
+ memoryUsedMb: Math.max(0, Math.round(((endMemory - startMemory) / (1024 * 1024)) * 100) / 100),
169
+ };
170
+ }
171
+ /**
172
+ * Get console output from the sandbox
173
+ */
174
+ getConsoleOutput() {
175
+ return [...this.logBuffer];
176
+ }
177
+ /**
178
+ * Clear console output buffer
179
+ */
180
+ clearConsoleOutput() {
181
+ this.logBuffer.length = 0;
182
+ }
183
+ /**
184
+ * Check if sandbox is healthy
185
+ */
186
+ isHealthy() {
187
+ return !this.disposed;
188
+ }
189
+ /**
190
+ * Dispose of the sandbox and release resources
191
+ */
192
+ dispose() {
193
+ if (this.disposed)
194
+ return;
195
+ this.disposed = true;
196
+ // vm.Context doesn't need explicit cleanup, but we mark as disposed
197
+ this.logBuffer.length = 0;
198
+ }
199
+ }
200
+ /**
201
+ * Pool of sandbox instances for reuse
202
+ */
203
+ export class SandboxPool {
204
+ options;
205
+ sandboxOptions;
206
+ available = [];
207
+ inUse = new Set();
208
+ disposed = false;
209
+ cleanupInterval = null;
210
+ constructor(poolOptions, sandboxOptions) {
211
+ this.options = { ...DEFAULT_POOL_OPTIONS, ...poolOptions };
212
+ this.sandboxOptions = { ...DEFAULT_SANDBOX_OPTIONS, ...sandboxOptions };
213
+ }
214
+ /**
215
+ * Initialize the pool with minimum instances
216
+ */
217
+ initialize() {
218
+ logger.info(`Initializing sandbox pool with ${String(this.options.minInstances)} instances`, {
219
+ module: "CODEMODE",
220
+ });
221
+ for (let i = 0; i < this.options.minInstances; i++) {
222
+ const sandbox = CodeModeSandbox.create(this.sandboxOptions);
223
+ this.available.push(sandbox);
224
+ }
225
+ // Start cleanup interval
226
+ this.cleanupInterval = setInterval(() => {
227
+ this.cleanup();
228
+ }, this.options.idleTimeoutMs);
229
+ }
230
+ /**
231
+ * Acquire a sandbox from the pool
232
+ */
233
+ acquire() {
234
+ if (this.disposed) {
235
+ throw new Error("Pool has been disposed");
236
+ }
237
+ // Try to get an available sandbox
238
+ while (this.available.length > 0) {
239
+ const sandbox = this.available.pop();
240
+ if (sandbox?.isHealthy()) {
241
+ this.inUse.add(sandbox);
242
+ return sandbox;
243
+ }
244
+ // Sandbox is unhealthy, dispose it
245
+ sandbox?.dispose();
246
+ }
247
+ // Create a new sandbox if under limit
248
+ const totalCount = this.inUse.size;
249
+ if (totalCount < this.options.maxInstances) {
250
+ const sandbox = CodeModeSandbox.create(this.sandboxOptions);
251
+ this.inUse.add(sandbox);
252
+ return sandbox;
253
+ }
254
+ // Pool exhausted
255
+ throw new Error(`Sandbox pool exhausted (max: ${String(this.options.maxInstances)})`);
256
+ }
257
+ /**
258
+ * Release a sandbox back to the pool
259
+ */
260
+ release(sandbox) {
261
+ if (!this.inUse.has(sandbox)) {
262
+ return;
263
+ }
264
+ this.inUse.delete(sandbox);
265
+ if (this.disposed) {
266
+ sandbox.dispose();
267
+ return;
268
+ }
269
+ // Return to pool if healthy and under limit
270
+ if (sandbox.isHealthy() &&
271
+ this.available.length < this.options.maxInstances) {
272
+ sandbox.clearConsoleOutput();
273
+ this.available.push(sandbox);
274
+ }
275
+ else {
276
+ sandbox.dispose();
277
+ }
278
+ }
279
+ /**
280
+ * Execute code using a pooled sandbox
281
+ */
282
+ async execute(code, apiBindings) {
283
+ const sandbox = this.acquire();
284
+ try {
285
+ return await sandbox.execute(code, apiBindings);
286
+ }
287
+ finally {
288
+ this.release(sandbox);
289
+ }
290
+ }
291
+ /**
292
+ * Clean up excess idle sandboxes
293
+ */
294
+ cleanup() {
295
+ // Remove unhealthy sandboxes
296
+ const healthy = [];
297
+ for (const sandbox of this.available) {
298
+ if (sandbox.isHealthy()) {
299
+ healthy.push(sandbox);
300
+ }
301
+ else {
302
+ sandbox.dispose();
303
+ }
304
+ }
305
+ this.available.length = 0;
306
+ this.available.push(...healthy);
307
+ // Trim to minimum
308
+ while (this.available.length > this.options.minInstances) {
309
+ const sandbox = this.available.pop();
310
+ sandbox?.dispose();
311
+ }
312
+ }
313
+ /**
314
+ * Get pool statistics
315
+ */
316
+ getStats() {
317
+ return {
318
+ available: this.available.length,
319
+ inUse: this.inUse.size,
320
+ max: this.options.maxInstances,
321
+ };
322
+ }
323
+ /**
324
+ * Dispose of all sandboxes in the pool
325
+ */
326
+ dispose() {
327
+ if (this.disposed)
328
+ return;
329
+ this.disposed = true;
330
+ if (this.cleanupInterval) {
331
+ clearInterval(this.cleanupInterval);
332
+ this.cleanupInterval = null;
333
+ }
334
+ for (const sandbox of this.available) {
335
+ sandbox.dispose();
336
+ }
337
+ this.available.length = 0;
338
+ for (const sandbox of this.inUse) {
339
+ sandbox.dispose();
340
+ }
341
+ this.inUse.clear();
342
+ logger.info("Sandbox pool disposed", { module: "CODEMODE" });
343
+ }
344
+ }
345
+ //# sourceMappingURL=sandbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/codemode/sandbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * mysql-mcp - Code Mode Security
3
+ *
4
+ * Input validation, rate limiting, and audit logging for code execution.
5
+ */
6
+ import { type SecurityConfig, type ValidationResult, type ExecutionRecord, type SandboxResult } from "./types.js";
7
+ /**
8
+ * Security manager for Code Mode executions
9
+ */
10
+ export declare class CodeModeSecurityManager {
11
+ private readonly config;
12
+ private readonly rateLimitMap;
13
+ constructor(config?: Partial<SecurityConfig>);
14
+ /**
15
+ * Validate code before execution
16
+ */
17
+ validateCode(code: string): ValidationResult;
18
+ /**
19
+ * Check rate limit for a client
20
+ * @returns true if within limits, false if rate limited
21
+ */
22
+ checkRateLimit(clientId: string): boolean;
23
+ /**
24
+ * Get remaining rate limit for a client
25
+ */
26
+ getRateLimitRemaining(clientId: string): number;
27
+ /**
28
+ * Sanitize and truncate result if too large
29
+ */
30
+ sanitizeResult(result: unknown): unknown;
31
+ /**
32
+ * Log execution for audit purposes
33
+ */
34
+ auditLog(execution: ExecutionRecord): void;
35
+ /**
36
+ * Create execution record for audit
37
+ */
38
+ createExecutionRecord(code: string, result: SandboxResult, readonly: boolean, clientId?: string): ExecutionRecord;
39
+ /**
40
+ * Clean up old rate limit entries
41
+ */
42
+ cleanupRateLimits(): void;
43
+ }
44
+ //# sourceMappingURL=security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.d.ts","sourceRoot":"","sources":["../../src/codemode/security.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAEL,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,aAAa,EACnB,MAAM,YAAY,CAAC;AAEpB;;GAEG;AACH,qBAAa,uBAAuB;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAiB;IACxC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAGzB;gBAEQ,MAAM,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC;IAI5C;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,gBAAgB;IA6B5C;;;OAGG;IACH,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAuBzC;;OAEG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM;IAQ/C;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO;IAoBxC;;OAEG;IACH,QAAQ,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI;IAgC1C;;OAEG;IACH,qBAAqB,CACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,EACrB,QAAQ,EAAE,OAAO,EACjB,QAAQ,CAAC,EAAE,MAAM,GAChB,eAAe;IAWlB;;OAEG;IACH,iBAAiB,IAAI,IAAI;CAQ1B"}
@@ -0,0 +1,149 @@
1
+ /**
2
+ * mysql-mcp - Code Mode Security
3
+ *
4
+ * Input validation, rate limiting, and audit logging for code execution.
5
+ */
6
+ import { logger } from "../utils/logger.js";
7
+ import { DEFAULT_SECURITY_CONFIG, } from "./types.js";
8
+ /**
9
+ * Security manager for Code Mode executions
10
+ */
11
+ export class CodeModeSecurityManager {
12
+ config;
13
+ rateLimitMap = new Map();
14
+ constructor(config) {
15
+ this.config = { ...DEFAULT_SECURITY_CONFIG, ...config };
16
+ }
17
+ /**
18
+ * Validate code before execution
19
+ */
20
+ validateCode(code) {
21
+ const errors = [];
22
+ // Check code length
23
+ if (!code || typeof code !== "string") {
24
+ errors.push("Code must be a non-empty string");
25
+ return { valid: false, errors };
26
+ }
27
+ if (code.length > this.config.maxCodeLength) {
28
+ errors.push(`Code exceeds maximum length of ${String(this.config.maxCodeLength)} bytes`);
29
+ return { valid: false, errors };
30
+ }
31
+ // Check for blocked patterns
32
+ for (const pattern of this.config.blockedPatterns) {
33
+ if (pattern.test(code)) {
34
+ errors.push(`Blocked pattern detected: ${pattern.source}`);
35
+ }
36
+ }
37
+ return {
38
+ valid: errors.length === 0,
39
+ errors,
40
+ };
41
+ }
42
+ /**
43
+ * Check rate limit for a client
44
+ * @returns true if within limits, false if rate limited
45
+ */
46
+ checkRateLimit(clientId) {
47
+ const now = Date.now();
48
+ const windowMs = 60000; // 1 minute window
49
+ const existing = this.rateLimitMap.get(clientId);
50
+ if (!existing || now >= existing.resetTime) {
51
+ // Start new window
52
+ this.rateLimitMap.set(clientId, {
53
+ count: 1,
54
+ resetTime: now + windowMs,
55
+ });
56
+ return true;
57
+ }
58
+ if (existing.count >= this.config.maxExecutionsPerMinute) {
59
+ return false;
60
+ }
61
+ existing.count++;
62
+ return true;
63
+ }
64
+ /**
65
+ * Get remaining rate limit for a client
66
+ */
67
+ getRateLimitRemaining(clientId) {
68
+ const existing = this.rateLimitMap.get(clientId);
69
+ if (!existing || Date.now() >= existing.resetTime) {
70
+ return this.config.maxExecutionsPerMinute;
71
+ }
72
+ return Math.max(0, this.config.maxExecutionsPerMinute - existing.count);
73
+ }
74
+ /**
75
+ * Sanitize and truncate result if too large
76
+ */
77
+ sanitizeResult(result) {
78
+ try {
79
+ const serialized = JSON.stringify(result);
80
+ if (serialized.length > this.config.maxResultSize) {
81
+ return {
82
+ _truncated: true,
83
+ _originalSize: serialized.length,
84
+ _maxSize: this.config.maxResultSize,
85
+ preview: serialized.substring(0, 1000) + "...",
86
+ };
87
+ }
88
+ return result;
89
+ }
90
+ catch {
91
+ return {
92
+ _error: "Result could not be serialized",
93
+ _type: typeof result,
94
+ };
95
+ }
96
+ }
97
+ /**
98
+ * Log execution for audit purposes
99
+ */
100
+ auditLog(execution) {
101
+ const { id, clientId, codePreview, result, readonly } = execution;
102
+ const logContext = {
103
+ module: "CODEMODE",
104
+ operation: "execute",
105
+ entityId: id,
106
+ clientId: clientId ?? "anonymous",
107
+ readonly,
108
+ success: result.success,
109
+ wallTimeMs: result.metrics.wallTimeMs,
110
+ memoryUsedMb: result.metrics.memoryUsedMb,
111
+ };
112
+ if (result.success) {
113
+ logger.info(`Code execution completed: ${codePreview.substring(0, 50)}...`, logContext);
114
+ }
115
+ else {
116
+ const errorContext = {
117
+ ...logContext,
118
+ ...(result.error !== undefined ? { error: result.error } : {}),
119
+ ...(result.stack !== undefined ? { stack: result.stack } : {}),
120
+ };
121
+ logger.warning(`Code execution failed: ${result.error ?? "unknown error"}`, errorContext);
122
+ }
123
+ }
124
+ /**
125
+ * Create execution record for audit
126
+ */
127
+ createExecutionRecord(code, result, readonly, clientId) {
128
+ return {
129
+ id: crypto.randomUUID(),
130
+ clientId,
131
+ timestamp: new Date(),
132
+ codePreview: code.length > 200 ? code.substring(0, 200) + "..." : code,
133
+ result,
134
+ readonly,
135
+ };
136
+ }
137
+ /**
138
+ * Clean up old rate limit entries
139
+ */
140
+ cleanupRateLimits() {
141
+ const now = Date.now();
142
+ for (const [clientId, entry] of this.rateLimitMap) {
143
+ if (now >= entry.resetTime) {
144
+ this.rateLimitMap.delete(clientId);
145
+ }
146
+ }
147
+ }
148
+ }
149
+ //# sourceMappingURL=security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security.js","sourceRoot":"","sources":["../../src/codemode/security.ts"],"names":[],"mappings":"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"}