@loop_ouroboros/mcp-hub-lite 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (374) hide show
  1. package/CHANGELOG.md +47 -0
  2. package/dist/client/assets/{HomeView-Cr1jX73N.js → HomeView-Bu2joUvW.js} +1 -1
  3. package/dist/client/assets/ResourceDetailView-BvrhDCD1.js +1 -0
  4. package/dist/client/assets/ResourceDetailView-DUJZbegl.css +1 -0
  5. package/dist/client/assets/ResourcesView-Cc8RHtia.css +1 -0
  6. package/dist/client/assets/ResourcesView-LjqioF_s.js +1 -0
  7. package/dist/client/assets/ServerDashboard-BfLeFDGw.css +1 -0
  8. package/dist/client/assets/ServerDashboard-FhHJFvUi.js +1 -0
  9. package/dist/client/assets/ServerDetail-BKV-M4qT.js +2 -0
  10. package/dist/client/assets/ServerDetail-CtnNKJGx.css +1 -0
  11. package/dist/client/assets/{ServerListView-Bws09jNR.css → ServerListView-B-bPljsO.css} +1 -1
  12. package/dist/client/assets/ServerListView-BXgtDyt3.js +36 -0
  13. package/dist/client/assets/ServerStatusTags.vue_vue_type_script_setup_true_lang-D-ooYNdN.js +1 -0
  14. package/dist/client/assets/SettingsView-CMFG91Z4.js +1 -0
  15. package/dist/client/assets/SettingsView-GkBOKL0V.css +1 -0
  16. package/dist/client/assets/ToolCallDialog-Bf4Xe4gH.js +1 -0
  17. package/dist/client/assets/ToolsView-DFpha1z0.js +1 -0
  18. package/dist/client/assets/_baseClone-Bp9Rjwd7.js +1 -0
  19. package/dist/client/assets/el-form-item-B4LbJ6OO.css +1 -0
  20. package/dist/client/assets/el-form-item-DdSUWYsl.js +12 -0
  21. package/dist/client/assets/el-input-99gMrutP.js +1 -0
  22. package/dist/client/assets/el-input-BH4BZKnG.css +1 -0
  23. package/dist/client/assets/{el-loading-Csv24uBk.js → el-loading-CIQ5pD5u.js} +1 -1
  24. package/dist/client/assets/el-overlay-BVM6msGX.js +1 -0
  25. package/dist/client/assets/{el-select-C0U_l4IZ.css → el-overlay-CBvdpA69.css} +1 -1
  26. package/dist/client/assets/{ResourceDetailView-BdOaL_-o.css → el-radio-group-B0bauIRR.css} +1 -1
  27. package/dist/client/assets/el-radio-group-DhXWy7ry.js +1 -0
  28. package/dist/client/assets/el-skeleton-item-BLY1jEuR.css +1 -0
  29. package/dist/client/assets/el-skeleton-item-DJz-Us12.js +1 -0
  30. package/dist/client/assets/el-switch-BBrS-_6y.css +1 -0
  31. package/dist/client/assets/el-switch-Bu8AQ5uM.js +1 -0
  32. package/dist/client/assets/el-tab-pane-BnGMaV56.js +1 -0
  33. package/dist/client/assets/el-table-column-BMWOaLS_.js +1 -0
  34. package/dist/client/assets/el-table-column-BdvRS9Y2.css +1 -0
  35. package/dist/client/assets/index-C2V-ZGji.js +1 -0
  36. package/dist/client/assets/{index-BsDWtoIl.css → index-DpH6ZSbs.css} +1 -1
  37. package/dist/client/assets/index-vhkqgpmN.js +2 -0
  38. package/dist/client/assets/omit-CqPQN3XP.js +1 -0
  39. package/dist/client/assets/{raf-DDfJOMYh.js → raf-C2wXzaVU.js} +1 -1
  40. package/dist/client/assets/{vue-vendor-6ny5zj9i.js → vue-vendor-BLHLXXJK.js} +1 -1
  41. package/dist/client/index.html +3 -3
  42. package/dist/server/shared/models/resource.model.d.ts +2 -1
  43. package/dist/server/shared/models/resource.model.d.ts.map +1 -1
  44. package/dist/server/shared/models/server.model.d.ts +363 -5
  45. package/dist/server/shared/models/server.model.d.ts.map +1 -1
  46. package/dist/server/shared/models/server.model.js +220 -1
  47. package/dist/server/shared/models/session.model.d.ts +2 -56
  48. package/dist/server/shared/models/session.model.d.ts.map +1 -1
  49. package/dist/server/shared/models/session.model.js +2 -55
  50. package/dist/server/shared/models/tool.model.d.ts +4 -2
  51. package/dist/server/shared/models/tool.model.d.ts.map +1 -1
  52. package/dist/server/shared/types/client.types.d.ts +4 -32
  53. package/dist/server/shared/types/client.types.d.ts.map +1 -1
  54. package/dist/server/shared/types/client.types.js +3 -2
  55. package/dist/server/shared/types/index.d.ts +3 -3
  56. package/dist/server/shared/types/index.d.ts.map +1 -1
  57. package/dist/server/shared/types/index.js +3 -3
  58. package/dist/server/shared/types/session-context.types.d.ts +35 -0
  59. package/dist/server/shared/types/session-context.types.d.ts.map +1 -0
  60. package/dist/server/shared/types/session-context.types.js +5 -0
  61. package/dist/server/shared/types/websocket.types.d.ts +17 -10
  62. package/dist/server/shared/types/websocket.types.d.ts.map +1 -1
  63. package/dist/server/src/api/mcp/debug-response-wrapper.d.ts.map +1 -1
  64. package/dist/server/src/api/mcp/debug-response-wrapper.js +26 -1
  65. package/dist/server/src/api/mcp/gateway.d.ts +1 -3
  66. package/dist/server/src/api/mcp/gateway.d.ts.map +1 -1
  67. package/dist/server/src/api/mcp/gateway.js +34 -61
  68. package/dist/server/src/api/mcp/session-context-extractor.d.ts +5 -5
  69. package/dist/server/src/api/mcp/session-context-extractor.d.ts.map +1 -1
  70. package/dist/server/src/api/mcp/session-context-extractor.js +15 -39
  71. package/dist/server/src/api/web/clients.js +2 -2
  72. package/dist/server/src/api/web/hub-tools.d.ts +2 -2
  73. package/dist/server/src/api/web/hub-tools.d.ts.map +1 -1
  74. package/dist/server/src/api/web/hub-tools.js +3 -54
  75. package/dist/server/src/api/web/mcp-status.d.ts +1 -1
  76. package/dist/server/src/api/web/mcp-status.d.ts.map +1 -1
  77. package/dist/server/src/api/web/mcp-status.js +71 -30
  78. package/dist/server/src/api/web/resources.d.ts.map +1 -1
  79. package/dist/server/src/api/web/resources.js +28 -22
  80. package/dist/server/src/api/web/search.d.ts +2 -16
  81. package/dist/server/src/api/web/search.d.ts.map +1 -1
  82. package/dist/server/src/api/web/search.js +24 -45
  83. package/dist/server/src/api/web/servers.d.ts +3 -3
  84. package/dist/server/src/api/web/servers.d.ts.map +1 -1
  85. package/dist/server/src/api/web/servers.js +70 -25
  86. package/dist/server/src/api/web/sessions.js +1 -1
  87. package/dist/server/src/api/ws/ws-handler.d.ts.map +1 -1
  88. package/dist/server/src/api/ws/ws-handler.js +4 -2
  89. package/dist/server/src/app.d.ts.map +1 -1
  90. package/dist/server/src/app.js +0 -4
  91. package/dist/server/src/cli/commands/list.js +2 -2
  92. package/dist/server/src/cli/commands/status.d.ts.map +1 -1
  93. package/dist/server/src/cli/commands/status.js +41 -30
  94. package/dist/server/src/cli/index.d.ts.map +1 -1
  95. package/dist/server/src/cli/index.js +2 -1
  96. package/dist/server/src/cli/server.d.ts +11 -2
  97. package/dist/server/src/cli/server.d.ts.map +1 -1
  98. package/dist/server/src/config/config-change-logger.d.ts +22 -0
  99. package/dist/server/src/config/config-change-logger.d.ts.map +1 -1
  100. package/dist/server/src/config/config-change-logger.js +135 -11
  101. package/dist/server/src/config/config-loader.d.ts +6 -5
  102. package/dist/server/src/config/config-loader.d.ts.map +1 -1
  103. package/dist/server/src/config/config-loader.js +54 -16
  104. package/dist/server/src/config/config-manager.d.ts +51 -43
  105. package/dist/server/src/config/config-manager.d.ts.map +1 -1
  106. package/dist/server/src/config/config-manager.js +84 -66
  107. package/dist/server/src/config/config-migrator.d.ts +82 -0
  108. package/dist/server/src/config/config-migrator.d.ts.map +1 -0
  109. package/dist/server/src/config/config-migrator.js +348 -0
  110. package/dist/server/src/config/config-saver.d.ts +2 -0
  111. package/dist/server/src/config/config-saver.d.ts.map +1 -1
  112. package/dist/server/src/config/config-saver.js +8 -2
  113. package/dist/server/src/config/config.schema.d.ts +10 -102
  114. package/dist/server/src/config/config.schema.d.ts.map +1 -1
  115. package/dist/server/src/config/config.schema.js +15 -98
  116. package/dist/server/src/config/path-validator.d.ts +27 -0
  117. package/dist/server/src/config/path-validator.d.ts.map +1 -0
  118. package/dist/server/src/config/path-validator.js +53 -0
  119. package/dist/server/src/config/server-config-manager.d.ts +37 -31
  120. package/dist/server/src/config/server-config-manager.d.ts.map +1 -1
  121. package/dist/server/src/config/server-config-manager.js +222 -66
  122. package/dist/server/src/config/type-converter.d.ts.map +1 -1
  123. package/dist/server/src/config/type-converter.js +3 -2
  124. package/dist/server/src/index.js +1 -1
  125. package/dist/server/src/models/event.model.d.ts +17 -10
  126. package/dist/server/src/models/event.model.d.ts.map +1 -1
  127. package/dist/server/src/models/server.model.d.ts +17 -3
  128. package/dist/server/src/models/server.model.d.ts.map +1 -1
  129. package/dist/server/src/models/server.model.js +2 -1
  130. package/dist/server/src/models/system-tools.constants.d.ts +10 -27
  131. package/dist/server/src/models/system-tools.constants.d.ts.map +1 -1
  132. package/dist/server/src/models/system-tools.constants.js +4 -8
  133. package/dist/server/src/pid/manager.d.ts.map +1 -1
  134. package/dist/server/src/pid/manager.js +2 -1
  135. package/dist/server/src/server/dev-server.js +34 -20
  136. package/dist/server/src/server/runner.d.ts.map +1 -1
  137. package/dist/server/src/server/runner.js +41 -26
  138. package/dist/server/src/services/client-tracker.service.d.ts +3 -128
  139. package/dist/server/src/services/client-tracker.service.d.ts.map +1 -1
  140. package/dist/server/src/services/client-tracker.service.js +4 -200
  141. package/dist/server/src/services/connection/connection-manager.d.ts +85 -103
  142. package/dist/server/src/services/connection/connection-manager.d.ts.map +1 -1
  143. package/dist/server/src/services/connection/connection-manager.js +286 -241
  144. package/dist/server/src/services/connection/tool-cache.d.ts +27 -25
  145. package/dist/server/src/services/connection/tool-cache.d.ts.map +1 -1
  146. package/dist/server/src/services/connection/tool-cache.js +50 -55
  147. package/dist/server/src/services/gateway/gateway.service.d.ts +2 -0
  148. package/dist/server/src/services/gateway/gateway.service.d.ts.map +1 -1
  149. package/dist/server/src/services/gateway/gateway.service.js +15 -19
  150. package/dist/server/src/services/gateway/global-transport.d.ts +10 -0
  151. package/dist/server/src/services/gateway/global-transport.d.ts.map +1 -0
  152. package/dist/server/src/services/gateway/global-transport.js +42 -0
  153. package/dist/server/src/services/gateway/request-handlers/call-tool-handler.d.ts.map +1 -1
  154. package/dist/server/src/services/gateway/request-handlers/call-tool-handler.js +67 -65
  155. package/dist/server/src/services/gateway/request-handlers/index.d.ts +1 -1
  156. package/dist/server/src/services/gateway/request-handlers/index.d.ts.map +1 -1
  157. package/dist/server/src/services/gateway/request-handlers/index.js +1 -1
  158. package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts +1 -4
  159. package/dist/server/src/services/gateway/request-handlers/initialize-handler.d.ts.map +1 -1
  160. package/dist/server/src/services/gateway/request-handlers/initialize-handler.js +16 -55
  161. package/dist/server/src/services/gateway/request-handlers/initialize.constants.d.ts +35 -0
  162. package/dist/server/src/services/gateway/request-handlers/initialize.constants.d.ts.map +1 -0
  163. package/dist/server/src/services/gateway/request-handlers/initialize.constants.js +44 -0
  164. package/dist/server/src/services/gateway/request-handlers/resources-handler.d.ts.map +1 -1
  165. package/dist/server/src/services/gateway/request-handlers/resources-handler.js +5 -4
  166. package/dist/server/src/services/gateway/request-handlers/system-tools-handler.d.ts.map +1 -1
  167. package/dist/server/src/services/gateway/request-handlers/system-tools-handler.js +32 -77
  168. package/dist/server/src/services/gateway/request-handlers/tools-handler.d.ts.map +1 -1
  169. package/dist/server/src/services/gateway/request-handlers/tools-handler.js +4 -3
  170. package/dist/server/src/services/gateway/tool-list-generator.d.ts.map +1 -1
  171. package/dist/server/src/services/gateway/tool-list-generator.js +37 -16
  172. package/dist/server/src/services/gateway/types.d.ts +2 -1
  173. package/dist/server/src/services/gateway/types.d.ts.map +1 -1
  174. package/dist/server/src/services/hub-manager.service.d.ts +32 -238
  175. package/dist/server/src/services/hub-manager.service.d.ts.map +1 -1
  176. package/dist/server/src/services/hub-manager.service.js +89 -267
  177. package/dist/server/src/services/hub-tools/index.d.ts +1 -3
  178. package/dist/server/src/services/hub-tools/index.d.ts.map +1 -1
  179. package/dist/server/src/services/hub-tools/index.js +1 -2
  180. package/dist/server/src/services/hub-tools/instance-matcher.d.ts +62 -0
  181. package/dist/server/src/services/hub-tools/instance-matcher.d.ts.map +1 -0
  182. package/dist/server/src/services/hub-tools/instance-matcher.js +132 -0
  183. package/dist/server/src/services/hub-tools/instance-selector.d.ts +29 -0
  184. package/dist/server/src/services/hub-tools/instance-selector.d.ts.map +1 -0
  185. package/dist/server/src/services/hub-tools/instance-selector.js +103 -0
  186. package/dist/server/src/services/hub-tools/resource-generator.d.ts +25 -5
  187. package/dist/server/src/services/hub-tools/resource-generator.d.ts.map +1 -1
  188. package/dist/server/src/services/hub-tools/resource-generator.js +259 -64
  189. package/dist/server/src/services/hub-tools/server-selector.d.ts +26 -13
  190. package/dist/server/src/services/hub-tools/server-selector.d.ts.map +1 -1
  191. package/dist/server/src/services/hub-tools/server-selector.js +44 -37
  192. package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts +1 -4
  193. package/dist/server/src/services/hub-tools/system-tool-definitions.d.ts.map +1 -1
  194. package/dist/server/src/services/hub-tools/system-tool-definitions.js +17 -80
  195. package/dist/server/src/services/hub-tools/tool-search.d.ts +7 -7
  196. package/dist/server/src/services/hub-tools/tool-search.d.ts.map +1 -1
  197. package/dist/server/src/services/hub-tools/tool-search.js +10 -4
  198. package/dist/server/src/services/hub-tools/types.d.ts +2 -2
  199. package/dist/server/src/services/hub-tools/types.d.ts.map +1 -1
  200. package/dist/server/src/services/hub-tools.service.d.ts +43 -72
  201. package/dist/server/src/services/hub-tools.service.d.ts.map +1 -1
  202. package/dist/server/src/services/hub-tools.service.js +185 -110
  203. package/dist/server/src/services/search/search-cache.d.ts +0 -19
  204. package/dist/server/src/services/search/search-cache.d.ts.map +1 -1
  205. package/dist/server/src/services/search/search-cache.js +0 -24
  206. package/dist/server/src/services/search/search-core.service.d.ts +5 -5
  207. package/dist/server/src/services/search/search-core.service.js +11 -11
  208. package/dist/server/src/services/session/session-manager.d.ts +12 -256
  209. package/dist/server/src/services/session/session-manager.d.ts.map +1 -1
  210. package/dist/server/src/services/session/session-manager.js +23 -583
  211. package/dist/server/src/services/session-tracker.service.d.ts +124 -0
  212. package/dist/server/src/services/session-tracker.service.d.ts.map +1 -0
  213. package/dist/server/src/services/session-tracker.service.js +176 -0
  214. package/dist/server/src/services/system-tool-handler.d.ts.map +1 -1
  215. package/dist/server/src/services/system-tool-handler.js +7 -17
  216. package/dist/server/src/utils/composite-key.d.ts +29 -0
  217. package/dist/server/src/utils/composite-key.d.ts.map +1 -0
  218. package/dist/server/src/utils/composite-key.js +39 -0
  219. package/dist/server/src/utils/error-handler.d.ts.map +1 -1
  220. package/dist/server/src/utils/error-handler.js +3 -2
  221. package/dist/server/src/utils/index.d.ts +2 -0
  222. package/dist/server/src/utils/index.d.ts.map +1 -1
  223. package/dist/server/src/utils/index.js +2 -0
  224. package/dist/server/src/utils/instance-id.d.ts +22 -0
  225. package/dist/server/src/utils/instance-id.d.ts.map +1 -0
  226. package/dist/server/src/utils/instance-id.js +59 -0
  227. package/dist/server/src/utils/json-utils.d.ts +4 -4
  228. package/dist/server/src/utils/json-utils.d.ts.map +1 -1
  229. package/dist/server/src/utils/json-utils.js +10 -4
  230. package/dist/server/src/utils/logger/dev-logger.d.ts +2 -1
  231. package/dist/server/src/utils/logger/dev-logger.d.ts.map +1 -1
  232. package/dist/server/src/utils/logger/log-colors.d.ts +1 -0
  233. package/dist/server/src/utils/logger/log-colors.d.ts.map +1 -1
  234. package/dist/server/src/utils/logger/log-colors.js +2 -1
  235. package/dist/server/src/utils/logger/log-context.d.ts +1 -0
  236. package/dist/server/src/utils/logger/log-context.d.ts.map +1 -1
  237. package/dist/server/src/utils/logger/log-formatter.d.ts +28 -0
  238. package/dist/server/src/utils/logger/log-formatter.d.ts.map +1 -1
  239. package/dist/server/src/utils/logger/log-formatter.js +287 -5
  240. package/dist/server/src/utils/logger/log-modules.d.ts +15 -12
  241. package/dist/server/src/utils/logger/log-modules.d.ts.map +1 -1
  242. package/dist/server/src/utils/logger/log-modules.js +8 -8
  243. package/dist/server/src/utils/logger/log-output.d.ts +2 -2
  244. package/dist/server/src/utils/logger/log-output.d.ts.map +1 -1
  245. package/dist/server/src/utils/logger/log-output.js +27 -6
  246. package/dist/server/src/utils/logger/logger.d.ts +13 -0
  247. package/dist/server/src/utils/logger/logger.d.ts.map +1 -1
  248. package/dist/server/src/utils/logger/logger.js +42 -7
  249. package/dist/server/src/utils/parameter-validator.d.ts +10 -0
  250. package/dist/server/src/utils/parameter-validator.d.ts.map +1 -0
  251. package/dist/server/src/utils/parameter-validator.js +53 -0
  252. package/dist/server/src/utils/process-tree.d.ts +49 -0
  253. package/dist/server/src/utils/process-tree.d.ts.map +1 -0
  254. package/dist/server/src/utils/process-tree.js +285 -0
  255. package/dist/server/src/utils/request-context.d.ts +12 -30
  256. package/dist/server/src/utils/request-context.d.ts.map +1 -1
  257. package/dist/server/src/utils/request-context.js +10 -30
  258. package/dist/server/src/utils/sort-utils.d.ts +40 -0
  259. package/dist/server/src/utils/sort-utils.d.ts.map +1 -0
  260. package/dist/server/src/utils/sort-utils.js +131 -0
  261. package/dist/server/src/utils/tool-args-parser.d.ts +0 -4
  262. package/dist/server/src/utils/tool-args-parser.d.ts.map +1 -1
  263. package/dist/server/src/utils/tool-args-parser.js +0 -7
  264. package/dist/server/src/utils/transports/sse-transport.d.ts +16 -1
  265. package/dist/server/src/utils/transports/sse-transport.d.ts.map +1 -1
  266. package/dist/server/src/utils/transports/sse-transport.js +55 -9
  267. package/dist/server/src/utils/transports/stdio-transport.d.ts +24 -53
  268. package/dist/server/src/utils/transports/stdio-transport.d.ts.map +1 -1
  269. package/dist/server/src/utils/transports/stdio-transport.js +66 -247
  270. package/dist/server/src/utils/transports/streamable-http-transport.d.ts +24 -1
  271. package/dist/server/src/utils/transports/streamable-http-transport.d.ts.map +1 -1
  272. package/dist/server/src/utils/transports/streamable-http-transport.js +68 -8
  273. package/dist/server/src/utils/transports/transport-factory.d.ts +9 -4
  274. package/dist/server/src/utils/transports/transport-factory.d.ts.map +1 -1
  275. package/dist/server/src/utils/transports/transport-factory.js +33 -13
  276. package/dist/server/src/utils/transports/transport.interface.d.ts +6 -0
  277. package/dist/server/src/utils/transports/transport.interface.d.ts.map +1 -1
  278. package/dist/server/src/utils/version.d.ts +11 -0
  279. package/dist/server/src/utils/version.d.ts.map +1 -0
  280. package/dist/server/src/utils/version.js +57 -0
  281. package/dist/server/tests/contract/mcp-protocol/initialize.test.js +24 -24
  282. package/dist/server/tests/contract/mcp-protocol/tools-call.test.js +49 -45
  283. package/dist/server/tests/contract/mcp-protocol/tools-list.test.js +35 -36
  284. package/dist/server/tests/evaluation/evaluation.test.js +10 -9
  285. package/dist/server/tests/integration/api/gateway.test.js +24 -39
  286. package/dist/server/tests/integration/gateway/fault-tolerance.test.js +65 -25
  287. package/dist/server/tests/integration/gateway/mcp-connection.test.js +53 -61
  288. package/dist/server/tests/server.test.js +27 -16
  289. package/dist/server/tests/temp/temp-run-docling.d.ts +2 -0
  290. package/dist/server/tests/temp/temp-run-docling.d.ts.map +1 -0
  291. package/dist/server/tests/temp/temp-run-docling.js +53 -0
  292. package/dist/server/tests/temp/test-stack.d.ts +6 -0
  293. package/dist/server/tests/temp/test-stack.d.ts.map +1 -0
  294. package/dist/server/tests/temp/test-stack.js +40 -0
  295. package/dist/server/tests/types/test-helpers.d.ts +1 -2
  296. package/dist/server/tests/types/test-helpers.d.ts.map +1 -1
  297. package/dist/server/tests/unit/config/config-loader-automatic-migration.test.d.ts +2 -0
  298. package/dist/server/tests/unit/config/config-loader-automatic-migration.test.d.ts.map +1 -0
  299. package/dist/server/tests/unit/config/config-loader-automatic-migration.test.js +199 -0
  300. package/dist/server/tests/unit/config/config-migrator.test.d.ts +2 -0
  301. package/dist/server/tests/unit/config/config-migrator.test.d.ts.map +1 -0
  302. package/dist/server/tests/unit/config/config-migrator.test.js +316 -0
  303. package/dist/server/tests/unit/config/config-saver.test.d.ts +2 -0
  304. package/dist/server/tests/unit/config/config-saver.test.d.ts.map +1 -0
  305. package/dist/server/tests/unit/config/config-saver.test.js +200 -0
  306. package/dist/server/tests/unit/config/config.schema.test.d.ts +2 -0
  307. package/dist/server/tests/unit/config/config.schema.test.d.ts.map +1 -0
  308. package/dist/server/tests/unit/config/config.schema.test.js +347 -0
  309. package/dist/server/tests/unit/server/runner.test.js +86 -62
  310. package/dist/server/tests/unit/services/connection/connection-manager.test.d.ts +2 -0
  311. package/dist/server/tests/unit/services/connection/connection-manager.test.d.ts.map +1 -0
  312. package/dist/server/tests/unit/services/connection/connection-manager.test.js +112 -0
  313. package/dist/server/tests/unit/services/hub-manager-service.test.js +112 -46
  314. package/dist/server/tests/unit/services/hub-manager.test.js +25 -15
  315. package/dist/server/tests/unit/services/hub-tools/instance-selector.test.d.ts +2 -0
  316. package/dist/server/tests/unit/services/hub-tools/instance-selector.test.d.ts.map +1 -0
  317. package/dist/server/tests/unit/services/hub-tools/instance-selector.test.js +195 -0
  318. package/dist/server/tests/unit/services/hub-tools/server-selector.test.d.ts +2 -0
  319. package/dist/server/tests/unit/services/hub-tools/server-selector.test.d.ts.map +1 -0
  320. package/dist/server/tests/unit/services/hub-tools/server-selector.test.js +190 -0
  321. package/dist/server/tests/unit/services/hub-tools.service.test.js +560 -334
  322. package/dist/server/tests/unit/services/instance-matcher.test.d.ts +2 -0
  323. package/dist/server/tests/unit/services/instance-matcher.test.d.ts.map +1 -0
  324. package/dist/server/tests/unit/services/instance-matcher.test.js +256 -0
  325. package/dist/server/tests/unit/services/session-manager.test.js +26 -436
  326. package/dist/server/tests/unit/utils/config.test.js +88 -186
  327. package/dist/server/tests/unit/utils/json-utils.test.js +107 -13
  328. package/dist/server/tests/unit/utils/logger-formatter.test.d.ts +2 -0
  329. package/dist/server/tests/unit/utils/logger-formatter.test.d.ts.map +1 -0
  330. package/dist/server/tests/unit/utils/logger-formatter.test.js +66 -0
  331. package/dist/server/tests/unit/utils/logger.test.js +101 -0
  332. package/dist/server/tests/unit/utils/parameter-validator.test.d.ts +2 -0
  333. package/dist/server/tests/unit/utils/parameter-validator.test.d.ts.map +1 -0
  334. package/dist/server/tests/unit/utils/parameter-validator.test.js +63 -0
  335. package/dist/server/tests/unit/utils/process-tree.test.d.ts +2 -0
  336. package/dist/server/tests/unit/utils/process-tree.test.d.ts.map +1 -0
  337. package/dist/server/tests/unit/utils/process-tree.test.js +129 -0
  338. package/dist/server/tests/unit/utils/request-context.test.js +9 -28
  339. package/dist/server/tests/unit/utils/sort-utils.test.d.ts +2 -0
  340. package/dist/server/tests/unit/utils/sort-utils.test.d.ts.map +1 -0
  341. package/dist/server/tests/unit/utils/sort-utils.test.js +220 -0
  342. package/dist/server/tests/unit/utils/transport-factory.test.d.ts +2 -0
  343. package/dist/server/tests/unit/utils/transport-factory.test.d.ts.map +1 -0
  344. package/dist/server/tests/unit/utils/transport-factory.test.js +55 -0
  345. package/package.json +1 -1
  346. package/dist/client/assets/ResourceDetailView-BQ49hk0c.js +0 -1
  347. package/dist/client/assets/ResourcesView-BYZfWtia.js +0 -1
  348. package/dist/client/assets/ResourcesView-CjMklkyv.css +0 -1
  349. package/dist/client/assets/ServerDashboard-7_8Og9JJ.css +0 -1
  350. package/dist/client/assets/ServerDashboard-DHcxwKeh.js +0 -2
  351. package/dist/client/assets/ServerListView-DralUL71.js +0 -30
  352. package/dist/client/assets/ServerStatusTags.vue_vue_type_script_setup_true_lang-BHiTFM7-.js +0 -1
  353. package/dist/client/assets/SessionsView-BCGRTqem.js +0 -1
  354. package/dist/client/assets/SettingsView-BLfxa6PZ.js +0 -1
  355. package/dist/client/assets/ToolCallDialog-DQ0OQ1mD.js +0 -1
  356. package/dist/client/assets/ToolsView-BLB6x3tC.js +0 -1
  357. package/dist/client/assets/_baseClone-Bo5mBgsT.js +0 -1
  358. package/dist/client/assets/el-form-item-BVMLpmVC.css +0 -1
  359. package/dist/client/assets/el-form-item-BmeJKVSi.js +0 -12
  360. package/dist/client/assets/el-input-CeZiq23m.js +0 -1
  361. package/dist/client/assets/el-input-CmuHb8HS.css +0 -1
  362. package/dist/client/assets/el-overlay-B2ZKM6Up.css +0 -1
  363. package/dist/client/assets/el-overlay-iw_hrrlC.js +0 -1
  364. package/dist/client/assets/el-select-B73uRP_Y.js +0 -1
  365. package/dist/client/assets/el-tab-pane-BgOTBn4X.js +0 -1
  366. package/dist/client/assets/el-table-column-Ld4GSD3x.js +0 -1
  367. package/dist/client/assets/el-table-column-T_mV9jNw.css +0 -1
  368. package/dist/client/assets/el-tag-DYmSo8Bx.js +0 -1
  369. package/dist/client/assets/el-tag-DjxZVOpb.css +0 -1
  370. package/dist/client/assets/index-COYaYRbH.js +0 -1
  371. package/dist/client/assets/index-Cfcvxyee.js +0 -2
  372. package/dist/client/assets/index-PhuI36Zi.js +0 -1
  373. package/dist/client/assets/omit-7EL6VJO4.js +0 -1
  374. package/dist/client/assets/vnode-upjuIlvm.js +0 -1
