@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
@@ -65,9 +65,9 @@ describe("Performance Tests", () => {
65
65
  expect(cachedCallTime.avg).toBeLessThan(0.5);
66
66
  });
67
67
 
68
- it("should return consistent count of 193 tools", () => {
68
+ it("should return consistent count of 192 tools", () => {
69
69
  const tools = getAllToolNames();
70
- expect(tools).toHaveLength(193);
70
+ expect(tools).toHaveLength(192);
71
71
  });
72
72
  });
73
73
 
@@ -165,7 +165,7 @@ describe("Performance Tests", () => {
165
165
  describe("filterTools performance", () => {
166
166
  const mockHandler = async () => ({ result: "ok" });
167
167
 
168
- it("should filter 193 tools efficiently", () => {
168
+ it("should filter 192 tools efficiently", () => {
169
169
  // Create mock tools matching all tool names
170
170
  const allToolNames = getAllToolNames();
171
171
  const mockTools: ToolDefinition[] = allToolNames.map((name) => ({
@@ -198,7 +198,7 @@ describe("Performance Tests", () => {
198
198
 
199
199
  // First call builds the cache
200
200
  const firstCall = adapter.getToolDefinitions();
201
- expect(firstCall).toHaveLength(193);
201
+ expect(firstCall).toHaveLength(192);
202
202
 
203
203
  // Subsequent calls should return same reference (cached)
204
204
  const secondCall = adapter.getToolDefinitions();
@@ -213,7 +213,7 @@ describe("Performance Tests", () => {
213
213
  expect(timing.avg).toBeLessThan(0.5);
214
214
  });
215
215
 
216
- it("should return consistent tool count of 193 regardless of filter default", () => {
216
+ it("should return consistent tool count of 192 regardless of filter default", () => {
217
217
  const adapter = new MySQLAdapter();
218
218
 
219
219
  // getToolDefinitions returns ALL definitions available in the adapter,
@@ -221,7 +221,7 @@ describe("Performance Tests", () => {
221
221
  // Wait, MySQLAdapter.getToolDefinitions() returns all tools?
222
222
  // Yes, checking the implementation... it usually does.
223
223
  const tools = adapter.getToolDefinitions();
224
- expect(tools).toHaveLength(193);
224
+ expect(tools).toHaveLength(192);
225
225
  });
226
226
  });
227
227
  });
@@ -322,26 +322,57 @@ export abstract class DatabaseAdapter {
322
322
  * Register a single prompt with the MCP server
323
323
  */
324
324
  protected registerPrompt(server: McpServer, prompt: PromptDefinition): void {
325
- // Build Zod schema from prompt.arguments definitions
326
- const zodShape: Record<string, z.ZodType> = {};
327
- if (prompt.arguments) {
325
+ // Build a Zod raw shape from prompt.arguments so the SDK can
326
+ // advertise argument metadata in prompts/list via promptArgumentsFromSchema().
327
+ //
328
+ // ALL fields are .optional() because the SDK validates BEFORE our handler
329
+ // runs. If required fields used z.string() (non-optional), clients that
330
+ // invoke prompts without filling in required args would get a raw Zod
331
+ // error instead of our graceful guide message. Required-ness is enforced
332
+ // by the handler-level missing-arg check below.
333
+ let argsSchema: Record<string, z.ZodType> | undefined;
334
+ if (prompt.arguments && prompt.arguments.length > 0) {
335
+ argsSchema = {};
328
336
  for (const arg of prompt.arguments) {
329
- zodShape[arg.name] = arg.required
330
- ? z.string().describe(arg.description)
331
- : z.string().optional().describe(arg.description);
337
+ argsSchema[arg.name] = z.string().optional().describe(arg.description);
332
338
  }
333
339
  }
334
340
 
335
- server.registerPrompt(
341
+ const registered = server.registerPrompt(
336
342
  prompt.name,
337
343
  {
338
344
  description: prompt.description,
339
- argsSchema: zodShape,
345
+ argsSchema,
340
346
  },
341
347
  async (providedArgs) => {
342
348
  const context = this.createContext();
343
349
  // Cast args to Record<string, string> for handler compatibility
344
- const args = providedArgs as Record<string, string>;
350
+ const args = (providedArgs ?? {}) as Record<string, string>;
351
+
352
+ // Check for missing required arguments
353
+ const requiredArgs = prompt.arguments?.filter((a) => a.required) ?? [];
354
+ const missingArgs = requiredArgs.filter((a) => !args[a.name]);
355
+ if (missingArgs.length > 0) {
356
+ // Return a helpful guide listing expected arguments
357
+ const argList = (prompt.arguments ?? [])
358
+ .map(
359
+ (a) =>
360
+ `- **${a.name}**${a.required ? " (required)" : " (optional)"}: ${a.description}`,
361
+ )
362
+ .join("\n");
363
+ return {
364
+ messages: [
365
+ {
366
+ role: "user" as const,
367
+ content: {
368
+ type: "text" as const,
369
+ text: `# ${prompt.name}\n\n${prompt.description}\n\n## Arguments\n\n${argList}\n\nPlease provide the required arguments to use this prompt.`,
370
+ },
371
+ },
372
+ ],
373
+ };
374
+ }
375
+
345
376
  const result = await prompt.handler(args, context);
346
377
  return {
347
378
  messages: [
@@ -359,6 +390,24 @@ export abstract class DatabaseAdapter {
359
390
  };
360
391
  },
361
392
  );
393
+
394
+ // Patch the SDK's stored Zod object schema to accept `undefined` input.
395
+ // The SDK's prompts/get handler calls safeParseAsync(argsSchema, args)
396
+ // where args may be `undefined` when clients omit them. Zod v4's
397
+ // z.object().safeParse(undefined) rejects — but we need it to succeed
398
+ // (coercing to {}) so our handler-level required-arg check can provide
399
+ // a graceful guide message instead of a raw Zod crash.
400
+ // The metadata (shape, type) is preserved for promptArgumentsFromSchema().
401
+ if (registered.argsSchema) {
402
+ const schema = registered.argsSchema as unknown as {
403
+ _zod: { run: (ctx: { value: unknown }) => unknown };
404
+ };
405
+ const originalRun = schema._zod.run.bind(schema._zod);
406
+ schema._zod.run = (ctx: { value: unknown }) => {
407
+ ctx.value ??= {};
408
+ return originalRun(ctx);
409
+ };
410
+ }
362
411
  }
363
412
 
364
413
  // =========================================================================
@@ -370,7 +370,22 @@ describe("DatabaseAdapter", () => {
370
370
  mockServer = {
371
371
  registerTool: vi.fn(),
372
372
  registerResource: vi.fn(),
373
- registerPrompt: vi.fn(),
373
+ // Return a RegisteredPrompt-like object so `registered.argsSchema`
374
+ // is accessible for schema patching in DatabaseAdapter.registerPrompt()
375
+ registerPrompt: vi.fn().mockImplementation((_name, config, _cb) => {
376
+ // Mimic SDK: if argsSchema is provided, create a z.object() from it.
377
+ // Use a mock with _zod.run so the patching code doesn't crash.
378
+ let argsSchema: unknown = undefined;
379
+ if (config?.argsSchema) {
380
+ argsSchema = {
381
+ _zod: {
382
+ def: { type: "object", shape: config.argsSchema },
383
+ run: vi.fn((ctx: { value: unknown }) => ctx),
384
+ },
385
+ };
386
+ }
387
+ return { argsSchema };
388
+ }),
374
389
  };
375
390
  });
376
391
 
@@ -438,7 +453,7 @@ describe("DatabaseAdapter", () => {
438
453
  );
439
454
  });
440
455
 
441
- it("should handle prompts with arguments", () => {
456
+ it("should pass argsSchema for prompts with arguments so SDK advertises them", () => {
442
457
  const promptWithArgs: PromptDefinition = {
443
458
  name: "arg_prompt",
444
459
  description: "desc",
@@ -454,18 +469,84 @@ describe("DatabaseAdapter", () => {
454
469
  ]);
455
470
  adapter.registerPrompts(mockServer as never);
456
471
 
472
+ // argsSchema must be a Zod raw shape so the SDK can:
473
+ // 1. Advertise arguments in prompts/list
474
+ // 2. Validate arguments in prompts/get
475
+ const calledConfig = mockServer.registerPrompt.mock.calls[0][1];
476
+ expect(calledConfig.argsSchema).toBeDefined();
477
+ expect(calledConfig.argsSchema).toHaveProperty("required_arg");
478
+ expect(calledConfig.argsSchema).toHaveProperty("optional_arg");
479
+ });
480
+
481
+ it("should not pass argsSchema for prompts without arguments", () => {
482
+ adapter.registerPrompts(mockServer as never);
483
+
457
484
  expect(mockServer.registerPrompt).toHaveBeenCalledWith(
458
- "arg_prompt",
485
+ "test_prompt",
459
486
  expect.objectContaining({
460
- description: "desc",
461
- argsSchema: expect.objectContaining({
462
- required_arg: expect.anything(),
463
- optional_arg: expect.anything(),
464
- }),
487
+ description: "A test prompt",
488
+ argsSchema: undefined,
465
489
  }),
466
490
  expect.any(Function),
467
491
  );
468
492
  });
493
+
494
+ it("should pass argsSchema for prompts with all-optional arguments", () => {
495
+ const allOptionalPrompt: PromptDefinition = {
496
+ name: "all_optional_prompt",
497
+ description: "All optional args",
498
+ arguments: [
499
+ { name: "opt_a", description: "optional a", required: false },
500
+ { name: "opt_b", description: "optional b", required: false },
501
+ ],
502
+ handler: async () => "result",
503
+ };
504
+
505
+ vi.spyOn(adapter, "getPromptDefinitions").mockReturnValue([
506
+ allOptionalPrompt,
507
+ ]);
508
+ adapter.registerPrompts(mockServer as never);
509
+
510
+ // argsSchema must be a Zod raw shape (even when all optional)
511
+ // so the SDK advertises arguments in prompts/list
512
+ const calledConfig = mockServer.registerPrompt.mock.calls[0][1];
513
+ expect(calledConfig.argsSchema).toBeDefined();
514
+ expect(calledConfig.argsSchema).toHaveProperty("opt_a");
515
+ expect(calledConfig.argsSchema).toHaveProperty("opt_b");
516
+ });
517
+
518
+ it("should return guide message when required args are missing", async () => {
519
+ const promptWithRequired: PromptDefinition = {
520
+ name: "required_prompt",
521
+ description: "Needs args",
522
+ arguments: [
523
+ { name: "operation", description: "The operation", required: true },
524
+ { name: "note", description: "A note", required: false },
525
+ ],
526
+ handler: async () => "should not reach",
527
+ };
528
+
529
+ vi.spyOn(adapter, "getPromptDefinitions").mockReturnValue([
530
+ promptWithRequired,
531
+ ]);
532
+ adapter.registerPrompts(mockServer as never);
533
+
534
+ // Call handler with no args (simulates MCP client sending undefined)
535
+ const handler = mockServer.registerPrompt.mock.calls[0][2] as Function;
536
+ const result = await handler({});
537
+
538
+ // Should return a guide message, not the handler output
539
+ expect(result.messages[0].content.text).toContain("required_prompt");
540
+ expect(result.messages[0].content.text).toContain(
541
+ "**operation** (required)",
542
+ );
543
+ expect(result.messages[0].content.text).toContain(
544
+ "**note** (optional)",
545
+ );
546
+ expect(result.messages[0].content.text).toContain(
547
+ "Please provide the required arguments",
548
+ );
549
+ });
469
550
  });
470
551
 
471
552
  describe("handler execution", () => {
@@ -269,13 +269,19 @@ export class MySQLAdapter extends DatabaseAdapter {
269
269
  const startTime = Date.now();
270
270
 
271
271
  try {
272
- const [results, fields] = await connection.execute(sql, params);
272
+ const [results, fields] = await connection.execute(
273
+ sql,
274
+ params as (string | number | null)[],
275
+ );
273
276
  return this.processExecutionResult(results, fields, startTime);
274
277
  } catch (error) {
275
278
  if (this.isUnsupportedPreparedStatementError(error)) {
276
279
  // Fallback to text protocol
277
280
  try {
278
- const [results, fields] = await connection.query(sql, params);
281
+ const [results, fields] = await connection.query(
282
+ sql,
283
+ params as (string | number | null)[],
284
+ );
279
285
  return this.processExecutionResult(results, fields, startTime);
280
286
  } catch (fallbackError) {
281
287
  const err = fallbackError as Error;
@@ -544,6 +550,15 @@ export class MySQLAdapter extends DatabaseAdapter {
544
550
  return this.pool;
545
551
  }
546
552
 
553
+ /**
554
+ * Clear the schema metadata cache.
555
+ * Should be called after any DDL operation (CREATE/DROP/ALTER TABLE, INDEX, VIEW)
556
+ * to prevent stale metadata from being served during the cache TTL window.
557
+ */
558
+ clearSchemaCache(): void {
559
+ this.schemaManager.clearCache();
560
+ }
561
+
547
562
  /**
548
563
  * Get IDs of all active transactions (for Code Mode cleanup)
549
564
  */
@@ -201,9 +201,10 @@ export class SchemaManager {
201
201
  : "TABLE_SCHEMA = DATABASE()";
202
202
  const params = schemaName ? [schemaName, shortTableName] : [shortTableName];
203
203
 
204
- // Get column information
205
- const columnsResult = await this.executor.executeQuery(
206
- `
204
+ // Performance optimization: run column and table queries in parallel
205
+ const [columnsResult, tableResult] = await Promise.all([
206
+ this.executor.executeQuery(
207
+ `
207
208
  SELECT
208
209
  COLUMN_NAME as name,
209
210
  DATA_TYPE as type,
@@ -219,8 +220,23 @@ export class SchemaManager {
219
220
  AND TABLE_NAME = ?
220
221
  ORDER BY ORDINAL_POSITION
221
222
  `,
222
- params,
223
- );
223
+ params,
224
+ ),
225
+ this.executor.executeQuery(
226
+ `
227
+ SELECT
228
+ TABLE_TYPE as type,
229
+ ENGINE as engine,
230
+ TABLE_ROWS as rowCount,
231
+ TABLE_COLLATION as collation,
232
+ TABLE_COMMENT as comment
233
+ FROM information_schema.TABLES
234
+ WHERE ${schemaClause}
235
+ AND TABLE_NAME = ?
236
+ `,
237
+ params,
238
+ ),
239
+ ]);
224
240
 
225
241
  const columns: ColumnInfo[] = (columnsResult.rows ?? []).map((row) => ({
226
242
  name: row["name"] as string,
@@ -234,22 +250,6 @@ export class SchemaManager {
234
250
  comment: row["comment"] as string | undefined,
235
251
  }));
236
252
 
237
- // Get table info
238
- const tableResult = await this.executor.executeQuery(
239
- `
240
- SELECT
241
- TABLE_TYPE as type,
242
- ENGINE as engine,
243
- TABLE_ROWS as rowCount,
244
- TABLE_COLLATION as collation,
245
- TABLE_COMMENT as comment
246
- FROM information_schema.TABLES
247
- WHERE ${schemaClause}
248
- AND TABLE_NAME = ?
249
- `,
250
- params,
251
- );
252
-
253
253
  const tableRow = tableResult.rows?.[0];
254
254
 
255
255
  const result: TableInfo = {
@@ -606,7 +606,7 @@ describe("MySQLAdapter", () => {
606
606
  const first = adapter.getToolDefinitions();
607
607
  const second = adapter.getToolDefinitions();
608
608
  expect(first).toBe(second); // Same reference = cached
609
- expect(first.length).toBe(193);
609
+ expect(first.length).toBe(192);
610
610
  });
611
611
  });
612
612
 
@@ -256,31 +256,21 @@ function createSchemaDesignPrompt(): PromptDefinition {
256
256
  ],
257
257
  handler: (args: Record<string, string>, _context: RequestContext) => {
258
258
  return Promise.resolve(`
259
- You are a MySQL database architect. Design a schema for: ${args["entity"]}
259
+ Design a MySQL schema for: ${args["entity"]}
260
260
 
261
261
  ${args["requirements"] ? `Requirements: ${args["requirements"]}` : ""}
262
262
 
263
- Please provide:
264
- 1. CREATE TABLE statement with:
265
- - Appropriate data types
266
- - Primary key
267
- - Indexes for common queries
268
- - Foreign key relationships if applicable
269
- - Engine: InnoDB (for transactions)
270
- - Charset: utf8mb4 (for full Unicode support)
271
-
272
- 2. Explanation of design choices
273
-
274
- 3. Sample INSERT statements
275
-
276
- 4. Common SELECT queries with indexes
277
-
278
- Best practices to follow:
279
- - Use underscore_case for column names
280
- - Include created_at and updated_at timestamps
281
- - Use UNSIGNED for positive-only integers
282
- - Consider JSON columns for flexible data
283
- - Add appropriate indexes based on query patterns
263
+ Provide a CREATE TABLE statement with:
264
+ - Appropriate data types
265
+ - Primary key
266
+ - Indexes for common queries
267
+ - Foreign key relationships if applicable
268
+ - Engine: InnoDB (for transactions)
269
+ - Charset: utf8mb4 (for full Unicode support)
270
+
271
+ Follow these conventions: underscore_case columns, created_at/updated_at timestamps, UNSIGNED for positive integers, JSON columns where appropriate.
272
+
273
+ Briefly explain key design decisions.
284
274
  `);
285
275
  },
286
276
  };
@@ -82,7 +82,7 @@ PROXYSQL_PASSWORD=admin
82
82
  Use ProxySQL tools to verify:
83
83
  - \`proxysql_status\` - Check ProxySQL is running
84
84
  - \`proxysql_servers\` - List configured servers
85
- - \`proxysql_hostgroups\` - View hostgroup configuration
85
+ - \`proxysql_connection_pool\` - View connection pool stats (filterable by hostgroup_id)
86
86
  - \`proxysql_query_rules\` - Review routing rules
87
87
  - \`proxysql_query_digest\` - Analyze query patterns
88
88
 
@@ -22,15 +22,14 @@ export function createDocstoreResource(
22
22
  },
23
23
  handler: async (_uri: string, _context: RequestContext) => {
24
24
  try {
25
- // Check if X Plugin is enabled
26
- const pluginResult = await adapter.executeQuery(
27
- "SELECT PLUGIN_STATUS FROM information_schema.PLUGINS WHERE PLUGIN_NAME = 'mysqlx'",
28
- );
29
- const pluginRow = pluginResult.rows?.[0];
30
- const xPluginEnabled = pluginRow?.["PLUGIN_STATUS"] === "ACTIVE";
31
-
32
- // Get collections (tables with _id column and doc JSON column)
33
- const collectionsResult = await adapter.executeQuery(`
25
+ // Performance optimization: run both independent queries in parallel
26
+ const [pluginResult, collectionsResult] = await Promise.all([
27
+ // Check if X Plugin is enabled
28
+ adapter.executeQuery(
29
+ "SELECT PLUGIN_STATUS FROM information_schema.PLUGINS WHERE PLUGIN_NAME = 'mysqlx'",
30
+ ),
31
+ // Get collections (tables with _id column and doc JSON column)
32
+ adapter.executeQuery(`
34
33
  SELECT
35
34
  t.TABLE_NAME as collection_name,
36
35
  t.TABLE_ROWS as row_count,
@@ -51,7 +50,11 @@ export function createDocstoreResource(
51
50
  AND c2.COLUMN_NAME = '_id'
52
51
  )
53
52
  ORDER BY t.TABLE_NAME
54
- `);
53
+ `),
54
+ ]);
55
+
56
+ const pluginRow = pluginResult.rows?.[0];
57
+ const xPluginEnabled = pluginRow?.["PLUGIN_STATUS"] === "ACTIVE";
55
58
 
56
59
  return {
57
60
  xPluginEnabled,
@@ -21,17 +21,12 @@ export function createEventsResource(
21
21
  priority: 0.6,
22
22
  },
23
23
  handler: async (_uri: string, _context: RequestContext) => {
24
- // Get scheduler status
25
- const schedulerResult = await adapter.executeQuery(
26
- "SHOW VARIABLES LIKE 'event_scheduler'",
27
- );
28
- const schedulerRow = schedulerResult.rows?.[0];
29
- const schedulerVal = schedulerRow?.["Value"];
30
- const schedulerStatus =
31
- typeof schedulerVal === "string" ? schedulerVal : "OFF";
32
-
33
- // Get all events
34
- const eventsResult = await adapter.executeQuery(`
24
+ // Performance optimization: run both independent queries in parallel
25
+ const [schedulerResult, eventsResult] = await Promise.all([
26
+ // Get scheduler status
27
+ adapter.executeQuery("SHOW VARIABLES LIKE 'event_scheduler'"),
28
+ // Get all events
29
+ adapter.executeQuery(`
35
30
  SELECT
36
31
  EVENT_SCHEMA as schema_name,
37
32
  EVENT_NAME as name,
@@ -43,7 +38,12 @@ export function createEventsResource(
43
38
  LAST_EXECUTED as last_executed
44
39
  FROM information_schema.EVENTS
45
40
  ORDER BY EVENT_SCHEMA, EVENT_NAME
46
- `);
41
+ `),
42
+ ]);
43
+ const schedulerRow = schedulerResult.rows?.[0];
44
+ const schedulerVal = schedulerRow?.["Value"];
45
+ const schedulerStatus =
46
+ typeof schedulerVal === "string" ? schedulerVal : "OFF";
47
47
 
48
48
  return {
49
49
  schedulerEnabled: schedulerStatus === "ON",
@@ -32,7 +32,7 @@ export function createIndexesResource(
32
32
  return { error: "No database selected" };
33
33
  }
34
34
 
35
- // Get index statistics
35
+ // Get index statistics (required)
36
36
  const indexResult = await adapter.executeQuery(
37
37
  `
38
38
  SELECT
@@ -50,11 +50,15 @@ export function createIndexesResource(
50
50
  [database],
51
51
  );
52
52
 
53
- // Try to get index usage from performance_schema if available
53
+ // Performance optimization: run unused + duplicate queries in parallel
54
+ // Both are optional — they may fail on older MySQL versions
54
55
  let unusedIndexes: unknown[] = [];
56
+ let duplicateIndexes: unknown[] = [];
57
+
55
58
  try {
56
- const unusedResult = await adapter.executeQuery(
57
- `
59
+ const [unusedResult, dupResult] = await Promise.all([
60
+ adapter.executeQuery(
61
+ `
58
62
  SELECT
59
63
  object_schema as schema_name,
60
64
  object_name as table_name,
@@ -65,18 +69,10 @@ export function createIndexesResource(
65
69
  AND index_name != 'PRIMARY'
66
70
  AND count_star = 0
67
71
  `,
68
- [database],
69
- );
70
- unusedIndexes = unusedResult.rows ?? [];
71
- } catch {
72
- // Performance schema may not be available
73
- }
74
-
75
- // Get duplicate/redundant indexes
76
- let duplicateIndexes: unknown[] = [];
77
- try {
78
- const dupResult = await adapter.executeQuery(
79
- `
72
+ [database],
73
+ ),
74
+ adapter.executeQuery(
75
+ `
80
76
  SELECT
81
77
  a.TABLE_NAME as table_name,
82
78
  a.INDEX_NAME as redundant_index,
@@ -94,11 +90,13 @@ export function createIndexesResource(
94
90
  AND (a.INDEX_NAME != 'PRIMARY' AND b.INDEX_NAME != 'PRIMARY')
95
91
  GROUP BY a.TABLE_NAME, a.INDEX_NAME, a.COLUMN_NAME, b.INDEX_NAME
96
92
  `,
97
- [database],
98
- );
93
+ [database],
94
+ ),
95
+ ]);
96
+ unusedIndexes = unusedResult.rows ?? [];
99
97
  duplicateIndexes = dupResult.rows ?? [];
100
98
  } catch {
101
- // May fail on older MySQL versions
99
+ // Performance schema may not be available on older MySQL versions
102
100
  }
103
101
 
104
102
  return {
@@ -23,10 +23,30 @@ export function createInnodbResource(
23
23
  priority: 0.7,
24
24
  },
25
25
  handler: async (_uri: string, _context: RequestContext) => {
26
- // Get buffer pool status
27
- const bufferPoolResult = await adapter.executeQuery(`
26
+ // Performance optimization: run all three independent queries in parallel
27
+ const [bufferPoolResult, configResult, opsResult] = await Promise.all([
28
+ // Get buffer pool status
29
+ adapter.executeQuery(`
28
30
  SHOW GLOBAL STATUS WHERE Variable_name LIKE 'Innodb_buffer_pool%'
29
- `);
31
+ `),
32
+ // Get buffer pool size configuration
33
+ adapter.executeQuery(`
34
+ SHOW GLOBAL VARIABLES WHERE Variable_name IN (
35
+ 'innodb_buffer_pool_size', 'innodb_buffer_pool_instances',
36
+ 'innodb_log_file_size', 'innodb_log_files_in_group',
37
+ 'innodb_flush_log_at_trx_commit', 'innodb_file_per_table'
38
+ )
39
+ `),
40
+ // Get row operations
41
+ adapter.executeQuery(`
42
+ SHOW GLOBAL STATUS WHERE Variable_name IN (
43
+ 'Innodb_rows_read', 'Innodb_rows_inserted',
44
+ 'Innodb_rows_updated', 'Innodb_rows_deleted',
45
+ 'Innodb_data_reads', 'Innodb_data_writes',
46
+ 'Innodb_os_log_written', 'Innodb_log_writes'
47
+ )
48
+ `),
49
+ ]);
30
50
 
31
51
  const bufferPool: Record<string, number> = {};
32
52
  for (const row of bufferPoolResult.rows ?? []) {
@@ -36,30 +56,11 @@ export function createInnodbResource(
36
56
  );
37
57
  }
38
58
 
39
- // Get buffer pool size configuration
40
- const configResult = await adapter.executeQuery(`
41
- SHOW GLOBAL VARIABLES WHERE Variable_name IN (
42
- 'innodb_buffer_pool_size', 'innodb_buffer_pool_instances',
43
- 'innodb_log_file_size', 'innodb_log_files_in_group',
44
- 'innodb_flush_log_at_trx_commit', 'innodb_file_per_table'
45
- )
46
- `);
47
-
48
59
  const config: Record<string, string> = {};
49
60
  for (const row of configResult.rows ?? []) {
50
61
  config[row["Variable_name"] as string] = row["Value"] as string;
51
62
  }
52
63
 
53
- // Get row operations
54
- const opsResult = await adapter.executeQuery(`
55
- SHOW GLOBAL STATUS WHERE Variable_name IN (
56
- 'Innodb_rows_read', 'Innodb_rows_inserted',
57
- 'Innodb_rows_updated', 'Innodb_rows_deleted',
58
- 'Innodb_data_reads', 'Innodb_data_writes',
59
- 'Innodb_os_log_written', 'Innodb_log_writes'
60
- )
61
- `);
62
-
63
64
  const operations: Record<string, number> = {};
64
65
  for (const row of opsResult.rows ?? []) {
65
66
  operations[row["Variable_name"] as string] = parseInt(