@neverinfamous/mysql-mcp 2.3.1 → 3.0.1

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 (345) hide show
  1. package/.dockerignore +1 -0
  2. package/.gitattributes +18 -0
  3. package/.github/workflows/codeql.yml +2 -2
  4. package/.github/workflows/docker-publish.yml +5 -5
  5. package/CHANGELOG.md +348 -122
  6. package/DOCKER_README.md +81 -40
  7. package/README.md +87 -46
  8. package/VERSION +1 -1
  9. package/dist/__tests__/mocks/adapter.d.ts.map +1 -1
  10. package/dist/__tests__/mocks/adapter.js +2 -0
  11. package/dist/__tests__/mocks/adapter.js.map +1 -1
  12. package/dist/adapters/DatabaseAdapter.d.ts.map +1 -1
  13. package/dist/adapters/DatabaseAdapter.js +50 -9
  14. package/dist/adapters/DatabaseAdapter.js.map +1 -1
  15. package/dist/adapters/mysql/MySQLAdapter.d.ts +6 -0
  16. package/dist/adapters/mysql/MySQLAdapter.d.ts.map +1 -1
  17. package/dist/adapters/mysql/MySQLAdapter.js +8 -0
  18. package/dist/adapters/mysql/MySQLAdapter.js.map +1 -1
  19. package/dist/adapters/mysql/SchemaManager.js +16 -15
  20. package/dist/adapters/mysql/SchemaManager.js.map +1 -1
  21. package/dist/adapters/mysql/prompts/index.js +10 -20
  22. package/dist/adapters/mysql/prompts/index.js.map +1 -1
  23. package/dist/adapters/mysql/prompts/proxysqlSetup.js +1 -1
  24. package/dist/adapters/mysql/resources/docstore.d.ts.map +1 -1
  25. package/dist/adapters/mysql/resources/docstore.js +10 -7
  26. package/dist/adapters/mysql/resources/docstore.js.map +1 -1
  27. package/dist/adapters/mysql/resources/events.js +11 -8
  28. package/dist/adapters/mysql/resources/events.js.map +1 -1
  29. package/dist/adapters/mysql/resources/indexes.d.ts.map +1 -1
  30. package/dist/adapters/mysql/resources/indexes.js +12 -15
  31. package/dist/adapters/mysql/resources/indexes.js.map +1 -1
  32. package/dist/adapters/mysql/resources/innodb.d.ts.map +1 -1
  33. package/dist/adapters/mysql/resources/innodb.js +20 -17
  34. package/dist/adapters/mysql/resources/innodb.js.map +1 -1
  35. package/dist/adapters/mysql/resources/locks.d.ts.map +1 -1
  36. package/dist/adapters/mysql/resources/locks.js +9 -6
  37. package/dist/adapters/mysql/resources/locks.js.map +1 -1
  38. package/dist/adapters/mysql/resources/performance.d.ts.map +1 -1
  39. package/dist/adapters/mysql/resources/performance.js +15 -15
  40. package/dist/adapters/mysql/resources/performance.js.map +1 -1
  41. package/dist/adapters/mysql/resources/spatial.d.ts.map +1 -1
  42. package/dist/adapters/mysql/resources/spatial.js +9 -6
  43. package/dist/adapters/mysql/resources/spatial.js.map +1 -1
  44. package/dist/adapters/mysql/resources/sysschema.d.ts.map +1 -1
  45. package/dist/adapters/mysql/resources/sysschema.js +12 -9
  46. package/dist/adapters/mysql/resources/sysschema.js.map +1 -1
  47. package/dist/adapters/mysql/tools/admin/backup.d.ts.map +1 -1
  48. package/dist/adapters/mysql/tools/admin/backup.js +170 -121
  49. package/dist/adapters/mysql/tools/admin/backup.js.map +1 -1
  50. package/dist/adapters/mysql/tools/admin/maintenance.d.ts.map +1 -1
  51. package/dist/adapters/mysql/tools/admin/maintenance.js +106 -57
  52. package/dist/adapters/mysql/tools/admin/maintenance.js.map +1 -1
  53. package/dist/adapters/mysql/tools/admin/monitoring.d.ts.map +1 -1
  54. package/dist/adapters/mysql/tools/admin/monitoring.js +183 -101
  55. package/dist/adapters/mysql/tools/admin/monitoring.js.map +1 -1
  56. package/dist/adapters/mysql/tools/cluster/group-replication.d.ts.map +1 -1
  57. package/dist/adapters/mysql/tools/cluster/group-replication.js +164 -120
  58. package/dist/adapters/mysql/tools/cluster/group-replication.js.map +1 -1
  59. package/dist/adapters/mysql/tools/cluster/innodb-cluster.d.ts.map +1 -1
  60. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js +212 -145
  61. package/dist/adapters/mysql/tools/cluster/innodb-cluster.js.map +1 -1
  62. package/dist/adapters/mysql/tools/codemode/index.d.ts.map +1 -1
  63. package/dist/adapters/mysql/tools/codemode/index.js +6 -4
  64. package/dist/adapters/mysql/tools/codemode/index.js.map +1 -1
  65. package/dist/adapters/mysql/tools/core.d.ts.map +1 -1
  66. package/dist/adapters/mysql/tools/core.js +152 -29
  67. package/dist/adapters/mysql/tools/core.js.map +1 -1
  68. package/dist/adapters/mysql/tools/docstore.d.ts.map +1 -1
  69. package/dist/adapters/mysql/tools/docstore.js +340 -163
  70. package/dist/adapters/mysql/tools/docstore.js.map +1 -1
  71. package/dist/adapters/mysql/tools/events.d.ts.map +1 -1
  72. package/dist/adapters/mysql/tools/events.js +284 -198
  73. package/dist/adapters/mysql/tools/events.js.map +1 -1
  74. package/dist/adapters/mysql/tools/json/core.d.ts.map +1 -1
  75. package/dist/adapters/mysql/tools/json/core.js +11 -39
  76. package/dist/adapters/mysql/tools/json/core.js.map +1 -1
  77. package/dist/adapters/mysql/tools/json/enhanced.d.ts.map +1 -1
  78. package/dist/adapters/mysql/tools/json/enhanced.js +15 -33
  79. package/dist/adapters/mysql/tools/json/enhanced.js.map +1 -1
  80. package/dist/adapters/mysql/tools/json/helpers.d.ts.map +1 -1
  81. package/dist/adapters/mysql/tools/json/helpers.js +13 -24
  82. package/dist/adapters/mysql/tools/json/helpers.js.map +1 -1
  83. package/dist/adapters/mysql/tools/partitioning.js +3 -0
  84. package/dist/adapters/mysql/tools/partitioning.js.map +1 -1
  85. package/dist/adapters/mysql/tools/performance/analysis.d.ts.map +1 -1
  86. package/dist/adapters/mysql/tools/performance/analysis.js +89 -60
  87. package/dist/adapters/mysql/tools/performance/analysis.js.map +1 -1
  88. package/dist/adapters/mysql/tools/performance/optimization.d.ts.map +1 -1
  89. package/dist/adapters/mysql/tools/performance/optimization.js +151 -127
  90. package/dist/adapters/mysql/tools/performance/optimization.js.map +1 -1
  91. package/dist/adapters/mysql/tools/proxysql.d.ts +1 -1
  92. package/dist/adapters/mysql/tools/proxysql.d.ts.map +1 -1
  93. package/dist/adapters/mysql/tools/proxysql.js +289 -176
  94. package/dist/adapters/mysql/tools/proxysql.js.map +1 -1
  95. package/dist/adapters/mysql/tools/replication.js +75 -49
  96. package/dist/adapters/mysql/tools/replication.js.map +1 -1
  97. package/dist/adapters/mysql/tools/roles.d.ts.map +1 -1
  98. package/dist/adapters/mysql/tools/roles.js +224 -182
  99. package/dist/adapters/mysql/tools/roles.js.map +1 -1
  100. package/dist/adapters/mysql/tools/router.d.ts.map +1 -1
  101. package/dist/adapters/mysql/tools/router.js +168 -67
  102. package/dist/adapters/mysql/tools/router.js.map +1 -1
  103. package/dist/adapters/mysql/tools/schema/constraints.d.ts.map +1 -1
  104. package/dist/adapters/mysql/tools/schema/constraints.js +21 -3
  105. package/dist/adapters/mysql/tools/schema/constraints.js.map +1 -1
  106. package/dist/adapters/mysql/tools/schema/management.d.ts.map +1 -1
  107. package/dist/adapters/mysql/tools/schema/management.js +61 -14
  108. package/dist/adapters/mysql/tools/schema/management.js.map +1 -1
  109. package/dist/adapters/mysql/tools/schema/routines.d.ts.map +1 -1
  110. package/dist/adapters/mysql/tools/schema/routines.js +27 -4
  111. package/dist/adapters/mysql/tools/schema/routines.js.map +1 -1
  112. package/dist/adapters/mysql/tools/schema/scheduled_events.d.ts.map +1 -1
  113. package/dist/adapters/mysql/tools/schema/scheduled_events.js +24 -3
  114. package/dist/adapters/mysql/tools/schema/scheduled_events.js.map +1 -1
  115. package/dist/adapters/mysql/tools/schema/triggers.d.ts.map +1 -1
  116. package/dist/adapters/mysql/tools/schema/triggers.js +23 -2
  117. package/dist/adapters/mysql/tools/schema/triggers.js.map +1 -1
  118. package/dist/adapters/mysql/tools/schema/views.d.ts.map +1 -1
  119. package/dist/adapters/mysql/tools/schema/views.js +47 -7
  120. package/dist/adapters/mysql/tools/schema/views.js.map +1 -1
  121. package/dist/adapters/mysql/tools/security/audit.d.ts.map +1 -1
  122. package/dist/adapters/mysql/tools/security/audit.js +102 -34
  123. package/dist/adapters/mysql/tools/security/audit.js.map +1 -1
  124. package/dist/adapters/mysql/tools/security/data-protection.d.ts.map +1 -1
  125. package/dist/adapters/mysql/tools/security/data-protection.js +264 -205
  126. package/dist/adapters/mysql/tools/security/data-protection.js.map +1 -1
  127. package/dist/adapters/mysql/tools/security/encryption.d.ts.map +1 -1
  128. package/dist/adapters/mysql/tools/security/encryption.js +137 -104
  129. package/dist/adapters/mysql/tools/security/encryption.js.map +1 -1
  130. package/dist/adapters/mysql/tools/shell/backup.d.ts.map +1 -1
  131. package/dist/adapters/mysql/tools/shell/backup.js +71 -59
  132. package/dist/adapters/mysql/tools/shell/backup.js.map +1 -1
  133. package/dist/adapters/mysql/tools/shell/restore.d.ts.map +1 -1
  134. package/dist/adapters/mysql/tools/shell/restore.js +61 -47
  135. package/dist/adapters/mysql/tools/shell/restore.js.map +1 -1
  136. package/dist/adapters/mysql/tools/spatial/geometry.d.ts.map +1 -1
  137. package/dist/adapters/mysql/tools/spatial/geometry.js +19 -5
  138. package/dist/adapters/mysql/tools/spatial/geometry.js.map +1 -1
  139. package/dist/adapters/mysql/tools/spatial/operations.d.ts.map +1 -1
  140. package/dist/adapters/mysql/tools/spatial/operations.js +42 -17
  141. package/dist/adapters/mysql/tools/spatial/operations.js.map +1 -1
  142. package/dist/adapters/mysql/tools/spatial/queries.d.ts.map +1 -1
  143. package/dist/adapters/mysql/tools/spatial/queries.js +109 -57
  144. package/dist/adapters/mysql/tools/spatial/queries.js.map +1 -1
  145. package/dist/adapters/mysql/tools/spatial/setup.d.ts.map +1 -1
  146. package/dist/adapters/mysql/tools/spatial/setup.js +103 -50
  147. package/dist/adapters/mysql/tools/spatial/setup.js.map +1 -1
  148. package/dist/adapters/mysql/tools/stats/comparative.d.ts.map +1 -1
  149. package/dist/adapters/mysql/tools/stats/comparative.js +128 -79
  150. package/dist/adapters/mysql/tools/stats/comparative.js.map +1 -1
  151. package/dist/adapters/mysql/tools/stats/descriptive.d.ts.map +1 -1
  152. package/dist/adapters/mysql/tools/stats/descriptive.js +174 -102
  153. package/dist/adapters/mysql/tools/stats/descriptive.js.map +1 -1
  154. package/dist/adapters/mysql/tools/sysschema/activity.d.ts.map +1 -1
  155. package/dist/adapters/mysql/tools/sysschema/activity.js +50 -25
  156. package/dist/adapters/mysql/tools/sysschema/activity.js.map +1 -1
  157. package/dist/adapters/mysql/tools/sysschema/performance.d.ts.map +1 -1
  158. package/dist/adapters/mysql/tools/sysschema/performance.js +121 -66
  159. package/dist/adapters/mysql/tools/sysschema/performance.js.map +1 -1
  160. package/dist/adapters/mysql/tools/sysschema/resources.d.ts.map +1 -1
  161. package/dist/adapters/mysql/tools/sysschema/resources.js +101 -64
  162. package/dist/adapters/mysql/tools/sysschema/resources.js.map +1 -1
  163. package/dist/adapters/mysql/tools/text/fulltext.d.ts.map +1 -1
  164. package/dist/adapters/mysql/tools/text/fulltext.js +18 -32
  165. package/dist/adapters/mysql/tools/text/fulltext.js.map +1 -1
  166. package/dist/adapters/mysql/tools/transactions.d.ts.map +1 -1
  167. package/dist/adapters/mysql/tools/transactions.js +48 -23
  168. package/dist/adapters/mysql/tools/transactions.js.map +1 -1
  169. package/dist/adapters/mysql/types/proxysql-types.d.ts +15 -0
  170. package/dist/adapters/mysql/types/proxysql-types.d.ts.map +1 -1
  171. package/dist/adapters/mysql/types/proxysql-types.js +33 -1
  172. package/dist/adapters/mysql/types/proxysql-types.js.map +1 -1
  173. package/dist/adapters/mysql/types/router-types.d.ts +1 -1
  174. package/dist/adapters/mysql/types/router-types.js +1 -1
  175. package/dist/adapters/mysql/types/router-types.js.map +1 -1
  176. package/dist/adapters/mysql/types/shell-types.js +2 -2
  177. package/dist/adapters/mysql/types/shell-types.js.map +1 -1
  178. package/dist/adapters/mysql/types.d.ts +485 -21
  179. package/dist/adapters/mysql/types.d.ts.map +1 -1
  180. package/dist/adapters/mysql/types.js +546 -19
  181. package/dist/adapters/mysql/types.js.map +1 -1
  182. package/dist/auth/scopes.js +1 -1
  183. package/dist/auth/scopes.js.map +1 -1
  184. package/dist/codemode/api.d.ts +3 -2
  185. package/dist/codemode/api.d.ts.map +1 -1
  186. package/dist/codemode/api.js +80 -5
  187. package/dist/codemode/api.js.map +1 -1
  188. package/dist/codemode/sandbox-factory.js +1 -1
  189. package/dist/codemode/sandbox-factory.js.map +1 -1
  190. package/dist/codemode/types.d.ts +26 -0
  191. package/dist/codemode/types.d.ts.map +1 -1
  192. package/dist/codemode/types.js +2 -0
  193. package/dist/codemode/types.js.map +1 -1
  194. package/dist/codemode/worker-sandbox.d.ts +4 -2
  195. package/dist/codemode/worker-sandbox.d.ts.map +1 -1
  196. package/dist/codemode/worker-sandbox.js +66 -7
  197. package/dist/codemode/worker-sandbox.js.map +1 -1
  198. package/dist/codemode/worker-script.d.ts +3 -0
  199. package/dist/codemode/worker-script.d.ts.map +1 -1
  200. package/dist/codemode/worker-script.js +128 -75
  201. package/dist/codemode/worker-script.js.map +1 -1
  202. package/dist/constants/ServerInstructions.d.ts +1 -1
  203. package/dist/constants/ServerInstructions.d.ts.map +1 -1
  204. package/dist/constants/ServerInstructions.js +37 -31
  205. package/dist/constants/ServerInstructions.js.map +1 -1
  206. package/dist/filtering/ToolConstants.d.ts +1 -1
  207. package/dist/filtering/ToolConstants.d.ts.map +1 -1
  208. package/dist/filtering/ToolConstants.js +1 -2
  209. package/dist/filtering/ToolConstants.js.map +1 -1
  210. package/dist/pool/ConnectionPool.d.ts.map +1 -1
  211. package/dist/pool/ConnectionPool.js.map +1 -1
  212. package/dist/transports/http.d.ts.map +1 -1
  213. package/dist/transports/http.js +6 -0
  214. package/dist/transports/http.js.map +1 -1
  215. package/dist/utils/validators.d.ts +1 -1
  216. package/dist/utils/validators.d.ts.map +1 -1
  217. package/dist/utils/validators.js.map +1 -1
  218. package/package.json +4 -4
  219. package/releases/v3.0.0-release-notes.md +81 -0
  220. package/releases/v3.0.1-release-notes.md +20 -0
  221. package/src/__tests__/mocks/adapter.ts +3 -0
  222. package/src/__tests__/perf.test.ts +6 -6
  223. package/src/adapters/DatabaseAdapter.ts +58 -9
  224. package/src/adapters/__tests__/DatabaseAdapter.test.ts +89 -8
  225. package/src/adapters/mysql/MySQLAdapter.ts +17 -2
  226. package/src/adapters/mysql/SchemaManager.ts +21 -21
  227. package/src/adapters/mysql/__tests__/MySQLAdapter.test.ts +1 -1
  228. package/src/adapters/mysql/prompts/index.ts +12 -22
  229. package/src/adapters/mysql/prompts/proxysqlSetup.ts +1 -1
  230. package/src/adapters/mysql/resources/docstore.ts +13 -10
  231. package/src/adapters/mysql/resources/events.ts +12 -12
  232. package/src/adapters/mysql/resources/indexes.ts +17 -19
  233. package/src/adapters/mysql/resources/innodb.ts +23 -22
  234. package/src/adapters/mysql/resources/locks.ts +9 -7
  235. package/src/adapters/mysql/resources/performance.ts +23 -18
  236. package/src/adapters/mysql/resources/spatial.ts +9 -7
  237. package/src/adapters/mysql/resources/sysschema.ts +12 -11
  238. package/src/adapters/mysql/tools/__tests__/core.test.ts +126 -55
  239. package/src/adapters/mysql/tools/__tests__/docstore.test.ts +459 -88
  240. package/src/adapters/mysql/tools/__tests__/events.test.ts +281 -103
  241. package/src/adapters/mysql/tools/__tests__/proxysql.test.ts +128 -28
  242. package/src/adapters/mysql/tools/__tests__/replication.test.ts +48 -2
  243. package/src/adapters/mysql/tools/__tests__/roles.test.ts +15 -18
  244. package/src/adapters/mysql/tools/__tests__/router.test.ts +32 -5
  245. package/src/adapters/mysql/tools/__tests__/security.test.ts +126 -2
  246. package/src/adapters/mysql/tools/__tests__/security_injection.test.ts +84 -76
  247. package/src/adapters/mysql/tools/__tests__/security_integration.test.ts +47 -51
  248. package/src/adapters/mysql/tools/__tests__/spatial.test.ts +11 -10
  249. package/src/adapters/mysql/tools/__tests__/spatial_handler.test.ts +54 -38
  250. package/src/adapters/mysql/tools/__tests__/stats.test.ts +285 -152
  251. package/src/adapters/mysql/tools/__tests__/transactions.test.ts +13 -13
  252. package/src/adapters/mysql/tools/admin/__tests__/backup.test.ts +171 -25
  253. package/src/adapters/mysql/tools/admin/__tests__/maintenance.test.ts +240 -4
  254. package/src/adapters/mysql/tools/admin/__tests__/monitoring-summary.test.ts +274 -0
  255. package/src/adapters/mysql/tools/admin/__tests__/monitoring.test.ts +94 -5
  256. package/src/adapters/mysql/tools/admin/backup.ts +193 -143
  257. package/src/adapters/mysql/tools/admin/maintenance.ts +118 -69
  258. package/src/adapters/mysql/tools/admin/monitoring.ts +201 -125
  259. package/src/adapters/mysql/tools/cluster/__tests__/group-replication.test.ts +69 -0
  260. package/src/adapters/mysql/tools/cluster/__tests__/innodb-cluster.test.ts +141 -0
  261. package/src/adapters/mysql/tools/cluster/group-replication.ts +172 -132
  262. package/src/adapters/mysql/tools/cluster/innodb-cluster.ts +231 -157
  263. package/src/adapters/mysql/tools/codemode/__tests__/codemode-tool.test.ts +227 -0
  264. package/src/adapters/mysql/tools/codemode/index.ts +5 -3
  265. package/src/adapters/mysql/tools/core.ts +152 -38
  266. package/src/adapters/mysql/tools/docstore.ts +422 -205
  267. package/src/adapters/mysql/tools/events.ts +334 -233
  268. package/src/adapters/mysql/tools/json/__tests__/core.test.ts +20 -0
  269. package/src/adapters/mysql/tools/json/__tests__/enhanced.test.ts +82 -50
  270. package/src/adapters/mysql/tools/json/__tests__/helpers.test.ts +42 -3
  271. package/src/adapters/mysql/tools/json/core.ts +21 -42
  272. package/src/adapters/mysql/tools/json/enhanced.ts +22 -37
  273. package/src/adapters/mysql/tools/json/helpers.ts +21 -25
  274. package/src/adapters/mysql/tools/partitioning.ts +3 -0
  275. package/src/adapters/mysql/tools/performance/__tests__/analysis.test.ts +98 -5
  276. package/src/adapters/mysql/tools/performance/__tests__/optimization-coverage.test.ts +515 -0
  277. package/src/adapters/mysql/tools/performance/__tests__/optimization.test.ts +187 -0
  278. package/src/adapters/mysql/tools/performance/analysis.ts +95 -69
  279. package/src/adapters/mysql/tools/performance/optimization.ts +182 -153
  280. package/src/adapters/mysql/tools/proxysql.ts +314 -209
  281. package/src/adapters/mysql/tools/replication.ts +84 -57
  282. package/src/adapters/mysql/tools/roles.ts +274 -226
  283. package/src/adapters/mysql/tools/router.ts +181 -85
  284. package/src/adapters/mysql/tools/schema/__tests__/constraints.test.ts +13 -0
  285. package/src/adapters/mysql/tools/schema/__tests__/management.test.ts +60 -25
  286. package/src/adapters/mysql/tools/schema/__tests__/scheduled_events.test.ts +11 -0
  287. package/src/adapters/mysql/tools/schema/__tests__/triggers.test.ts +25 -4
  288. package/src/adapters/mysql/tools/schema/__tests__/views.test.ts +46 -14
  289. package/src/adapters/mysql/tools/schema/constraints.ts +22 -3
  290. package/src/adapters/mysql/tools/schema/management.ts +60 -15
  291. package/src/adapters/mysql/tools/schema/routines.ts +26 -4
  292. package/src/adapters/mysql/tools/schema/scheduled_events.ts +25 -3
  293. package/src/adapters/mysql/tools/schema/triggers.ts +27 -2
  294. package/src/adapters/mysql/tools/schema/views.ts +46 -8
  295. package/src/adapters/mysql/tools/security/__tests__/audit.test.ts +90 -4
  296. package/src/adapters/mysql/tools/security/audit.ts +113 -39
  297. package/src/adapters/mysql/tools/security/data-protection.ts +293 -233
  298. package/src/adapters/mysql/tools/security/encryption.ts +172 -139
  299. package/src/adapters/mysql/tools/shell/__tests__/backup.test.ts +29 -0
  300. package/src/adapters/mysql/tools/shell/backup.ts +90 -73
  301. package/src/adapters/mysql/tools/shell/restore.ts +62 -48
  302. package/src/adapters/mysql/tools/spatial/__tests__/operations.test.ts +22 -14
  303. package/src/adapters/mysql/tools/spatial/__tests__/queries.test.ts +65 -51
  304. package/src/adapters/mysql/tools/spatial/geometry.ts +23 -7
  305. package/src/adapters/mysql/tools/spatial/operations.ts +60 -31
  306. package/src/adapters/mysql/tools/spatial/queries.ts +142 -65
  307. package/src/adapters/mysql/tools/spatial/setup.ts +121 -55
  308. package/src/adapters/mysql/tools/stats/__tests__/comparative.test.ts +12 -10
  309. package/src/adapters/mysql/tools/stats/comparative.ts +150 -98
  310. package/src/adapters/mysql/tools/stats/descriptive.ts +204 -127
  311. package/src/adapters/mysql/tools/sysschema/__tests__/error-paths.test.ts +222 -0
  312. package/src/adapters/mysql/tools/sysschema/__tests__/performance.test.ts +45 -0
  313. package/src/adapters/mysql/tools/sysschema/__tests__/resources.test.ts +6 -3
  314. package/src/adapters/mysql/tools/sysschema/activity.ts +52 -27
  315. package/src/adapters/mysql/tools/sysschema/performance.ts +132 -68
  316. package/src/adapters/mysql/tools/sysschema/resources.ts +105 -67
  317. package/src/adapters/mysql/tools/text/__tests__/fulltext.test.ts +45 -17
  318. package/src/adapters/mysql/tools/text/fulltext.ts +27 -38
  319. package/src/adapters/mysql/tools/transactions.ts +49 -24
  320. package/src/adapters/mysql/types/proxysql-types.ts +38 -1
  321. package/src/adapters/mysql/types/router-types.ts +1 -1
  322. package/src/adapters/mysql/types/shell-types.ts +2 -2
  323. package/src/adapters/mysql/types.ts +632 -19
  324. package/src/auth/__tests__/scopes.test.ts +2 -2
  325. package/src/auth/scopes.ts +1 -1
  326. package/src/codemode/__tests__/api.test.ts +417 -0
  327. package/src/codemode/__tests__/sandbox-factory.test.ts +158 -0
  328. package/src/codemode/__tests__/sandbox.test.ts +301 -0
  329. package/src/codemode/__tests__/security.test.ts +368 -0
  330. package/src/codemode/__tests__/worker-sandbox.test.ts +179 -0
  331. package/src/codemode/__tests__/worker-script.test.ts +226 -0
  332. package/src/codemode/api.ts +89 -5
  333. package/src/codemode/sandbox-factory.ts +1 -1
  334. package/src/codemode/types.ts +34 -0
  335. package/src/codemode/worker-sandbox.ts +74 -7
  336. package/src/codemode/worker-script.ts +157 -86
  337. package/src/constants/ServerInstructions.ts +37 -31
  338. package/src/filtering/ToolConstants.ts +1 -2
  339. package/src/filtering/__tests__/ToolFilter.test.ts +9 -9
  340. package/src/pool/ConnectionPool.ts +4 -1
  341. package/src/transports/__tests__/http.test.ts +15 -3
  342. package/src/transports/http.ts +12 -0
  343. package/src/utils/validators.ts +2 -1
  344. package/vitest.config.ts +3 -1
  345. package/CODE_MODE.md +0 -245
