@neverinfamous/mysql-mcp 2.3.0 → 3.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.
Files changed (347) hide show
  1. package/.dockerignore +1 -0
  2. package/.gitattributes +18 -0
  3. package/.github/workflows/codeql.yml +2 -10
  4. package/.github/workflows/docker-publish.yml +15 -13
  5. package/CHANGELOG.md +287 -1
  6. package/DOCKER_README.md +100 -265
  7. package/Dockerfile +5 -0
  8. package/README.md +124 -59
  9. package/VERSION +1 -1
  10. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  11. package/dist/__tests__/mocks/adapter.js +2 -0
  12. package/dist/__tests__/mocks/adapter.js.map +1 -1
  13. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  14. package/dist/adapters/DatabaseAdapter.js +50 -9
  15. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  16. package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
  17. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  18. package/dist/adapters/mysql/MySQLAdapter.js +8 -0
  19. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  20. package/dist/adapters/mysql/SchemaManager.js +16 -15
  21. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  22. package/dist/adapters/mysql/prompts/index.js +10 -20
  23. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  24. package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
  25. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  26. package/dist/adapters/mysql/resources/docstore.js +10 -7
  27. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  28. package/dist/adapters/mysql/resources/events.js +11 -8
  29. package/dist/adapters/mysql/resources/events.js.map +1 -1
  30. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  31. package/dist/adapters/mysql/resources/indexes.js +12 -15
  32. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  33. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  34. package/dist/adapters/mysql/resources/innodb.js +20 -17
  35. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  36. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  37. package/dist/adapters/mysql/resources/locks.js +9 -6
  38. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  39. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  40. package/dist/adapters/mysql/resources/performance.js +15 -15
  41. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  42. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  43. package/dist/adapters/mysql/resources/spatial.js +9 -6
  44. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  45. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  46. package/dist/adapters/mysql/resources/sysschema.js +12 -9
  47. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  48. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  49. package/dist/adapters/mysql/tools/admin/backup.js +170 -121
  50. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  51. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  52. package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
  53. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  54. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  55. package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
  56. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  57. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  58. package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
  59. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  60. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  61. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
  62. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  63. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
  64. package/dist/adapters/mysql/tools/codemode/index.js +6 -4
  65. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
  66. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  67. package/dist/adapters/mysql/tools/core.js +152 -29
  68. package/dist/adapters/mysql/tools/core.js.map +1 -1
  69. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  70. package/dist/adapters/mysql/tools/docstore.js +340 -163
  71. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  72. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  73. package/dist/adapters/mysql/tools/events.js +284 -198
  74. package/dist/adapters/mysql/tools/events.js.map +1 -1
  75. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  76. package/dist/adapters/mysql/tools/json/core.js +11 -39
  77. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  78. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  79. package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
  80. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  81. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  82. package/dist/adapters/mysql/tools/json/helpers.js +13 -24
  83. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  84. package/dist/adapters/mysql/tools/partitioning.js +3 -0
  85. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  86. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  87. package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
  88. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  89. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  90. package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
  91. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  92. package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
  93. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  94. package/dist/adapters/mysql/tools/proxysql.js +289 -176
  95. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  96. package/dist/adapters/mysql/tools/replication.js +75 -49
  97. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  98. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  99. package/dist/adapters/mysql/tools/roles.js +224 -182
  100. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  101. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  102. package/dist/adapters/mysql/tools/router.js +168 -67
  103. package/dist/adapters/mysql/tools/router.js.map +1 -1
  104. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  105. package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
  106. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  107. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  108. package/dist/adapters/mysql/tools/schema/management.js +61 -14
  109. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  110. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  111. package/dist/adapters/mysql/tools/schema/routines.js +27 -4
  112. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  113. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  114. package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
  115. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  116. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  117. package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
  118. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  119. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  120. package/dist/adapters/mysql/tools/schema/views.js +47 -7
  121. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  122. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  123. package/dist/adapters/mysql/tools/security/audit.js +102 -34
  124. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  125. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  126. package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
  127. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  128. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  129. package/dist/adapters/mysql/tools/security/encryption.js +137 -104
  130. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  131. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  132. package/dist/adapters/mysql/tools/shell/backup.js +71 -59
  133. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  134. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  135. package/dist/adapters/mysql/tools/shell/restore.js +61 -47
  136. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  137. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  138. package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
  139. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  140. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  141. package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
  142. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  143. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  144. package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
  145. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  146. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  147. package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
  148. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  149. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  150. package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
  151. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  152. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  153. package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
  154. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  155. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  156. package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
  157. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  158. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  159. package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
  160. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  161. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  162. package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
  163. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  164. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  165. package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
  166. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  167. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  168. package/dist/adapters/mysql/tools/transactions.js +48 -23
  169. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  170. package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
  171. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  172. package/dist/adapters/mysql/types/proxysql-types.js +33 -1
  173. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  174. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  175. package/dist/adapters/mysql/types/router-types.js +1 -1
  176. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  177. package/dist/adapters/mysql/types/shell-types.js +2 -2
  178. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  179. package/dist/adapters/mysql/types.d.ts +485 -21
  180. package/dist/adapters/mysql/types.d.ts.map +1 -1
  181. package/dist/adapters/mysql/types.js +546 -19
  182. package/dist/adapters/mysql/types.js.map +1 -1
  183. package/dist/auth/scopes.js +1 -1
  184. package/dist/auth/scopes.js.map +1 -1
  185. package/dist/codemode/api.d.ts +3 -2
  186. package/dist/codemode/api.d.ts.map +1 -1
  187. package/dist/codemode/api.js +80 -5
  188. package/dist/codemode/api.js.map +1 -1
  189. package/dist/codemode/sandbox-factory.js +1 -1
  190. package/dist/codemode/sandbox-factory.js.map +1 -1
  191. package/dist/codemode/types.d.ts +26 -0
  192. package/dist/codemode/types.d.ts.map +1 -1
  193. package/dist/codemode/types.js +2 -0
  194. package/dist/codemode/types.js.map +1 -1
  195. package/dist/codemode/worker-sandbox.d.ts +4 -2
  196. package/dist/codemode/worker-sandbox.d.ts.map +1 -1
  197. package/dist/codemode/worker-sandbox.js +66 -7
  198. package/dist/codemode/worker-sandbox.js.map +1 -1
  199. package/dist/codemode/worker-script.d.ts +3 -0
  200. package/dist/codemode/worker-script.d.ts.map +1 -1
  201. package/dist/codemode/worker-script.js +128 -75
  202. package/dist/codemode/worker-script.js.map +1 -1
  203. package/dist/constants/ServerInstructions.d.ts +1 -1
  204. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  205. package/dist/constants/ServerInstructions.js +37 -31
  206. package/dist/constants/ServerInstructions.js.map +1 -1
  207. package/dist/filtering/ToolConstants.d.ts +1 -1
  208. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  209. package/dist/filtering/ToolConstants.js +1 -2
  210. package/dist/filtering/ToolConstants.js.map +1 -1
  211. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  212. package/dist/pool/ConnectionPool.js.map +1 -1
  213. package/dist/transports/http.d.ts.map +1 -1
  214. package/dist/transports/http.js +6 -0
  215. package/dist/transports/http.js.map +1 -1
  216. package/dist/utils/validators.d.ts +1 -1
  217. package/dist/utils/validators.d.ts.map +1 -1
  218. package/dist/utils/validators.js.map +1 -1
  219. package/package.json +4 -4
  220. package/releases/v2.3.0-release-notes.md +20 -20
  221. package/releases/v2.3.1-release-notes.md +34 -0
  222. package/releases/v3.0.0-release-notes.md +81 -0
  223. package/src/__tests__/mocks/adapter.ts +3 -0
  224. package/src/__tests__/perf.test.ts +6 -6
  225. package/src/adapters/DatabaseAdapter.ts +58 -9
  226. package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
  227. package/src/adapters/mysql/MySQLAdapter.ts +17 -2
  228. package/src/adapters/mysql/SchemaManager.ts +21 -21
  229. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
  230. package/src/adapters/mysql/prompts/index.ts +12 -22
  231. package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
  232. package/src/adapters/mysql/resources/docstore.ts +13 -10
  233. package/src/adapters/mysql/resources/events.ts +12 -12
  234. package/src/adapters/mysql/resources/indexes.ts +17 -19
  235. package/src/adapters/mysql/resources/innodb.ts +23 -22
  236. package/src/adapters/mysql/resources/locks.ts +9 -7
  237. package/src/adapters/mysql/resources/performance.ts +23 -18
  238. package/src/adapters/mysql/resources/spatial.ts +9 -7
  239. package/src/adapters/mysql/resources/sysschema.ts +12 -11
  240. package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
  241. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
  242. package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
  243. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
  244. package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
  245. package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
  246. package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
  247. package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
  248. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
  249. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -50
  250. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
  251. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
  252. package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
  253. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
  254. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
  255. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
  256. package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
  257. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
  258. package/src/adapters/mysql/tools/admin/backup.ts +193 -143
  259. package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
  260. package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
  261. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
  262. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
  263. package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
  264. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
  265. package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
  266. package/src/adapters/mysql/tools/codemode/index.ts +5 -3
  267. package/src/adapters/mysql/tools/core.ts +152 -38
  268. package/src/adapters/mysql/tools/docstore.ts +422 -205
  269. package/src/adapters/mysql/tools/events.ts +334 -233
  270. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
  271. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
  272. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
  273. package/src/adapters/mysql/tools/json/core.ts +21 -42
  274. package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
  275. package/src/adapters/mysql/tools/json/helpers.ts +21 -25
  276. package/src/adapters/mysql/tools/partitioning.ts +3 -0
  277. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
  278. package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
  279. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
  280. package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
  281. package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
  282. package/src/adapters/mysql/tools/proxysql.ts +314 -209
  283. package/src/adapters/mysql/tools/replication.ts +84 -57
  284. package/src/adapters/mysql/tools/roles.ts +274 -226
  285. package/src/adapters/mysql/tools/router.ts +181 -85
  286. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
  287. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
  288. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
  289. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
  290. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
  291. package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
  292. package/src/adapters/mysql/tools/schema/management.ts +60 -15
  293. package/src/adapters/mysql/tools/schema/routines.ts +26 -4
  294. package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
  295. package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
  296. package/src/adapters/mysql/tools/schema/views.ts +46 -8
  297. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
  298. package/src/adapters/mysql/tools/security/audit.ts +113 -39
  299. package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
  300. package/src/adapters/mysql/tools/security/encryption.ts +172 -139
  301. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
  302. package/src/adapters/mysql/tools/shell/backup.ts +90 -73
  303. package/src/adapters/mysql/tools/shell/restore.ts +62 -48
  304. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
  305. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
  306. package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
  307. package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
  308. package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
  309. package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
  310. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
  311. package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
  312. package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
  313. package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
  314. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
  315. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
  316. package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
  317. package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
  318. package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
  319. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
  320. package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
  321. package/src/adapters/mysql/tools/transactions.ts +49 -24
  322. package/src/adapters/mysql/types/proxysql-types.ts +38 -1
  323. package/src/adapters/mysql/types/router-types.ts +1 -1
  324. package/src/adapters/mysql/types/shell-types.ts +2 -2
  325. package/src/adapters/mysql/types.ts +632 -19
  326. package/src/auth/__tests__/scopes.test.ts +2 -2
  327. package/src/auth/scopes.ts +1 -1
  328. package/src/codemode/__tests__/api.test.ts +417 -0
  329. package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
  330. package/src/codemode/__tests__/sandbox.test.ts +301 -0
  331. package/src/codemode/__tests__/security.test.ts +368 -0
  332. package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
  333. package/src/codemode/__tests__/worker-script.test.ts +226 -0
  334. package/src/codemode/api.ts +89 -5
  335. package/src/codemode/sandbox-factory.ts +1 -1
  336. package/src/codemode/types.ts +34 -0
  337. package/src/codemode/worker-sandbox.ts +74 -7
  338. package/src/codemode/worker-script.ts +157 -86
  339. package/src/constants/ServerInstructions.ts +37 -31
  340. package/src/filtering/ToolConstants.ts +1 -2
  341. package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
  342. package/src/pool/ConnectionPool.ts +4 -1
  343. package/src/transports/__tests__/http.test.ts +15 -3
  344. package/src/transports/http.ts +12 -0
  345. package/src/utils/validators.ts +2 -1
  346. package/vitest.config.ts +3 -1
  347. package/CODE_MODE.md +0 -245