@@ -1,12 +1,14 @@
1
1
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
2
  import { TransportFactory } from '../../utils/transports/transport-factory.js';
3
3
  import { logger, LOG_MODULES, formatMcpMessageForLogging, logNotificationMessage } from '../../utils/logger.js';
4
+ import { getAppVersion } from '../../utils/version.js';
4
5
  import { getMcpCommDebugSetting } from '../../utils/json-utils.js';
5
6
  import { logStorage } from '../log-storage.service.js';
6
7
  import { eventBus, EventTypes } from '../event-bus.service.js';
7
8
  import { hubManager } from '../hub-manager.service.js';
8
9
  import { MCP_HUB_LITE_SERVER } from '../../models/system-tools.constants.js';
9
10
  import { ToolCache } from './tool-cache.js';
11
+ import { getCompositeKey } from '../../utils/composite-key.js';
10
12
  /**
11
13
  * Manages MCP (Model Context Protocol) server connections and provides a unified interface
12
14
  * for tool and resource operations across multiple connected servers.
@@ -15,19 +17,19 @@ import { ToolCache } from './tool-cache.js';
15
17
  * - Establishing connections via various transport protocols (stdio, SSE, HTTP)
16
18
  * - Managing client instances and transport layers
17
19
  * - Caching tools and resources for performance optimization
18
- * - Providing both server ID-based and server name-based access patterns
20
+ * - Providing both composite key-based and server name-based access patterns
19
21
  * - Handling connection events and error recovery
20
22
  * - Supporting bidirectional communication for tool execution
21
23
  *
22
- * The manager uses ToolCache for both server ID-level and server name-level
24
+ * The manager uses ToolCache for both composite key-level and server name-level
23
25
  * operations to optimize different access patterns while ensuring data consistency.
24
26
  *
25
27
  * @example
26
28
  * ```typescript
27
29
  * const manager = new McpConnectionManager();
28
- * await manager.connect(serverConfig);
29
- * const tools = await manager.getTools(serverId);
30
- * const result = await manager.callTool(serverId, 'tool-name', { param: 'value' });
30
+ * await manager.connect('my-server', 0, serverConfig);
31
+ * const tools = await manager.getTools('my-server', 0);
32
+ * const result = await manager.callTool('my-server', 0, 'tool-name', { param: 'value' });
31
33
  * ```
32
34
  */