@@ -6,13 +6,22 @@
6
6
  * 5 tools total.
7
7
  */
8
8
 
9
- import { z } from "zod";
9
+ import { z, ZodError } from "zod";
10
10
  import type { MySQLAdapter } from "../../MySQLAdapter.js";
11
11
  import type {
12
12
  ToolDefinition,
13
13
  RequestContext,
14
14
  } from "../../../../types/index.js";
15
15
 
16
+ // =============================================================================
17
+ // Helpers
18
+ // =============================================================================
19
+
20
+ /** Extract human-readable messages from a ZodError instead of raw JSON array */
21
+ function formatZodError(error: ZodError): string {
22
+ return error.issues.map((i) => i.message).join("; ");
23
+ }
24
+
16
25
  // =============================================================================
17
26
  // Schemas
18
27
  // =============================================================================
@@ -44,14 +53,8 @@ const TimeSeriesSchema = z.object({
44
53
  table: z.string().describe("Table name"),
45
54
  valueColumn: z.string().describe("Numeric column for values"),
46
55
  timeColumn: z.string().describe("Timestamp/datetime column"),
47
- interval: z
48
- .enum(["minute", "hour", "day", "week", "month"])
49
- .default("day")
50
- .describe("Aggregation interval"),
51
- aggregation: z
52
- .enum(["avg", "sum", "count", "min", "max"])
53
- .default("avg")
54
- .describe("Aggregation function"),
56
+ interval: z.string().default("day").describe("Aggregation interval"),
57
+ aggregation: z.string().default("avg").describe("Aggregation function"),
55
58
  where: z.string().optional().describe("Optional WHERE clause condition"),
56
59
  limit: z.number().default(100).describe("Maximum number of data points"),
57
60
  });