package/.dockerignore CHANGED
@@ -31,6 +31,7 @@ __tests__/
31
31
  *.test.ts
32
32
  *.spec.ts
33
33
  coverage/
34
+ test-results.json
34
35
 
35
36
  # GitHub
36
37
  .github/
package/.gitattributes ADDED
@@ -0,0 +1,18 @@
1
+ # Auto-detect text files and normalize line endings to LF in the repo
2
+ * text=auto eol=lf
3
+
4
+ # Explicitly mark shell scripts as LF (safety net)
5
+ *.sh text eol=lf
6
+
7
+ # Dockerfile must be LF
8
+ Dockerfile text eol=lf
9
+
10
+ # Keep Windows scripts as CRLF
11
+ *.ps1 text eol=crlf
12
+ *.cmd text eol=crlf
13
+ *.bat text eol=crlf
14
+
15
+ # Binary files - no line ending conversion
16
+ *.png binary
17
+ *.jpg binary
18
+ *.ico binary
@@ -2,7 +2,7 @@ name: "CodeQL Analysis"
2
2
 
3
3
  on:
4
4
  push:
5
- branches: ["master"]
5
+ branches: ["main"]
6
6
  paths:
7
7
  - "**.js"
8
8
  - "**.jsx"
@@ -12,15 +12,7 @@ on:
12
12
  - "**.cjs"
13
13
  - "package.json"
14
14
  pull_request:
15
- branches: ["master"]
16
- paths:
17
- - "**.js"
18
- - "**.jsx"
19
- - "**.ts"
20
- - "**.tsx"
21
- - "**.mjs"
22
- - "**.cjs"
23
- - "package.json"
15
+ branches: ["main"]
24
16
  schedule:
25
17
  - cron: "0 0 * * 1"
26
18
  workflow_dispatch:
@@ -4,7 +4,7 @@ on:
4
4
  push:
5
5
  tags: ["v*"]
6
6
  pull_request:
7
- branches: [master]
7
+ branches: [main]
8
8
 
9
9
  env:
10
10
  REGISTRY: docker.io
@@ -213,16 +213,18 @@ jobs:
213
213
  curl -sSfL https://raw.githubusercontent.com/docker/scout-cli/main/install.sh | sh -s --
214
214
  docker images local-scan:latest
215
215
  echo "🔍 Running Docker Scout security scan"
216
- if timeout 480 docker scout cves local-scan:latest > scout_output.txt 2>&1; then
217
- echo "📊 Scan completed successfully"
218
- cat scout_output.txt
219
- if grep -E "(CRITICAL|HIGH)" scout_output.txt | grep -v "0 " > /dev/null; then
220
- echo "⚠️ Critical or high severity vulnerabilities detected (informational)"
216
+ if timeout 480 docker scout cves local-scan:latest --only-fixed --exit-code 2>&1 | tee scout_output.txt; then
217
+ echo " No fixable vulnerabilities detected"
218
+ else
219
+ SCOUT_EXIT=$?
220
+ if [ "$SCOUT_EXIT" -eq 2 ]; then
221
+ echo "❌ Fixable vulnerabilities detected — blocking deployment"
222
+ cat scout_output.txt
223
+ exit 1
221
224
  else
222
- echo " No critical/high severity vulnerabilities"
225
+ echo "⚠️ Docker Scout scan failed or timed out (exit code: $SCOUT_EXIT)"
226
+ cat scout_output.txt
223
227
  fi
224
- else
225
- echo "⚠️ Docker Scout scan timed out or failed"
226
228
  fi
227
229
 
228
230
  # Merge platform images into multi-arch manifest
@@ -238,7 +240,7 @@ jobs:
238
240
  deployments: write
239
241
 
240
242
  environment:
241
- name: ${{ github.ref == 'refs/heads/master' && 'production' || '' }}
243
+ name: ${{ github.ref == 'refs/heads/main' && 'production' || '' }}
242
244
  url: https://hub.docker.com/r/writenotenow/mysql-mcp
243
245
 
244
246
  steps:
@@ -301,7 +303,7 @@ jobs:
301
303
 
302
304
  # Update Docker Hub description
303
305
  - name: Update Docker Hub Description
304
- if: github.ref == 'refs/heads/master'
306
+ if: github.ref == 'refs/heads/main'
305
307
  uses: peter-evans/dockerhub-description@v5
306
308
  continue-on-error: true
307
309
  timeout-minutes: 5
@@ -310,10 +312,10 @@ jobs:
310
312
  password: ${{ secrets.DOCKER_PASSWORD }}
311
313
  repository: ${{ env.IMAGE_NAME }}
312
314
  readme-filepath: ./DOCKER_README.md
313
- short-description: "MySQL MCP Server: 193 tools, Code Mode, Tool Filtering, Connection Pooling, HTTP/SSE & OAuth 2.1"
315
+ short-description: "MySQL MCP Server: 192 tools, Code Mode, Tool Filtering, Connection Pooling, HTTP/SSE & OAuth 2.1"
314
316
 
315
317
  - name: Deployment Summary
316
- if: github.ref == 'refs/heads/master'
318
+ if: github.ref == 'refs/heads/main'
317
319
  run: |
318
320
  echo "✅ Successfully published Docker images to production"
319
321
  echo "🐳 Registry: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}"
