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