@@ -90,19 +93,18 @@ export function createDescriptiveStatsTool(
90
93
  idempotentHint: true,
91
94
  },
92
95
  handler: async (params: unknown, _context: RequestContext) => {
93
- const { table, column, where } = DescriptiveStatsSchema.parse(params);
94
-
95
- // Validate identifiers
96
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
97
- throw new Error("Invalid table name");
98
- }
99
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(column)) {
100
- throw new Error("Invalid column name");
101
- }
96
+ try {
97
+ const { table, column, where } = DescriptiveStatsSchema.parse(params);
98
+ // Validate identifiers
99
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
100
+ return { success: false, error: "Invalid table name" };
101
+ }
102
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(column)) {
103
+ return { success: false, error: "Invalid column name" };
104
+ }
102
105
 
103
- const whereClause = where ? `WHERE ${where}` : "";
106
+ const whereClause = where ? `WHERE ${where}` : "";
104
107
 
105
- try {
106
108
  // Get basic count for median calculation
107
109
  const countResult = await adapter.executeQuery(
108
110
  `SELECT COUNT(*) as count FROM \`${table}\` ${whereClause}`,
@@ -175,9 +177,19 @@ export function createDescriptiveStatsTool(
175
177
  sum: stats?.["sum"] ?? null,
176
178
  };
177
179
  } catch (error) {
178
- const msg = error instanceof Error ? error.message : String(error);
180
+ if (error instanceof ZodError) {
181
+ return { success: false, error: formatZodError(error) };
182
+ }
183
+ const msg = (error instanceof Error ? error.message : String(error))
184
+ .replace(/^Query failed: /, "")
185
+ .replace(/^Execute failed: /, "");
179
186
  if (msg.includes("doesn't exist")) {
180
- return { exists: false, table };
187
+ return {
188
+ exists: false,
189
+ table:
190
+ ((params as Record<string, unknown>)?.["table"] as string) ??
191
+ "unknown",
192
+ };
181
193
  }
182
194
  return { success: false, error: msg };
183
195
  }
@@ -201,20 +213,19 @@ export function createPercentilesTool(adapter: MySQLAdapter): ToolDefinition {
201
213
  idempotentHint: true,
202
214
  },
203
215
  handler: async (params: unknown, _context: RequestContext) => {
204
- const { table, column, percentiles, where } =
205
- PercentilesSchema.parse(params);
206
-
207
- // Validate identifiers
208
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
209
- throw new Error("Invalid table name");
210
- }
211
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(column)) {
212
- throw new Error("Invalid column name");
213
- }
216
+ try {
217
+ const { table, column, percentiles, where } =
218
+ PercentilesSchema.parse(params);
219
+ // Validate identifiers
220
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
221
+ return { success: false, error: "Invalid table name" };
222
+ }
223
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(column)) {
224
+ return { success: false, error: "Invalid column name" };
225
+ }
214
226
 