package/CHANGELOG.md CHANGED
@@ -5,7 +5,293 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
- ## [Unreleased]
8
+ ## [3.0.0] - 2026-02-26
9
+
10
+ ### Added
11
+
12
+ - **`mysql_export_table` Batch Parameter** — New optional `batch` parameter (default: 1) groups rows into multi-row `INSERT INTO ... VALUES (...), (...), ...` statements, reducing payload size by ~40-50% for large exports. Example: `batch: 50` produces one INSERT statement per 50 rows instead of one per row
13
+
14
+ ### Improved
15
+
16
+ - **`mysql_security_audit` Default Limit Reduction** — Reduced default `limit` from 100 to 20 (matching `mysql_binlog_events`), preventing ~18KB payloads of repetitive `performance_schema` events on default calls
17
+ - **`mysql_security_audit` `eventType` Description Accuracy** — Updated parameter description from misleading `"CONNECT"`, `"QUERY"` examples to accurate `performance_schema` event names (`"Execute"`, `"Ping"`, `"begin"`), and documented LIKE matching behavior
18
+ - **ServerInstructions Audit Fallback Documentation** — Split the security enterprise features bullet to separately document `mysql_security_audit` fallback behavior: `performance_schema` fallback mode, `startTime` filter limitations, `eventType` LIKE matching, and default limit
19
+
20
+ ### Fixed
21
+
22
+ - **No-Argument Prompts Zod Validation Error** — All 9 prompts without required arguments (`mysql_tool_index`, `mysql_setup_router`, `mysql_setup_proxysql`, `mysql_setup_shell`, `mysql_setup_events`, `mysql_sys_schema_guide`, `mysql_setup_spatial`, `mysql_setup_cluster`, `mysql_setup_docstore`) failed with `MCP error -32602: Invalid arguments ... expected object, received undefined` when invoked. Root cause: `DatabaseAdapter.registerPrompt()` always passed `argsSchema: {}` to the SDK even for no-argument prompts, which created `z.object({})` and rejected `undefined` input from clients. Fixed by passing `argsSchema: undefined` when `prompt.arguments` is empty
23
+
24
+ - **All Prompts with Arguments — Zod Validation Error** — All 10 prompts with arguments (`mysql_quick_schema`, `mysql_database_health_check`, `mysql_backup_strategy`, `mysql_index_tuning`, `mysql_setup_replication`, `mysql_query_builder`, `mysql_quick_query`, `mysql_schema_design`, `mysql_performance_analysis`, `mysql_migration`) failed with `MCP error -32602: Invalid arguments ... expected object, received undefined` when invoked without arguments. Root cause: `DatabaseAdapter.registerPrompt()` built a Zod schema whenever `prompt.arguments.length > 0`, and the SDK wrapped it into `z.object({...})` via `normalizeObjectSchema()`. Even with all fields marked `.optional()`, `z.object().safeParse(undefined)` always rejects `undefined` input — making field-level optionality irrelevant. Two previous fix attempts addressed field-level optionality (`.optional()`, handler-level validation) but not the schema-level rejection. Definitive fix: `argsSchema` is now always `undefined` for all prompts, so the SDK skips Zod validation entirely. Handler-level required-arg validation (already present) returns a helpful guide message when required arguments are missing
25
+
26
+ - **`mysql_doc_list_collections` False-Positive Collection Detection** — Detection query only checked for a `doc JSON` column without verifying `_id` column existence, causing any table with a `doc JSON` column (e.g., `test_json_docs`) to be listed as a document collection. Added `_id` column check via `JOIN` on `information_schema.COLUMNS`, matching the documented heuristic ("tables containing a `doc JSON` column with an `_id` field")
27
+
28
+ - **Docstore Schema Detection (7 Tools)** — `mysql_doc_find`, `mysql_doc_add`, `mysql_doc_modify`, `mysql_doc_remove`, `mysql_doc_create_index`, `mysql_doc_create_collection`, and `mysql_doc_drop_collection` incorrectly returned `{ exists: false, collection }` or leaked raw SQL errors when a nonexistent `schema` parameter was provided. Upgraded `checkCollectionExists` to a discriminated return type that distinguishes schema-not-found from collection-not-found, added `ER_BAD_DB_ERROR` catch to `create_collection`, and added schema pre-check to `drop_collection`. All 7 tools now consistently return `{ exists: false, schema }` for nonexistent schemas, matching the P154 pattern
29
+ - **Security Tool Error-Field Consistency (3 Handlers)** — Three security tool error paths (`mysql_security_audit` access-denied, `mysql_security_firewall_status` plugin check failure, `mysql_security_firewall_rules` table access error) returned `{ success: false, message }` without the standard `error` field, making them inconsistent with the `{ success: false, error }` convention used across all other tools. Added `error` field to all three responses (keeping `message` for backward compatibility)
30
+ - **Security Tool Redundant `message` Field Removal (3 Handlers)** — Three security tool error paths (`mysql_security_audit` access-denied, `mysql_security_firewall_status` plugin check failure, `mysql_security_firewall_rules` table access error) returned both `error` and `message` fields with identical or redundant content. Removed the `message` field from all three, standardizing on the `error` field exclusively for `{ success: false }` responses
31
+ - **`mysql_security_ssl_status` Empty Cipher Default** — The `str()` helper in `encryption.ts` treated empty strings as valid, so `currentCipher` returned `""` instead of `"None"` when SSL was disabled (MySQL returns `Ssl_cipher: ""`). Changed `str()` to treat empty strings as absent, activating the `"None"` default. Same fix applies to `sslVersion` (`"N/A"` default) and `requireSecureTransport` (`"OFF"` default)
32
+ - **Security Tool Catch-Block Error Shape Consistency** — Three catch blocks in `audit.ts` returned domain-specific shapes (`{ available: false }`, `{ installed: false }`) without `success: false`, making them inconsistent with the `{ success: false, error }` convention used across all other tools. Added `success: false` to `mysql_security_audit` (audit-related errors), `mysql_security_firewall_rules` (table access errors), and `mysql_security_firewall_status` (plugin check failures)
33
+
34
+ - **Schema Tool Zod Validation Leaks (6 Handlers)** — All 6 schema handler files (`constraints.ts`, `scheduled_events.ts`, `views.ts`, `management.ts`, `routines.ts`, `triggers.ts`) called `Schema.parse(params)` outside any `try/catch` block, causing raw Zod validation errors to propagate as MCP exceptions. Additionally, `list_constraints` (`type`), `list_events` (`status`), and `create_view` (`algorithm`, `checkOption`) used `z.enum()` directly on their `inputSchema`, causing the MCP framework to reject invalid values with raw `-32602` errors before handlers could intercept. Applied Split Schema pattern: created permissive `*Base` schemas with `z.string()` for `inputSchema` visibility, kept strict `z.enum()` schemas for handler-level parsing inside `try/catch` with `ZodError` detection and `formatZodError()` formatting, matching the Dual-Schema pattern used by admin, backup, and other tool groups
35
+ - **`mysql_check_table` Zod Enum Validation Leak** — The `option` parameter used `z.enum()` on `CheckTableSchemaBase`, causing invalid option values (e.g., `"INVALID_OPTION"`) to be rejected at the MCP framework level with a raw `-32602` Zod validation error before the handler's `try/catch` could intercept. Widened to `z.string()` on the Base schema while keeping `z.enum()` on the handler-parsed `CheckTableSchema`, so invalid values are caught inside `try/catch` and returned as `{ success: false, error }`
36
+ - **`mysql_binlog_events` Negative Limit Acceptance** — `BinlogEventsSchema` used `z.number().optional()` without `.nonnegative()`, allowing negative `limit` values (e.g., `-1`) to pass Zod validation and be string-interpolated into SQL via `LIMIT ${limit}`, producing a raw MySQL syntax error. Added `.nonnegative()` so negative values are rejected at the Zod validation level with structured `{ success: false, error }` responses
37
+ - **`mysql_binlog_events` Zod Parse Outside `try/catch` / Split Schema Violation** — `BinlogEventsSchema.parse(params)` was called outside the handler's `try/catch` block, and the same strict schema was used as `inputSchema`, causing Zod validation errors to propagate as raw MCP `-32602` exceptions. Applied Split Schema pattern: created permissive `BinlogEventsSchemaBase` for `inputSchema` visibility, kept strict `BinlogEventsSchema` (with `.nonnegative()`) for handler parsing inside a new outer `try/catch` with `ZodError` detection and human-readable error formatting
38
+
39
+ - **`mysql_flush_tables` Missing `error` Field on Nonexistent Tables** — When called with nonexistent tables, the response returned `{ success: false, notFound, flushed }` without the standard `error` field required by the error consistency convention. Added `error: "Tables not found: ..."` to the response, matching the `{ success: false, error }` pattern used by all other tools. The `notFound` and `flushed` arrays remain as additional context
40
+
41
+ - **`mysql_json_index_suggest` DDL for Qualified Table Names** — Generated `indexDdl` wrapped qualified table names in a single backtick pair (`` `schema.table` ``) instead of properly escaping each part (`` `schema`.`table` ``), producing invalid MySQL syntax. The index name also included the schema prefix (e.g., `idx_schema.table_key`), which is invalid as an unquoted identifier. Fixed by using `escapeQualifiedTable()` for the `ALTER TABLE` clause and extracting just the table basename for the index name
42
+ - **Transaction Tool Zod Validation Leaks (`mysql_transaction_begin`, `mysql_transaction_execute`)** — Both tools used `z.enum()` for their `isolationLevel` parameter, and called Zod's `parse()` outside their `try/catch` blocks (or lacked `try/catch` entirely). This caused invalid enum values to be rejected with raw `-32602` errors before the handler could intercept them. Applied Split Schema pattern with widened `z.string()` base schemas, moved `parse()` inside `try/catch`, and returned structured `{ success: false, error }` responses for validation failures.
43
+ - **Core Tool Zod Validation Leaks (8 Tools)** — `mysql_read_query`, `mysql_write_query`, `mysql_list_tables`, `mysql_describe_table`, `mysql_create_table`, `mysql_drop_table`, `mysql_get_indexes`, and `mysql_create_index` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when missing required parameters or invalid types were passed. Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by all other tool groups.
44
+ - **`mysql_drop_table` Default Behavior** — The `ifExists` parameter in `DropTableSchemaBase` defaulted to `true`, contradicting the documented behavior and generic SQL defaults where it should be false unless explicitly requested. Changed the default value to `false`.
45
+
46
+ ### Security
47
+
48
+ - **Worker Sandbox API Bridge (Critical)** — The `CODEMODE_ISOLATION=worker` mode spawned a Worker thread but the `mysql.*` API bindings were non-functional — `serializeBindings()` stripped all functions to method name arrays, and `worker-script.ts` set `mysql: {}` (empty object). Implemented a `MessagePort`-based RPC bridge: the main thread listens on `port1` for `{ id, group, method, args }` requests and dispatches to real `MySQLAdapter` methods; the worker builds async proxy stubs via `buildMysqlProxy()` that send RPC requests through `port2` and await responses. Changed default sandbox mode from `vm` to `worker` for stronger V8 isolate separation. Readonly enforcement, `resourceLimits` memory caps, and timeout mechanisms remain fully functional
49
+
50
+ - **Code Mode Readonly Enforcement (Critical)** — The `readonly: true` flag on `mysql_execute_code` was accepted but never enforced — write tools (`writeQuery`, `dropTable`, `createTable`, `createIndex`) executed normally. Readonly mode now replaces write-oriented tool groups (`transactions`, `admin`, `backup`, `partitioning`, `roles`, `events`, `shell`) with stubs returning `{ success: false, error }`, and blocks individual write methods in mixed groups (`core`, `docstore`, `schema`, `json`, `fulltext`, `spatial`) with descriptive error messages
51
+ - **Worker Memory Limits Enforced (Critical)** — `WorkerSandbox` now passes `resourceLimits` (`maxOldGenerationSizeMb`, `maxYoungGenerationSizeMb`) to the `Worker` constructor, enforcing V8 heap limits. Previously, `memoryLimitMb` in sandbox options was accepted but ignored
52
+ - **Core Tool Group Scope Mapping (High)** — Fixed `core` tool group OAuth scope from `READ` → `WRITE`. The `core` group contains `writeQuery`, `dropTable`, `createTable`, and `createIndex`, which are write/DDL operations. A `READ`-scoped OAuth client could previously execute arbitrary write operations through `core` tools
53
+ - **HTTP Security Headers (Medium)** — Added `Strict-Transport-Security` (2-year max-age), `Referrer-Policy` (no-referrer), and `Permissions-Policy` (camera/microphone/geolocation denied) to all HTTP transport responses, complementing existing CSP, X-Frame-Options, X-Content-Type-Options, X-XSS-Protection, and Cache-Control headers
54
+ - **Sandbox Blocked Pattern Hardening (Medium)** — Added detection for bracket-notation constructor access (`['constructor']`) and `Reflect.construct` bypass vectors, closing two confirmed regex blocklist gaps in Code Mode security validation
55
+
56
+ ### Fixed
57
+
58
+ - **Router 404 Response Differentiation** — All 9 router tools returned `{ available: false, error }` for both "Router is down" (ECONNREFUSED, timeout, TLS, 401/500) and "route/metadata/pool not found" (404) scenarios, making them indistinguishable. `routerFetch` now attaches `statusCode` to thrown errors and `safeRouterFetch` detects 404 responses, returning `{ success: false, error }` (standard error convention) instead of `{ available: false }` (reserved for actual connectivity failures)
59
+ - **`ConnectionPoolStatusSchema` Field Mismatch** — Schema defined `reusedConnections` which never appeared in actual Router REST API responses. Replaced with `stashedServerConnections` to match the real API response shape (`idleServerConnections` + `stashedServerConnections`)
60
+ - **`safeRouterFetch` Stale JSDoc** — Docstring referenced `{ available: false, reason }` but implementation uses `{ available: false, error }` (corrected during the earlier `reason` → `error` normalization)
61
+ - **Router Tool Catch-Block Error Shape Consistency** — 7 parameterized router handlers (`route_status`, `route_health`, `route_connections`, `route_destinations`, `route_blocked_hosts`, `metadata_status`, `pool_status`) had a defense-in-depth catch branch returning `{ available: false, error }` for unexpected non-Zod exceptions, inconsistent with the `{ success: false, error }` convention used by all other tool groups. Changed to `{ success: false, error }`. The `{ available: false }` shape is now reserved exclusively for `safeRouterFetch` connectivity failures
62
+
63
+ ### Improved
64
+
65
+ - **ServerInstructions Router Error Documentation** — Updated unavailability handling documentation to describe both error shapes: `{ available: false, error }` for connectivity failures and `{ success: false, error }` for 404 (nonexistent route/metadata/pool)
66
+
67
+ ### Fixed
68
+
69
+ - **ProxySQL Split Schema Validation Leaks** — 5 ProxySQL tools (`proxysql_servers`, `proxysql_connection_pool`, `proxysql_query_rules`, `proxysql_query_digest`, `proxysql_global_variables`) used strict Zod schemas as `inputSchema`, causing the MCP framework to reject invalid inputs (negative `hostgroup_id`, negative/float `limit`) with raw `-32602` errors before the handler's `try/catch` could format them. Applied Split Schema pattern: permissive Base schemas for MCP framework visibility, strict schemas for handler-level parsing. All validation failures now return `{ success: false, error }` structured responses
70
+ - **Router Tool Error Field Normalization (`reason` → `error`)** — All 9 router tools returned `{ available: false, reason }` for unavailability/error responses, violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` contexts. Renamed to `{ available: false, error }` for consistency with all other tool groups
71
+ - **Router Tool Zod Validation Leaks (7 Handlers)** — `mysql_router_route_status`, `mysql_router_route_health`, `mysql_router_route_connections`, `mysql_router_route_destinations`, `mysql_router_route_blocked_hosts`, `mysql_router_metadata_status`, and `mysql_router_pool_status` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when invalid parameter types were passed (e.g., `routeName: 123`). Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by all other tool groups
72
+
73
+ ### Security
74
+
75
+ - **ProxySQL Numeric Interpolation Hardening** — Added `Math.max(0, Math.floor())` defense-in-depth for all 5 SQL-interpolated numeric parameters (`hostgroup_id`, `limit`) across `proxysql_servers`, `proxysql_connection_pool`, `proxysql_query_rules`, `proxysql_query_digest`, and `proxysql_global_variables`. Zod validates first, but coercion prevents any bypass from reaching SQL
76
+ - **ProxySQL `like` Pattern Validation** — `proxysql_global_variables` `like` parameter previously only applied single-quote escaping, leaving a potential SQL injection surface. Added `LIKE_SAFE_RE` regex validation that rejects patterns containing characters outside `[a-zA-Z0-9_%\-. *]` with a structured error before any SQL interpolation
77
+
78
+ ### Improved
79
+
80
+ - **ProxySQL `formatZodError` Consistency** — Replaced inline `error.issues.map(i => i.message).join("; ")` in all 11 ProxySQL handler catch blocks with centralized `formatZodError()` helper, matching the pattern used across all other tool groups
81
+ - **ServerInstructions ProxySQL Documentation** — Documented `like` pattern safe character set validation, `hostgroup_id` non-negative integer constraint, and `limit` non-negative integer constraint for query analysis tools
82
+
83
+ ### Fixed
84
+
85
+ - **Redundant `proxysql_hostgroups` Tool Removed** — `proxysql_hostgroups` and `proxysql_connection_pool` both queried `SELECT * FROM stats_mysql_connection_pool` with identical response shapes, making `proxysql_hostgroups` completely redundant. Removed `proxysql_hostgroups` — use `proxysql_connection_pool` (which supports `hostgroup_id` filtering) instead. ProxySQL tool count: 12 → 11, total tools: 193 → 192
86
+ - **ProxySQL `hostgroup_id` Negative Value Acceptance** — `ProxySQLHostgroupInputSchema` used `z.number().int().optional()` without `.nonnegative()`, allowing negative `hostgroup_id` values (e.g., `-1`) to silently return empty results. Added `.nonnegative()` so negative values are rejected at the Zod validation level with structured `{ success: false, error }` responses
87
+
88
+ ### Improved
89
+
90
+ - **ServerInstructions ProxySQL Documentation** — Updated backend servers documentation to reflect removal of `proxysql_hostgroups` and document that `hostgroup_id` must be a non-negative integer
91
+
92
+ - **ProxySQL `limit` Float and Negative Acceptance** — `ProxySQLLimitInputSchema` and `ProxySQLVariableFilterSchema` used `z.number().optional()` without `.int()` or `.min(0)`, allowing float values (e.g., `1.5`) and negative limits (e.g., `-5`) to pass validation and be interpolated into SQL. Added `.int().min(0)` to both schemas so non-integer and negative limits are rejected at the Zod validation level with structured error responses
93
+ - **ProxySQL `hostgroup_id` Float Acceptance** — `ProxySQLHostgroupInputSchema` used `z.number().optional()` without `.int()`, allowing float values like `1.5` to be interpolated into SQL `WHERE hostgroup_id = 1.5`. Added `.int()` so non-integer hostgroup IDs are rejected at validation
94
+
95
+ ### Improved
96
+
97
+ - **ServerInstructions ProxySQL Error Documentation** — Updated ProxySQL error handling documentation from "propagate connection errors" to document that all 12 tools return `{ success: false, error }` for connection failures, query errors, and invalid parameters. Added `hostgroup_id` integer-only and `limit` non-negative integer constraints
98
+
99
+ - **`mysql_cluster_instances` Prepared Statement Incompatibility** — Both the primary InnoDB Cluster metadata query and the Group Replication fallback query used `LIMIT ?` parameterized placeholders, which are incompatible with `performance_schema` and `mysql_innodb_cluster_metadata` tables in the `mysql2` prepared statement protocol (`Incorrect arguments to mysqld_stmt_execute`). Changed to string-interpolated `LIMIT ${String(limit)}` (safe: value is Zod-validated as `z.number().int().min(0)`), matching the pattern used by `mysql_security_audit` for `performance_schema` queries
100
+ - **`mysql_cluster_instances` Fallback Error Context Lost** — When the primary InnoDB Cluster metadata query fails and the GR fallback query also fails, only the fallback error was returned, discarding the primary error (often the actual root cause). Now includes `primaryError` field in the error response for complete diagnostic context
101
+
102
+ ### Improved
103
+
104
+ - **ServerInstructions Cluster Instances Documentation** — Documented `mysql_cluster_instances` fallback behavior from InnoDB Cluster metadata to Group Replication member data, and the `source: "group_replication"` field present in fallback responses
105
+
106
+ ### Security
107
+
108
+ - **`mysql_doc_find` Filter SQL Injection Fix** — The `filter` parameter was interpolated directly into the SQL query (`WHERE JSON_EXTRACT(doc, '${filter}') IS NOT NULL`), allowing arbitrary SQL injection via crafted filter values (e.g., `$') IS NOT NULL OR 1=1 -- `). Added `JSON_PATH_RE` validation regex that rejects any filter containing characters outside the valid JSON path set (`$`, `.`, `[`, `]`, `*`, alphanumeric, underscore). Invalid paths now return `{ success: false, error: "Invalid JSON path filter: ..." }` instead of executing
109
+ - **`parseDocFilter` Field Name Validation Hardening** — Added explicit `IDENTIFIER_RE` validation for field names extracted from `field=value` filter patterns as defense-in-depth. While the existing regex already limited field names to identifier characters, the explicit check ensures future regex changes cannot introduce injection surfaces
110
+
111
+ ### Improved
112
+
113
+ - **Docstore Schema Parameter (5 Tools)** — `mysql_doc_add`, `mysql_doc_find`, `mysql_doc_modify`, `mysql_doc_remove`, and `mysql_doc_create_index` now accept an optional `schema` parameter for cross-database collection access. Previously these 5 tools hardcoded `DATABASE()` for collection existence checks and query execution, making collections created in non-default databases invisible. All 5 tools now pass `schema` to `checkCollectionExists()` and use `escapeTableRef()` for qualified table references (`` `schema`.`collection` ``)
114
+ - **ServerInstructions Docstore Schema Documentation** — Updated docstore section to document the new `schema` parameter on all 5 tools, added `mysql_doc_collection_info` to the schema existence check documentation, and documented `mysql_doc_find` JSON path validation behavior
115
+
116
+ ### Fixed
117
+
118
+ - **`mysql_cluster_instances` Float Limit Acceptance** — `LimitSchema` used `z.number().min(0)` without `.int()`, allowing float values like `0.5` to pass Zod validation but cause a MySQL syntax error (`near '0.5'`). Added `.int()` constraint so non-integer limits are rejected with a structured error response
119
+ - **`mysql_cluster_instances` Split Schema Violation** — `inputSchema` used the strict `LimitSchema` (with `.int().min(0)`) directly, causing the MCP framework to reject invalid values (e.g., `limit: -1`) with a raw `-32602` Zod error before the handler's `try/catch` could intercept. Created `LimitSchemaBase` (permissive `z.number().optional()`) for `inputSchema`, keeping the strict `LimitSchema` for handler-level parsing inside `try/catch`, matching the Dual-Schema pattern used across all other tool groups
120
+ - **`mysql_cluster_switchover` `currentPrimary` Field Disappearing from JSON** — When no primary exists (GR offline), `members.find()` returns `undefined`, which JSON serialization silently drops — making the `currentPrimary` field absent from the response instead of explicitly `null`. Added `?? null` fallback so the field is always present. Also added `currentPrimary: null` to the error catch block so the field is present even on query failures
121
+ - **`mysql_gr_flow_control` Inconsistent Error Shape** — The `gr_flow_control` catch block returned `{ success: false, error }` while all other 4 GR tools return domain-specific defaults with an `error` field (`{ enabled: false }`, `{ members: [], count: 0 }`, `{ hasPrimary: false }`, `{ memberStats: [], gtid: {...} }`). Changed to return `{ configuration: {}, memberQueues: [], isThrottling: false, error }` for consistency
122
+
123
+ ### Improved
124
+
125
+ - **ServerInstructions Cluster Documentation** — Updated `mysql_cluster_instances` documentation to clarify `limit` must be a non-negative integer (not just `min: 0`). Updated `mysql_cluster_switchover` to document that `currentPrimary` is `null` (not absent) when no primary exists
126
+
127
+ - **`mysql_security_audit` Fallback Filter Gap** — `eventType` and `startTime` parameters were silently ignored in the `performance_schema` fallback branch (when `mysql.audit_log` table is unavailable). `eventType` now generates an `EVENT_NAME LIKE ?` condition. `startTime` is documented as inapplicable (performance_schema uses picosecond counters, not ISO timestamps) and a `filtersIgnored`/`note` field is included in the response when it cannot be applied
128
+ - **`mysql_security_audit` Generic Catch-Block Error** — Catch block returned `{available: false, message: "Audit logging is not enabled..."}` for all exceptions, including non-audit failures (connection loss, permission denied, etc.). Now inspects the error message: audit-related errors (table doesn't exist, access denied) still return the `{available: false}` response, while all other errors return `{success: false, error}` matching the structured error convention used across all other tools
129
+ - **`mysql_security_audit` Performance Schema Query Column Mismatch** — The `performance_schema.events_statements_history` fallback query referenced `HOST` (nonexistent column) and `CURRENT_USER` (MySQL function returning current session user, not the statement's author), causing `Unknown column 'HOST'` errors. Fixed by JOINing with `performance_schema.threads` for `PROCESSLIST_USER`/`PROCESSLIST_HOST`, providing accurate per-statement user and host information
130
+ - **`mysql_security_audit` Prepared Statement Incompatibility** — The `performance_schema` fallback query used parameterized `?` placeholders, but MySQL's `performance_schema` does not support prepared statements, causing `Incorrect arguments to mysqld_stmt_execute` errors. Converted to text-protocol query with safe string interpolation (values are Zod-validated or single-quote-escaped)
131
+
132
+ ### Improved
133
+
134
+ - **JSON Tool Split Schema Migration** — Migrated 9 JSON tools (`json_insert`, `json_replace`, `json_remove`, `json_array_append`, `json_get`, `json_update`, `json_normalize`, `json_stats`, `json_index_suggest`) from inline Zod schemas to the Dual-Schema pattern in `types.ts`. All 9 tools now support parameter aliases (`tableName`/`name` for `table`, `col` for `column`, `filter` for `where`), matching the 5 tools (`json_extract`, `json_set`, `json_contains`, `json_keys`, `json_search`) that already supported aliases
135
+ - **`mysql_stats_histogram` Buckets Clamping Warning** — When `buckets > 1024` is requested with `update: true`, the tool now includes a `warning` field (e.g., `"Requested 2000 buckets; clamped to max 1024"`) on the response instead of silently clamping. Matches the warning pattern used by `mysql_create_index` for HASH→BTREE conversion
136
+ - **`mysql_kill_query` Split Schema Consistency** — Added `KillQuerySchemaBase` to align with the Dual-Schema pattern used by all other admin tools. `inputSchema` now uses `KillQuerySchemaBase` (visible to MCP clients) while handler parsing continues to use `KillQuerySchema`. No functional change — ensures consistent architecture across the admin group
137
+ - **`mysql_json_validate` Error Clarity** — Stripped verbose `Execute failed: ` prefix from error messages returned when MySQL throws on severely malformed JSON input. Error responses now show only the meaningful MySQL error text
138
+ - **`mysql_json_validate` Error Prefix Expansion** — Expanded error prefix stripping regex to also remove `Query failed: ` prefix, which was still leaking through on certain MySQL driver error paths. Both `Query failed:` and `Execute failed:` prefixes are now stripped
139
+
140
+ - **ServerInstructions JSON Documentation** — Added missing documentation for mandatory `where` parameter on JSON write tools (`json_set`, `json_insert`, `json_replace`, `json_remove`, `json_array_append`) and documented that `json_remove` accepts a `paths` array instead of a single `path` string
141
+
142
+ - **Fulltext Tool Split Schema Migration** — Migrated 3 fulltext tools (`mysql_fulltext_drop`, `mysql_fulltext_boolean`, `mysql_fulltext_expand`) from inline Zod schemas to the Dual-Schema pattern in `types.ts`. All 3 tools now support parameter aliases (`tableName`/`name` for `table`), matching the 2 tools (`mysql_fulltext_create`, `mysql_fulltext_search`) that already supported aliases
143
+
144
+ - **ServerInstructions Schema Documentation** — Updated `mysql_create_schema`, `mysql_drop_schema`, and `mysql_create_view` error response documentation from `{ success: false, reason }` to `{ success: false, error }` matching the corrected handler behavior. Added missing documentation for `mysql_list_triggers` optional `table` parameter with P154 behavior (`{ exists: false, table }` for nonexistent tables)
145
+
146
+ - **ServerInstructions Events Documentation** — Added missing `includeDisabled` parameter documentation for `mysql_event_list`. Updated error response field from `{ success: false, reason }` to `{ success: false, error }` in the "Graceful error handling" bullet
147
+
148
+ - **ServerInstructions Sysschema Documentation** — Corrected `mysql_sys_schema_stats` error response documentation from `{ exists: false, schema }` to `{ success: false, error }`, matching the actual handler implementation which returns `{ success: false, error: "Schema 'X' does not exist" }`
149
+
150
+ - **ServerInstructions Docstore Documentation** — Updated `mysql_doc_create_collection`, `mysql_doc_drop_collection`, and `mysql_doc_create_index` error response documentation from `{ success: false, reason }` to `{ success: false, error }` matching the corrected handler behavior. Added `schema` parameter documentation for `create_collection` and `drop_collection`
151
+
152
+ - **ServerInstructions Cluster Documentation** — Added missing `limit` parameter documentation for `mysql_cluster_instances` (default: 100, min: 0). Added GR error handling note documenting that all 5 GR tools return structured errors with `error` field on query failure. Added `currentPrimary` field documentation for `mysql_cluster_switchover` response
153
+
154
+ ### Fixed
155
+
156
+ - **Cluster Tool Zod Validation Leaks (3 Tools)** — `mysql_cluster_status`, `mysql_cluster_instances`, and `mysql_cluster_router_status` called `Schema.parse(params)` outside their `try/catch` blocks, causing raw Zod validation errors to propagate as MCP exceptions when invalid parameter types were passed (e.g., `summary: "yes"`, `limit: "abc"`). Moved all `parse()` calls inside `try/catch` with `ZodError` detection and human-readable error formatting, matching the pattern used by admin and backup tools
157
+ - **`mysql_cluster_instances` Negative Limit Guard** — Added `.min(0)` to `LimitSchema.limit` to reject negative values at the Zod validation level. Previously, `limit: -5` passed Zod validation but was string-interpolated into SQL via `LIMIT ${String(limit)}`, producing a raw MySQL syntax error
158
+ - **`mysql_cluster_instances` Fallback Error Swallowing** — When the primary InnoDB Cluster metadata query fails, the handler falls back to a GR-only query. Previously, the fallback query was not wrapped in its own `try/catch`, so if both the primary and fallback queries failed, the fallback error would propagate as a raw MCP exception. Now wrapped in nested `try/catch` returning `{ instances: [], count: 0, error }` for complete error containment
159
+ - **`mysql_cluster_router_status` Missing Error Field** — The `catch` block returned `{ available: false, message, suggestion }` without an `error` field, making it impossible for consumers to distinguish between "metadata not available" and a specific query failure. Added `error` field with `ZodError` detection matching the pattern used by the other cluster tool catch blocks
160
+
161
+ - **Docstore Tool Raw Error Leaks** — All 9 docstore tools (`mysql_doc_list_collections`, `mysql_doc_create_collection`, `mysql_doc_drop_collection`, `mysql_doc_find`, `mysql_doc_add`, `mysql_doc_modify`, `mysql_doc_remove`, `mysql_doc_create_index`, `mysql_doc_collection_info`) lacked full `try/catch` wrapping, causing raw Zod validation errors, identifier validation throws, and MySQL exceptions to propagate as MCP errors. All 9 tools now return `{ success: false, error }` matching the structured error pattern used by all other tool groups
162
+ - **Docstore Tool Error Field Normalization** — `mysql_doc_create_collection`, `mysql_doc_drop_collection`, and `mysql_doc_create_index` returned `{ success: false, reason }` for error conditions. Changed all to `{ success: false, error }`, reserving `reason` exclusively for informational `{ success: true, skipped: true }` responses
163
+ - **Docstore Tool `schema` Parameter Implementation** — `mysql_doc_create_collection` and `mysql_doc_drop_collection` accepted `schema` via Zod but ignored it. Both tools now use the `schema` parameter to generate qualified table references (`\`schema\`.\`name\``) and pass it to `checkCollectionExists` for schema-aware existence checks
164
+ - **Docstore Tool Identifier Validation** — All 9 tools that validate collection/index names previously threw raw `Error("Invalid collection name")` or `Error("Invalid index name")`, leaking as MCP exceptions. Converted all to structured `{ success: false, error }` returns. `mysql_doc_modify` also converted `throw new Error("No modifications specified")` to a structured return
165
+ - **`mysql_doc_create_collection` `ifNotExists` Skipped Indicator** — With `ifNotExists: true`, creating a collection that already exists returned `{ success: true, collection }` with no indication the operation was a no-op. Now pre-checks collection existence and returns `{ success: true, skipped: true, collection, reason: "Collection already exists" }`, matching the pattern used by `mysql_create_table`, `mysql_event_create`, `mysql_create_schema`, and other create tools
166
+ - **`mysql_doc_collection_info` Schema Existence Check (P154)** — When an explicit `schema` parameter was provided for a nonexistent schema, the tool returned `{ exists: false, collection }`, incorrectly implying the collection didn't exist when it was the schema that was missing. Now pre-checks schema existence via `information_schema.SCHEMATA` and returns `{ exists: false, schema }` for nonexistent schemas, matching the pattern used by `mysql_doc_list_collections`
167
+
168
+ - **Sysschema Tool Raw Error Leaks** — All 8 sysschema tools (`mysql_sys_user_summary`, `mysql_sys_host_summary`, `mysql_sys_statement_summary`, `mysql_sys_wait_summary`, `mysql_sys_io_summary`, `mysql_sys_innodb_lock_waits`, `mysql_sys_schema_stats`, `mysql_sys_memory_summary`) lacked `try/catch` around handler logic, causing raw Zod validation errors and MySQL exceptions to propagate as MCP errors. All 8 tools now return `{ success: false, error }` matching the structured error pattern used by all other tool groups
169
+ - **Sysschema Performance Tool Zod Validation Leaks** — `mysql_sys_statement_summary` (`orderBy`), `mysql_sys_wait_summary` (`type`), and `mysql_sys_io_summary` (`type`) used `z.enum()` in their schemas, causing invalid enum values to be rejected at the MCP framework level with raw `-32602` errors before the handler's `try/catch` could intercept. Widened to `z.string()` with handler-level validation guards returning `{ success: false, error: "Invalid orderBy/type: '...' — expected one of: ..." }`
170
+ - **`mysql_sys_schema_stats` P154 Error Response Shape** — Nonexistent schema response changed from non-standard `{ exists: false, schema }` to `{ success: false, error: "Schema 'X' does not exist" }`, matching the `{ success: false, error }` convention used across all other tools
171
+ - **Schema Tool Raw Error Leaks (`mysql_create_schema`, `mysql_drop_schema`)** — `mysql_create_schema` threw raw `Error("Invalid schema name")` for invalid names, leaking as an MCP exception instead of returning `{ success: false, error }`. `mysql_drop_schema` had two raw throws: `Error("Invalid schema name")` and `Error("Cannot drop system schema")`. Both catch-all code paths also rethrew raw MySQL errors. All `throw` statements replaced with structured `{ success: false, error }` returns
172
+ - **`mysql_create_schema` Unsanitized Charset/Collation** — `charset` and `collation` parameters were interpolated directly into SQL without validation, allowing injection payloads (e.g., `charset: "utf8mb4; DROP DATABASE testdb; --"`) to leak raw MySQL syntax errors. Added alphanumeric regex validation for both parameters, returning `{ success: false, error }` for invalid values
173
+ - **`mysql_create_view` Raw Error Leak** — `validateQualifiedIdentifier(name, "view")` was called outside the `try/catch` block, causing invalid view names to throw a raw `ValidationError` as an MCP exception. Wrapped in `try/catch` returning `{ success: false, error }`
174
+ - **Schema Tool Error Field Normalization (`mysql_create_view`, `mysql_create_schema`, `mysql_drop_schema`)** — `mysql_create_view` returned `{ success: false, reason }` for all 3 error paths (validation, duplicate, catch-all). `mysql_create_schema` and `mysql_drop_schema` each had 1 error path using `reason` instead of `error` (duplicate schema, nonexistent schema). Changed all 5 occurrences to `{ success: false, error }`, reserving `reason` exclusively for informational `{ success: true, skipped: true }` responses
175
+ - **Code Mode `schema.help()` Incorrect `createView` Example** — Help example used `sql` parameter (`mysql.schema.createView({ name: '...', sql: '...' })`) but `mysql_create_view` requires `definition`. Using `sql` caused a Zod validation error. Changed to `definition` in the help example
176
+ - **`mysql_list_stored_procedures` / `mysql_list_functions` Dead `type` Parameter** — Both tools exposed a `type` enum parameter (`["PROCEDURE", "FUNCTION"]`) in their shared `ListObjectsSchema`, but neither handler used it — both hardcoded `ROUTINE_TYPE = 'PROCEDURE'` and `ROUTINE_TYPE = 'FUNCTION'` respectively. Removed the misleading `type` field from the schema
177
+ - **`mysql_list_triggers` Missing P154 Table Existence Check** — When `table` parameter was provided, the handler filtered `INFORMATION_SCHEMA.TRIGGERS` without validating table existence, silently returning `{ triggers: [], count: 0 }` for nonexistent tables. Added a table existence check returning `{ exists: false, table }`, matching the pattern used by `mysql_list_constraints`
178
+
179
+ - **`mysql_index_usage` / `mysql_table_stats` Raw Error Leaks** — Both tools lacked `try/catch` around their main query execution, causing raw MySQL errors to propagate as MCP exceptions when `performance_schema` or `information_schema` queries failed. Both now return `{ success: false, error }` matching the structured error pattern used by the other 6 performance tools
180
+ - **`mysql_slow_queries` `minTime` Unit Conversion** — The `minTime` parameter (documented as seconds) used a multiplier of 10⁹ (nanoseconds) when comparing against `AVG_TIMER_WAIT`, which is measured in picoseconds (10⁻¹²). This made the filter 1000× too lenient: `minTime: 100` filtered at 100 milliseconds instead of 100 seconds. Corrected multiplier to 10¹²
181
+ - **Performance Server-Level Tools Raw Error Leaks** — `mysql_slow_queries`, `mysql_query_stats`, `mysql_buffer_pool_stats`, and `mysql_thread_stats` called `executeReadQuery()` without `try/catch`, causing raw MySQL errors to propagate as MCP exceptions when `performance_schema` was unavailable or queries failed. All 4 tools now return `{ success: false, error }` matching the structured error pattern used by `mysql_explain` and `mysql_explain_analyze`
182
+ - **`mysql_query_stats` Schema Extraction** — Moved inline Zod schema from `analysis.ts` to `QueryStatsSchema` in `types.ts` for consistency with other performance tool schemas (`SlowQuerySchema`, `IndexUsageSchema`, `TableStatsSchema`)
183
+
184
+ - **`mysql_fulltext_create` / `mysql_fulltext_drop` Error Field Normalization** — Both tools returned `{ success: false, reason }` for duplicate index and nonexistent index errors, violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` contexts. Changed to `{ success: false, error }` for consistency with all other tools
185
+ - **`mysql_fulltext_create` Column Error Misclassification (P154)** — Tool returned `{ exists: false, table }` for nonexistent columns, incorrectly indicating the table didn't exist. Now distinguishes `ER_KEY_COLUMN_DOES_NOT_EXITS` (errno 1072, "Key column 'X' doesn't exist") from generic "doesn't exist" errors, returning `{ success: false, error }` for invalid columns while preserving `{ exists: false, table }` only for genuinely missing tables
186
+ - **`mysql_fulltext_create` / `mysql_fulltext_drop` Raw Error Leaks** — Both tools had catch-all code paths that threw raw JavaScript exceptions instead of returning structured `{ success: false, error }` responses. All `throw` statements replaced with structured returns
187
+
188
+ - **Optimization Tool Split Schema Migration** — Migrated `mysql_index_recommendation` and `mysql_force_index` from inline Zod schemas to the Dual-Schema pattern in `types.ts`. Both tools now support parameter aliases (`tableName`/`name` for `table`), matching the pattern used by Performance and Core tools
189
+ - **Optimization Tool Raw Error Leaks** — `mysql_index_recommendation`, `mysql_query_rewrite`, `mysql_force_index`, and `mysql_optimizer_trace` lacked full `try/catch` wrapping, causing raw exceptions from adapter failures, Zod parse errors, or trace-fetch failures. All 4 tools now return `{ success: false, error }` matching the structured error pattern used by the performance and fulltext tools
190
+ - **`mysql_optimizer_trace` Zod Validation Leak** — `schema.parse(params)` was executed outside the `try/catch` block, causing missing `query` parameter to throw a raw Zod validation error as an MCP exception instead of returning `{ success: false, error }`. Moved parse inside `try/catch` with a `tracingEnabled` guard so `SET optimizer_trace="enabled=off"` only runs if tracing was actually enabled
191
+ - **`mysql_query_rewrite` `explainError` Adapter Prefix Leak** — The `explainError` field included verbose adapter prefixes (`Query failed: Execute failed: ...`) when EXPLAIN failed. Now strips both prefixes to return only the meaningful MySQL error message
192
+
193
+ - **Admin Tool `repair_table` Split Schema Migration** — Migrated `mysql_repair_table` from an inline Zod schema to the Dual-Schema pattern in `types.ts` (`RepairTableSchemaBase`/`RepairTableSchema`). Tool now supports parameter aliases (`table`/`tableName`/`name` for `tables`), matching the pattern used by `mysql_optimize_table`, `mysql_analyze_table`, `mysql_check_table`, and `mysql_flush_tables`
194
+ - **Admin DDL Tool Raw Error Leaks** — `mysql_optimize_table`, `mysql_analyze_table`, `mysql_check_table`, and `mysql_repair_table` lacked `try/catch` around schema parsing and query execution, causing raw Zod validation errors and MySQL exceptions to propagate as MCP errors. All 4 tools now return `{ success: false, error }` matching the structured error pattern used by the other admin tools
195
+ - **`mysql_flush_tables` Raw Error Leak** — Handler lacked a `try/catch` block entirely, causing Zod validation errors and adapter failures to propagate as raw MCP exceptions. Now wrapped in `try/catch` matching the pattern used by the other 5 admin tools, returning `{ success: false, error }` for all failures
196
+ - **`mysql_kill_query` Zod Parse Outside try/catch** — `KillQuerySchema.parse(params)` was executed before the `try/catch` block, causing Zod validation errors (e.g., missing `processId`) to throw as raw MCP exceptions instead of returning `{ success: false, error }`. Moved parse inside `try/catch`
197
+ - **Admin Tool Zod Error Formatting** — All 6 admin tools (`optimize_table`, `analyze_table`, `check_table`, `repair_table`, `flush_tables`, `kill_query`) returned raw Zod JSON array strings (e.g., `[{"code":"custom","path":[],...}]`) in the `error` field when validation failed. Now extracts human-readable `.message` from each Zod issue using `ZodError` instance detection (e.g., `"tables (or table/tableName/name alias) is required"`)
198
+ - **Monitoring Tool Raw Error Leaks** — `mysql_show_processlist`, `mysql_show_status`, `mysql_show_variables`, `mysql_innodb_status`, `mysql_pool_stats`, and `mysql_server_health` lacked `try/catch` around handler logic, causing raw Zod validation errors and MySQL exceptions to propagate as MCP errors. All 6 tools now return `{ success: false, error }` matching the structured error pattern used by the other monitoring tool (`mysql_replication_status`) and all admin tools
199
+ - **`mysql_show_status` / `mysql_show_variables` `limit: 0` Zod Validation Leak** — Both tools used `.positive()` on the `limit` schema field, causing `limit: 0` to be rejected at the MCP framework level with a raw `-32602` Zod validation error before the handler's `try/catch` could intercept. Removed `.positive()` from both `ShowStatusSchema` and `ShowVariablesSchema` and added handler-level `limit >= 1` guards that return `{ success: false, error: "limit must be a positive integer" }`
200
+ - **Backup Tool Raw Error Leaks** — All 4 backup tools (`mysql_export_table`, `mysql_import_data`, `mysql_create_dump`, `mysql_restore_dump`) had Zod `parse()` calls outside `try/catch`, causing validation errors to propagate as raw MCP `-32602` exceptions. Moved all parse calls inside `try/catch` with `ZodError` detection for human-readable messages, matching the pattern used by admin and monitoring tools
201
+ - **Backup Tool Error Message Prefix Leak** — `mysql_export_table` and `mysql_import_data` returned error messages with verbose `Query failed: Execute failed: ` adapter prefixes. Now strips both prefixes to return only the meaningful MySQL error message
202
+ - **`mysql_export_table` `limit: 0` Zod Validation Leak** — `ExportTableSchemaBase` used `.positive()` on the `limit` schema field, causing `limit: 0` to be rejected at the MCP framework level with a raw `-32602` Zod validation error before the handler's `try/catch` could intercept. Removed `.positive()` from `ExportTableSchemaBase` while retaining it in the handler-parsed `ExportTableSchema`, so the error is caught inside `try/catch` and returned as `{ success: false, error }`
203
+ - **`mysql_gtid_status` Raw Error Leak** — Handler executed three sequential `executeQuery()` calls without a `try/catch` block, causing raw MySQL errors to propagate as MCP exceptions when GTID queries failed. Now wrapped in `try/catch` returning `{ success: false, error }` matching the structured error pattern used by all other replication tools
204
+ - **`mysql_master_status` Non-Standard Error Response** — Handler returned `{ error, details }` when both `SHOW BINARY LOG STATUS` and `SHOW MASTER STATUS` failed, missing the `success: false` marker and using the non-standard `details` field. Now returns `{ success: false, error }` matching the convention used by all other tools
205
+ - **`mysql_binlog_events` `limit: 0` Unbounded Response** — MySQL's `SHOW BINLOG EVENTS ... LIMIT 0` returns ALL events (unlike `SELECT ... LIMIT 0` which returns none), producing ~1.3MB payloads. Added handler-level guard that returns `{ events: [] }` immediately when `limit` is `0`, preventing the unbounded query
206
+ - **Shell Tool Zod Validation Leaks (`mysqlsh_dump_schemas`, `mysqlsh_dump_tables`, `mysqlsh_run_script`)** — All three tools had `parse()` calls outside their `try/catch` blocks, causing Zod validation errors (e.g., `schemas: []`, `tables: []`, `script: ""`) to propagate as raw MCP `-32602` exceptions instead of structured `{ success: false, error }` responses. Moved `parse()` inside `try/catch` with `ZodError` detection and human-readable `formatZodError()` formatting. Additionally, `ShellDumpSchemasInputSchema` and `ShellDumpTablesInputSchema` used `.min(1)` on the base schema, causing empty arrays to be rejected at the MCP framework level before the handler's `try/catch` could intercept. Removed `.min(1)` from both base schemas and added handler-level empty-array guards that return `{ success: false, error: "At least one schema/table name is required" }`
207
+ - **Events Tool Zod Enum Validation Leaks (`mysql_event_create`, `mysql_event_alter`)** — Both tools used `z.enum()` for `onCompletion`, `schedule.type`, and `schedule.intervalUnit` fields, causing invalid enum values to be rejected at the MCP framework level with raw `-32602` Zod validation errors before the handler's `try/catch` could intercept. Widened all 3 enum fields to `z.string()` in both `EventCreateSchema` and `EventAlterSchema`, with handler-level validation guards returning `{ success: false, error: "Invalid ...: '...' — expected one of: ..." }`. Added `ZodError` detection and `formatZodError()` helper to all 6 event handler catch blocks
208
+
209
+ - **Spatial Tool Raw Error Leaks (6 Tools)** — `mysql_spatial_create_column`, `mysql_spatial_create_index`, `mysql_spatial_distance`, `mysql_spatial_distance_sphere`, `mysql_spatial_contains`, and `mysql_spatial_within` had identifier validation (`throw new Error("Invalid table/column/index name")`) outside their `try/catch` blocks, causing raw MCP exceptions for invalid identifiers. Moved all validation inside `try/catch` to return `{ success: false, error }`. Added `ZodError` detection, `formatZodError()`, and type-safe `paramStr()` helper to `setup.ts` and `queries.ts`
210
+ - **Spatial Tool Error Message Prefix Leak (10 Tools)** — All 10 handler-level spatial tools (`create_column`, `create_index`, `point`, `polygon`, `distance`, `distance_sphere`, `contains`, `within`, `intersection`, `buffer`, `transform`, `geojson`) returned error messages with verbose `Query failed: Execute failed:` adapter prefixes. Added `stripErrorPrefix()` to all 4 spatial source files (`setup.ts`, `queries.ts`, `geometry.ts`, `operations.ts`)
211
+ - **`mysql_spatial_geojson` Zod Validation Leak** — `GeoJSONSchema` used `.refine()` to validate that exactly one of `geometry`/`geoJson` was provided, but `parse()` was called outside the handler's `try/catch`, causing raw Zod errors. Split schema into `GeoJSONSchemaBase` (for `inputSchema`) and `GeoJSONSchema` (with `.refine()`, for parsing inside handler). Handler now catches `ZodError` and returns `{ success: false, error }`
212
+ - **`mysql_spatial_buffer` `segments: 0` Zod Validation Leak** — `BufferSchema` used `.min(1)` on the `segments` field, causing `segments: 0` to be rejected at the MCP framework level with a raw `-32602` Zod validation error. Removed `.min(1)` from base schema and added handler-level guard returning `{ success: false, error: "segments must be >= 1" }`
213
+ - **`mysql_spatial_create_index` Nullable Column Error Now Returns Instead of Throwing** — When a SPATIAL index was requested on a nullable column, the handler threw `new Error("Cannot create SPATIAL index on nullable column...")` which was caught by its own catch block but added unnecessary throw-catch overhead and inconsistent error prefix handling. Changed to direct `return { success: false, error }` with the same actionable message
214
+ - **`mysql_spatial_create_column` Zod Enum Validation Leak** — `SpatialColumnSchema` used `z.enum()` for the `type` field, causing invalid geometry types (e.g., `"INVALID_TYPE"`) to be rejected at the MCP framework level with a raw `-32602` Zod validation error before the handler's `try/catch` could intercept. Widened to `z.string().default("GEOMETRY")` with handler-level validation guard returning `{ success: false, error: "Invalid type: '...' — expected one of: ..." }`
215
+ - **Spatial Tool `schema.table` Identifier Support (6 Tools)** — `mysql_spatial_distance`, `mysql_spatial_distance_sphere`, `mysql_spatial_contains`, `mysql_spatial_within`, `mysql_spatial_create_column`, and `mysql_spatial_create_index` used a local regex `/^[a-zA-Z_][a-zA-Z0-9_]*$/` for table validation, rejecting qualified `schema.table` names. Replaced with shared `validateQualifiedIdentifier()` and `escapeQualifiedTable()` from `validators.ts`, matching the pattern used by JSON, text, and fulltext tools. For `create_index`, `information_schema` queries now split schema/table for prepared-statement params
216
+ - **Spatial Tool `SELECT *` Binary Column Payload (4 Tools)** — `mysql_spatial_distance`, `mysql_spatial_distance_sphere`, `mysql_spatial_contains`, and `mysql_spatial_within` used `SELECT *`, returning the raw binary spatial column object in the payload alongside usable `latitude`/`longitude` columns. Added `ST_AsText()` for the spatial column (producing a `_wkt` field) and filtered out the raw binary column from each result row
217
+
218
+ - **`mysql_json_get` Nonexistent Row Detection** — Tool returned `{ value: null }` for both nonexistent rows and existing rows with null JSON paths, making them indistinguishable. Now returns `{ value: null, rowFound: false }` when the target row ID does not exist, while existing rows with null paths continue to return `{ value: null }` without the `rowFound` field
219
+ - **`mysql_json_keys` Missing `count` Field** — Tool response lacked a `count` field, unlike other read tools (`json_search`, `json_contains`) which include it. Added `count` to the response for consistency
220
+
221
+ - **`mysql_optimizer_trace` Error Prefix Leak** — Error messages from the inner query execution catch block included verbose adapter prefixes (`Query failed: Execute failed: ...`). Now strips both prefixes to return only the meaningful MySQL error message, matching the pattern used by `mysql_query_rewrite`'s `explainError`
222
+ - **`mysql_json_update` Error Field Normalization** — Tool returned `{ success: false, reason: "No row found..." }` when no matching row existed, violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` contexts. Changed to `{ success: false, error: "No row found..." }` for consistency with all other tools
223
+ - **`mysql_json_keys` Null Row Filtering** — Tool returned `{ json_keys: null }` rows for records where the queried JSON path didn't exist, inflating response payloads with useless entries. Added `HAVING json_keys IS NOT NULL` to filter these out
224
+ - **`mysql_json_search` Payload Reduction (P137)** — Tool still included the full JSON document column in `SELECT` results despite the changelog claiming P137 minimal payload was applied. Removed the column from the SELECT to return only `id` and `match_path`, matching the actual documented behavior
225
+ - **`mysql_json_stats` Numeric Type Consistency** — Aggregate values (`avg`, `nullCount`, etc.) were returned as strings due to MySQL's DECIMAL type handling by the driver. Wrapped all aggregate results with `Number()` to ensure consumers always receive numeric types
226
+ - **`mysql_create_index` Column Error Misclassification (P154)** — Tool previously returned `{ exists: false, table }` for nonexistent columns, incorrectly indicating the table didn't exist. Now distinguishes `ER_BAD_FIELD_ERROR` ("Key column 'X' doesn't exist") from `ER_NO_SUCH_TABLE` ("Table 'X' doesn't exist"), returning `{ success: false, error: "Column 'X' does not exist in table 'Y'" }` for invalid columns while preserving `{ exists: false, table }` only for genuinely missing tables
227
+ - **`mysql_create_index` / `mysql_create_table` / `mysql_drop_table` Raw Error Leaks** — All three tools had code paths that threw raw JavaScript exceptions instead of returning structured `{ success: false, error }` responses (validation errors for invalid names, catch-all errors for unexpected failures). All `throw` statements replaced with structured returns
228
+ - **`mysql_list_tables` Nonexistent Database (P154)** — Tool returned an empty `{ tables: [], count: 0 }` for nonexistent `database` parameter values, indistinguishable from a valid empty database. Now pre-checks database existence via `information_schema.SCHEMATA` and returns `{ exists: false, database, message }` when the database does not exist
229
+ - **`mysql_create_table` `ifNotExists` Skipped Indicator** — With `ifNotExists: true`, creating a table that already exists returned `{ success: true, tableName }` with no indication the operation was a no-op. Now pre-checks table existence and returns `{ success: true, skipped: true, tableName, reason: "Table already exists" }`, matching the pattern used by `mysql_drop_table`, `mysql_event_create`, `mysql_create_schema`, and other create tools
230
+ - **Error Field Normalization (`reason` → `error`)** — Standardized all `{ success: false }` error responses to use `error` as the field name instead of `reason`. Applied across `core.ts` (8 instances), `transactions.ts` (13 instances), and `spatial/setup.ts` (4 instances). The `reason` field is now reserved exclusively for informational `{ success: true, skipped: true, reason: "..." }` responses. Updated ServerInstructions and test-tools-prompt to reflect the new convention
231
+
232
+ - **Events Tool Raw Error Leaks (`mysql_event_create`, `mysql_event_alter`, `mysql_event_drop`)** — All three write handlers had validation throws (`"Invalid event name"`, `"executeAt is required..."`, `"No modifications specified"`) and catch-all re-throws that leaked as raw MCP exceptions. Wrapped all handler bodies in top-level `try/catch` returning `{ success: false, error }`, matching the pattern used by schema, core, and admin tools
233
+ - **Events Tool Error Field Normalization (`reason` → `error`)** — All three event write tools returned `{ success: false, reason }` for known error cases (duplicate event, nonexistent event). Changed to `{ success: false, error }`, reserving `reason` exclusively for informational `{ success: true, skipped: true }` responses. Updated ServerInstructions to match
234
+ - **Events Test Alignment** — Updated 13 tests in `events.test.ts` to match the new structured-return behavior: replaced `.rejects.toThrow()` assertions with `expect(result).toEqual({ success: false, error })`, and updated `reason` field references to `error` in graceful-error-handling tests
235
+ - **Events Read Handler Raw Error Leaks (`mysql_event_list`, `mysql_event_status`, `mysql_scheduler_status`)** — All three read handlers lacked `try/catch` around handler logic, causing raw Zod validation errors and MySQL exceptions to propagate as MCP errors. All 3 tools now return `{ success: false, error }` matching the structured error pattern used by the events write tools and all other tool groups
236
+ - **Stats Tool Zod Validation Leaks (`mysql_stats_time_series`, `mysql_stats_sampling`)** — Both tools had `Schema.parse(params)` and identifier validation outside the `try/catch` block, causing Zod validation errors (e.g., invalid `interval` or `aggregation` enum values for `time_series`) to propagate as raw MCP `-32602` exceptions instead of structured `{ success: false, error }` responses. Moved `parse()` and validation inside `try/catch` with `ZodError` detection and `formatZodError()` formatting for all 5 tools in `descriptive.ts` (`descriptive`, `percentiles`, `distribution`, `time_series`, `sampling`) for consistency
237
+ - **Stats Tool Zod Validation Leaks (`mysql_stats_correlation`, `mysql_stats_regression`, `mysql_stats_histogram`)** — All three handlers in `comparative.ts` called `Schema.parse(params)` outside their `try/catch` blocks, causing Zod validation errors (e.g., missing required fields) to propagate as raw MCP `-32602` exceptions instead of structured `{ success: false, error }` responses. Moved `parse()` inside `try/catch` with `ZodError` detection and `formatZodError()` formatting, matching the pattern used by all tools in `descriptive.ts`
238
+ - **`mysql_stats_distribution` `buckets: 0` Division-by-Zero** — Calling with `buckets: 0` caused a division-by-zero in bucket size calculation, producing `Infinity` in the SQL query and a misleading `Unknown column 'Infinity'` error. Added handler-level guard returning `{ success: false, error: "buckets must be at least 1" }`
239
+ - **Events Write Handler Error Prefix Leak (`mysql_event_create`, `mysql_event_alter`)** — Both tools returned error messages with verbose `Query failed: Execute failed: ` adapter prefixes in their catch-all error paths. Now strips both prefixes to return only the meaningful MySQL error message
240
+ - **Stats Tool Raw Error Leaks (All 8 Tools)** — All 8 stats tools (`mysql_stats_descriptive`, `mysql_stats_percentiles`, `mysql_stats_correlation`, `mysql_stats_distribution`, `mysql_stats_time_series`, `mysql_stats_regression`, `mysql_stats_sampling`, `mysql_stats_histogram`) performed identifier validation (`throw new Error("Invalid table/column name")`) outside of `try/catch` blocks, causing raw MCP exceptions instead of structured `{ success: false, error }` responses. Moved all validation inside `try/catch` and changed throws to structured returns
241
+ - **Stats Tool Error Message Prefix Leak (7 Tools)** — `mysql_stats_descriptive`, `mysql_stats_percentiles`, `mysql_stats_correlation`, `mysql_stats_distribution`, `mysql_stats_time_series`, `mysql_stats_regression`, and `mysql_stats_sampling` returned error messages with verbose `Query failed: Execute failed: ` adapter prefixes. Now strips both prefixes to return only the meaningful MySQL error message
242
+ - **`mysql_stats_regression` Non-Standard Error Response** — Insufficient data response returned `{ error: "...", sampleSize: 0 }` without `success: false`, deviating from the `{ success: false, error }` convention used across all other tools. Now includes `success: false`
243
+ - **`mysql_stats_histogram` Missing `try/catch`** — Handler had no outer `try/catch` block, causing raw MCP exceptions if `information_schema` queries or `ANALYZE TABLE` operations failed. Wrapped entire handler body in `try/catch` returning `{ success: false, error }` matching the pattern used by all other stats tools
244
+ - **Security Tool Raw Error Leaks (All 9 Tools)** — All 9 security tools (`mysql_security_ssl_status`, `mysql_security_encryption_status`, `mysql_security_password_validate`, `mysql_security_audit`, `mysql_security_firewall_status`, `mysql_security_firewall_rules`, `mysql_security_mask_data`, `mysql_security_user_privileges`, `mysql_security_sensitive_tables`) had incomplete `try/catch` coverage — `ssl_status` and `encryption_status` lacked handlers entirely, while the remaining 7 had Zod `parse()` calls outside their `try/catch` blocks. All 9 handlers now wrap entire bodies in `try/catch` with `ZodError` detection via `formatZodError()` and adapter prefix stripping via `stripErrorPrefix()`, returning `{ success: false, error }` for all failure paths
245
+ - **Security Tool Zod Validation Leaks (`mysql_security_mask_data`, `mysql_security_firewall_rules`)** — `mysql_security_mask_data` used `z.enum()` for the `type` parameter and `mysql_security_firewall_rules` used `z.enum()` for the `mode` parameter, causing invalid values to be rejected at the MCP framework level with raw `-32602` Zod validation errors before the handler's `try/catch` could intercept. Widened both to `z.string()` with handler-level validation guards returning `{ success: false, error: "Invalid type/mode: '...' — expected one of: ..." }`
246
+ - **`mysql_security_audit` SQL Interpolation for LIMIT** — Both audit log query paths (performance_schema fallback on line 110 and mysql.audit_log on line 147) used string interpolation for the `LIMIT` value (`` `LIMIT ${String(limit)}` ``). While Zod validates `limit` as `z.number()`, this violates the parameterized query pattern used by all other tools. Changed to `?` placeholders with `queryParams.push(limit)`
247
+ - **`mysql_security_user_privileges` SHOW GRANTS Identifier Quoting** — `SHOW GRANTS FOR '${userName}'@'${userHost}'` used single-quote string interpolation, which is technically a SQL injection surface (values come from trusted `mysql.user` rows, but usernames containing single quotes would break the query). Changed to backtick-quoted identifiers (`\`${userName}\`@\`${userHost}\``) matching MySQL's own `SHOW GRANTS` output format
248
+ - **Roles Tool Raw Error Leaks (All 8 Tools)** — All 8 roles tools (`mysql_role_list`, `mysql_role_create`, `mysql_role_drop`, `mysql_role_grants`, `mysql_role_grant`, `mysql_role_assign`, `mysql_role_revoke`, `mysql_user_roles`) lacked outer `try/catch` around handler logic, causing raw Zod validation errors, `validateIdentifier` throws, regex name validation throws, and unmatched catch-all re-throws to propagate as MCP exceptions. All 8 tools now return `{ success: false, error }` matching the structured error pattern used by all other tool groups
249
+ - **Roles Tool Error Field Normalization (`reason` → `error`)** — `mysql_role_create`, `mysql_role_drop`, and `mysql_role_revoke` returned `{ success: false, reason }` for error conditions (duplicate role, nonexistent role, role not assigned), violating the convention where `reason` is reserved for informational `{ success: true, skipped: true }` responses. Changed all 3 occurrences to `{ success: false, error }` for consistency with all other tools. Updated ServerInstructions to match
250
+ - **Roles Tool `validateIdentifier` Entity Label** — `mysql_role_grants`, `mysql_role_assign`, and `mysql_role_revoke` used `validateIdentifier(role, "column")`, producing misleading `"Invalid column name: ..."` error messages when role identifier validation failed. Changed entity label to `"role"` for accurate `"Invalid role name: ..."` messages
251
+
252
+ ### Infrastructure
253
+
254
+ - **`.gitattributes` Line Ending Normalization** — Added `.gitattributes` to enforce LF line endings in the repository (`* text=auto eol=lf`), with explicit CRLF exceptions for Windows-only scripts (`.ps1`, `.cmd`, `.bat`). Prevents cross-platform line ending corruption from contributors with differing `core.autocrlf` settings
255
+ - **Vitest JSON Reporter** — Added JSON reporter to `vitest.config.ts` outputting `test-results.json` for reliable agent consumption of test results. Added `test-results.json` to both `.gitignore` and `.dockerignore`
256
+
257
+ ### Documentation
258
+
259
+ - **README.md / DOCKER_README.md "Deterministic Error Handling"** — Added "deterministic error handling" to the introduction blurbs and a new "Deterministic Error Handling" row to the "What Sets Us Apart" feature table in both READMEs, highlighting structured `{success, error}` responses across all tools
260
+
261
+ ### Security
262
+
263
+ - **CVE Fix: `hono` Timing Comparison Hardening (GHSA-gq3j-xvxp-8hrf)** — Updated transitive dependency `hono` to ≥4.11.10 via `npm audit fix` to add timing comparison hardening in `basicAuth` and `bearerAuth` middleware, preventing timing-based credential leakage
264
+ - **CVE Fix: `rollup` Arbitrary File Write via Path Traversal (GHSA-mw96-cpmx-2vgc)** — Updated transitive dependency `rollup` (via `vitest` → `vite`) from <4.58.1 to 4.59.0 via `npm audit fix` to fix a high-severity arbitrary file write vulnerability through path traversal in generated bundle output
265
+
266
+ ### Changed
267
+
268
+ - **`mysql2` 3.18.0 Type Compatibility** — Adjusted `MySQLAdapter.executeOnConnection()` and `ConnectionPool.execute()` to satisfy mysql2 3.18.0's stricter `QueryValues` type constraint on `execute()` and `query()` parameter signatures
269
+
270
+ ### Performance
271
+
272
+ - **Cache Invalidation After DDL Operations** — Added `clearSchemaCache()` call to 14 DDL tool handlers across 7 files (`core.ts`, `docstore.ts`, `schema/views.ts`, `spatial/setup.ts`, `text/fulltext.ts`, `partitioning.ts`) to prevent stale metadata from being served during the cache TTL window after CREATE/DROP/ALTER operations. Previously, DDL operations would succeed but `describeTable`/`listTables`/`getSchema` could return outdated metadata for up to 30 seconds
273
+ - **`SchemaManager.describeTable()` Parallelized** — The two independent `information_schema` queries (COLUMNS + TABLES) in `describeTable()` are now executed concurrently via `Promise.all()` instead of sequentially, reducing latency on cache misses
274
+ - **Resource Handler Parallelization** — Parallelized independent queries in 8 resource handlers using `Promise.all()`: `innodb.ts` (3 queries), `sysschema.ts` (3 queries), `spatial.ts` (2 queries), `locks.ts` (2 queries), `events.ts` (2 queries), `docstore.ts` (2 queries), `indexes.ts` (3 queries), `performance.ts` (2 queries). Previously all queries were executed sequentially
275
+ - **Test Suite Parallelism** — Increased `vitest.config.ts` `maxWorkers` from 1 to 4, reducing total test suite duration from ~66s to ~37s (44% faster). Import time (previously 39% of total) now benefits from parallel module loading
276
+
277
+ ### Dependencies
278
+
279
+ - `@modelcontextprotocol/sdk`: 1.26.0 → 1.27.1
280
+ - `@types/node`: 25.2.3 → 25.3.1
281
+ - `eslint`: 10.0.0 → 10.0.2
282
+ - `mysql2`: 3.17.2 → 3.18.1
283
+ - `typescript-eslint`: 8.56.0 → 8.56.1
284
+
285
+ ## [2.3.1] - 2026-02-18
286
+
287
+ ### Security
288
+
289
+ - **CVE Fix: `tar` Path Traversal (CVE-2026-26960)** — Patched npm's bundled `tar` (< 7.5.8) in the Dockerfile runtime stage to fix a high-severity path traversal vulnerability that allowed arbitrary file read/write via crafted hardlinks.
290
+
291
+ ### Changed
292
+
293
+ - **Docker Scout Security Gate Hardened** — Docker Scout scan in `docker-publish.yml` now **blocks deployments** on any fixable CVE (any severity) using `--only-fixed --exit-code`. Unfixable zero-day CVEs are allowed through. Previously the scan was informational only and never failed the workflow.
294
+ - **CodeQL Workflow PR Trigger** — Removed `paths` filter from `pull_request` trigger in `codeql.yml` so the `analyze (javascript-typescript)` required check always runs on PRs. The existing `check-files` step handles skipping analysis for non-code PRs.
9
295
 
10
296
  ## [2.3.0] - 2026-02-18
11
297