33
35
  export class McpConnectionManager {
@@ -36,17 +38,22 @@ export class McpConnectionManager {
36
38
  serverStatus = new Map();
37
39
  _toolCache = new ToolCache();
38
40
  resourceCache = new Map();
41
+ // Track composite keys by server name
42
+ serverNameToCompositeKeys = new Map();
39
43
  constructor() {
40
44
  // Listen for server deletion events and automatically disconnect
41
45
  eventBus.subscribe(EventTypes.SERVER_DELETED, (data) => {
42
46
  const serverName = data;
43
47
  // Find all instances by server name and disconnect them
44
- const serverInstances = hubManager.getServerInstanceByName(serverName);
45
- serverInstances.forEach((instance) => {
46
- this.disconnect(instance.id).catch((err) => {
47
- logger.warn(`Failed to disconnect deleted server instance ${instance.id}:`, err, LOG_MODULES.CONNECTION_MANAGER);
48
- });
49
- });
48
+ const compositeKeys = this.serverNameToCompositeKeys.get(serverName);
49
+ if (compositeKeys) {
50
+ for (const compositeKey of compositeKeys) {
51
+ const { serverIndex } = parseCompositeKey(compositeKey);
52
+ this.disconnect(serverName, serverIndex).catch((err) => {
53
+ logger.warn(`Failed to disconnect deleted server instance ${compositeKey}:`, err, LOG_MODULES.CONNECTION_MANAGER);
54
+ });
55
+ }
56
+ }
50
57
  });
51
58
  }
52
59
  /**
@@ -65,7 +72,9 @@ export class McpConnectionManager {
65
72
  * successful connection, and SERVER_STATUS_CHANGE events with error details
66
73
  * on failure.
67
74
  *
68
- * @param {ServerConfig & ServerInstanceConfig} server - Server configuration containing
75
+ * @param {string} serverName - Server name
76
+ * @param {number} serverIndex - Instance index
77
+ * @param {ServerRuntimeConfig & Partial<ServerInstanceConfig>} server - Server configuration containing
69
78
  * connection details, transport type, and instance-specific parameters
70
79
  * @returns {Promise<boolean>} True if connection succeeds, false if it fails
71
80
  * @throws {Error} If server ID is missing or required configuration is invalid
@@ -78,31 +87,34 @@ export class McpConnectionManager {
78
87
  * command: 'npx my-mcp-server',
79
88
  * name: 'My MCP Server'
80
89
  * };
81
- * const success = await manager.connect(serverConfig);
90
+ * const success = await manager.connect('My MCP Server', 0, serverConfig);
82
91
  * if (success) {
83
92
  * console.log('Connected successfully');
84
93
  * }
85
94
  * ```
86
95
  */
87
- async connect(server) {
96
+ async connect(serverName, serverIndex, server) {
88
97
  let serverInfo;
98
+ // Extract serverId at the very beginning for consistent usage in both try and catch blocks
99
+ const serverId = server.id || 'unknown';
100
+ const compositeKey = getCompositeKey(serverName, serverIndex);
89
101
  try {
90
- logger.info(`Connecting to server [${server.id || 'unknown'}]...`, LOG_MODULES.CONNECTION_MANAGER);
91
102
  // Validate server configuration
92
103
  if (!server.id) {
93
104
  throw new Error('Server ID is required');
94
105
  }
106
+ logger.info(`Connecting to server [${compositeKey}] (${serverId})...`, LOG_MODULES.CONNECTION_MANAGER);
95
107
  // First set starting state (connected: false, no error)
96
- this.serverStatus.set(server.id, {
108
+ this.serverStatus.set(compositeKey, {
97
109
  connected: false,
98
110
  lastCheck: Date.now(),
99
111
  toolsCount: 0,
100
112
  resourcesCount: 0
101
113
  });
102
114
  // Get server name from server instance ID (via hubManager.getServerById)
103
- serverInfo = hubManager.getServerById(server.id);
115
+ serverInfo = hubManager.getServerById(serverId);
104
116
  if (!serverInfo) {
105
- throw new Error(`Server not found for instance: ${server.id}`);
117
+ throw new Error(`Server not found for instance: ${serverId}`);
106
118
  }
107
119
  if (server.type === 'stdio' && (!server.command || server.command.trim() === '')) {
108
120
  throw new Error('STDIO server requires a valid command');
@@ -113,11 +125,10 @@ export class McpConnectionManager {
113
125
  throw new Error(`${displayType.toUpperCase()} server requires a valid URL`);
114
126
  }
115
127
  // Create transport based on server type
116
- const serverName = serverInfo.name;
117
128
  const transport = TransportFactory.createTransport({
118
129
  ...server,
119
130
  name: serverName
120
- }, server.id);
131
+ }, compositeKey);
121
132
  // Always set up message handler for notifications/message
122
133
  transport.onmessage = (message) => {
123
134
  // Communication debug logs: controlled by MCP_COMM_DEBUG environment variable
@@ -126,7 +137,7 @@ export class McpConnectionManager {
126
137
  logger.debug(`MCP message received: ${logMessage}`, LOG_MODULES.CONNECTION_MANAGER);
127
138
  }
128
139
  // Log notifications/message to application logs (always enabled)
129
- logNotificationMessage(message, serverName, server.id);
140
+ logNotificationMessage(message, serverName, compositeKey);
130
141
  };
131
142
  // Wrap send method for debug logging (if enabled)
132
143
  if (getMcpCommDebugSetting()) {
@@ -146,17 +157,25 @@ export class McpConnectionManager {
146
157
  // Handle transport close events
147
158
  if ('onclose' in transport) {
148
159
  transport.onclose = () => {
149
- logger.info(`Transport closed for server [${server.id}]`, LOG_MODULES.CONNECTION_MANAGER);
150
- const currentStatus = this.serverStatus.get(server.id);
160
+ logger.info(`Transport closed for server [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
161
+ const currentStatus = this.serverStatus.get(compositeKey);
151
162
  // Only update status if it was previously connected or starting
152
163
  if (currentStatus && (currentStatus.connected || !currentStatus.error)) {
153
- this.serverStatus.set(server.id, {
164
+ this.serverStatus.set(compositeKey, {
154
165
  connected: false,
155
166
  lastCheck: Date.now(),
156
167
  toolsCount: 0,
157
168
  resourcesCount: 0,
158
169
  error: 'Connection closed unexpectedly'
159
170
  });
171
+ // Publish server status change event
172
+ eventBus.publish(EventTypes.SERVER_STATUS_CHANGE, {
173
+ serverName,
174
+ serverIndex,
175
+ status: 'error',
176
+ error: 'Connection closed unexpectedly',
177
+ timestamp: Date.now()
178
+ });
160
179
  }
161
180
  };
162
181
  }
@@ -182,30 +201,33 @@ export class McpConnectionManager {
182
201
  }
183
202
  }
184
203
  if (!isJsonRpc) {
185
- // Use server ID and name for log storage
186
- const serverId = server?.id ?? 'unknown';
187
- logStorage.append(serverId, 'info', `[${serverName}] [STDOUT] ${data}`);
204
+ // Use composite key for log storage
205
+ logStorage.append(compositeKey, 'info', `[${serverName}] [STDOUT] ${data}`);
188
206
  }
189
207
  }
190
208
  };
191
209
  }
192
210
  if ('onstderr' in transport) {
193
211
  transport.onstderr = (data) => {
194
- // Use server ID and name for log storage
195
- const serverId = server?.id ?? 'unknown';
196
- logStorage.append(serverId, 'error', `[${serverName}] [STDERR] ${data}`);
212
+ // Use composite key for log storage
213
+ logStorage.append(compositeKey, 'error', `[${serverName}] [STDERR] ${data}`);
197
214
  };
198
215
  }
199
216
  const client = new Client({
200
217
  name: MCP_HUB_LITE_SERVER,
201
- version: '1.0.0'
218
+ version: getAppVersion()
202
219
  }, {
203
220
  capabilities: {}
204
221
  });
205
222
  await client.connect(transport);
206
- this.clients.set(server.id, client);
207
- this.transports.set(server.id, transport);
208
- this._toolCache.setNameMapping(serverInfo.name, server.id);
223
+ this.clients.set(compositeKey, client);
224
+ this.transports.set(compositeKey, transport);
225
+ this._toolCache.setNameMapping(serverName, compositeKey);
226
+ // Register composite key for this server name
227
+ if (!this.serverNameToCompositeKeys.has(serverName)) {
228
+ this.serverNameToCompositeKeys.set(serverName, new Set());
229
+ }
230
+ this.serverNameToCompositeKeys.get(serverName).add(compositeKey);
209
231
  // Get PID if available (only for stdio transport)
210
232
  let pid;
211
233
  if ('pid' in transport && typeof transport.pid === 'number') {
@@ -214,49 +236,43 @@ export class McpConnectionManager {
214
236
  // Get server version
215
237
  const clientServerInfo = client.getServerVersion();
216
238
  const serverVersion = clientServerInfo?.version || clientServerInfo?.name;
217
- // Update server instance info (merge pid and startTime)
218
- const instances = hubManager.getServerInstanceByName(serverName);
219
- const instanceIndex = instances.findIndex((inst) => inst.id === server.id);
220
- if (instanceIndex !== -1) {
221
- hubManager.updateServerInstance(serverName, instanceIndex, {
222
- pid: pid,
223
- startTime: Date.now() // Startup time is the same as timestamp
224
- });
225
- }
226
- this.serverStatus.set(server.id, {
239
+ this.serverStatus.set(compositeKey, {
227
240
  connected: true,
228
241
  lastCheck: Date.now(),
229
242
  toolsCount: 0,
230
243
  resourcesCount: 0,
231
244
  pid: pid,
232
245
  startTime: Date.now(),
233
- version: serverVersion,
234
- hash: server.hash
246
+ version: serverVersion
235
247
  });
236
- logger.info(`Connected to server [${server.id}]`, LOG_MODULES.CONNECTION_MANAGER);
248
+ logger.info(`Connected to server [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
237
249
  // Publish server connected event
238
250
  eventBus.publish(EventTypes.SERVER_CONNECTED, {
239
- serverId: server.id,
251
+ serverName,
252
+ serverIndex,
240
253
  status: 'online',
241
254
  timestamp: Date.now()
242
255
  });
243
256
  // Publish server status change event
244
257
  eventBus.publish(EventTypes.SERVER_STATUS_CHANGE, {
245
- serverId: server.id,
258
+ serverName,
259
+ serverIndex,
246
260
  status: 'online',
247
261
  timestamp: Date.now()
248
262
  });
249
263
  // Fetch tools and resources immediately (only for bidirectional transports)
250
264
  if (server.type !== 'sse') {
251
- const tools = await this.refreshTools(server.id);
252
- const resources = await this.refreshResources(server.id);
265
+ const tools = await this.refreshTools(serverName, serverIndex);
266
+ const resources = await this.refreshResources(serverName, serverIndex);
253
267
  // Publish tools and resources updated event
254
268
  eventBus.publish(EventTypes.TOOLS_UPDATED, {
255
- serverId: server.id,
269
+ serverName,
270
+ serverIndex,
256
271
  tools
257
272
  });
258
273
  eventBus.publish(EventTypes.RESOURCES_UPDATED, {
259
- serverId: server.id,
274
+ serverName,
275
+ serverIndex,
260
276
  resources
261
277
  });
262
278
  }
@@ -266,9 +282,8 @@ export class McpConnectionManager {
266
282
  return true;
267
283
  }
268
284
  catch (error) {
269
- logger.error(`Failed to connect to server ${serverInfo?.name || server.id || 'unknown'}:`, error, LOG_MODULES.CONNECTION_MANAGER);
270
- const serverId = server.id || 'unknown';
271
- this.serverStatus.set(serverId, {
285
+ logger.error(`Failed to connect to server ${compositeKey}:`, error, LOG_MODULES.CONNECTION_MANAGER);
286
+ this.serverStatus.set(compositeKey, {
272
287
  connected: false,
273
288
  error: error instanceof Error ? error.message : String(error),
274
289
  lastCheck: Date.now(),
@@ -277,7 +292,8 @@ export class McpConnectionManager {
277
292
  });
278
293
  // Publish server status change event (error state)
279
294
  eventBus.publish(EventTypes.SERVER_STATUS_CHANGE, {
280
- serverId,
295
+ serverName,
296
+ serverIndex,
281
297
  status: 'error',
282
298
  error: error instanceof Error ? error.message : String(error),
283
299
  timestamp: Date.now()
@@ -297,26 +313,28 @@ export class McpConnectionManager {
297
313
  * upon completion and handles any errors during the disconnection process
298
314
  * without throwing exceptions.
299
315
  *
300
- * @param {string} serverId - Unique identifier of the server instance to disconnect
316
+ * @param {string} serverName - Server name
317
+ * @param {number} serverIndex - Instance index
301
318
  * @returns {Promise<void>} Resolves when disconnection is complete
302
319
  *
303
320
  * @example
304
321
  * ```typescript
305
- * await manager.disconnect('my-server-1');
322
+ * await manager.disconnect('my-server', 0);
306
323
  * console.log('Server disconnected');
307
324
  * ```
308
325
  */
309
- async disconnect(serverId) {
310
- logger.info(`Disconnecting from server [${serverId}]...`, LOG_MODULES.CONNECTION_MANAGER);
311
- const client = this.clients.get(serverId);
312
- const transport = this.transports.get(serverId);
326
+ async disconnect(serverName, serverIndex) {
327
+ const compositeKey = getCompositeKey(serverName, serverIndex);
328
+ logger.info(`Disconnecting from server [${compositeKey}]...`, LOG_MODULES.CONNECTION_MANAGER);
329
+ const client = this.clients.get(compositeKey);
330
+ const transport = this.transports.get(compositeKey);
313
331
  try {
314
332
  if (client) {
315
333
  try {
316
334
  await client.close();
317
335
  }
318
336
  catch (e) {
319
- logger.warn(`Error closing client for [${serverId}]:`, e, LOG_MODULES.CONNECTION_MANAGER);
337
+ logger.warn(`Error closing client for [${compositeKey}]:`, e, LOG_MODULES.CONNECTION_MANAGER);
320
338
  }
321
339
  }
322
340
  if (transport && typeof transport.close === 'function') {
@@ -324,15 +342,23 @@ export class McpConnectionManager {
324
342
  }
325
343
  }
326
344
  catch (error) {
327
- logger.error(`Error disconnecting server [${serverId}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
345
+ logger.error(`Error disconnecting server [${compositeKey}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
328
346
  }
329
347
  finally {
330
- this.clients.delete(serverId);
331
- this.transports.delete(serverId);
332
- this._toolCache.clearTools(serverId);
333
- this.resourceCache.delete(serverId);
334
- this._toolCache.removeNameMappingById(serverId);
335
- this.serverStatus.set(serverId, {
348
+ this.clients.delete(compositeKey);
349
+ this.transports.delete(compositeKey);
350
+ this._toolCache.clearTools(serverName, serverIndex);
351
+ this.resourceCache.delete(compositeKey);
352
+ this._toolCache.removeNameMappingById(compositeKey);
353
+ // Remove from serverNameToCompositeKeys
354
+ const keys = this.serverNameToCompositeKeys.get(serverName);
355
+ if (keys) {
356
+ keys.delete(compositeKey);
357
+ if (keys.size === 0) {
358
+ this.serverNameToCompositeKeys.delete(serverName);
359
+ }
360
+ }
361
+ this.serverStatus.set(compositeKey, {
336
362
  connected: false,
337
363
  lastCheck: Date.now(),
338
364
  toolsCount: 0,
@@ -340,17 +366,19 @@ export class McpConnectionManager {
340
366
  });
341
367
  // Publish server disconnected event
342
368
  eventBus.publish(EventTypes.SERVER_DISCONNECTED, {
343
- serverId,
369
+ serverName,
370
+ serverIndex,
344
371
  status: 'offline',
345
372
  timestamp: Date.now()
346
373
  });
347
374
  // Publish server status change event
348
375
  eventBus.publish(EventTypes.SERVER_STATUS_CHANGE, {
349
- serverId,
376
+ serverName,
377
+ serverIndex,
350
378
  status: 'offline',
351
379
  timestamp: Date.now()
352
380
  });
353
- logger.info(`Disconnected from server [${serverId}]`, LOG_MODULES.CONNECTION_MANAGER);
381
+ logger.info(`Disconnected from server [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
354
382
  }
355
383
  }
356
384
  /**
@@ -371,16 +399,17 @@ export class McpConnectionManager {
371
399
  */
372
400
  async disconnectAll() {
373
401
  logger.info('Disconnecting all servers...', LOG_MODULES.CONNECTION_MANAGER);
374
- const serverIds = Array.from(this.clients.keys());
375
- logger.info(`Found ${serverIds.length} connected server(s)`, LOG_MODULES.CONNECTION_MANAGER);
376
- const disconnectPromises = serverIds.map(async (id) => {
377
- logger.info(`Disconnecting server [${id}]...`, LOG_MODULES.CONNECTION_MANAGER);
402
+ const compositeKeys = Array.from(this.clients.keys());
403
+ logger.info(`Found ${compositeKeys.length} connected server(s)`, LOG_MODULES.CONNECTION_MANAGER);
404
+ const disconnectPromises = compositeKeys.map(async (compositeKey) => {
405
+ const { serverName, serverIndex } = parseCompositeKey(compositeKey);
406
+ logger.info(`Disconnecting server [${compositeKey}]...`, LOG_MODULES.CONNECTION_MANAGER);
378
407
  try {
379
- await this.disconnect(id);
380
- logger.info(`Successfully disconnected server [${id}]`, LOG_MODULES.CONNECTION_MANAGER);
408
+ await this.disconnect(serverName, serverIndex);
409
+ logger.info(`Successfully disconnected server [${compositeKey}]`, LOG_MODULES.CONNECTION_MANAGER);
381
410
  }
382
411
  catch (error) {
383
- logger.error(`Failed to disconnect server [${id}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
412
+ logger.error(`Failed to disconnect server [${compositeKey}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
384
413
  }
385
414
  });
386
415
  await Promise.all(disconnectPromises);
@@ -390,46 +419,47 @@ export class McpConnectionManager {
390
419
  * Refreshes the tool cache for a specific server by fetching the latest tool list.
391
420
  *
392
421
  * This method queries the connected MCP server for its current set of available tools,
393
- * updates both the server ID-level and server name-level caches, and maintains
422
+ * updates both the composite key-level and server name-level caches, and maintains
394
423
  * accurate tool counts in the server status. It handles server name resolution
395
424
  * to ensure proper caching across multiple instances of the same server.
396
425
  *
397
- * @param {string} serverId - Unique identifier of the server instance to refresh
426
+ * @param {string} serverName - Server name
427
+ * @param {number} serverIndex - Instance index
398
428
  * @returns {Promise<Tool[]>} Array of updated tools with server context
399
429
  * @throws {Error} If the server is not connected or tool listing fails
400
430
  *
401
431
  * @example
402
432
  * ```typescript
403
- * const tools = await manager.refreshTools('my-server-1');
433
+ * const tools = await manager.refreshTools('my-server', 0);
404
434
  * console.log(`Found ${tools.length} tools`);
405
435
  * ```
406
436
  */
407
- async refreshTools(serverId) {
408
- const client = this.clients.get(serverId);
437
+ async refreshTools(serverName, serverIndex) {
438
+ const compositeKey = getCompositeKey(serverName, serverIndex);
439
+ const client = this.clients.get(compositeKey);
409
440
  if (!client) {
410
- throw new Error(`Server ${serverId} not connected`);
441
+ throw new Error(`Server ${compositeKey} not connected`);
411
442
  }
412
443
  try {
413
444
  const result = await client.listTools();
414
- const serverName = this._toolCache.getServerNameById(serverId);
415
445
  const tools = result.tools.map((t) => ({
416
446
  name: t.name,
417
447
  description: t.description,
418
448
  inputSchema: t.inputSchema,
419
449
  serverName: serverName
420
450
  }));
421
- this._toolCache.setTools(serverId, tools, serverName !== 'unknown' ? serverName : undefined);
451
+ this._toolCache.setTools(serverName, serverIndex, tools);
422
452
  // Update status
423
- const status = this.serverStatus.get(serverId);
453
+ const status = this.serverStatus.get(compositeKey);
424
454
  if (status) {
425
455
  status.toolsCount = tools.length;
426
456
  status.lastCheck = Date.now();
427
457
  }
428
- logger.info(`Refreshed tools for server [${serverId}]: ${tools.length} tools found`, LOG_MODULES.CONNECTION_MANAGER);
458
+ logger.info(`Refreshed tools for server [${compositeKey}]: ${tools.length} tools found`, LOG_MODULES.CONNECTION_MANAGER);
429
459
  return tools;
430
460
  }
431
461
  catch (error) {
432
- logger.error(`Failed to list tools for server [${serverId}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
462
+ logger.error(`Failed to list tools for server [${compositeKey}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
433
463
  throw error;
434
464
  }
435
465
  }
@@ -445,26 +475,28 @@ export class McpConnectionManager {
445
475
  * which indicate that the server doesn't implement the resources protocol, treating
446
476
  * this as a normal case rather than an error.
447
477
  *
448
- * @param {string} serverId - Unique identifier of the server instance to refresh
478
+ * @param {string} serverName - Server name
479
+ * @param {number} serverIndex - Instance index
449
480
  * @returns {Promise<Resource[]>} Array of available resources, empty if unsupported
450
481
  * @throws {Error} If the server is not connected or resource listing fails unexpectedly
451
482
  *
452
483
  * @example
453
484
  * ```typescript
454
- * const resources = await manager.refreshResources('my-server-1');
485
+ * const resources = await manager.refreshResources('my-server', 0);
455
486
  * console.log(`Found ${resources.length} resources`);
456
487
  * ```
457
488
  */
458
- async refreshResources(serverId) {
459
- const client = this.clients.get(serverId);
489
+ async refreshResources(serverName, serverIndex) {
490
+ const compositeKey = getCompositeKey(serverName, serverIndex);
491
+ const client = this.clients.get(compositeKey);
460
492
  if (!client) {
461
- throw new Error(`Server ${serverId} not connected`);
493
+ throw new Error(`Server ${compositeKey} not connected`);
462
494
  }
463
495
  try {
464
496
  // Check if client actually supports listResources method
465
497
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
466
498
  if (typeof client.listResources !== 'function') {
467
- logger.warn(`Server [${serverId}] does not support resources listing`, LOG_MODULES.CONNECTION_MANAGER);
499
+ logger.warn(`Server [${compositeKey}] does not support resources listing`, LOG_MODULES.CONNECTION_MANAGER);
468
500
  return [];
469
501
  }
470
502
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -474,23 +506,25 @@ export class McpConnectionManager {
474
506
  name: r.name,
475
507
  uri: r.uri,
476
508
  mimeType: r.mimeType,
477
- description: r.description
509
+ description: r.description,
510
+ serverName: serverName,
511
+ serverIndex: serverIndex
478
512
  }));
479
- this.resourceCache.set(serverId, resources);
513
+ this.resourceCache.set(compositeKey, resources);
480
514
  // Update status
481
- const status = this.serverStatus.get(serverId);
515
+ const status = this.serverStatus.get(compositeKey);
482
516
  if (status) {
483
517
  status.resourcesCount = resources.length;
484
518
  status.lastCheck = Date.now();
485
519
  }
486
- logger.info(`Refreshed resources for server [${serverId}]: ${resources.length} resources found`, LOG_MODULES.CONNECTION_MANAGER);
520
+ logger.info(`Refreshed resources for server [${compositeKey}]: ${resources.length} resources found`, LOG_MODULES.CONNECTION_MANAGER);
487
521
  return resources;
488
522
  }
489
523
  catch (error) {
490
524
  // Check if error is "Method not found" (MCP error -32601), which means server doesn't implement resources
491
525
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
492
526
  if (error && typeof error === 'object' && 'code' in error && error.code === -32601) {
493
- logger.info(`Server [${serverId}] does not support resources functionality`, LOG_MODULES.CONNECTION_MANAGER);
527
+ logger.info(`Server [${compositeKey}] does not support resources functionality`, LOG_MODULES.CONNECTION_MANAGER);
494
528
  }
495
529
  else if (error &&
496
530
  typeof error === 'object' &&
@@ -499,15 +533,15 @@ export class McpConnectionManager {
499
533
  typeof error.message === 'string' &&
500
534
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
501
535
  error.message.includes('Method not found')) {
502
- logger.info(`Server [${serverId}] does not support resources functionality`, LOG_MODULES.CONNECTION_MANAGER);
536
+ logger.info(`Server [${compositeKey}] does not support resources functionality`, LOG_MODULES.CONNECTION_MANAGER);
503
537
  }
504
538
  else {
505
- logger.warn(`Failed to list resources for server [${serverId}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
539
+ logger.warn(`Failed to list resources for server [${compositeKey}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
506
540
  }
507
541
  // Even if server doesn't support resources, store empty array in cache to ensure subsequent calls hit cache
508
- this.resourceCache.set(serverId, []);
542
+ this.resourceCache.set(compositeKey, []);
509
543
  // Update server status
510
- const status = this.serverStatus.get(serverId);
544
+ const status = this.serverStatus.get(compositeKey);
511
545
  if (status) {
512
546
  status.resourcesCount = 0;
513
547
  status.lastCheck = Date.now();
@@ -521,19 +555,21 @@ export class McpConnectionManager {
521
555
  * This method provides access to the server's operational state including connection
522
556
  * status, error information, tool/resource counts, and process details.
523
557
  *
524
- * @param {string} serverId - Unique identifier of the server instance
558
+ * @param {string} serverName - Server name
559
+ * @param {number} serverIndex - Instance index
525
560
  * @returns {ServerStatus | undefined} Current status object or undefined if not found
526
561
  *
527
562
  * @example
528
563
  * ```typescript
529
- * const status = manager.getStatus('my-server-1');
564
+ * const status = manager.getStatus('my-server', 0);
530
565
  * if (status?.connected) {
531
566
  * console.log('Server is connected');
532
567
  * }
533
568
  * ```
534
569
  */
535
- getStatus(serverId) {
536
- return this.serverStatus.get(serverId);
570
+ getStatus(serverName, serverIndex) {
571
+ const compositeKey = getCompositeKey(serverName, serverIndex);
572
+ return this.serverStatus.get(compositeKey);
537
573
  }
538
574
  /**
539
575
  * Retrieves cached tools for a specific server instance.
@@ -542,17 +578,18 @@ export class McpConnectionManager {
542
578
  * which may be empty if tools haven't been refreshed yet or if the server
543
579
  * doesn't provide any tools. The method includes logging for debugging purposes.
544
580
  *
545
- * @param {string} serverId - Unique identifier of the server instance
581
+ * @param {string} serverName - Server name
582
+ * @param {number} serverIndex - Instance index
546
583
  * @returns {Tool[]} Array of cached tools, empty if none available
547
584
  *
548
585
  * @example
549
586
  * ```typescript
550
- * const tools = manager.getTools('my-server-1');
587
+ * const tools = manager.getTools('my-server', 0);
551
588
  * console.log(`Server has ${tools.length} tools`);
552
589
  * ```
553
590
  */
554
- getTools(serverId) {
555
- return this._toolCache.getTools(serverId);
591
+ getTools(serverName, serverIndex) {
592
+ return this._toolCache.getTools(serverName, serverIndex);
556
593
  }
557
594
  /**
558
595
  * Retrieves cached resources for a specific server instance.
@@ -562,19 +599,21 @@ export class McpConnectionManager {
562
599
  * support resources, or if the server doesn't provide any resources. The method
563
600
  * includes logging for debugging purposes.
564
601
  *
565
- * @param {string} serverId - Unique identifier of the server instance
602
+ * @param {string} serverName - Server name
603
+ * @param {number} serverIndex - Instance index
566
604
  * @returns {Resource[]} Array of cached resources, empty if none available
567
605
  *
568
606
  * @example
569
607
  * ```typescript
570
- * const resources = manager.getResources('my-server-1');
608
+ * const resources = manager.getResources('my-server', 0);
571
609
  * console.log(`Server has ${resources.length} resources`);
572
610
  * ```
573
611
  */
574
- getResources(serverId) {
575
- const resources = this.resourceCache.get(serverId) || [];
576
- const fromCache = this.resourceCache.has(serverId);
577
- logger.debug(`getResources for [${serverId}]: returned ${resources.length} resources (${fromCache ? 'from cache' : 'no cache'})`, LOG_MODULES.CONNECTION_MANAGER);
612
+ getResources(serverName, serverIndex) {
613
+ const compositeKey = getCompositeKey(serverName, serverIndex);
614
+ const resources = this.resourceCache.get(compositeKey) || [];
615
+ const fromCache = this.resourceCache.has(compositeKey);
616
+ logger.debug(`getResources for [${compositeKey}]: returned ${resources.length} resources (${fromCache ? 'from cache' : 'no cache'})`, LOG_MODULES.CONNECTION_MANAGER);
578
617
  return resources;
579
618
  }
580
619
  /**
@@ -583,21 +622,23 @@ export class McpConnectionManager {
583
622
  * This method delegates the resource reading operation to the underlying MCP client,
584
623
  * providing direct access to server-provided resources through their URIs.
585
624
  *
586
- * @param {string} serverId - Unique identifier of the connected server instance
625
+ * @param {string} serverName - Server name
626
+ * @param {number} serverIndex - Instance index
587
627
  * @param {string} uri - Resource URI to read (e.g., "file:///path/to/file")
588
628
  * @returns {Promise<unknown>} Resource content as returned by the server
589
629
  * @throws {Error} If the server is not connected or resource reading fails
590
630
  *
591
631
  * @example
592
632
  * ```typescript
593
- * const content = await manager.readResource('my-server-1', 'hub://config/settings.json');
633
+ * const content = await manager.readResource('my-server', 0, 'hub://config/settings.json');
594
634
  * console.log('Resource content:', content);
595
635
  * ```
596
636
  */
597
- async readResource(serverId, uri) {
598
- const client = this.clients.get(serverId);
637
+ async readResource(serverName, serverIndex, uri) {
638
+ const compositeKey = getCompositeKey(serverName, serverIndex);
639
+ const client = this.clients.get(compositeKey);
599
640
  if (!client) {
600
- throw new Error(`Server ${serverId} not connected`);
641
+ throw new Error(`Server ${compositeKey} not connected`);
601
642
  }
602
643
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
603
644
  return client.readResource({ uri });
@@ -605,7 +646,7 @@ export class McpConnectionManager {
605
646
  /**
606
647
  * Retrieves all cached tools from all connected server instances.
607
648
  *
608
- * This method aggregates tools from all server ID-level caches into a single array,
649
+ * This method aggregates tools from all composite key-level caches into a single array,
609
650
  * providing a unified view of all available tools across all connected servers.
610
651
  * The returned tools include server context information for proper identification.
611
652
  *
@@ -621,18 +662,18 @@ export class McpConnectionManager {
621
662
  return this._toolCache.getAllTools();
622
663
  }
623
664
  /**
624
- * Retrieves all tool cache entries as server ID to tools mapping.
665
+ * Retrieves all tool cache entries as composite key to tools mapping.
625
666
  *
626
- * This method returns the raw tool cache structure as an array of [serverId, tools] tuples,
667
+ * This method returns the raw tool cache structure as an array of [compositeKey, tools] tuples,
627
668
  * providing direct access to the internal caching mechanism for debugging or advanced use cases.
628
669
  *
629
- * @returns {[string, Tool[]][]} Array of [serverId, tools] tuples representing the cache
670
+ * @returns {[string, Tool[]][]} Array of [compositeKey, tools] tuples representing the cache
630
671
  *
631
672
  * @example
632
673
  * ```typescript
633
674
  * const cacheEntries = manager.getToolCacheEntries();
634
- * cacheEntries.forEach(([serverId, tools]) => {
635
- * console.log(`Server ${serverId} has ${tools.length} tools`);
675
+ * cacheEntries.forEach(([compositeKey, tools]) => {
676
+ * console.log(`Server ${compositeKey} has ${tools.length} tools`);
636
677
  * });
637
678
  * ```
638
679
  */
@@ -640,112 +681,97 @@ export class McpConnectionManager {
640
681
  return this._toolCache.getToolCacheEntries();
641
682
  }
642
683
  /**
643
- * Resolves a server name to its corresponding server instance ID.
684
+ * Resolves a server name to its corresponding composite key for a specific instance index.
644
685
  *
645
- * This method provides reverse lookup from server names (as defined in configuration)
646
- * to the unique server instance IDs used internally for connection management.
647
- * It's useful when you have a server name but need the instance ID for operations.
686
+ * This method provides lookup from server names (as defined in configuration)
687
+ * to composite keys used internally for connection management.
648
688
  *
649
689
  * @param {string} name - Server name as defined in the configuration
650
- * @returns {string | undefined} Corresponding server instance ID or undefined if not found
690
+ * @param {number} index - Instance index
691
+ * @returns {string | undefined} Corresponding composite key or undefined if not found
651
692
  *
652
693
  * @example
653
694
  * ```typescript
654
- * const serverId = manager.getServerIdByName('my-mcp-server');
655
- * if (serverId) {
656
- * const status = manager.getStatus(serverId);
695
+ * const compositeKey = manager.getCompositeKeyByName('my-mcp-server', 0);
696
+ * if (compositeKey) {
697
+ * const status = manager.getStatus(compositeKey);
657
698
  * }
658
699
  * ```
659
700
  */
660
- getServerIdByName(name) {
661
- return this._toolCache.getServerIdByName(name);
701
+ getCompositeKeyByName(name, index) {
702
+ const compositeKey = getCompositeKey(name, index);
703
+ if (this.clients.has(compositeKey)) {
704
+ return compositeKey;
705
+ }
706
+ return undefined;
662
707
  }
663
708
  /**
664
- * Retrieves the MCP client instance for a server by its name.
709
+ * Retrieves the MCP client instance for a server by its name and index.
665
710
  *
666
- * This method resolves a server name to its instance ID and returns the corresponding
711
+ * This method resolves a composite key and returns the corresponding
667
712
  * MCP client instance, providing direct access to the underlying SDK client for
668
713
  * advanced operations that aren't covered by the manager's high-level methods.
669
714
  *
670
715
  * @param {string} name - Server name as defined in the configuration
716
+ * @param {number} index - Instance index
671
717
  * @returns {Client | undefined} MCP client instance or undefined if not connected
672
718
  *
673
719
  * @example
674
720
  * ```typescript
675
- * const client = manager.getClientByName('my-mcp-server');
721
+ * const client = manager.getClient('my-mcp-server', 0);
676
722
  * if (client) {
677
723
  * // Use direct client methods for advanced operations
678
724
  * const result = await client.listPrompts();
679
725
  * }
680
726
  * ```
681
727
  */
682
- getClientByName(name) {
683
- const serverId = this._toolCache.getServerIdByName(name);
684
- if (!serverId) {
685
- return undefined;
686
- }
687
- return this.clients.get(serverId);
728
+ getClient(name, index) {
729
+ const compositeKey = getCompositeKey(name, index);
730
+ return this.clients.get(compositeKey);
688
731
  }
689
732
  /**
690
- * Calls a tool on a connected server using the server name instead of instance ID.
691
- *
692
- * This method provides a convenient way to execute tools when you have a server name
693
- * rather than an instance ID. It resolves the server name to its instance ID and
694
- * delegates to the callTool method for actual execution.
733
+ * Calls a tool on a connected server using the server name and index.
695
734
  *
696
735
  * The method is wrapped in OpenTelemetry tracing for observability and includes
697
736
  * comprehensive error handling with proper logging.
698
737
  *
699
- * @param {string} name - Server name as defined in the configuration
738
+ * @param {string} serverName - Server name
739
+ * @param {number} serverIndex - Instance index
700
740
  * @param {string} toolName - Name of the tool to execute
701
741
  * @param {Record<string, unknown>} args - Arguments to pass to the tool
702
742
  * @returns {Promise<unknown>} Tool execution result as returned by the server
703
- * @throws {Error} If server is not connected, not found, or tool execution fails
743
+ * @throws {Error} If server is not connected or tool execution fails
704
744
  *
705
745
  * @example
706
746
  * ```typescript
707
- * const result = await manager.callToolByName('my-mcp-server', 'list-files', {
747
+ * const result = await manager.callTool('my-server', 0, 'list-files', {
708
748
  * directory: '/home/user'
709
749
  * });
710
750
  * console.log('Tool result:', result);
711
751
  * ```
712
752
  */
713
- async callToolByName(name, toolName, args) {
714
- const serverId = this._toolCache.getServerIdByName(name);
715
- if (!serverId) {
716
- throw new Error(`Server ${name} not connected or not found`);
753
+ async callTool(serverName, serverIndex, toolName, args) {
754
+ const compositeKey = getCompositeKey(serverName, serverIndex);
755
+ const client = this.clients.get(compositeKey);
756
+ if (!client) {
757
+ throw new Error(`Server ${compositeKey} not connected`);
717
758
  }
718
- return this.callTool(serverId, toolName, args);
719
- }
720
- /**
721
- * Retrieves the connection status for a server using its name instead of instance ID.
722
- *
723
- * This method resolves a server name to its instance ID and returns the corresponding
724
- * server status, providing a convenient way to check server health when working with
725
- * server names rather than instance IDs.
726
- *
727
- * @param {string} name - Server name as defined in the configuration
728
- * @returns {ServerStatus | undefined} Current status object or undefined if not found/connected
729
- *
730
- * @example
731
- * ```typescript
732
- * const status = manager.getStatusByName('my-mcp-server');
733
- * if (status?.connected) {
734
- * console.log('Server is online');
735
- * }
736
- * ```
737
- */
738
- getStatusByName(name) {
739
- const serverId = this._toolCache.getServerIdByName(name);
740
- if (!serverId) {
741
- return undefined;
759
+ try {
760
+ const result = await client.callTool({
761
+ name: toolName,
762
+ arguments: args
763
+ });
764
+ return result;
765
+ }
766
+ catch (error) {
767
+ logger.error(`Failed to call tool ${toolName} on server [${compositeKey}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
768
+ throw error;
742
769
  }
743
- return this.serverStatus.get(serverId);
744
770
  }
745
771
  /**
746
772
  * Retrieves cached tools for a server using its name instead of instance ID.
747
773
  *
748
- * This method resolves a server name to its instance ID and returns the corresponding
774
+ * This method resolves a server name to its composite key and returns the corresponding
749
775
  * cached tool list, providing a convenient way to access tools when working with
750
776
  * server names rather than instance IDs.
751
777
  *
@@ -759,16 +785,12 @@ export class McpConnectionManager {
759
785
  * ```
760
786
  */
761
787
  getToolsByName(name) {
762
- const serverId = this._toolCache.getServerIdByName(name);
763
- if (!serverId) {
764
- return [];
765
- }
766
- return this._toolCache.getTools(serverId);
788
+ return this._toolCache.getToolsByServerName(name);
767
789
  }
768
790
  /**
769
791
  * Retrieves cached resources for a server using its name instead of instance ID.
770
792
  *
771
- * This method resolves a server name to its instance ID and returns the corresponding
793
+ * This method resolves a server name to its composite key and returns the corresponding
772
794
  * cached resource list, providing a convenient way to access resources when working with
773
795
  * server names rather than instance IDs.
774
796
  *
@@ -782,11 +804,17 @@ export class McpConnectionManager {
782
804
  * ```
783
805
  */
784
806
  getResourcesByName(name) {
785
- const serverId = this._toolCache.getServerIdByName(name);
786
- if (!serverId) {
807
+ // Aggregate resources from all instances of this server name
808
+ const compositeKeys = this.serverNameToCompositeKeys.get(name);
809
+ if (!compositeKeys) {
787
810
  return [];
788
811
  }
789
- return this.resourceCache.get(serverId) || [];
812
+ const allResources = [];
813
+ for (const compositeKey of compositeKeys) {
814
+ const resources = this.resourceCache.get(compositeKey) || [];
815
+ allResources.push(...resources);
816
+ }
817
+ return allResources;
790
818
  }
791
819
  /**
792
820
  * Retrieves a specific tool by name from a server's cached tools.
@@ -828,10 +856,8 @@ export class McpConnectionManager {
828
856
  */
829
857
  getAllResources() {
830
858
  const result = {};
831
- // Group resources by server name
832
- for (const [serverId, resources] of this.resourceCache.entries()) {
833
- // Find server name for this ID
834
- const serverName = this._toolCache.getServerNameById(serverId);
859
+ for (const [compositeKey, resources] of this.resourceCache.entries()) {
860
+ const { serverName } = parseCompositeKey(compositeKey);
835
861
  if (!result[serverName]) {
836
862
  result[serverName] = [];
837
863
  }
@@ -839,45 +865,6 @@ export class McpConnectionManager {
839
865
  }
840
866
  return result;
841
867
  }
842
- /**
843
- * Executes a tool on a connected MCP server using its instance ID.
844
- *
845
- * This is the primary method for executing tools on connected servers. It delegates
846
- * the actual execution to the underlying MCP client and includes comprehensive
847
- * error handling with proper logging. The method is wrapped in OpenTelemetry tracing
848
- * for observability and monitoring.
849
- *
850
- * @param {string} serverId - Unique identifier of the connected server instance
851
- * @param {string} toolName - Name of the tool to execute
852
- * @param {Record<string, unknown>} args - Arguments to pass to the tool
853
- * @returns {Promise<unknown>} Tool execution result as returned by the server
854
- * @throws {Error} If server is not connected or tool execution fails
855
- *
856
- * @example
857
- * ```typescript
858
- * const result = await manager.callTool('my-server-1', 'list-files', {
859
- * directory: '/home/user'
860
- * });
861
- * console.log('Tool result:', result);
862
- * ```
863
- */
864
- async callTool(serverId, toolName, args) {
865
- const client = this.clients.get(serverId);
866
- if (!client) {
867
- throw new Error(`Server ${serverId} not connected`);
868
- }
869
- try {
870
- const result = await client.callTool({
871
- name: toolName,
872
- arguments: args
873
- });
874
- return result;
875
- }
876
- catch (error) {
877
- logger.error(`Failed to call tool ${toolName} on server [${serverId}]:`, error, LOG_MODULES.CONNECTION_MANAGER);
878
- throw error;
879
- }
880
- }
881
868
  /**
882
869
  * Retrieves cached tools for a specific server name from the server name-level cache.
883
870
  *
@@ -897,6 +884,48 @@ export class McpConnectionManager {
897
884
  getToolsByServerName(serverName) {
898
885
  return this._toolCache.getToolsByServerName(serverName);
899
886
  }
887
+ /**
888
+ * Gets the status of the first connected instance for a server name.
889
+ * This is a backward compatibility method for code that expects getStatusByName.
890
+ *
891
+ * @param name - Server name
892
+ * @returns ServerStatus or undefined if not connected
893
+ */
894
+ getStatusByName(name) {
895
+ const compositeKeys = this.serverNameToCompositeKeys.get(name);
896
+ if (!compositeKeys || compositeKeys.size === 0) {
897
+ return undefined;
898
+ }
899
+ // Return status of the first connected instance
900
+ for (const compositeKey of compositeKeys) {
901
+ const status = this.serverStatus.get(compositeKey);
902
+ if (status?.connected) {
903
+ return status;
904
+ }
905
+ }
906
+ return undefined;
907
+ }
908
+ /**
909
+ * Gets the composite key of the first connected instance for a server name.
910
+ * This is a backward compatibility method for code that expects getServerIdByName.
911
+ *
912
+ * @param name - Server name
913
+ * @returns Composite key or undefined if no instance is connected
914
+ */
915
+ getServerIdByName(name) {
916
+ const compositeKeys = this.serverNameToCompositeKeys.get(name);
917
+ if (!compositeKeys || compositeKeys.size === 0) {
918
+ return undefined;
919
+ }
920
+ // Return the composite key of the first connected instance
921
+ for (const compositeKey of compositeKeys) {
922
+ const status = this.serverStatus.get(compositeKey);
923
+ if (status?.connected) {
924
+ return compositeKey;
925
+ }
926
+ }
927
+ return undefined;
928
+ }
900
929
  /**
901
930
  * Retrieves all cached tools from all servers using the server name-level cache.
902
931
  *
@@ -926,4 +955,20 @@ export class McpConnectionManager {
926
955
  return this._toolCache.internalToolCache;
927
956
  }
928
957
  }
958
+ /**
959
+ * Parses a composite key back into serverName and serverIndex
960
+ */
961
+ function parseCompositeKey(key) {
962
+ const lastDashIndex = key.lastIndexOf('-');
963
+ if (lastDashIndex === -1) {
964
+ return null;
965
+ }
966
+ const serverName = key.slice(0, lastDashIndex);
967
+ const serverIndexPart = key.slice(lastDashIndex + 1);
968
+ const serverIndex = parseInt(serverIndexPart, 10);
969
+ if (isNaN(serverIndex)) {
970
+ return null;
971
+ }
972
+ return { serverName, serverIndex };
973
+ }
929
974
  export const mcpConnectionManager = new McpConnectionManager();