@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,17 +1,157 @@
1
+ import { fileURLToPath } from 'url';
2
+ import { dirname, join } from 'path';
3
+ import fs from 'fs';
1
4
  import { hubManager } from '../hub-manager.service.js';
2
5
  import { mcpConnectionManager } from '../mcp-connection-manager.js';
3
- import { hasValidId, selectBestInstance } from './server-selector.js';
6
+ import { hasValidId, selectBestInstance, getServerDescription } from './server-selector.js';
7
+ /**
8
+ * Maps Hub URI to original MCP URI for resource forwarding.
9
+ * Key: Hub URI (e.g., "hub://servers/exa-ai/0/tools/list")
10
+ * Value: Original MCP URI (e.g., "exa://tools/list")
11
+ */
12
+ const hubToMcpUriMap = new Map();
13
+ /**
14
+ * Clears the Hub to MCP URI mapping.
15
+ * Should be called before regenerating resources.
16
+ */
17
+ export function clearHubToMcpUriMap() {
18
+ hubToMcpUriMap.clear();
19
+ }
20
+ /**
21
+ * Maps an MCP native URI to hub format.
22
+ * Example: "exa://tools/list" -> "hub://servers/exa-ai/0/tools/list"
23
+ * Also registers the mapping in hubToMcpUriMap for reverse lookup.
24
+ *
25
+ * @param serverName - The server name
26
+ * @param instanceIndex - The instance index
27
+ * @param mcpUri - The native MCP URI (e.g., "exa://tools/list")
28
+ * @returns The hub-formatted URI
29
+ */
30
+ function getMcpPathFromUri(mcpUri) {
31
+ return mcpUri.replace(/^[a-zA-Z][a-zA-Z0-9+.-]*:(\/\/)?/, '');
32
+ }
33
+ function mapMcpUriToHub(serverName, instanceIndex, mcpUri) {
34
+ // Remove the scheme prefix (e.g., "exa://" or "exa:")
35
+ const mcpPath = getMcpPathFromUri(mcpUri);
36
+ const hubUri = `hub://servers/${serverName}/${instanceIndex}/${mcpPath}`;
37
+ // Register mapping for reverse lookup in readResource
38
+ hubToMcpUriMap.set(hubUri, mcpUri);
39
+ return hubUri;
40
+ }
41
+ /**
42
+ * Restores a missing Hub -> MCP URI mapping by scanning the current instance resources.
43
+ */
44
+ function restoreMcpUriMapping(serverName, instanceIndex, _instanceId, mcpPath) {
45
+ const instanceResources = mcpConnectionManager.getResources(serverName, instanceIndex);
46
+ for (const resource of instanceResources) {
47
+ const originalUri = resource.uri;
48
+ if (typeof originalUri !== 'string') {
49
+ continue;
50
+ }
51
+ if (getMcpPathFromUri(originalUri) !== mcpPath) {
52
+ continue;
53
+ }
54
+ const hubUri = `hub://servers/${serverName}/${instanceIndex}/${mcpPath}`;
55
+ hubToMcpUriMap.set(hubUri, originalUri);
56
+ return originalUri;
57
+ }
58
+ return null;
59
+ }
60
+ /**
61
+ * Parses a hub URI and extracts components.
62
+ * Supports:
63
+ * - hub://servers/{name} - Server metadata
64
+ * - hub://servers/{name}/tools - Tools list
65
+ * - hub://servers/{name}/resources - Resources list
66
+ * - hub://servers/{name}/{instanceIndex}/{mcpPath} - MCP native resource forwarding
67
+ *
68
+ * @param uri - The hub URI to parse
69
+ * @returns Parsed components, 'unknown' if format is valid but resource type is unknown, or null if format is invalid
70
+ */
71
+ function parseHubUri(uri) {
72
+ if (!uri.startsWith('hub://')) {
73
+ return null;
74
+ }
75
+ const parts = uri.replace('hub://', '').split('/');
76
+ if (parts.length < 2 || parts[0] !== 'servers') {
77
+ return null;
78
+ }
79
+ const serverName = parts[1];
80
+ // hub://servers/{name} - no instance index
81
+ if (parts.length === 2) {
82
+ return { serverName };
83
+ }
84
+ // hub://servers/{name}/tools or hub://servers/{name}/resources
85
+ // These are list requests, not MCP forwarding
86
+ if (parts.length === 3) {
87
+ const resourceType = parts[2];
88
+ if (resourceType === 'tools' || resourceType === 'resources') {
89
+ return { serverName, listType: resourceType };
90
+ }
91
+ // Unknown resource type but valid URI format
92
+ return 'unknown';
93
+ }
94
+ // hub://servers/{name}/{instanceIndex}/{mcpPath}
95
+ const instanceIndex = parseInt(parts[2], 10);
96
+ if (isNaN(instanceIndex) || parts.length < 4) {
97
+ return null;
98
+ }
99
+ const mcpPath = parts.slice(3).join('/');
100
+ return { serverName, instanceIndex, mcpPath };
101
+ }
102
+ /**
103
+ * Path to the use guide Markdown file.
104
+ */
105
+ const __filename = fileURLToPath(import.meta.url);
106
+ const __dirname = dirname(__filename);
107
+ const USE_GUIDE_PATH = join(__dirname, 'use-guide.md');
108
+ /**
109
+ * Loads the use guide content from the Markdown file.
110
+ *
111
+ * @returns {string} Markdown formatted use guide content
112
+ */
113
+ function loadUseGuideContent() {
114
+ try {
115
+ return fs.readFileSync(USE_GUIDE_PATH, 'utf-8');
116
+ }
117
+ catch {
118
+ // Fallback in case the file can't be read
119
+ return `# MCP Hub Lite Use Guide
120
+
121
+ ## Overview
122
+
123
+ MCP Hub Lite is a lightweight MCP (Model Context Protocol) gateway that acts as a unified interface between AI assistants and multiple backend MCP servers.
124
+
125
+ ## Note
126
+
127
+ The complete use guide is currently unavailable. Please check the MCP Hub Lite documentation at https://github.com/your-org/mcp-hub-lite for more information.
128
+ `;
129
+ }
130
+ }
131
+ /**
132
+ * URI for the use guide resource.
133
+ */
134
+ export const USE_GUIDE_URI = 'hub://use-guide';
135
+ /**
136
+ * Name of the use guide resource.
137
+ */
138
+ export const USE_GUIDE_NAME = 'MCP Hub Lite Use Guide';
139
+ /**
140
+ * Description of the use guide resource.
141
+ */
142
+ export const USE_GUIDE_DESCRIPTION = 'Comprehensive guide to using MCP Hub Lite gateway and its features';
143
+ /**
144
+ * MIME type for the use guide resource.
145
+ */
146
+ export const USE_GUIDE_MIME_TYPE = 'text/markdown';
4
147
  /**
5
148
  * Generates dynamic Hub resources based on currently connected MCP servers.
6
149
  *
7
150
  * This method creates virtual resources that represent the current state of connected
8
- * servers, including server metadata, available tools, and server resources. Each
9
- * resource has a unique URI following the hub://servers/{serverName}[/type] pattern.
151
+ * servers. Each resource has a unique URI following the hub://servers/{serverName} pattern.
10
152
  *
11
153
  * The generated resources include:
12
154
  * - Server metadata: hub://servers/{serverName}
13
- * - Tools list: hub://servers/{serverName}/tools
14
- * - Resources list: hub://servers/{serverName}/resources (only if server has resources)
15
155
  *
16
156
  * @returns {Resource[]} Array of dynamically generated MCP resource objects
17
157
  *
@@ -23,46 +163,57 @@ import { hasValidId, selectBestInstance } from './server-selector.js';
23
163
  */