215
- const whereClause = where ? `WHERE ${where}` : "";
227
+ const whereClause = where ? `WHERE ${where}` : "";
216
228
 
217
- try {
218
229
  // Get total count
219
230
  const countResult = await adapter.executeQuery(
220
231
  `SELECT COUNT(*) as cnt FROM \`${table}\` ${whereClause}`,
@@ -253,9 +264,19 @@ export function createPercentilesTool(adapter: MySQLAdapter): ToolDefinition {
253
264
  percentiles: percentileResults,
254
265
  };
255
266
  } catch (error) {
256
- const msg = error instanceof Error ? error.message : String(error);
267
+ if (error instanceof ZodError) {
268
+ return { success: false, error: formatZodError(error) };
269
+ }
270
+ const msg = (error instanceof Error ? error.message : String(error))
271
+ .replace(/^Query failed: /, "")
272
+ .replace(/^Execute failed: /, "");
257
273
  if (msg.includes("doesn't exist")) {
258
- return { exists: false, table };
274
+ return {
275
+ exists: false,
276
+ table:
277
+ ((params as Record<string, unknown>)?.["table"] as string) ??
278
+ "unknown",
279
+ };
259
280
  }
260
281
  return { success: false, error: msg };
261
282
  }
@@ -280,20 +301,22 @@ export function createDistributionTool(adapter: MySQLAdapter): ToolDefinition {
280
301
  idempotentHint: true,
281
302
  },
282
303
  handler: async (params: unknown, _context: RequestContext) => {
283
- const { table, column, buckets, where } =
284
- DistributionSchema.parse(params);
285
-
286
- // Validate identifiers
287
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
288
- throw new Error("Invalid table name");
289
- }
290
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(column)) {
291
- throw new Error("Invalid column name");
292
- }
304
+ try {
305
+ const { table, column, buckets, where } =
306
+ DistributionSchema.parse(params);
307
+ // Validate identifiers
308
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
309
+ return { success: false, error: "Invalid table name" };
310
+ }
311
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(column)) {
312
+ return { success: false, error: "Invalid column name" };
313
+ }
314
+ if (buckets < 1) {
315
+ return { success: false, error: "buckets must be at least 1" };
316
+ }
293
317
 
