@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
@@ -11,131 +11,325 @@ describe('HubToolsService', () => {
11
11
  hubToolsService = new HubToolsService();
12
12
  // Clear mock calls between tests to avoid state pollution
13
13
  vi.clearAllMocks();
14
+ // Clear the generated resources cache
15
+ hubToolsService.generatedResourcesCache =
16
+ null;
14
17
  });
15
18
  describe('listServers', () => {
16
- it('should return array of server names only', async () => {
19
+ it('should return Record of server names to descriptions', async () => {
17
20
  // Arrange
18
21
  const mockServers = [
19
22
  {
20
23
  name: 'Test Server 1',
21
24
  config: {
22
- type: 'stdio',
23
- command: 'test-command',
24
- args: [],
25
- enabled: true,
26
- allowedTools: [],
27
- timeout: 30000
25
+ template: {
26
+ type: 'stdio',
27
+ command: 'test-command',
28
+ args: [],
29
+ env: {},
30
+ headers: {},
31
+ aggregatedTools: [],
32
+ timeout: 30000,
33
+ description: 'File system operations',
34
+ tags: {}
35
+ },
36
+ instances: [
37
+ {
38
+ id: 'test-server-1-instance',
39
+ enabled: true,
40
+ args: [],
41
+ env: {},
42
+ headers: {},
43
+ tags: {}
44
+ }
45
+ ],
46
+ tagDefinitions: []
28
47
  }
29
48
  },
30
49
  {
31
50
  name: 'Test Server 2',
32
51
  config: {
33
- type: 'sse',
34
- url: 'http://example.com',
35
- args: [],
36
- enabled: true,
37
- allowedTools: [],
38
- timeout: 30000
52
+ template: {
53
+ type: 'sse',
54
+ url: 'http://example.com',
55
+ args: [],
56
+ env: {},
57
+ headers: {},
58
+ aggregatedTools: [],
59
+ timeout: 30000,
60
+ tags: {}
61
+ },
62
+ instances: [
63
+ {
64
+ id: 'test-server-2-instance',
65
+ enabled: true,
66
+ args: [],
67
+ env: {},
68
+ headers: {},
69
+ tags: {}
70
+ }
71
+ ],
72
+ tagDefinitions: []
39
73
  }
40
74
  }
41
75
  ];
42
76
  vi.mocked(hubManager.getAllServers).mockReturnValue(mockServers);
77
+ vi.mocked(hubManager.getServerInstancesByName).mockImplementation((name) => {
78
+ const server = mockServers.find((s) => s.name === name);
79
+ return server?.config.instances || [];
80
+ });
81
+ vi.mocked(hubManager.getServerByName).mockImplementation((name) => {
82
+ const server = mockServers.find((s) => s.name === name);
83
+ return server?.config;
84
+ });
85
+ vi.mocked(mcpConnectionManager.getStatusByName).mockImplementation(() => {
86
+ return {
87
+ connected: true,
88
+ lastCheck: Date.now(),
89
+ toolsCount: 0,
90
+ resourcesCount: 0
91
+ };
92
+ });
43
93
  // Act
44
94
  const servers = await hubToolsService.listServers();
45
95
  // Assert
46
- expect(servers).toEqual(['Test Server 1', 'Test Server 2']);
96
+ expect(servers).toEqual({
97
+ 'Test Server 1': 'File system operations',
98
+ 'Test Server 2': 'Connected MCP server: Test Server 2'
99
+ });
47
100
  expect(hubManager.getAllServers).toHaveBeenCalledTimes(1);
48
101
  });
49
- });
50
- describe('findServers', () => {
51
- it('should find servers matching name pattern (case-insensitive)', async () => {
102
+ it('should use default description when server has no description', async () => {
52
103
  // Arrange
53
104
  const mockServers = [
54
105
  {
55
- name: 'Test Server 1',
106
+ name: 'server1',
56
107
  config: {
57
- type: 'stdio',
58
- command: 'test-command',
59
- args: [],
60
- enabled: true,
61
- allowedTools: [],
62
- timeout: 30000
108
+ template: {
109
+ type: 'stdio',
110
+ command: 'test-command',
111
+ args: [],
112
+ env: {},
113
+ headers: {},
114
+ aggregatedTools: [],
115
+ timeout: 30000,
116
+ tags: {}
117
+ },
118
+ instances: [
119
+ {
120
+ id: 'server1-instance',
121
+ enabled: true,
122
+ args: [],
123
+ env: {},
124
+ headers: {},
125
+ tags: {}
126
+ }
127
+ ],
128
+ tagDefinitions: []
63
129
  }
64
- },
130
+ }
131
+ ];
132
+ vi.mocked(hubManager.getAllServers).mockReturnValue(mockServers);
133
+ vi.mocked(hubManager.getServerInstancesByName).mockImplementation((name) => {
134
+ const server = mockServers.find((s) => s.name === name);
135
+ return server?.config.instances || [];
136
+ });
137
+ vi.mocked(hubManager.getServerByName).mockImplementation((name) => {
138
+ const server = mockServers.find((s) => s.name === name);
139
+ return server?.config;
140
+ });
141
+ vi.mocked(mcpConnectionManager.getStatusByName).mockImplementation(() => {
142
+ return {
143
+ connected: true,
144
+ lastCheck: Date.now(),
145
+ toolsCount: 0,
146
+ resourcesCount: 0
147
+ };
148
+ });
149
+ // Act
150
+ const servers = await hubToolsService.listServers();
151
+ // Assert
152
+ expect(servers).toEqual({
153
+ server1: 'Connected MCP server: server1'
154
+ });
155
+ });
156
+ it('should use provided description when available', async () => {
157
+ // Arrange
158
+ const mockServers = [
65
159
  {
66
- name: 'Production Server',
160
+ name: 'filesystem',
67
161
  config: {
68
- type: 'sse',
69
- url: 'http://example.com',
70
- args: [],
71
- enabled: true,
72
- allowedTools: [],
73
- timeout: 30000
162
+ template: {
163
+ type: 'stdio',
164
+ command: 'test-command',
165
+ args: [],
166
+ env: {},
167
+ headers: {},
168
+ aggregatedTools: [],
169
+ timeout: 30000,
170
+ description: 'File system operations',
171
+ tags: {}
172
+ },
173
+ instances: [
174
+ {
175
+ id: 'filesystem-instance',
176
+ enabled: true,
177
+ args: [],
178
+ env: {},
179
+ headers: {},
180
+ tags: {}
181
+ }
182
+ ],
183
+ tagDefinitions: []
74
184
  }
75
185
  },
76
186
  {
77
- name: 'Development Server',
187
+ name: 'time',
78
188
  config: {
79
- type: 'http',
80
- url: 'http://dev.example.com',
81
- args: [],
82
- enabled: true,
83
- allowedTools: [],
84
- timeout: 30000
189
+ template: {
190
+ type: 'sse',
191
+ url: 'http://example.com',
192
+ args: [],
193
+ env: {},
194
+ headers: {},
195
+ aggregatedTools: [],
196
+ timeout: 30000,
197
+ description: 'Time and timezone utilities',
198
+ tags: {}
199
+ },
200
+ instances: [
201
+ {
202
+ id: 'time-instance',
203
+ enabled: true,
204
+ args: [],
205
+ env: {},
206
+ headers: {},
207
+ tags: {}
208
+ }
209
+ ],
210
+ tagDefinitions: []
85
211
  }
86
212
  }
87
213
  ];
88
214
  vi.mocked(hubManager.getAllServers).mockReturnValue(mockServers);
89
- // Act
90
- const results = await hubToolsService.findServers({
91
- pattern: 'server',
92
- searchIn: 'name',
93
- caseSensitive: false
215
+ vi.mocked(hubManager.getServerInstancesByName).mockImplementation((name) => {
216
+ const server = mockServers.find((s) => s.name === name);
217
+ return server?.config.instances || [];
218
+ });
219
+ vi.mocked(hubManager.getServerByName).mockImplementation((name) => {
220
+ const server = mockServers.find((s) => s.name === name);
221
+ return server?.config;
94
222
  });
223
+ vi.mocked(mcpConnectionManager.getStatusByName).mockImplementation(() => {
224
+ return {
225
+ connected: true,
226
+ lastCheck: Date.now(),
227
+ toolsCount: 0,
228
+ resourcesCount: 0
229
+ };
230
+ });
231
+ // Act
232
+ const servers = await hubToolsService.listServers();
95
233
  // Assert
96
- expect(results).toEqual(['Test Server 1', 'Production Server', 'Development Server']);
97
- expect(hubManager.getAllServers).toHaveBeenCalledTimes(1);
234
+ expect(servers).toEqual({
235
+ filesystem: 'File system operations',
236
+ time: 'Time and timezone utilities'
237
+ });
98
238
  });
99
- it('should find servers matching name pattern (case-sensitive)', async () => {
239
+ it('should only include connected servers in the result', async () => {
100
240
  // Arrange
101
241
  const mockServers = [
102
242
  {
103
- name: 'Test Server 1',
243
+ name: 'Connected Server',
104
244
  config: {
105
- type: 'stdio',
106
- command: 'test-command',
107
- args: [],
108
- enabled: true,
109
- allowedTools: [],
110
- timeout: 30000
245
+ template: {
246
+ type: 'stdio',
247
+ command: 'test-command',
248
+ args: [],
249
+ env: {},
250
+ headers: {},
251
+ aggregatedTools: [],
252
+ timeout: 30000,
253
+ description: 'This server is connected',
254
+ tags: {}
255
+ },
256
+ instances: [
257
+ {
258
+ id: 'connected-server-instance',
259
+ enabled: true,
260
+ args: [],
261
+ env: {},
262
+ headers: {},
263
+ tags: {}
264
+ }
265
+ ],
266
+ tagDefinitions: []
111
267
  }
112
268
  },
113
269
  {
114
- name: 'production server',
270
+ name: 'Disconnected Server',
115
271
  config: {
116
- type: 'sse',
117
- url: 'http://example.com',
118
- args: [],
119
- enabled: true,
120
- allowedTools: [],
121
- timeout: 30000
272
+ template: {
273
+ type: 'sse',
274
+ url: 'http://example.com',
275
+ args: [],
276
+ env: {},
277
+ headers: {},
278
+ aggregatedTools: [],
279
+ timeout: 30000,
280
+ description: 'This server is disconnected',
281
+ tags: {}
282
+ },
283
+ instances: [
284
+ {
285
+ id: 'disconnected-server-instance',
286
+ enabled: true,
287
+ args: [],
288
+ env: {},
289
+ headers: {},
290
+ tags: {}
291
+ }
292
+ ],
293
+ tagDefinitions: []
122
294
  }
123
295
  }
124
296
  ];
125
297
  vi.mocked(hubManager.getAllServers).mockReturnValue(mockServers);
126
- // Act
127
- const results = await hubToolsService.findServers({
128
- pattern: 'Server',
129
- searchIn: 'name',
130
- caseSensitive: true
298
+ vi.mocked(hubManager.getServerInstancesByName).mockImplementation((name) => {
299
+ const server = mockServers.find((s) => s.name === name);
300
+ return server?.config.instances || [];
301
+ });
302
+ vi.mocked(hubManager.getServerByName).mockImplementation((name) => {
303
+ const server = mockServers.find((s) => s.name === name);
304
+ return server?.config;
305
+ });
306
+ vi.mocked(mcpConnectionManager.getStatusByName).mockImplementation((name) => {
307
+ if (name === 'Connected Server') {
308
+ return {
309
+ connected: true,
310
+ lastCheck: Date.now(),
311
+ toolsCount: 0,
312
+ resourcesCount: 0
313
+ };
314
+ }
315
+ return {
316
+ connected: false,
317
+ lastCheck: Date.now(),
318
+ toolsCount: 0,
319
+ resourcesCount: 0
320
+ };
131
321
  });
322
+ // Act
323
+ const servers = await hubToolsService.listServers();
132
324
  // Assert
133
- expect(results).toEqual(['Test Server 1']);
134
- expect(hubManager.getAllServers).toHaveBeenCalledTimes(1);
325
+ expect(servers).toEqual({
326
+ 'Connected Server': 'This server is connected'
327
+ });
328
+ expect(servers).not.toHaveProperty('Disconnected Server');
135
329
  });
136
330
  });
137
- describe('listAllToolsInServer', () => {
138
- it('should return tools from a specific server', async () => {
331
+ describe('listToolsInServer', () => {
332
+ it('should return tool summaries from a specific server (without inputSchema)', async () => {
139
333
  // Arrange
140
334
  const serverName = 'Test Server';
141
335
  const serverId = '1';
@@ -157,147 +351,50 @@ describe('HubToolsService', () => {
157
351
  serverName: 'Test Server'
158
352
  }
159
353
  ];
160
- // getServerInstanceByName should return ServerInstanceConfig objects (with id, timestamp, hash)
161
- const mockInstance = { id: serverId, timestamp: Date.now(), hash: 'hash1' };
162
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
163
- vi.mocked(hubManager.getServerByName).mockReturnValue({
164
- type: 'stdio',
165
- command: 'test-command',
166
- args: [],
354
+ // Expected tool summaries (without inputSchema)
355
+ const expectedToolSummaries = [
356
+ { name: 'readFile', description: 'Read file contents', serverName: 'Test Server' },
357
+ { name: 'writeFile', description: 'Write file contents', serverName: 'Test Server' }
358
+ ];
359
+ // getServerInstancesByName should return ServerInstance objects
360
+ const mockInstance = {
361
+ id: serverId,
167
362
  enabled: true,
168
- allowedTools: [],
169
- timeout: 30000
363
+ args: [],
364
+ env: {},
365
+ headers: {},
366
+ tags: {}
367
+ };
368
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
369
+ vi.mocked(hubManager.getServerByName).mockReturnValue({
370
+ template: {
371
+ type: 'stdio',
372
+ command: 'test-command',
373
+ args: [],
374
+ env: {},
375
+ headers: {},
376
+ aggregatedTools: [],
377
+ timeout: 30000
378
+ },
379
+ instances: [mockInstance],
380
+ tagDefinitions: []
170
381
  });
171
- vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
382
+ vi.mocked(mcpConnectionManager.getToolsByServerName).mockReturnValue(mockTools);
172
383
  // Act
173
- const result = await hubToolsService.listAllToolsInServer({ serverName });
384
+ const result = await hubToolsService.listToolsInServer({ serverName });
174
385
  // Assert
175
386
  expect(result).toEqual({
176
387
  serverName,
177
- tools: mockTools
388
+ tools: expectedToolSummaries
178
389
  });
179
- expect(hubManager.getServerInstanceByName).toHaveBeenCalledTimes(1);
180
- expect(hubManager.getServerInstanceByName).toHaveBeenCalledWith(serverName);
181
- expect(mcpConnectionManager.getTools).toHaveBeenCalledWith(serverId);
390
+ expect(mcpConnectionManager.getToolsByServerName).toHaveBeenCalledWith(serverName);
182
391
  });
183
392
  it('should throw error if server not found', async () => {
184
393
  // Arrange
185
394
  const serverName = 'Non-existent Server';
186
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([]);
187
- vi.mocked(hubManager.getServerByName).mockReturnValue(undefined);
395
+ vi.mocked(mcpConnectionManager.getToolsByServerName).mockReturnValue([]);
188
396
  // Act & Assert
189
- await expect(hubToolsService.listAllToolsInServer({ serverName })).rejects.toThrow(`Server not found: ${serverName}`);
190
- });
191
- });
192
- describe('findToolsInServer', () => {
193
- it('should find tools matching pattern in server', async () => {
194
- // Arrange
195
- const serverName = 'Test Server';
196
- const serverId = '1';
197
- const mockTools = [
198
- {
199
- name: 'readFile',
200
- description: 'Read file contents',
201
- inputSchema: { type: 'object', properties: {}, required: [] },
202
- serverName: 'Test Server'
203
- },
204
- {
205
- name: 'writeFile',
206
- description: 'Write file contents',
207
- inputSchema: { type: 'object', properties: {}, required: [] },
208
- serverName: 'Test Server'
209
- },
210
- {
211
- name: 'listFiles',
212
- description: 'List files in directory',
213
- inputSchema: { type: 'object', properties: {}, required: [] },
214
- serverName: 'Test Server'
215
- }
216
- ];
217
- const mockInstance = { id: serverId, timestamp: Date.now(), hash: 'hash1' };
218
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
219
- vi.mocked(hubManager.getServerByName).mockReturnValue({
220
- type: 'stdio',
221
- command: 'test-command',
222
- args: [],
223
- enabled: true,
224
- allowedTools: [],
225
- timeout: 30000
226
- });
227
- vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
228
- // Act
229
- const result = await hubToolsService.findToolsInServer({
230
- serverName,
231
- pattern: 'File',
232
- searchIn: 'both',
233
- caseSensitive: false
234
- });
235
- // Assert
236
- expect(result).toEqual({
237
- serverName,
238
- tools: [
239
- {
240
- name: 'readFile',
241
- description: 'Read file contents',
242
- inputSchema: { type: 'object', properties: {}, required: [] },
243
- serverName: 'Test Server'
244
- },
245
- {
246
- name: 'writeFile',
247
- description: 'Write file contents',
248
- inputSchema: { type: 'object', properties: {}, required: [] },
249
- serverName: 'Test Server'
250
- },
251
- {
252
- name: 'listFiles',
253
- description: 'List files in directory',
254
- inputSchema: { type: 'object', properties: {}, required: [] },
255
- serverName: 'Test Server'
256
- }
257
- ]
258
- });
259
- });
260
- it('should return empty array if no tools match', async () => {
261
- // Arrange
262
- const serverName = 'Test Server';
263
- const serverId = '1';
264
- const mockTools = [
265
- {
266
- name: 'unmatchedTool',
267
- description: 'This should not match',
268
- inputSchema: { type: 'object', properties: {}, required: [] },
269
- serverName: 'Test Server'
270
- },
271
- {
272
- name: 'anotherUnmatchedTool',
273
- description: 'This should also not match',
274
- inputSchema: { type: 'object', properties: {}, required: [] },
275
- serverName: 'Test Server'
276
- }
277
- ];
278
- const mockInstance = { id: serverId, timestamp: Date.now(), hash: 'hash1' };
279
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
280
- vi.mocked(hubManager.getServerByName).mockReturnValue({
281
- type: 'stdio',
282
- command: 'test-command',
283
- args: [],
284
- enabled: true,
285
- allowedTools: [],
286
- timeout: 30000
287
- });
288
- vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
289
- // Act
290
- const result = await hubToolsService.findToolsInServer({
291
- serverName,
292
- pattern: 'File',
293
- searchIn: 'both',
294
- caseSensitive: false
295
- });
296
- // Assert
297
- expect(result).toEqual({
298
- serverName,
299
- tools: []
300
- });
397
+ await expect(hubToolsService.listToolsInServer({ serverName })).rejects.toThrow(`Server not found: ${serverName}`);
301
398
  });
302
399
  });
303
400
  describe('getTool', () => {
@@ -320,17 +417,29 @@ describe('HubToolsService', () => {
320
417
  serverName: 'Test Server'
321
418
  }
322
419
  ];
323
- const mockInstance = { id: serverId, timestamp: Date.now(), hash: 'hash1' };
324
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
325
- vi.mocked(hubManager.getServerByName).mockReturnValue({
326
- type: 'stdio',
327
- command: 'test-command',
328
- args: [],
420
+ const mockInstance = {
421
+ id: serverId,
329
422
  enabled: true,
330
- allowedTools: [],
331
- timeout: 30000
423
+ args: [],
424
+ env: {},
425
+ headers: {},
426
+ tags: {}
427
+ };
428
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
429
+ vi.mocked(hubManager.getServerByName).mockReturnValue({
430
+ template: {
431
+ type: 'stdio',
432
+ command: 'test-command',
433
+ args: [],
434
+ env: {},
435
+ headers: {},
436
+ aggregatedTools: [],
437
+ timeout: 30000
438
+ },
439
+ instances: [mockInstance],
440
+ tagDefinitions: []
332
441
  });
333
- vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
442
+ vi.mocked(mcpConnectionManager.getToolsByServerName).mockReturnValue(mockTools);
334
443
  // Act
335
444
  const tool = await hubToolsService.getTool({ serverName, toolName });
336
445
  // Assert
@@ -349,15 +458,27 @@ describe('HubToolsService', () => {
349
458
  serverName: 'Test Server'
350
459
  }
351
460
  ];
352
- const mockInstance = { id: serverId, timestamp: Date.now(), hash: 'hash1' };
353
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
354
- vi.mocked(hubManager.getServerByName).mockReturnValue({
355
- type: 'stdio',
356
- command: 'test-command',
357
- args: [],
461
+ const mockInstance = {
462
+ id: serverId,
358
463
  enabled: true,
359
- allowedTools: [],
360
- timeout: 30000
464
+ args: [],
465
+ env: {},
466
+ headers: {},
467
+ tags: {}
468
+ };
469
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
470
+ vi.mocked(hubManager.getServerByName).mockReturnValue({
471
+ template: {
472
+ type: 'stdio',
473
+ command: 'test-command',
474
+ args: [],
475
+ env: {},
476
+ headers: {},
477
+ aggregatedTools: [],
478
+ timeout: 30000
479
+ },
480
+ instances: [mockInstance],
481
+ tagDefinitions: []
361
482
  });
362
483
  vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
363
484
  // Act
@@ -371,30 +492,44 @@ describe('HubToolsService', () => {
371
492
  // Arrange
372
493
  const serverName = 'Test Server';
373
494
  const serverId = '1';
495
+ const serverIndex = 0;
374
496
  const toolName = 'readFile';
375
497
  const toolArgs = { path: '/test/file.txt' };
376
498
  const expectedResult = { content: 'Test file content' };
377
- const mockInstance = { id: serverId, timestamp: Date.now(), hash: 'hash1' };
378
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
379
- vi.mocked(hubManager.getServerByName).mockReturnValue({
380
- type: 'stdio',
381
- command: 'test-command',
382
- args: [],
499
+ const mockInstance = {
500
+ id: serverId,
501
+ index: serverIndex,
383
502
  enabled: true,
384
- allowedTools: [],
385
- timeout: 30000
503
+ args: [],
504
+ env: {},
505
+ headers: {},
506
+ tags: {}
507
+ };
508
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
509
+ vi.mocked(hubManager.getServerByName).mockReturnValue({
510
+ template: {
511
+ type: 'stdio',
512
+ command: 'test-command',
513
+ args: [],
514
+ env: {},
515
+ headers: {},
516
+ aggregatedTools: [],
517
+ timeout: 30000
518
+ },
519
+ instances: [mockInstance],
520
+ tagDefinitions: []
386
521
  });
387
522
  vi.mocked(mcpConnectionManager.callTool).mockResolvedValue(expectedResult);
388
523
  // Act
389
524
  const result = await hubToolsService.callTool({ serverName, toolName, toolArgs });
390
525
  // Assert
391
526
  expect(result).toEqual(expectedResult);
392
- expect(mcpConnectionManager.callTool).toHaveBeenCalledWith(serverId, toolName, toolArgs);
527
+ expect(mcpConnectionManager.callTool).toHaveBeenCalledWith(serverName, serverIndex, toolName, toolArgs);
393
528
  });
394
529
  it('should throw error if server not found when calling tool', async () => {
395
530
  // Arrange
396
531
  const serverName = 'Non-existent Server';
397
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([]);
532
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([]);
398
533
  vi.mocked(hubManager.getServerByName).mockReturnValue(undefined);
399
534
  // Act & Assert
400
535
  await expect(hubToolsService.callTool({ serverName, toolName: 'readFile', toolArgs: {} })).rejects.toThrow(`Server not found: ${serverName}`);
@@ -407,29 +542,41 @@ describe('HubToolsService', () => {
407
542
  {
408
543
  name: 'Server 1',
409
544
  config: {
410
- type: 'stdio',
411
- command: 'test-command',
412
- args: [],
413
- enabled: true,
414
- allowedTools: [],
415
- timeout: 30000
545
+ template: {
546
+ type: 'stdio',
547
+ command: 'test-command',
548
+ args: [],
549
+ env: {},
550
+ headers: {},
551
+ aggregatedTools: [],
552
+ timeout: 30000,
553
+ tags: {}
554
+ },
555
+ instances: [],
556
+ tagDefinitions: []
416
557
  }
417
558
  },
418
559
  {
419
560
  name: 'Server 2',
420
561
  config: {
421
- type: 'sse',
422
- url: 'http://example.com',
423
- args: [],
424
- enabled: true,
425
- allowedTools: [],
426
- timeout: 30000
562
+ template: {
563
+ type: 'sse',
564
+ url: 'http://example.com',
565
+ args: [],
566
+ env: {},
567
+ headers: {},
568
+ aggregatedTools: [],
569
+ timeout: 30000,
570
+ tags: {}
571
+ },
572
+ instances: [],
573
+ tagDefinitions: []
427
574
  }
428
575
  }
429
576
  ];
430
577
  const mockServerInstances = {
431
- 'Server 1': [{ id: '1', timestamp: Date.now(), hash: 'hash1' }],
432
- 'Server 2': [{ id: '2', timestamp: Date.now(), hash: 'hash2' }]
578
+ 'Server 1': [{ id: '1', enabled: true, args: [], env: {}, headers: {}, tags: {} }],
579
+ 'Server 2': [{ id: '2', enabled: true, args: [], env: {}, headers: {}, tags: {} }]
433
580
  };
434
581
  const mockTools = [
435
582
  {
@@ -445,8 +592,17 @@ describe('HubToolsService', () => {
445
592
  serverName: 'Server 1'
446
593
  }
447
594
  ];
595
+ // Expected tool summaries (without inputSchema)
596
+ const expectedToolSummariesServer1 = [
597
+ { name: 'readFile', description: 'Read file contents', serverName: 'Server 1' },
598
+ { name: 'writeFile', description: 'Write file contents', serverName: 'Server 1' }
599
+ ];
600
+ const expectedToolSummariesServer2 = [
601
+ { name: 'readFile', description: 'Read file contents', serverName: 'Server 2' },
602
+ { name: 'writeFile', description: 'Write file contents', serverName: 'Server 2' }
603
+ ];
448
604
  vi.mocked(hubManager.getAllServers).mockReturnValue(mockServers);
449
- vi.mocked(hubManager.getServerInstanceByName).mockImplementation((name) => mockServerInstances[name]);
605
+ vi.mocked(hubManager.getServerInstancesByName).mockImplementation((name) => mockServerInstances[name]);
450
606
  vi.mocked(hubManager.getServerByName).mockImplementation((name) => mockServers.find((s) => s.name === name)?.config);
451
607
  vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
452
608
  // Act
@@ -454,82 +610,69 @@ describe('HubToolsService', () => {
454
610
  // Assert - System tools under mcp-hub-lite
455
611
  expect(allTools).toHaveProperty('mcp-hub-lite');
456
612
  expect(Array.isArray(allTools['mcp-hub-lite'].tools)).toBe(true);
457
- // Assert system tools
613
+ // Assert system tools - should have 5 tools now
458
614
  const systemToolNames = allTools['mcp-hub-lite'].tools.map((t) => t.name);
459
615
  expect(systemToolNames).toContain('list_servers');
460
- expect(systemToolNames).toContain('find_servers');
461
- expect(systemToolNames).toContain('list_all_tools_in_server');
462
- expect(systemToolNames).toContain('find_tools_in_server');
616
+ expect(systemToolNames).toContain('list_tools_in_server');
463
617
  expect(systemToolNames).toContain('get_tool');
464
618
  expect(systemToolNames).toContain('call_tool');
465
- expect(systemToolNames).toContain('find_tools');
619
+ expect(systemToolNames).toContain('update_server_description');
620
+ expect(systemToolNames).toHaveLength(5);
466
621
  // Assert server tools - should have only name and description
467
- expect(allTools['Server 1'].tools).toEqual(mockTools);
468
- expect(allTools['Server 2'].tools).toEqual(mockTools);
469
- });
470
- });
471
- describe('findTools', () => {
472
- it('should find tools matching pattern across all servers', async () => {
473
- // Arrange
474
- const mockTools = {
475
- 'Server 1': {
476
- tools: [
477
- { name: 'readFile', description: 'Read file contents', serverName: 'Server 1' },
478
- { name: 'writeFile', description: 'Write file contents', serverName: 'Server 1' }
479
- ]
480
- },
481
- 'Server 2': {
482
- tools: [
483
- { name: 'listFiles', description: 'List files in directory', serverName: 'Server 2' }
484
- ]
485
- }
486
- };
487
- vi.spyOn(hubToolsService, 'listAllTools').mockResolvedValue(mockTools);
488
- // Act
489
- const results = await hubToolsService.findTools({
490
- pattern: 'File',
491
- searchIn: 'both',
492
- caseSensitive: false
493
- });
494
- // Assert
495
- expect(results).toEqual(mockTools);
622
+ expect(allTools['Server 1'].tools).toEqual(expectedToolSummariesServer1);
623
+ expect(allTools['Server 2'].tools).toEqual(expectedToolSummariesServer2);
496
624
  });
497
625
  });
498
626
  describe('listResources', () => {
499
- it('should return empty array when no servers are connected', async () => {
627
+ it('should return use-guide resource even when no servers are connected', async () => {
500
628
  // Arrange
501
629
  vi.mocked(hubManager.getAllServers).mockReturnValue([]);
502
630
  // Act
503
631
  const resources = await hubToolsService.listResources();
504
632
  // Assert
505
- expect(resources).toEqual([]);
506
- expect(hubManager.getAllServers).toHaveBeenCalledTimes(1);
633
+ expect(resources).toHaveLength(1);
634
+ expect(resources[0]).toEqual({
635
+ uri: 'hub://use-guide',
636
+ name: 'MCP Hub Lite Use Guide',
637
+ description: 'Comprehensive guide to using MCP Hub Lite gateway and its features',
638
+ mimeType: 'text/markdown',
639
+ serverId: undefined
640
+ });
507
641
  });
508
- it('should return dynamic resources for connected servers', async () => {
642
+ it('should return use-guide and server resources for connected servers', async () => {
509
643
  // Arrange
510
644
  const mockServers = [
511
645
  {
512
646
  name: 'Test Server',
513
647
  config: {
514
- type: 'stdio',
515
- command: 'test-command',
516
- args: [],
517
- enabled: true,
518
- allowedTools: [],
519
- timeout: 30000
648
+ template: {
649
+ type: 'stdio',
650
+ command: 'test-command',
651
+ args: [],
652
+ env: {},
653
+ headers: {},
654
+ aggregatedTools: [],
655
+ timeout: 30000,
656
+ tags: {}
657
+ },
658
+ instances: [
659
+ {
660
+ id: '1',
661
+ enabled: true,
662
+ args: [],
663
+ env: {},
664
+ headers: {},
665
+ tags: {},
666
+ index: 0,
667
+ displayName: 'Test Instance'
668
+ }
669
+ ],
670
+ tagDefinitions: []
520
671
  }
521
672
  }
522
673
  ];
523
- const mockInstance = {
524
- id: '1',
525
- timestamp: Date.now(),
526
- hash: 'hash1',
527
- status: 'online',
528
- lastHeartbeat: Date.now(),
529
- uptime: 1000
530
- };
531
674
  vi.mocked(hubManager.getAllServers).mockReturnValue(mockServers);
532
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
675
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue(mockServers[0].config.instances);
533
676
  vi.mocked(hubManager.getServerByName).mockReturnValue(mockServers[0].config);
534
677
  vi.mocked(mcpConnectionManager.getTools).mockReturnValue([
535
678
  { name: 'testTool', description: 'Test tool', serverName: 'test-server' }
@@ -539,48 +682,51 @@ describe('HubToolsService', () => {
539
682
  ]);
540
683
  // Act
541
684
  const resources = await hubToolsService.listResources();
542
- // Assert
543
- expect(resources).toHaveLength(3);
685
+ // Assert - the resource list should include use-guide and at least the server resource
686
+ expect(resources.length).toBeGreaterThanOrEqual(1);
687
+ // First resource should be use-guide
544
688
  expect(resources[0]).toEqual({
545
- uri: 'hub://servers/Test Server',
546
- name: 'Server: Test Server',
547
- description: 'Connected MCP server: Test Server',
548
- mimeType: 'application/json',
549
- serverId: '1'
550
- });
551
- expect(resources[1]).toEqual({
552
- uri: 'hub://servers/Test Server/tools',
553
- name: 'Tools: Test Server',
554
- description: '1 tools available from Test Server',
555
- mimeType: 'application/json',
556
- serverId: '1'
557
- });
558
- expect(resources[2]).toEqual({
559
- uri: 'hub://servers/Test Server/resources',
560
- name: 'Resources: Test Server',
561
- description: '1 resources available from Test Server',
562
- mimeType: 'application/json',
563
- serverId: '1'
689
+ uri: 'hub://use-guide',
690
+ name: 'MCP Hub Lite Use Guide',
691
+ description: 'Comprehensive guide to using MCP Hub Lite gateway and its features',
692
+ mimeType: 'text/markdown',
693
+ serverId: undefined
564
694
  });
565
695
  });
566
696
  });
567
697
  describe('readResource', () => {
698
+ it('should return use-guide content for use-guide URI', async () => {
699
+ // Act
700
+ const result = await hubToolsService.readResource('hub://use-guide');
701
+ // Assert
702
+ expect(typeof result).toBe('string');
703
+ expect(result).toContain('# MCP Hub Lite Use Guide');
704
+ expect(result).toContain('Getting Started');
705
+ expect(result).toContain('Progressive Discovery Workflow');
706
+ expect(result).toContain('System Tools Reference');
707
+ });
568
708
  it('should throw error for invalid URI format', async () => {
569
709
  // Act & Assert
570
710
  await expect(hubToolsService.readResource('invalid-uri')).rejects.toThrow('Invalid Hub resource URI');
571
- await expect(hubToolsService.readResource('hub://invalid')).rejects.toThrow('Invalid Hub resource URI format');
711
+ // Now hub://invalid is not necessarily invalid - it could be a valid single-segment URI
712
+ // The parser only rejects hub://servers/... format URIs that are invalid
572
713
  });
573
714
  it('should throw error for non-existent server', async () => {
574
715
  // Arrange
575
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([]);
716
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([]);
576
717
  // Act & Assert
577
718
  await expect(hubToolsService.readResource('hub://servers/NonExistent')).rejects.toThrow('Server not found or not connected');
578
719
  });
579
- it('should return server metadata for server URI', async () => {
720
+ it('should return server metadata for server URI with tools field', async () => {
580
721
  // Arrange
581
722
  const serverName = 'Test Server';
582
723
  const mockInstance = {
583
- id: '1',
724
+ id: 'test-instance',
725
+ enabled: true,
726
+ args: [],
727
+ env: {},
728
+ headers: {},
729
+ tags: { env: 'test' },
584
730
  timestamp: Date.now(),
585
731
  hash: 'hash1',
586
732
  status: 'online',
@@ -588,19 +734,38 @@ describe('HubToolsService', () => {
588
734
  uptime: 1000
589
735
  };
590
736
  const mockConfig = {
591
- type: 'stdio',
592
- command: 'test-command',
593
- args: [],
594
- enabled: true,
595
- allowedTools: [],
596
- timeout: 30000,
597
- tags: { env: 'test' }
737
+ template: {
738
+ type: 'stdio',
739
+ command: 'test-command',
740
+ args: [],
741
+ env: {},
742
+ headers: {},
743
+ aggregatedTools: [],
744
+ timeout: 30000
745
+ },
746
+ instances: [
747
+ {
748
+ id: 'test-instance',
749
+ enabled: true,
750
+ args: [],
751
+ env: {},
752
+ headers: {},
753
+ tags: { env: 'test' },
754
+ timestamp: Date.now(),
755
+ status: 'online',
756
+ lastHeartbeat: Date.now(),
757
+ uptime: 1000
758
+ }
759
+ ],
760
+ tagDefinitions: []
598
761
  };
599
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
762
+ const mockTools = [
763
+ { name: 'testTool', description: 'Test tool description', serverName: 'test-server' }
764
+ ];
765
+ // @ts-expect-error - Mocking for test purposes with extra fields
766
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
600
767
  vi.mocked(hubManager.getServerByName).mockReturnValue(mockConfig);
601
- vi.mocked(mcpConnectionManager.getTools).mockReturnValue([
602
- { name: 'testTool', serverName: 'test-server' }
603
- ]);
768
+ vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
604
769
  vi.mocked(mcpConnectionManager.getResources).mockReturnValue([
605
770
  { uri: 'test://resource', name: 'Test Resource' }
606
771
  ]);
@@ -611,10 +776,14 @@ describe('HubToolsService', () => {
611
776
  name: serverName,
612
777
  status: 'online',
613
778
  toolsCount: 1,
779
+ tools: { testTool: 'Test tool description' },
614
780
  resourcesCount: 1,
615
781
  tags: { env: 'test' },
782
+ // @ts-expect-error - Accessing extra fields on mock
616
783
  lastHeartbeat: mockInstance.lastHeartbeat,
617
- uptime: mockInstance.uptime
784
+ // @ts-expect-error - Accessing extra fields on mock
785
+ uptime: mockInstance.uptime,
786
+ description: `Connected MCP server: ${serverName}`
618
787
  });
619
788
  });
620
789
  it('should return tools list for tools URI', async () => {
@@ -622,6 +791,11 @@ describe('HubToolsService', () => {
622
791
  const serverName = 'Test Server';
623
792
  const mockInstance = {
624
793
  id: '1',
794
+ enabled: true,
795
+ args: [],
796
+ env: {},
797
+ headers: {},
798
+ tags: {},
625
799
  timestamp: Date.now(),
626
800
  hash: 'hash1',
627
801
  status: 'online',
@@ -629,7 +803,8 @@ describe('HubToolsService', () => {
629
803
  uptime: 1000
630
804
  };
631
805
  const mockTools = [{ name: 'testTool', description: 'Test tool', serverName: 'test-server' }];
632
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
806
+ // @ts-expect-error - Mocking for test purposes with extra fields
807
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
633
808
  vi.mocked(mcpConnectionManager.getTools).mockReturnValue(mockTools);
634
809
  // Act
635
810
  const result = await hubToolsService.readResource(`hub://servers/${serverName}/tools`);
@@ -641,6 +816,11 @@ describe('HubToolsService', () => {
641
816
  const serverName = 'Test Server';
642
817
  const mockInstance = {
643
818
  id: '1',
819
+ enabled: true,
820
+ args: [],
821
+ env: {},
822
+ headers: {},
823
+ tags: {},
644
824
  timestamp: Date.now(),
645
825
  hash: 'hash1',
646
826
  status: 'online',
@@ -648,25 +828,71 @@ describe('HubToolsService', () => {
648
828
  uptime: 1000
649
829
  };
650
830
  const mockResources = [{ uri: 'test://resource', name: 'Test Resource' }];
651
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
831
+ // @ts-expect-error - Mocking for test purposes with extra fields
832
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
652
833
  vi.mocked(mcpConnectionManager.getResources).mockReturnValue(mockResources);
653
834
  // Act
654
835
  const result = await hubToolsService.readResource(`hub://servers/${serverName}/resources`);
655
836
  // Assert
656
837
  expect(result).toEqual(mockResources);
657
838
  });
839
+ it('should restore missing mapping and forward Hub resource reads to the MCP URI', async () => {
840
+ // Arrange
841
+ const mockConfig = {
842
+ template: {
843
+ type: 'stdio',
844
+ command: 'test-command',
845
+ args: [],
846
+ env: {},
847
+ headers: {},
848
+ aggregatedTools: [],
849
+ timeout: 30000
850
+ },
851
+ instances: [
852
+ {
853
+ id: 'exa-instance-0',
854
+ index: 0,
855
+ enabled: true,
856
+ args: [],
857
+ env: {},
858
+ headers: {},
859
+ tags: {}
860
+ }
861
+ ],
862
+ tagDefinitions: []
863
+ };
864
+ const forwardedResponse = {
865
+ contents: [{ uri: 'exa://tools/list', mimeType: 'application/json', text: '[]' }]
866
+ };
867
+ vi.mocked(hubManager.getServerByName).mockReturnValue(mockConfig);
868
+ vi.mocked(mcpConnectionManager.getResources).mockReturnValue([
869
+ { uri: 'exa://tools/list', name: 'Tools List' }
870
+ ]);
871
+ vi.mocked(mcpConnectionManager.readResource).mockResolvedValue(forwardedResponse);
872
+ // Act
873
+ const result = await hubToolsService.readResource('hub://servers/exa-ai/0/tools/list');
874
+ // Assert
875
+ expect(result).toEqual(forwardedResponse);
876
+ expect(mcpConnectionManager.readResource).toHaveBeenCalledWith('exa-ai', 0, 'exa://tools/list');
877
+ });
658
878
  it('should throw error for unknown resource type', async () => {
659
879
  // Arrange
660
880
  const serverName = 'Test Server';
661
881
  const mockInstance = {
662
882
  id: '1',
883
+ enabled: true,
884
+ args: [],
885
+ env: {},
886
+ headers: {},
887
+ tags: {},
663
888
  timestamp: Date.now(),
664
889
  hash: 'hash1',
665
890
  status: 'online',
666
891
  lastHeartbeat: Date.now(),
667
892
  uptime: 1000
668
893
  };
669
- vi.mocked(hubManager.getServerInstanceByName).mockReturnValue([mockInstance]);
894
+ // @ts-expect-error - Mocking for test purposes with extra fields
895
+ vi.mocked(hubManager.getServerInstancesByName).mockReturnValue([mockInstance]);
670
896
  // Act & Assert
671
897
  await expect(hubToolsService.readResource(`hub://servers/${serverName}/unknown`)).rejects.toThrow('Unknown resource type');
672
898
  });