24
164
  export function generateDynamicResources() {
25
165
  const resources = [];
166
+ clearHubToMcpUriMap();
167
+ // Add use-guide resource first - it's always available
168
+ resources.push({
169
+ uri: USE_GUIDE_URI,
170
+ name: USE_GUIDE_NAME,
171
+ description: USE_GUIDE_DESCRIPTION,
172
+ mimeType: USE_GUIDE_MIME_TYPE
173
+ // System resources don't have serverName/serverIndex
174
+ });
26
175
  // Use the same access pattern as tools - directly access manager cache
27
176
  const servers = hubManager.getAllServers();
28
177
  for (const server of servers) {
29
- if (!hasValidId(server) || !server.config.enabled) {
178
+ if (!hasValidId(server)) {
30
179
  continue;
31
180
  }
32
- const bestInstance = selectBestInstance(server.name);
33
- if (!bestInstance || !bestInstance.instance.id) {
181
+ // Check if any instance is enabled
182
+ const hasEnabledInstance = server.config.instances.some((i) => i.enabled !== false);
183
+ if (!hasEnabledInstance) {
34
184
  continue;
35
185
  }
36
- const instanceId = bestInstance.instance.id;
37
- // Server metadata resource
38
- resources.push({
39
- uri: `hub://servers/${server.name}`,
40
- name: `Server: ${server.name}`,
41
- description: server.config.description || `Connected MCP server: ${server.name}`,
42
- mimeType: 'application/json',
43
- serverId: instanceId
44
- });
45
- // Tools resource - only add if server has tools
46
- const tools = mcpConnectionManager.getTools(instanceId);
47
- if (tools.length > 0) {
48
- resources.push({
49
- uri: `hub://servers/${server.name}/tools`,
50
- name: `Tools: ${server.name}`,
51
- description: `${tools.length} tools available from ${server.name}`,
52
- mimeType: 'application/json',
53
- serverId: instanceId
54
- });
55
- }
56
- // Resources resource - only add if server has resources
57
- const serverResources = mcpConnectionManager.getResources(instanceId);
58
- if (serverResources.length > 0) {
59
- resources.push({
60
- uri: `hub://servers/${server.name}/resources`,
61
- name: `Resources: ${server.name}`,
62
- description: `${serverResources.length} resources available from ${server.name}`,
63
- mimeType: 'application/json',
64
- serverId: instanceId
65
- });
186
+ // Iterate over all instances to expose each instance's resources
187
+ for (const instance of server.config.instances) {
188
+ if (instance.enabled === false) {
189
+ continue;
190
+ }
191
+ const instanceIndex = instance.index;
192
+ // Server metadata resource (one per server, not per instance)
193
+ if (instanceIndex === 0) {
194
+ resources.push({
195
+ uri: `hub://servers/${server.name}`,
196
+ name: `Server: ${server.name}`,
197
+ description: getServerDescription(server.config, server.name),
198
+ mimeType: 'application/json',
199
+ serverName: server.name,
200
+ serverIndex: instanceIndex
201
+ });
202
+ }
203
+ // Get MCP native resources and map to hub format
204
+ const instanceIdx = instanceIndex ?? 0;
205
+ const mcpResources = mcpConnectionManager.getResources(server.name, instanceIdx);
206
+ for (const res of mcpResources) {
207
+ // Format: Resource: {ServerName} - {Index}: {Native Name}
208
+ const displayName = `Resource:${server.name} - ${instanceIdx}:${res.name}`;
209
+ resources.push({
210
+ uri: mapMcpUriToHub(server.name, instanceIdx, res.uri),
211
+ name: displayName,
212
+ description: res.description,
213
+ mimeType: res.mimeType
214
+ // No serverId - instanceIndex is embedded in the URI
215
+ });
216
+ }
66
217
  }
67
218
  }
68
219
  return resources;
@@ -98,44 +249,88 @@ export async function readResource(uri) {
98
249
  if (!uri.startsWith('hub://')) {
99
250
  throw new Error(`Invalid Hub resource URI: ${uri}. Must start with 'hub://'`);
100
251
  }
252
+ // Check for use-guide resource first
253
+ if (uri === USE_GUIDE_URI) {
254
+ return loadUseGuideContent();
255
+ }
101
256
  // Parse URI
102
- const uriParts = uri.replace('hub://', '').split('/');
103
- if (uriParts.length < 2 || uriParts[0] !== 'servers') {
257
+ const parsed = parseHubUri(uri);
258
+ if (!parsed) {
104
259
  throw new Error(`Invalid Hub resource URI format: ${uri}`);
105
260
  }
106
- const serverName = uriParts[1];
107
- const resourceType = uriParts[2]; // 'tools', 'resources', or undefined for server metadata
108
- // Check if server exists and is connected
109
- const serverInfo = selectBestInstance(serverName);
110
- if (!serverInfo) {
111
- throw new Error(`Server not found or not connected: ${serverName}`);
112
- }
113
- const instanceId = serverInfo.instance.id;
114
- // Return appropriate content based on resource type
115
- if (!resourceType) {
116
- // Server metadata
117
- const serverConfig = hubManager.getServerByName(serverName);
118
- const tools = mcpConnectionManager.getTools(instanceId);
119
- const resources = mcpConnectionManager.getResources(instanceId);
261
+ // Handle unknown resource type
262
+ if (parsed === 'unknown') {
263
+ const parts = uri.replace('hub://', '').split('/');
264
+ const resourceType = parts[2];
265
+ throw new Error(`Unknown resource type: ${resourceType}`);
266
+ }
267
+ const { serverName, instanceIndex, mcpPath, listType } = parsed;
268
+ // Find server config
269
+ const serverConfig = hubManager.getServerByName(serverName);
270
+ if (!serverConfig) {
271
+ throw new Error(`Server not found: ${serverName}`);
272
+ }
273
+ // If no instanceIndex, check if this is a list request or metadata request
274
+ if (instanceIndex === undefined) {
275
+ // Handle list requests first
276
+ if (listType) {
277
+ // Use selectBestInstance to get an instance for the list
278
+ const serverInfo = selectBestInstance(serverName);
279
+ if (!serverInfo) {
280
+ throw new Error(`Server not found or not connected: ${serverName}`);
281
+ }
282
+ const instanceIndex = serverInfo.instance.index;
283
+ if (listType === 'tools') {
284
+ return mcpConnectionManager.getTools(serverName, instanceIndex);
285
+ }
286
+ else {
287
+ return mcpConnectionManager.getResources(serverName, instanceIndex);
288
+ }
289
+ }
290
+ // Server metadata request - use selectBestInstance to get runtime properties
291
+ const serverInfo = selectBestInstance(serverName);
292
+ if (!serverInfo) {
293
+ throw new Error(`Server not found or not connected: ${serverName}`);
294
+ }
295
+ const instanceIndex = serverInfo.instance.index;
296
+ const tools = mcpConnectionManager.getTools(serverName, instanceIndex);
297
+ const resources = mcpConnectionManager.getResources(serverName, instanceIndex);
298
+ // Build tool name to description map
299
+ const toolsMap = {};
300
+ for (const tool of tools) {
301
+ toolsMap[tool.name] = tool.description || '';
302
+ }
120
303
  return {
121
304
  name: serverName,
122
305
  status: serverInfo.instance.status,
123
306
  toolsCount: tools.length,
307
+ tools: toolsMap,
124
308
  resourcesCount: resources.length,
125
- tags: serverConfig?.tags || {},
309
+ tags: serverInfo.instance.tags || {},
126
310
  lastHeartbeat: serverInfo.instance.lastHeartbeat,
127
- uptime: serverInfo.instance.uptime
311
+ uptime: serverInfo.instance.uptime,
312
+ description: getServerDescription(serverConfig, serverName)
128
313
  };
129
314
  }
130
- else if (resourceType === 'tools') {
131
- // Tools list
132
- return mcpConnectionManager.getTools(instanceId);
315
+ // MCP native resource forwarding: hub://servers/{name}/{instanceIndex}/{mcpPath}
316
+ // Find the specific instance by index
317
+ const targetInstance = serverConfig.instances.find((i) => i.index === instanceIndex && i.enabled !== false);
318
+ if (!targetInstance) {
319
+ throw new Error(`Instance ${instanceIndex} not found or not enabled for server: ${serverName}`);
133
320
  }
134
- else if (resourceType === 'resources') {
135
- // Resources list
136
- return mcpConnectionManager.getResources(instanceId);
321
+ const instanceId = targetInstance.id;
322
+ // If mcpPath is empty, return instance-level info
323
+ if (!mcpPath) {
324
+ return mcpConnectionManager.getResources(serverName, instanceIndex);
137
325
  }
138
- else {
139
- throw new Error(`Unknown resource type: ${resourceType}`);
326
+ // Forward to MCP server for actual resource read
327
+ // Use the mapping to get the original MCP URI (hub://servers/exa-ai/0/tools/list -> exa://tools/list)
328
+ let originalMcpUri = hubToMcpUriMap.get(uri);
329
+ if (!originalMcpUri) {
330
+ originalMcpUri = restoreMcpUriMapping(serverName, instanceIndex, instanceId, mcpPath);
331
+ }
332
+ if (!originalMcpUri) {
333
+ throw new Error(`MCP URI not found in mapping for: ${uri}`);
140
334
  }
335
+ return mcpConnectionManager.readResource(serverName, instanceIndex, originalMcpUri);
141
336
  }
@@ -1,4 +1,16 @@
1
1
  import type { RequestOptions, ServerInstanceInfo, ValidServer } from './types.js';
2
+ /**
3
+ * Gets the description for a server, using a default if none is provided.
4
+ *
5
+ * @param serverConfig - Server configuration object (may contain description in template)
6
+ * @param serverName - Name of the server
7
+ * @returns The server description or a default one
8
+ */
9
+ export declare function getServerDescription(serverConfig: {
10
+ template?: {
11
+ description?: string;
12
+ };
13
+ } | undefined, serverName: string): string;
2
14
  /**
3
15
  * Type guard to validate that a server object has valid name and configuration.
4
16
  *
@@ -22,26 +34,24 @@ export declare function hasValidId(server: unknown): server is ValidServer;
22
34
  * Selects the best server instance based on server name and request options.
23
35
  *
24
36
  * This function resolves a server name to its configuration and instance details,
25
- * handling both single and multiple instance scenarios. Currently, it returns
26
- * the first instance for multi-instance servers, but the architecture supports
27
- * future extensions for intelligent instance selection based on session ID,
28
- * tags, client ID, or load conditions.
37
+ * handling both single and multiple instance scenarios using configurable instance
38
+ * selection strategies (random, round-robin, tag-match-unique).
29
39
  *
30
40
  * The function performs the following steps:
31
41
  * 1. Retrieves all instances of the specified server name
32
42
  * 2. Returns undefined if no instances are found
33
43
  * 3. Gets the server configuration from the hub manager
34
- * 4. For single-instance servers, returns the instance directly
35
- * 5. For multi-instance servers, currently returns the first instance (with future extension support)
44
+ * 4. Uses InstanceSelector to choose the best instance based on configured strategy
45
+ * 5. Handles errors based on the strictMode parameter
36
46
  *
37
- * Future extensions planned include:
38
- * - Session-aware instance selection based on sessionId
39
- * - Tag-based instance selection for matching specific requirements
40
- * - Load-balancing across multiple instances
41
- * - Client-specific instance assignment
47
+ * Supported instance selection strategies:
48
+ * - random: Randomly selects from enabled instances
49
+ * - round-robin: Cycles through enabled instances in order
50
+ * - tag-match-unique: Selects instance that uniquely matches request tags
42
51
  *
43
52
  * @param {string} serverName - Name of the server to select an instance for
44
53
  * @param {RequestOptions} [requestOptions] - Optional request options for instance selection
54
+ * @param {boolean} [strictMode=true] - Whether to throw errors for tag-match-unique failures (default: true)
45
55
  * @returns {{ name: string; config: ServerConfig; instance: ServerInstanceConfig & Record<string, unknown> } | undefined}
46
56
  * Server information with configuration and instance details, or undefined if not found
47
57
  *
@@ -52,12 +62,15 @@ export declare function hasValidId(server: unknown): server is ValidServer;
52
62
  * console.log(`Selected instance: ${serverInfo.instance.id}`);
53
63
  * }
54
64
  *
55
- * // With request options (future extension)
65
+ * // With request options for tag matching
56
66
  * const serverInfoWithOptions = selectBestInstance('my-mcp-server', {
57
67
  * sessionId: 'session-123',
58
68
  * tags: { environment: 'production' }
59
69
  * });
70
+ *
71
+ * // Non-strict mode for management operations
72
+ * const serverInfoNonStrict = selectBestInstance('my-mcp-server', undefined, false);
60
73
  * ```
61
74
  */
62
- export declare function selectBestInstance(serverName: string, requestOptions?: RequestOptions): ServerInstanceInfo | undefined;
75
+ export declare function selectBestInstance(serverName: string, requestOptions?: RequestOptions, strictMode?: boolean): ServerInstanceInfo | undefined;
63
76
  //# sourceMappingURL=server-selector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"server-selector.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/server-selector.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,WAAW,CAMjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,cAAc,GAC9B,kBAAkB,GAAG,SAAS,CA+ChC"}
1
+ {"version":3,"file":"server-selector.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/server-selector.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,YAAY,EAAE;IAAE,QAAQ,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,SAAS,EACjE,UAAU,EAAE,MAAM,GACjB,MAAM,CAER;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,IAAI,WAAW,CAMjE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,cAAc,CAAC,EAAE,cAAc,EAC/B,UAAU,GAAE,OAAc,GACzB,kBAAkB,GAAG,SAAS,CA8ChC"}
@@ -1,4 +1,17 @@
1
1
  import { hubManager } from '../hub-manager.service.js';
2
+ import { InstanceSelector, TagMatchUniqueError } from './instance-selector.js';
3
+ import { logger } from '../../utils/logger.js';
4
+ import { LOG_MODULES } from '../../utils/logger/log-modules.js';
5
+ /**
6
+ * Gets the description for a server, using a default if none is provided.
7
+ *
8
+ * @param serverConfig - Server configuration object (may contain description in template)
9
+ * @param serverName - Name of the server
10
+ * @returns The server description or a default one
11
+ */
12
+ export function getServerDescription(serverConfig, serverName) {
13
+ return serverConfig?.template?.description || `Connected MCP server: ${serverName}`;
14
+ }
2
15
  /**
3
16
  * Type guard to validate that a server object has valid name and configuration.
4
17
  *
@@ -28,26 +41,24 @@ export function hasValidId(server) {
28
41
  * Selects the best server instance based on server name and request options.
29
42
  *
30
43
  * This function resolves a server name to its configuration and instance details,
31
- * handling both single and multiple instance scenarios. Currently, it returns
32
- * the first instance for multi-instance servers, but the architecture supports
33
- * future extensions for intelligent instance selection based on session ID,
34
- * tags, client ID, or load conditions.
44
+ * handling both single and multiple instance scenarios using configurable instance
45
+ * selection strategies (random, round-robin, tag-match-unique).
35
46
  *
36
47
  * The function performs the following steps:
37
48
  * 1. Retrieves all instances of the specified server name
38
49
  * 2. Returns undefined if no instances are found
39
50
  * 3. Gets the server configuration from the hub manager
40
- * 4. For single-instance servers, returns the instance directly
41
- * 5. For multi-instance servers, currently returns the first instance (with future extension support)
51
+ * 4. Uses InstanceSelector to choose the best instance based on configured strategy
52
+ * 5. Handles errors based on the strictMode parameter
42
53
  *
43
- * Future extensions planned include:
44
- * - Session-aware instance selection based on sessionId
45
- * - Tag-based instance selection for matching specific requirements
46
- * - Load-balancing across multiple instances
47
- * - Client-specific instance assignment
54
+ * Supported instance selection strategies:
55
+ * - random: Randomly selects from enabled instances
56
+ * - round-robin: Cycles through enabled instances in order
57
+ * - tag-match-unique: Selects instance that uniquely matches request tags
48
58
  *
49
59
  * @param {string} serverName - Name of the server to select an instance for
50
60
  * @param {RequestOptions} [requestOptions] - Optional request options for instance selection
61
+ * @param {boolean} [strictMode=true] - Whether to throw errors for tag-match-unique failures (default: true)
51
62
  * @returns {{ name: string; config: ServerConfig; instance: ServerInstanceConfig & Record<string, unknown> } | undefined}
52
63
  * Server information with configuration and instance details, or undefined if not found
53
64
  *
@@ -58,16 +69,19 @@ export function hasValidId(server) {
58
69
  * console.log(`Selected instance: ${serverInfo.instance.id}`);
59
70
  * }
60
71
  *
61
- * // With request options (future extension)
72
+ * // With request options for tag matching
62
73
  * const serverInfoWithOptions = selectBestInstance('my-mcp-server', {
63
74
  * sessionId: 'session-123',
64
75
  * tags: { environment: 'production' }
65
76
  * });
77
+ *
78
+ * // Non-strict mode for management operations
79
+ * const serverInfoNonStrict = selectBestInstance('my-mcp-server', undefined, false);
66
80
  * ```
67
81
  */
68
- export function selectBestInstance(serverName, requestOptions) {
82
+ export function selectBestInstance(serverName, requestOptions, strictMode = true) {
69
83
  // Get all instances of the server
70
- const instances = hubManager.getServerInstanceByName(serverName);
84
+ const instances = hubManager.getServerInstancesByName(serverName);
71
85
  if (instances.length === 0) {
72
86
  return undefined;
73
87
  }
@@ -76,33 +90,26 @@ export function selectBestInstance(serverName, requestOptions) {
76
90
  if (!serverConfig) {
77
91
  return undefined;
78
92
  }
79
- // If there's only one instance, return it directly
80
- if (instances.length === 1) {
93
+ try {
94
+ // Use the new instance selector
95
+ const selectedInstance = InstanceSelector.selectInstance(serverName, serverConfig, requestOptions);
96
+ if (!selectedInstance) {
97
+ return undefined;
98
+ }
81
99
  return {
82
100
  name: serverName,
83
101
  config: serverConfig,
84
- instance: instances[0]
102
+ instance: selectedInstance
85
103
  };
86
104
  }
87
- // Multi-instance selection logic (for future extension)
88
- // Currently simplified implementation: return the first instance
89
- // Future extensions could support:
90
- // - Selecting specific instance based on sessionId
91
- // - Selecting optimal instance based on tags matching
92
- // - Selecting dedicated instance based on client ID
93
- // - Selecting instance based on load conditions
94
- // Although requestOptions is not currently used, it's kept for future extension
95
- if (requestOptions?.sessionId) {
96
- // In the future, specific instance can be selected based on sessionId
97
- // Currently return the first instance temporarily
98
- }
99
- if (requestOptions?.tags) {
100
- // In the future, optimal instance can be selected based on tags matching
101
- // Currently return the first instance temporarily
105
+ catch (error) {
106
+ // In strict mode, re-throw tag matching errors to maintain correct semantics
107
+ if (strictMode && error instanceof TagMatchUniqueError) {
108
+ // Re-throw with server context added to message
109
+ throw new Error(`[${serverName}] ${error.message}`);
110
+ }
111
+ // Handle other errors or non-strict mode gracefully
112
+ logger.error(`Instance selection failed for server ${serverName}:`, error, LOG_MODULES.SERVER_SELECTOR);
113
+ return undefined;
102
114
  }
103
- return {
104
- name: serverName,
105
- config: serverConfig,
106
- instance: instances[0] // Will be extended to intelligent selection logic later
107
- };
108
115
  }
@@ -27,12 +27,9 @@ export interface SystemToolDefinition {
27
27
  *
28
28
  * The method implements all standard system tools:
29
29
  * - list-servers: List all connected servers
30
- * - find-servers: Find servers matching a pattern
31
- * - list-all-tools-in-server: List tools from a specific server
32
- * - find-tools-in-server: Find tools in a specific server
30
+ * - list-tools-in-server: List tools from a specific server
33
31
  * - get-tool: Get complete tool schema
34
32
  * - call-tool: Call a specific tool from a specific server
35
- * - find-tools: Find tools across all servers
36
33
  *
37
34
  * @returns {Array<{ name: string; description: string; inputSchema: JsonSchema; annotations?: ToolAnnotations }>}
38
35
  * Array of system tool configurations
@@ -1 +1 @@
1
- {"version":3,"file":"system-tool-definitions.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/system-tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAY/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,EAAE,CAwMvD"}
1
+ {"version":3,"file":"system-tool-definitions.d.ts","sourceRoot":"","sources":["../../../../../src/services/hub-tools/system-tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAU/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,UAAU,CAAC;IACxB,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,EAAE,CA6IvD"}