294
- const whereClause = where ? `WHERE ${where}` : "";
318
+ const whereClause = where ? `WHERE ${where}` : "";
295
319
 
296
- try {
297
320
  // Get min/max for bucket calculation
298
321
  const rangeResult = await adapter.executeQuery(
299
322
  `SELECT MIN(\`${column}\`) as min_val, MAX(\`${column}\`) as max_val FROM \`${table}\` ${whereClause}`,
@@ -356,9 +379,19 @@ export function createDistributionTool(adapter: MySQLAdapter): ToolDefinition {
356
379
  maxValue: maxVal,
357
380
  };
358
381
  } catch (error) {
359
- const msg = error instanceof Error ? error.message : String(error);
382
+ if (error instanceof ZodError) {
383
+ return { success: false, error: formatZodError(error) };
384
+ }
385
+ const msg = (error instanceof Error ? error.message : String(error))
386
+ .replace(/^Query failed: /, "")
387
+ .replace(/^Execute failed: /, "");
360
388
  if (msg.includes("doesn't exist")) {
361
- return { exists: false, table };
389
+ return {
390
+ exists: false,
391
+ table:
392
+ ((params as Record<string, unknown>)?.["table"] as string) ??
393
+ "unknown",
394
+ };
362
395
  }
363
396
  return { success: false, error: msg };
364
397
  }
@@ -385,50 +418,68 @@ export function createTimeSeriesToolStats(
385
418
  idempotentHint: true,
386
419
  },
387
420
  handler: async (params: unknown, _context: RequestContext) => {
388
- const {
389
- table,
390
- valueColumn,
391
- timeColumn,
392
- interval,
393
- aggregation,
394
- where,
395
- limit,
396
- } = TimeSeriesSchema.parse(params);
397
-
398
- // Validate identifiers
399
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
400
- throw new Error("Invalid table name");
401
- }
402
- if (
403
- !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(valueColumn) ||
404
- !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(timeColumn)
405
- ) {
406
- throw new Error("Invalid column name");
407
- }
421
+ try {
422
+ const {
423
+ table,
424
+ valueColumn,
425
+ timeColumn,
426
+ interval,
427
+ aggregation,
428
+ where,
429
+ limit,
430
+ } = TimeSeriesSchema.parse(params);
408
431
 
409
- let dateFormat: string;
410
- switch (interval) {
411
- case "minute":
412
- dateFormat = "%Y-%m-%d %H:%i:00";
413
- break;
414
- case "hour":
415
- dateFormat = "%Y-%m-%d %H:00:00";
416
- break;
417
- case "day":
418
- dateFormat = "%Y-%m-%d";
419
- break;
420
- case "week":
421
- dateFormat = "%x-W%v";
422
- break;
423
- case "month":
424
- dateFormat = "%Y-%m";
425
- break;
426
- }
432
+ // Validate identifiers
433
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
434
+ return { success: false, error: "Invalid table name" };
435
+ }
436
+ if (
437
+ !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(valueColumn) ||
438
+ !/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(timeColumn)
439
+ ) {
440
+ return { success: false, error: "Invalid column name" };
441
+ }
427
442
 
428
- const whereClause = where ? `WHERE ${where}` : "";
429
- const aggFunc = aggregation.toUpperCase();
443
+ const validIntervals = ["minute", "hour", "day", "week", "month"];
444
+ if (!validIntervals.includes(interval)) {
445
+ return {
446
+ success: false,
447
+ error: `Invalid interval: '${interval}' — expected one of: ${validIntervals.join(", ")}`,
448
+ };
449
+ }
450
+ const validAggregations = ["avg", "sum", "count", "min", "max"];
451
+ if (!validAggregations.includes(aggregation)) {
452
+ return {
453
+ success: false,
454
+ error: `Invalid aggregation: '${aggregation}' — expected one of: ${validAggregations.join(", ")}`,
455
+ };
456
+ }
430
457
 
431
- const query = `
458
+ let dateFormat: string;
459
+ switch (interval) {
460
+ case "minute":
461
+ dateFormat = "%Y-%m-%d %H:%i:00";
462
+ break;
463
+ case "hour":
464
+ dateFormat = "%Y-%m-%d %H:00:00";
465
+ break;
466
+ case "day":
467
+ dateFormat = "%Y-%m-%d";
468
+ break;
469
+ case "week":
470
+ dateFormat = "%x-W%v";
471
+ break;
472
+ case "month":
473
+ dateFormat = "%Y-%m";
474
+ break;
475
+ default:
476
+ dateFormat = "%Y-%m-%d";
477
+ }
478
+
479
+ const whereClause = where ? `WHERE ${where}` : "";
480
+ const aggFunc = aggregation.toUpperCase();
481
+
482
+ const query = `
432
483
  SELECT
433
484
  DATE_FORMAT(\`${timeColumn}\`, '${dateFormat}') as period,
434
485
  ${aggFunc}(\`${valueColumn}\`) as value,
@@ -441,8 +492,6 @@ export function createTimeSeriesToolStats(
441
492
  ORDER BY period DESC
442
493
  LIMIT ${String(limit)}
443
494
  `;
444
-
445
- try {
446
495
  const result = await adapter.executeQuery(query);
447
496
 
448
497
  return {
@@ -454,9 +503,19 @@ export function createTimeSeriesToolStats(
454
503
  count: result.rows?.length ?? 0,
455
504
  };
456
505
  } catch (error) {
457
- const msg = error instanceof Error ? error.message : String(error);
506
+ if (error instanceof ZodError) {
507
+ return { success: false, error: formatZodError(error) };
508
+ }
509
+ const msg = (error instanceof Error ? error.message : String(error))
510
+ .replace(/^Query failed: /, "")
511
+ .replace(/^Execute failed: /, "");
458
512
  if (msg.includes("doesn't exist")) {
459
- return { exists: false, table };
513
+ return {
514
+ exists: false,
515
+ table:
516
+ ((params as Record<string, unknown>)?.["table"] as string) ??
517
+ "unknown",
518
+ };
460
519
  }
461
520
  return { success: false, error: msg };
462
521
  }
@@ -480,50 +539,58 @@ export function createSamplingTool(adapter: MySQLAdapter): ToolDefinition {
480
539
  idempotentHint: false, // Random results
481
540
  },
482
541
  handler: async (params: unknown, _context: RequestContext) => {
483
- const { table, sampleSize, columns, seed, where } =
484
- SamplingSchema.parse(params);
542
+ try {
543
+ const { table, sampleSize, columns, seed, where } =
544
+ SamplingSchema.parse(params);
485
545
 
486
- // Validate table name
487
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
488
- throw new Error("Invalid table name");
489
- }
546
+ if (sampleSize < 0) {
547
+ return { success: false, error: "sampleSize must be >= 0" };
548
+ }
549
+
550
+ // Validate table name
551
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(table)) {
552
+ return { success: false, error: "Invalid table name" };
553
+ }
490
554
 
491
- // Validate column names if provided
492
- const columnList =
493
- columns !== undefined && columns.length > 0
494
- ? columns
495
- .map((c) => {
496
- if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(c)) {
497
- throw new Error(`Invalid column name: ${c}`);
498
- }
499
- return `\`${c}\``;
500
- })
501
- .join(", ")
502
- : "*";
503
-
504
- const whereClause = where ? `WHERE ${where}` : "";
505
-
506
- // If seed is provided, use it for reproducibility
507
- let query: string;
508
- if (seed !== undefined) {
509
- query = `
555
+ // Validate column names if provided
556
+ if (columns) {
557
+ for (const c of columns) {
558
+ if (!/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(c)) {
559
+ return { success: false, error: `Invalid column name: ${c}` };
560
+ }
561
+ }
562
+ }
563
+
564
+ const columnList =
565
+ columns !== undefined && columns.length > 0
566
+ ? columns
567
+ .map((c) => {
568
+ return `\`${c}\``;
569
+ })
570
+ .join(", ")
571
+ : "*";
572
+
573
+ const whereClause = where ? `WHERE ${where}` : "";
574
+
575
+ // If seed is provided, use it for reproducibility
576
+ let query: string;
577
+ if (seed !== undefined) {
578
+ query = `
510
579
  SELECT ${columnList}
511
580
  FROM \`${table}\`
512
581
  ${whereClause}
513
582
  ORDER BY RAND(${String(seed)})
514
583
  LIMIT ${String(sampleSize)}
515
584
  `;
516
- } else {
517
- query = `
585
+ } else {
586
+ query = `
518
587
  SELECT ${columnList}
519
588
  FROM \`${table}\`
520
589
  ${whereClause}
521
590
  ORDER BY RAND()
522
591
  LIMIT ${String(sampleSize)}
523
592
  `;
524
- }
525
-
526
- try {
593
+ }
527
594
  const result = await adapter.executeQuery(query);
528
595
 
529
596
  return {
@@ -533,9 +600,19 @@ export function createSamplingTool(adapter: MySQLAdapter): ToolDefinition {
533
600
  seed: seed ?? null,
534
601
  };
535
602
  } catch (error) {
536
- const msg = error instanceof Error ? error.message : String(error);
603
+ if (error instanceof ZodError) {
604
+ return { success: false, error: formatZodError(error) };
605
+ }
606
+ const msg = (error instanceof Error ? error.message : String(error))
607
+ .replace(/^Query failed: /, "")
608
+ .replace(/^Execute failed: /, "");
537
609
  if (msg.includes("doesn't exist")) {
538
- return { exists: false, table };
610
+ return {
611
+ exists: false,
612
+ table:
613
+ ((params as Record<string, unknown>)?.["table"] as string) ??
614
+ "unknown",
615
+ };
539
616
  }
540
617
  return { success: false, error: msg };
541
618
  }
@@ -0,0 +1,222 @@
1
+ /**
2
+ * mysql-mcp - Sys Schema Error Path Tests
3
+ *
4
+ * Tests for error handling (ZodError, database errors) across all sysschema tools.
5
+ * These tests specifically target the catch blocks that are missed by happy-path tests.
6
+ */
7
+
8
+ import { describe, it, expect, vi, beforeEach } from "vitest";
9
+ import {
10
+ createSysUserSummaryTool,
11
+ createSysHostSummaryTool,
12
+ } from "../activity.js";
13
+ import {
14
+ createSysStatementSummaryTool,
15
+ createSysWaitSummaryTool,
16
+ createSysIOSummaryTool,
17
+ } from "../performance.js";
18
+ import {
19
+ createSysSchemaStatsTool,
20
+ createSysInnoDBLockWaitsTool,
21
+ createSysMemorySummaryTool,
22
+ } from "../resources.js";
23
+ import type { MySQLAdapter } from "../../../MySQLAdapter.js";
24
+ import {
25
+ createMockMySQLAdapter,
26
+ createMockRequestContext,
27
+ } from "../../../../../__tests__/mocks/index.js";
28
+
29
+ describe("Sys Schema Error Paths", () => {
30
+ let mockAdapter: ReturnType<typeof createMockMySQLAdapter>;
31
+ let mockContext: ReturnType<typeof createMockRequestContext>;
32
+
33
+ beforeEach(() => {
34
+ vi.clearAllMocks();
35
+ mockAdapter = createMockMySQLAdapter();
36
+ mockContext = createMockRequestContext();
37
+ });
38
+
39
+ // ===========================================================================
40
+ // Activity tools error paths
41
+ // ===========================================================================
42
+ describe("activity error paths", () => {
43
+ it("should handle database error in user summary", async () => {
44
+ mockAdapter.executeQuery.mockRejectedValue(
45
+ new Error("DB connection lost"),
46
+ );
47
+ const tool = createSysUserSummaryTool(
48
+ mockAdapter as unknown as MySQLAdapter,
49
+ );
50
+ const result = (await tool.handler({}, mockContext)) as {
51
+ success: boolean;
52
+ error: string;
53
+ };
54
+ expect(result.success).toBe(false);
55
+ expect(result.error).toContain("DB connection lost");
56
+ });
57
+
58
+ it("should handle non-Error thrown in user summary", async () => {
59
+ mockAdapter.executeQuery.mockRejectedValue("string error");
60
+ const tool = createSysUserSummaryTool(
61
+ mockAdapter as unknown as MySQLAdapter,
62
+ );
63
+ const result = (await tool.handler({}, mockContext)) as {
64
+ success: boolean;
65
+ error: string;
66
+ };
67
+ expect(result.success).toBe(false);
68
+ expect(result.error).toBe("string error");
69
+ });
70
+
71
+ it("should handle database error in host summary", async () => {
72
+ mockAdapter.executeQuery.mockRejectedValue(new Error("DB timeout"));
73
+ const tool = createSysHostSummaryTool(
74
+ mockAdapter as unknown as MySQLAdapter,
75
+ );
76
+ const result = (await tool.handler({}, mockContext)) as {
77
+ success: boolean;
78
+ error: string;
79
+ };
80
+ expect(result.success).toBe(false);
81
+ expect(result.error).toContain("DB timeout");
82
+ });
83
+
84
+ it("should handle non-Error thrown in host summary", async () => {
85
+ mockAdapter.executeQuery.mockRejectedValue(42);
86
+ const tool = createSysHostSummaryTool(
87
+ mockAdapter as unknown as MySQLAdapter,
88
+ );
89
+ const result = (await tool.handler({}, mockContext)) as {
90
+ success: boolean;
91
+ error: string;
92
+ };
93
+ expect(result.success).toBe(false);
94
+ expect(result.error).toBe("42");
95
+ });
96
+ });
97
+
98
+ // ===========================================================================
99
+ // Performance tools error paths
100
+ // ===========================================================================
101
+ describe("performance error paths", () => {
102
+ it("should handle database error in statement summary", async () => {
103
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Query failed"));
104
+ const tool = createSysStatementSummaryTool(
105
+ mockAdapter as unknown as MySQLAdapter,
106
+ );
107
+ const result = (await tool.handler({}, mockContext)) as {
108
+ success: boolean;
109
+ error: string;
110
+ };
111
+ expect(result.success).toBe(false);
112
+ expect(result.error).toContain("Query failed");
113
+ });
114
+
115
+ it("should handle database error in wait summary", async () => {
116
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Wait query error"));
117
+ const tool = createSysWaitSummaryTool(
118
+ mockAdapter as unknown as MySQLAdapter,
119
+ );
120
+ const result = (await tool.handler({}, mockContext)) as {
121
+ success: boolean;
122
+ error: string;
123
+ };
124
+ expect(result.success).toBe(false);
125
+ expect(result.error).toContain("Wait query error");
126
+ });
127
+
128
+ it("should handle database error in IO summary", async () => {
129
+ mockAdapter.executeQuery.mockRejectedValue(new Error("IO query error"));
130
+ const tool = createSysIOSummaryTool(
131
+ mockAdapter as unknown as MySQLAdapter,
132
+ );
133
+ const result = (await tool.handler({}, mockContext)) as {
134
+ success: boolean;
135
+ error: string;
136
+ };
137
+ expect(result.success).toBe(false);
138
+ expect(result.error).toContain("IO query error");
139
+ });
140
+
141
+ it("should handle non-Error thrown in statement summary", async () => {
142
+ mockAdapter.executeQuery.mockRejectedValue("raw string");
143
+ const tool = createSysStatementSummaryTool(
144
+ mockAdapter as unknown as MySQLAdapter,
145
+ );
146
+ const result = (await tool.handler({}, mockContext)) as {
147
+ success: boolean;
148
+ error: string;
149
+ };
150
+ expect(result.success).toBe(false);
151
+ expect(result.error).toBe("raw string");
152
+ });
153
+ });
154
+
155
+ // ===========================================================================
156
+ // Resources tools error paths
157
+ // ===========================================================================
158
+ describe("resources error paths", () => {
159
+ it("should handle database error in schema stats", async () => {
160
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Schema error"));
161
+ const tool = createSysSchemaStatsTool(
162
+ mockAdapter as unknown as MySQLAdapter,
163
+ );
164
+ const result = (await tool.handler({}, mockContext)) as {
165
+ success: boolean;
166
+ error: string;
167
+ };
168
+ expect(result.success).toBe(false);
169
+ expect(result.error).toContain("Schema error");
170
+ });
171
+
172
+ it("should handle database error in innodb lock waits", async () => {
173
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Lock error"));
174
+ const tool = createSysInnoDBLockWaitsTool(
175
+ mockAdapter as unknown as MySQLAdapter,
176
+ );
177
+ const result = (await tool.handler({}, mockContext)) as {
178
+ success: boolean;
179
+ error: string;
180
+ };
181
+ expect(result.success).toBe(false);
182
+ expect(result.error).toContain("Lock error");
183
+ });
184
+
185
+ it("should handle database error in memory summary", async () => {
186
+ mockAdapter.executeQuery.mockRejectedValue(new Error("Memory error"));
187
+ const tool = createSysMemorySummaryTool(
188
+ mockAdapter as unknown as MySQLAdapter,
189
+ );
190
+ const result = (await tool.handler({}, mockContext)) as {
191
+ success: boolean;
192
+ error: string;
193
+ };
194
+ expect(result.success).toBe(false);
195
+ expect(result.error).toContain("Memory error");
196
+ });
197
+
198
+ it("should handle non-Error thrown in lock waits", async () => {
199
+ mockAdapter.executeQuery.mockRejectedValue({ code: "UNKNOWN" });
200
+ const tool = createSysInnoDBLockWaitsTool(
201
+ mockAdapter as unknown as MySQLAdapter,
202
+ );
203
+ const result = (await tool.handler({}, mockContext)) as {
204
+ success: boolean;
205
+ error: string;
206
+ };
207
+ expect(result.success).toBe(false);
208
+ });
209
+
210
+ it("should handle non-Error thrown in memory summary", async () => {
211
+ mockAdapter.executeQuery.mockRejectedValue(undefined);
212
+ const tool = createSysMemorySummaryTool(
213
+ mockAdapter as unknown as MySQLAdapter,
214
+ );
215
+ const result = (await tool.handler({}, mockContext)) as {
216
+ success: boolean;
217
+ error: string;
218
+ };
219
+ expect(result.success).toBe(false);
220
+ });
221
+ });
222
+ });