@1mcp/agent 0.16.0 → 0.18.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 (172) hide show
  1. package/README.md +103 -11
  2. package/build/auth/sdkOAuthClientProvider.d.ts.map +1 -1
  3. package/build/auth/sdkOAuthClientProvider.js +1 -1
  4. package/build/auth/sdkOAuthClientProvider.js.map +1 -1
  5. package/build/commands/app/backups.d.ts +17 -0
  6. package/build/commands/app/backups.d.ts.map +1 -0
  7. package/build/commands/app/backups.js +162 -0
  8. package/build/commands/app/backups.js.map +1 -0
  9. package/build/commands/app/consolidate.d.ts +21 -0
  10. package/build/commands/app/consolidate.d.ts.map +1 -0
  11. package/build/commands/app/consolidate.js +383 -0
  12. package/build/commands/app/consolidate.js.map +1 -0
  13. package/build/commands/app/discover.d.ts +16 -0
  14. package/build/commands/app/discover.d.ts.map +1 -0
  15. package/build/commands/app/discover.js +79 -0
  16. package/build/commands/app/discover.js.map +1 -0
  17. package/build/commands/app/index.d.ts +12 -0
  18. package/build/commands/app/index.d.ts.map +1 -0
  19. package/build/commands/app/index.js +274 -0
  20. package/build/commands/app/index.js.map +1 -0
  21. package/build/commands/app/list.d.ts +16 -0
  22. package/build/commands/app/list.d.ts.map +1 -0
  23. package/build/commands/app/list.js +95 -0
  24. package/build/commands/app/list.js.map +1 -0
  25. package/build/commands/app/restore.d.ts +21 -0
  26. package/build/commands/app/restore.d.ts.map +1 -0
  27. package/build/commands/app/restore.js +265 -0
  28. package/build/commands/app/restore.js.map +1 -0
  29. package/build/commands/app/status.d.ts +16 -0
  30. package/build/commands/app/status.d.ts.map +1 -0
  31. package/build/commands/app/status.js +224 -0
  32. package/build/commands/app/status.js.map +1 -0
  33. package/build/commands/mcp/add.d.ts +19 -0
  34. package/build/commands/mcp/add.d.ts.map +1 -0
  35. package/build/commands/mcp/add.js +135 -0
  36. package/build/commands/mcp/add.js.map +1 -0
  37. package/build/commands/mcp/enable.d.ts +13 -0
  38. package/build/commands/mcp/enable.d.ts.map +1 -0
  39. package/build/commands/mcp/enable.js +100 -0
  40. package/build/commands/mcp/enable.js.map +1 -0
  41. package/build/commands/mcp/index.d.ts +12 -0
  42. package/build/commands/mcp/index.d.ts.map +1 -0
  43. package/build/commands/mcp/index.js +351 -0
  44. package/build/commands/mcp/index.js.map +1 -0
  45. package/build/commands/mcp/list.d.ts +11 -0
  46. package/build/commands/mcp/list.d.ts.map +1 -0
  47. package/build/commands/mcp/list.js +144 -0
  48. package/build/commands/mcp/list.js.map +1 -0
  49. package/build/commands/mcp/remove.d.ts +10 -0
  50. package/build/commands/mcp/remove.d.ts.map +1 -0
  51. package/build/commands/mcp/remove.js +89 -0
  52. package/build/commands/mcp/remove.js.map +1 -0
  53. package/build/commands/mcp/status.d.ts +10 -0
  54. package/build/commands/mcp/status.d.ts.map +1 -0
  55. package/build/commands/mcp/status.js +243 -0
  56. package/build/commands/mcp/status.js.map +1 -0
  57. package/build/commands/mcp/update.d.ts +18 -0
  58. package/build/commands/mcp/update.d.ts.map +1 -0
  59. package/build/commands/mcp/update.js +157 -0
  60. package/build/commands/mcp/update.js.map +1 -0
  61. package/build/commands/mcp/utils/configUtils.d.ts +64 -0
  62. package/build/commands/mcp/utils/configUtils.d.ts.map +1 -0
  63. package/build/commands/mcp/utils/configUtils.js +266 -0
  64. package/build/commands/mcp/utils/configUtils.js.map +1 -0
  65. package/build/commands/mcp/utils/doubleHyphenParser.d.ts +32 -0
  66. package/build/commands/mcp/utils/doubleHyphenParser.d.ts.map +1 -0
  67. package/build/commands/mcp/utils/doubleHyphenParser.js +61 -0
  68. package/build/commands/mcp/utils/doubleHyphenParser.js.map +1 -0
  69. package/build/commands/mcp/utils/validation.d.ts +33 -0
  70. package/build/commands/mcp/utils/validation.d.ts.map +1 -0
  71. package/build/commands/mcp/utils/validation.js +235 -0
  72. package/build/commands/mcp/utils/validation.js.map +1 -0
  73. package/build/constants.d.ts +11 -2
  74. package/build/constants.d.ts.map +1 -1
  75. package/build/constants.js +18 -5
  76. package/build/constants.js.map +1 -1
  77. package/build/core/capabilities/asyncLoadingOrchestrator.d.ts +96 -0
  78. package/build/core/capabilities/asyncLoadingOrchestrator.d.ts.map +1 -0
  79. package/build/core/capabilities/asyncLoadingOrchestrator.js +256 -0
  80. package/build/core/capabilities/asyncLoadingOrchestrator.js.map +1 -0
  81. package/build/core/capabilities/capabilityAggregator.d.ts +114 -0
  82. package/build/core/capabilities/capabilityAggregator.d.ts.map +1 -0
  83. package/build/core/capabilities/capabilityAggregator.js +234 -0
  84. package/build/core/capabilities/capabilityAggregator.js.map +1 -0
  85. package/build/core/client/clientManager.d.ts +29 -0
  86. package/build/core/client/clientManager.d.ts.map +1 -1
  87. package/build/core/client/clientManager.js +151 -2
  88. package/build/core/client/clientManager.js.map +1 -1
  89. package/build/core/loading/loadingStateTracker.d.ts +128 -0
  90. package/build/core/loading/loadingStateTracker.d.ts.map +1 -0
  91. package/build/core/loading/loadingStateTracker.js +211 -0
  92. package/build/core/loading/loadingStateTracker.js.map +1 -0
  93. package/build/core/loading/mcpLoadingManager.d.ts +156 -0
  94. package/build/core/loading/mcpLoadingManager.d.ts.map +1 -0
  95. package/build/core/loading/mcpLoadingManager.js +352 -0
  96. package/build/core/loading/mcpLoadingManager.js.map +1 -0
  97. package/build/core/notifications/notificationManager.d.ts +111 -0
  98. package/build/core/notifications/notificationManager.d.ts.map +1 -0
  99. package/build/core/notifications/notificationManager.js +232 -0
  100. package/build/core/notifications/notificationManager.js.map +1 -0
  101. package/build/core/server/agentConfig.d.ts +50 -0
  102. package/build/core/server/agentConfig.d.ts.map +1 -1
  103. package/build/core/server/agentConfig.js +68 -1
  104. package/build/core/server/agentConfig.js.map +1 -1
  105. package/build/core/server/serverManager.d.ts +1 -0
  106. package/build/core/server/serverManager.d.ts.map +1 -1
  107. package/build/core/server/serverManager.js +3 -0
  108. package/build/core/server/serverManager.js.map +1 -1
  109. package/build/core/types/transport.d.ts +2 -2
  110. package/build/index.js +133 -34
  111. package/build/index.js.map +1 -1
  112. package/build/logger/logger.d.ts +9 -0
  113. package/build/logger/logger.d.ts.map +1 -1
  114. package/build/logger/logger.js +49 -0
  115. package/build/logger/logger.js.map +1 -1
  116. package/build/logger/secureLogger.d.ts +22 -0
  117. package/build/logger/secureLogger.d.ts.map +1 -0
  118. package/build/logger/secureLogger.js +120 -0
  119. package/build/logger/secureLogger.js.map +1 -0
  120. package/build/server.d.ts +23 -2
  121. package/build/server.d.ts.map +1 -1
  122. package/build/server.js +83 -10
  123. package/build/server.js.map +1 -1
  124. package/build/services/configReloadService.d.ts +8 -0
  125. package/build/services/configReloadService.d.ts.map +1 -1
  126. package/build/services/configReloadService.js +68 -0
  127. package/build/services/configReloadService.js.map +1 -1
  128. package/build/transport/http/middlewares/mcpAvailabilityMiddleware.d.ts +79 -0
  129. package/build/transport/http/middlewares/mcpAvailabilityMiddleware.d.ts.map +1 -0
  130. package/build/transport/http/middlewares/mcpAvailabilityMiddleware.js +306 -0
  131. package/build/transport/http/middlewares/mcpAvailabilityMiddleware.js.map +1 -0
  132. package/build/transport/http/routes/healthRoutes.d.ts +2 -1
  133. package/build/transport/http/routes/healthRoutes.d.ts.map +1 -1
  134. package/build/transport/http/routes/healthRoutes.js +170 -1
  135. package/build/transport/http/routes/healthRoutes.js.map +1 -1
  136. package/build/transport/http/routes/sseRoutes.d.ts +2 -1
  137. package/build/transport/http/routes/sseRoutes.d.ts.map +1 -1
  138. package/build/transport/http/routes/sseRoutes.js +13 -1
  139. package/build/transport/http/routes/sseRoutes.js.map +1 -1
  140. package/build/transport/http/routes/streamableHttpRoutes.d.ts +2 -1
  141. package/build/transport/http/routes/streamableHttpRoutes.d.ts.map +1 -1
  142. package/build/transport/http/routes/streamableHttpRoutes.js +13 -1
  143. package/build/transport/http/routes/streamableHttpRoutes.js.map +1 -1
  144. package/build/transport/http/server.d.ts +7 -1
  145. package/build/transport/http/server.d.ts.map +1 -1
  146. package/build/transport/http/server.js +15 -4
  147. package/build/transport/http/server.js.map +1 -1
  148. package/build/transport/transportFactory.d.ts +4 -0
  149. package/build/transport/transportFactory.d.ts.map +1 -1
  150. package/build/transport/transportFactory.js +1 -1
  151. package/build/transport/transportFactory.js.map +1 -1
  152. package/build/utils/appDiscovery.d.ts +75 -0
  153. package/build/utils/appDiscovery.d.ts.map +1 -0
  154. package/build/utils/appDiscovery.js +358 -0
  155. package/build/utils/appDiscovery.js.map +1 -0
  156. package/build/utils/appPresets.d.ts +88 -0
  157. package/build/utils/appPresets.d.ts.map +1 -0
  158. package/build/utils/appPresets.js +430 -0
  159. package/build/utils/appPresets.js.map +1 -0
  160. package/build/utils/backupManager.d.ts +61 -0
  161. package/build/utils/backupManager.d.ts.map +1 -0
  162. package/build/utils/backupManager.js +314 -0
  163. package/build/utils/backupManager.js.map +1 -0
  164. package/build/utils/urlDetection.d.ts +35 -0
  165. package/build/utils/urlDetection.d.ts.map +1 -0
  166. package/build/utils/urlDetection.js +115 -0
  167. package/build/utils/urlDetection.js.map +1 -0
  168. package/build/utils/validationHelpers.d.ts +62 -0
  169. package/build/utils/validationHelpers.d.ts.map +1 -0
  170. package/build/utils/validationHelpers.js +252 -0
  171. package/build/utils/validationHelpers.js.map +1 -0
  172. package/package.json +9 -2
package/build/server.js CHANGED
@@ -4,30 +4,103 @@ import { createTransports } from './transport/transportFactory.js';
4
4
  import { ClientManager } from './core/client/clientManager.js';
5
5
  import { ServerManager } from './core/server/serverManager.js';
6
6
  import { McpConfigManager } from './config/mcpConfigManager.js';
7
+ import { AgentConfigManager } from './core/server/agentConfig.js';
7
8
  import configReloadService from './services/configReloadService.js';
9
+ import { McpLoadingManager } from './core/loading/mcpLoadingManager.js';
10
+ import { AsyncLoadingOrchestrator } from './core/capabilities/asyncLoadingOrchestrator.js';
8
11
  /**
9
12
  * Main function to set up the MCP server
13
+ * Conditionally uses async or legacy loading based on configuration
10
14
  */
11
15
  async function setupServer() {
12
16
  try {
13
17
  const mcpConfig = McpConfigManager.getInstance().getTransportConfig();
18
+ const agentConfig = AgentConfigManager.getInstance();
19
+ const asyncLoadingEnabled = agentConfig.isAsyncLoadingEnabled();
14
20
  // Create transports from configuration
15
21
  const transports = createTransports(mcpConfig);
16
22
  logger.info(`Created ${Object.keys(transports).length} transports`);
17
- // Create clients for each transport
18
- const clientManager = ClientManager.getOrCreateInstance();
19
- const clients = await clientManager.createClients(transports);
20
- logger.info(`Created ${clients.size} clients`);
21
- const serverManager = ServerManager.getOrCreateInstance({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, { capabilities: MCP_SERVER_CAPABILITIES }, clients, transports);
22
- // Initialize config reload service at server startup
23
- configReloadService.initialize(transports);
24
- logger.info('Server setup completed successfully');
25
- return serverManager;
23
+ if (asyncLoadingEnabled) {
24
+ logger.info('Using async loading mode - HTTP server will start immediately, MCP servers load in background');
25
+ return setupServerAsync(transports);
26
+ }
27
+ else {
28
+ logger.info('Using legacy synchronous loading mode - waiting for all MCP servers before starting HTTP server');
29
+ return setupServerSync(transports);
30
+ }
26
31
  }
27
32
  catch (error) {
28
33
  logger.error(`Failed to set up server: ${error}`);
29
34
  throw error;
30
35
  }
31
36
  }
32
- export { setupServer };
37
+ /**
38
+ * Set up server with async loading (new mode)
39
+ * HTTP server starts immediately, MCP servers load in background
40
+ */
41
+ async function setupServerAsync(transports) {
42
+ // Initialize client manager without connecting (for async loading)
43
+ const clientManager = ClientManager.getOrCreateInstance();
44
+ const clients = clientManager.initializeClientsAsync(transports);
45
+ logger.info(`Initialized storage for ${Object.keys(transports).length} MCP servers`);
46
+ // Create server manager with empty clients initially
47
+ const serverManager = ServerManager.getOrCreateInstance({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, { capabilities: MCP_SERVER_CAPABILITIES }, clients, transports);
48
+ // Initialize config reload service
49
+ configReloadService.initialize(transports);
50
+ // Create loading manager for async MCP server initialization
51
+ const loadingManager = new McpLoadingManager(clientManager);
52
+ // Create async loading orchestrator for capability tracking and notifications
53
+ const asyncOrchestrator = new AsyncLoadingOrchestrator(clients, serverManager, loadingManager);
54
+ asyncOrchestrator.initialize();
55
+ // Start async loading (non-blocking)
56
+ const loadingPromise = loadingManager
57
+ .startAsyncLoading(transports)
58
+ .then(() => {
59
+ logger.info('All MCP servers finished loading (successfully or failed)');
60
+ })
61
+ .catch((error) => {
62
+ logger.error('MCP loading process encountered an error:', error);
63
+ });
64
+ logger.info('Async server setup completed - HTTP server ready, MCP servers loading in background');
65
+ return {
66
+ serverManager,
67
+ loadingManager,
68
+ loadingPromise,
69
+ asyncOrchestrator,
70
+ };
71
+ }
72
+ /**
73
+ * Set up server with legacy synchronous loading
74
+ * Waits for all MCP servers to load before returning
75
+ */
76
+ async function setupServerSync(transports) {
77
+ // Use the standard synchronous client creation
78
+ const clientManager = ClientManager.getOrCreateInstance();
79
+ const clients = await clientManager.createClients(transports);
80
+ logger.info(`Connected to ${clients.size} MCP servers synchronously`);
81
+ // Create server manager with connected clients
82
+ const serverManager = ServerManager.getOrCreateInstance({ name: MCP_SERVER_NAME, version: MCP_SERVER_VERSION }, { capabilities: MCP_SERVER_CAPABILITIES }, clients, transports);
83
+ // Initialize config reload service
84
+ configReloadService.initialize(transports);
85
+ // Create a dummy loading manager for compatibility
86
+ const loadingManager = new McpLoadingManager(clientManager);
87
+ const loadingPromise = Promise.resolve(); // Already loaded
88
+ logger.info('Synchronous server setup completed - all MCP servers connected');
89
+ return {
90
+ serverManager,
91
+ loadingManager,
92
+ loadingPromise,
93
+ };
94
+ }
95
+ /**
96
+ * Legacy function for backward compatibility
97
+ * @deprecated Use setupServer() which returns ServerSetupResult
98
+ */
99
+ async function setupServerLegacy() {
100
+ const result = await setupServer();
101
+ // Wait for loading to complete for legacy behavior
102
+ await result.loadingPromise;
103
+ return result.serverManager;
104
+ }
105
+ export { setupServer, setupServerLegacy };
33
106
  //# sourceMappingURL=server.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AAC9F,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAChE,OAAO,mBAAmB,MAAM,mCAAmC,CAAC;AAEpE;;GAEG;AACH,KAAK,UAAU,WAAW;IACxB,IAAI,CAAC;QACH,MAAM,SAAS,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC,kBAAkB,EAAE,CAAC;QACtE,uCAAuC;QACvC,MAAM,UAAU,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC/C,MAAM,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,aAAa,CAAC,CAAC;QAEpE,oCAAoC;QACpC,MAAM,aAAa,GAAG,aAAa,CAAC,mBAAmB,EAAE,CAAC;QAC1D,MAAM,OAAO,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAC9D,MAAM,CAAC,IAAI,CAAC,WAAW,OAAO,CAAC,IAAI,UAAU,CAAC,CAAC;QAE/C,MAAM,aAAa,GAAG,aAAa,CAAC,mBAAmB,CACrD,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,kBAAkB,EAAE,EACtD,EAAE,YAAY,EAAE,uBAAuB,EAAE,EACzC,OAAO,EACP,UAAU,CACX,CAAC;QAEF,qDAAqD;QACrD,mBAAmB,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QAE3C,MAAM,CAAC,IAAI,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO,aAAa,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,CAAC,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAC;QAClD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -37,6 +37,14 @@ export declare class ConfigReloadService {
37
37
  * @param sessionId The session ID to remove
38
38
  */
39
39
  removeServerInfo(sessionId: string): void;
40
+ /**
41
+ * Send listChanged notifications to clients after config reload
42
+ */
43
+ private sendListChangedNotifications;
44
+ /**
45
+ * Trigger capability notifications for a specific inbound connection
46
+ */
47
+ private triggerCapabilityNotifications;
40
48
  /**
41
49
  * Stop the service and clean up resources
42
50
  */
@@ -1 +1 @@
1
- {"version":3,"file":"configReloadService.d.ts","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAM/F;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAC7C,OAAO,CAAC,eAAe,CAA6C;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,mBAAmB;IAOhD;;;OAGG;IACI,UAAU,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI;IAoB7E;;;OAGG;YACW,kBAAkB;IAiDhC;;;;OAIG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,IAAI;IAK/E;;;OAGG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKhD;;OAEG;IACI,IAAI,IAAI,IAAI;CAMpB;;AAED,wBAAiD"}
1
+ {"version":3,"file":"configReloadService.d.ts","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"AAEA,OAAO,EAAmB,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAM/F;;GAEG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAC7C,OAAO,CAAC,eAAe,CAA6C;IACpE,OAAO,CAAC,iBAAiB,CAAyC;IAClE,OAAO,CAAC,WAAW,CAAS;IAE5B;;OAEG;IACH,OAAO;IAEP;;;OAGG;WACW,WAAW,IAAI,mBAAmB;IAOhD;;;OAGG;IACI,UAAU,CAAC,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,GAAG,IAAI;IAoB7E;;;OAGG;YACW,kBAAkB;IAoDhC;;;;OAIG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,iBAAiB,GAAG,IAAI;IAK/E;;;OAGG;IACI,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAKhD;;OAEG;YACW,4BAA4B;IAuB1C;;OAEG;YACW,8BAA8B;IAgD5C;;OAEG;IACI,IAAI,IAAI,IAAI;CAMpB;;AAED,wBAAiD"}
@@ -80,6 +80,8 @@ export class ConfigReloadService {
80
80
  }
81
81
  // Update current transports
82
82
  this.currentTransports = newTransports;
83
+ // Trigger listChanged notifications after successful config reload
84
+ await this.sendListChangedNotifications();
83
85
  logger.info('Configuration reload completed successfully');
84
86
  }
85
87
  catch (error) {
@@ -106,6 +108,72 @@ export class ConfigReloadService {
106
108
  this.serverInstances.delete(sessionId);
107
109
  logger.debug(`Removed server info for session ${sessionId} from config reload service`);
108
110
  }
111
+ /**
112
+ * Send listChanged notifications to clients after config reload
113
+ */
114
+ async sendListChangedNotifications() {
115
+ try {
116
+ const serverManager = ServerManager.current;
117
+ const inboundConnections = serverManager.getInboundConnections();
118
+ // For each connected client, get their AsyncLoadingOrchestrator and refresh capabilities
119
+ for (const [sessionId, inboundConnection] of inboundConnections) {
120
+ try {
121
+ // Try to get the AsyncLoadingOrchestrator from the server context
122
+ // Note: This requires the orchestrator to be accessible
123
+ // We'll use a more direct approach to trigger listChanged notifications
124
+ await this.triggerCapabilityNotifications(inboundConnection);
125
+ }
126
+ catch (error) {
127
+ logger.error(`Failed to send listChanged notification for session ${sessionId}: ${error}`);
128
+ }
129
+ }
130
+ logger.info(`Sent listChanged notifications to ${inboundConnections.size} connected clients after config reload`);
131
+ }
132
+ catch (error) {
133
+ logger.error(`Failed to send listChanged notifications: ${error}`);
134
+ }
135
+ }
136
+ /**
137
+ * Trigger capability notifications for a specific inbound connection
138
+ */
139
+ async triggerCapabilityNotifications(inboundConnection) {
140
+ try {
141
+ // Get the current outbound connections (MCP servers)
142
+ const serverManager = ServerManager.current;
143
+ const outboundConnections = serverManager.getClients();
144
+ // Create a temporary capability aggregator to detect changes
145
+ const { CapabilityAggregator } = await import('../core/capabilities/capabilityAggregator.js');
146
+ const capabilityAggregator = new CapabilityAggregator(outboundConnections);
147
+ // Get the current capabilities
148
+ const changes = await capabilityAggregator.updateCapabilities();
149
+ // If there are capabilities to notify about, create notification manager and send
150
+ if (changes.hasChanges ||
151
+ changes.current.tools.length > 0 ||
152
+ changes.current.resources.length > 0 ||
153
+ changes.current.prompts.length > 0) {
154
+ const { NotificationManager } = await import('../core/notifications/notificationManager.js');
155
+ const notificationManager = new NotificationManager(inboundConnection);
156
+ // Force send notifications for all capability types that exist
157
+ const forcedChanges = {
158
+ toolsChanged: changes.current.tools.length > 0,
159
+ resourcesChanged: changes.current.resources.length > 0,
160
+ promptsChanged: changes.current.prompts.length > 0,
161
+ hasChanges: changes.current.tools.length > 0 ||
162
+ changes.current.resources.length > 0 ||
163
+ changes.current.prompts.length > 0,
164
+ addedServers: changes.addedServers,
165
+ removedServers: changes.removedServers,
166
+ current: changes.current,
167
+ previous: changes.previous,
168
+ };
169
+ notificationManager.handleCapabilityChanges(forcedChanges);
170
+ logger.debug(`Triggered listChanged notifications for capabilities: tools=${forcedChanges.toolsChanged}, resources=${forcedChanges.resourcesChanged}, prompts=${forcedChanges.promptsChanged}`);
171
+ }
172
+ }
173
+ catch (error) {
174
+ logger.error(`Error triggering capability notifications: ${error}`);
175
+ }
176
+ }
109
177
  /**
110
178
  * Stop the service and clean up resources
111
179
  */
@@ -1 +1 @@
1
- {"version":3,"file":"configReloadService.js","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,qBAAqB,CAAC;AACzC,OAAO,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEpF,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,iBAAiB,EAAE,MAAM,sCAAsC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAEhE;;GAEG;AACH,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAC,QAAQ,CAAsB;IACrC,eAAe,GAAmC,IAAI,GAAG,EAAE,CAAC;IAC5D,iBAAiB,GAAsC,EAAE,CAAC;IAC1D,WAAW,GAAG,KAAK,CAAC;IAE5B;;OAEG;IACH,gBAAuB,CAAC;IAExB;;;OAGG;IACI,MAAM,CAAC,WAAW;QACvB,IAAI,CAAC,mBAAmB,CAAC,QAAQ,EAAE,CAAC;YAClC,mBAAmB,CAAC,QAAQ,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAC3D,CAAC;QACD,OAAO,mBAAmB,CAAC,QAAQ,CAAC;IACtC,CAAC;IAED;;;OAGG;IACI,UAAU,CAAC,iBAAoD;QACpE,IAAI,CAAC,iBAAiB,GAAG,iBAAiB,CAAC;QAE3C,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC;QAErD,sDAAsD;QACtD,aAAa,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;QAE7E,mDAAmD;QACnD,aAAa,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;QAElC,uCAAuC;QACvC,aAAa,CAAC,EAAE,CAAC,iBAAiB,CAAC,wBAAwB,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEjG,2CAA2C;QAC3C,aAAa,CAAC,aAAa,EAAE,CAAC;QAE9B,MAAM,CAAC,IAAI,CAAC,mCAAmC,CAAC,CAAC;IACnD,CAAC;IAED;;;OAGG;IACK,KAAK,CAAC,kBAAkB,CAAC,SAA0C;QACzE,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,MAAM,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC;QAEhD,4CAA4C;QAC5C,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAEvE,IAAI,CAAC;YACH,+BAA+B;YAC/B,KAAK,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,IAAI,uBAAuB,EAAE,CAAC;gBACvD,IAAI,CAAC;oBACH,MAAM,SAAS,CAAC,KAAK,EAAE,CAAC;oBACxB,MAAM,CAAC,IAAI,CAAC,qBAAqB,GAAG,EAAE,CAAC,CAAC;gBAC1C,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,MAAM,CAAC,KAAK,CAAC,2BAA2B,GAAG,KAAK,KAAK,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC;YAED,mDAAmD;YACnD,MAAM,aAAa,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC;YAElD,wCAAwC;YACxC,MAAM,aAAa,GAAG,aAAa,CAAC,mBAAmB,EAAE,CAAC;YAC1D,MAAM,UAAU,GAAG,MAAM,aAAa,CAAC,aAAa,CAAC,aAAa,CAAC,CAAC;YAEpE,uDAAuD;YACvD,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC;YAC5C,aAAa,CAAC,0BAA0B,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YAEpE,uEAAuE;YACvE,KAAK,MAAM,UAAU,IAAI,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,EAAE,CAAC;gBACvD,MAAM,iBAAiB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;YAClD,CAAC;YAED,4BAA4B;YAC5B,IAAI,CAAC,iBAAiB,GAAG,aAAa,CAAC;YAEvC,MAAM,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,mCAAmC,KAAK,EAAE,CAAC,CAAC;QAC3D,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAED;;;;OAIG;IACI,gBAAgB,CAAC,SAAiB,EAAE,UAA6B;QACtE,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;QAChD,MAAM,CAAC,KAAK,CAAC,mCAAmC,SAAS,2BAA2B,CAAC,CAAC;IACxF,CAAC;IAED;;;OAGG;IACI,gBAAgB,CAAC,SAAiB;QACvC,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QACvC,MAAM,CAAC,KAAK,CAAC,mCAAmC,SAAS,6BAA6B,CAAC,CAAC;IAC1F,CAAC;IAED;;OAEG;IACI,IAAI;QACT,MAAM,aAAa,GAAG,gBAAgB,CAAC,WAAW,EAAE,CAAC;QACrD,aAAa,CAAC,YAAY,EAAE,CAAC;QAC7B,aAAa,CAAC,kBAAkB,CAAC,iBAAiB,CAAC,wBAAwB,CAAC,CAAC;QAC7E,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IAC/C,CAAC;CACF;AAED,eAAe,mBAAmB,CAAC,WAAW,EAAE,CAAC"}
1
+ {"version":3,"file":"configReloadService.js","sourceRoot":"","sources":["../../src/services/configReloadService.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+ import { McpLoadingManager } from '../../../core/loading/mcpLoadingManager.js';
3
+ /**
4
+ * Extended request interface to include MCP loading information
5
+ */
6
+ export interface McpRequest extends Request {
7
+ mcpAvailability?: {
8
+ availableServers: string[];
9
+ unavailableServers: string[];
10
+ loadingServers: string[];
11
+ oauthRequiredServers: string[];
12
+ hasPartialAvailability: boolean;
13
+ allServersReady: boolean;
14
+ requestedTags?: string[];
15
+ totalServersBeforeFiltering?: number;
16
+ };
17
+ }
18
+ /**
19
+ * Middleware options for MCP availability checking
20
+ */
21
+ export interface McpAvailabilityOptions {
22
+ /** Whether to allow requests when some servers are still loading */
23
+ allowPartialAvailability?: boolean;
24
+ /** Whether to include OAuth-required servers as available */
25
+ includeOAuthServers?: boolean;
26
+ /** Custom error message for unavailable servers */
27
+ unavailableMessage?: string;
28
+ /** Custom error message for loading servers */
29
+ loadingMessage?: string;
30
+ }
31
+ /**
32
+ * Creates middleware that checks MCP server availability before processing requests
33
+ *
34
+ * This middleware examines the loading state of MCP servers and provides different
35
+ * behaviors based on server availability and configuration options.
36
+ *
37
+ * @param loadingManager - The MCP loading manager instance
38
+ * @param options - Configuration options for availability checking
39
+ * @returns Express middleware function
40
+ *
41
+ * @example
42
+ * ```typescript
43
+ * const availabilityMiddleware = createMcpAvailabilityMiddleware(loadingManager, {
44
+ * allowPartialAvailability: true,
45
+ * includeOAuthServers: false,
46
+ * });
47
+ *
48
+ * router.post('/mcp', availabilityMiddleware, (req, res) => {
49
+ * // Handle MCP request with availability info in req.mcpAvailability
50
+ * });
51
+ * ```
52
+ */
53
+ export declare function createMcpAvailabilityMiddleware(loadingManager?: McpLoadingManager, options?: McpAvailabilityOptions): (req: McpRequest, res: Response, next: NextFunction) => void;
54
+ /**
55
+ * Utility function to get MCP availability info from request
56
+ */
57
+ export declare function getMcpAvailability(req: Request): {
58
+ availableServers: string[];
59
+ unavailableServers: string[];
60
+ loadingServers: string[];
61
+ oauthRequiredServers: string[];
62
+ hasPartialAvailability: boolean;
63
+ allServersReady: boolean;
64
+ requestedTags?: string[];
65
+ totalServersBeforeFiltering?: number;
66
+ } | undefined;
67
+ /**
68
+ * Utility function to check if all MCP servers are ready
69
+ */
70
+ export declare function areAllMcpServersReady(req: Request): boolean;
71
+ /**
72
+ * Utility function to get list of available MCP servers
73
+ */
74
+ export declare function getAvailableMcpServers(req: Request): string[];
75
+ /**
76
+ * Utility function to get list of loading MCP servers
77
+ */
78
+ export declare function getLoadingMcpServers(req: Request): string[];
79
+ //# sourceMappingURL=mcpAvailabilityMiddleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpAvailabilityMiddleware.d.ts","sourceRoot":"","sources":["../../../../src/transport/http/middlewares/mcpAvailabilityMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAG1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,4CAA4C,CAAC;AAM/E;;GAEG;AACH,MAAM,WAAW,UAAW,SAAQ,OAAO;IACzC,eAAe,CAAC,EAAE;QAChB,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,kBAAkB,EAAE,MAAM,EAAE,CAAC;QAC7B,cAAc,EAAE,MAAM,EAAE,CAAC;QACzB,oBAAoB,EAAE,MAAM,EAAE,CAAC;QAC/B,sBAAsB,EAAE,OAAO,CAAC;QAChC,eAAe,EAAE,OAAO,CAAC;QACzB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;QACzB,2BAA2B,CAAC,EAAE,MAAM,CAAC;KACtC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,wBAAwB,CAAC,EAAE,OAAO,CAAC;IACnC,6DAA6D;IAC7D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,mDAAmD;IACnD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAYD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,+BAA+B,CAC7C,cAAc,CAAC,EAAE,iBAAiB,EAClC,OAAO,GAAE,sBAA2B,IAI5B,KAAK,UAAU,EAAE,KAAK,QAAQ,EAAE,MAAM,YAAY,UA0R3D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO;sBA9VzB,MAAM,EAAE;wBACN,MAAM,EAAE;oBACZ,MAAM,EAAE;0BACF,MAAM,EAAE;4BACN,OAAO;qBACd,OAAO;oBACR,MAAM,EAAE;kCACM,MAAM;cAyVvC;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAG3D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAG7D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAG3D"}
@@ -0,0 +1,306 @@
1
+ import logger from '../../../logger/logger.js';
2
+ import { secureLogger } from '../../../logger/secureLogger.js';
3
+ import { LoadingState } from '../../../core/loading/loadingStateTracker.js';
4
+ import { getValidatedTags } from './scopeAuthMiddleware.js';
5
+ import { McpConfigManager } from '../../../config/mcpConfigManager.js';
6
+ import { sanitizeOAuthServerList } from '../../../logger/secureLogger.js';
7
+ /**
8
+ * Default options for MCP availability middleware
9
+ */
10
+ const DEFAULT_OPTIONS = {
11
+ allowPartialAvailability: true,
12
+ includeOAuthServers: false,
13
+ unavailableMessage: 'Some requested MCP servers are not available',
14
+ loadingMessage: 'Some requested MCP servers are still loading',
15
+ };
16
+ /**
17
+ * Creates middleware that checks MCP server availability before processing requests
18
+ *
19
+ * This middleware examines the loading state of MCP servers and provides different
20
+ * behaviors based on server availability and configuration options.
21
+ *
22
+ * @param loadingManager - The MCP loading manager instance
23
+ * @param options - Configuration options for availability checking
24
+ * @returns Express middleware function
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const availabilityMiddleware = createMcpAvailabilityMiddleware(loadingManager, {
29
+ * allowPartialAvailability: true,
30
+ * includeOAuthServers: false,
31
+ * });
32
+ *
33
+ * router.post('/mcp', availabilityMiddleware, (req, res) => {
34
+ * // Handle MCP request with availability info in req.mcpAvailability
35
+ * });
36
+ * ```
37
+ */
38
+ export function createMcpAvailabilityMiddleware(loadingManager, options = {}) {
39
+ const opts = { ...DEFAULT_OPTIONS, ...options };
40
+ return (req, res, next) => {
41
+ try {
42
+ // If no loading manager, assume all servers are available (legacy mode)
43
+ if (!loadingManager) {
44
+ logger.debug('No loading manager - assuming all servers available');
45
+ next();
46
+ return;
47
+ }
48
+ // Get requested tags from scope auth middleware
49
+ const requestedTags = getValidatedTags(res);
50
+ // If no specific tags requested, get all servers
51
+ const stateTracker = loadingManager.getStateTracker();
52
+ const allStates = stateTracker.getAllServerStates();
53
+ // Filter servers based on requested tags
54
+ // Tags are used to control which MCP servers are available for requests.
55
+ // When tags are specified, only servers that have ALL the requested tags will be included.
56
+ const allServers = Array.from(allStates.keys());
57
+ let relevantServers;
58
+ if (requestedTags && requestedTags.length > 0) {
59
+ // Get server configurations to access tags
60
+ const configManager = McpConfigManager.getInstance();
61
+ const transportConfig = configManager.getTransportConfig();
62
+ // Filter servers that have ALL requested tags
63
+ // This implements the "AND" logic: servers must have every requested tag
64
+ relevantServers = allServers.filter((serverName) => {
65
+ const serverConfig = transportConfig[serverName];
66
+ if (!serverConfig || !serverConfig.tags) {
67
+ // Server has no tags, so it doesn't match any tag request
68
+ return false;
69
+ }
70
+ // Check if server has ALL requested tags (case-insensitive matching)
71
+ const serverTags = serverConfig.tags.map((tag) => tag.toLowerCase());
72
+ const requestedTagsLower = requestedTags.map((tag) => tag.toLowerCase());
73
+ return requestedTagsLower.every((requestedTag) => serverTags.includes(requestedTag));
74
+ });
75
+ logger.debug(`Filtered ${relevantServers.length}/${allServers.length} servers ` + `with tags: ${requestedTags.join(', ')}`);
76
+ }
77
+ else {
78
+ relevantServers = allServers;
79
+ logger.debug(`Checking availability for all ${relevantServers.length} servers`);
80
+ }
81
+ // Categorize servers by state with detailed error information
82
+ const availableServers = [];
83
+ const unavailableServers = [];
84
+ const loadingServers = [];
85
+ const oauthRequiredServers = [];
86
+ // Collect detailed server information for error responses
87
+ const serverDetails = {};
88
+ for (const serverName of relevantServers) {
89
+ const serverInfo = stateTracker.getServerState(serverName);
90
+ if (!serverInfo) {
91
+ unavailableServers.push(serverName);
92
+ serverDetails[serverName] = {
93
+ state: 'unknown',
94
+ error: 'Server not found in loading state tracker',
95
+ };
96
+ continue;
97
+ }
98
+ // Store detailed information for this server
99
+ serverDetails[serverName] = {
100
+ state: serverInfo.state,
101
+ error: serverInfo.error?.message,
102
+ duration: serverInfo.duration,
103
+ retryCount: serverInfo.retryCount,
104
+ authUrl: serverInfo.authorizationUrl,
105
+ };
106
+ switch (serverInfo.state) {
107
+ case LoadingState.Ready:
108
+ availableServers.push(serverName);
109
+ break;
110
+ case LoadingState.Loading:
111
+ case LoadingState.Pending:
112
+ loadingServers.push(serverName);
113
+ break;
114
+ case LoadingState.AwaitingOAuth:
115
+ if (opts.includeOAuthServers) {
116
+ availableServers.push(serverName);
117
+ }
118
+ else {
119
+ oauthRequiredServers.push(serverName);
120
+ }
121
+ break;
122
+ case LoadingState.Failed:
123
+ case LoadingState.Cancelled:
124
+ default:
125
+ unavailableServers.push(serverName);
126
+ break;
127
+ }
128
+ }
129
+ // Calculate availability metrics
130
+ const hasPartialAvailability = availableServers.length > 0;
131
+ const allServersReady = relevantServers.length > 0 && availableServers.length === relevantServers.length;
132
+ // Add availability info to request
133
+ req.mcpAvailability = {
134
+ availableServers,
135
+ unavailableServers,
136
+ loadingServers,
137
+ oauthRequiredServers,
138
+ hasPartialAvailability,
139
+ allServersReady,
140
+ requestedTags: requestedTags && requestedTags.length > 0 ? requestedTags : undefined,
141
+ totalServersBeforeFiltering: requestedTags && requestedTags.length > 0 ? allServers.length : undefined,
142
+ };
143
+ // Log availability status
144
+ const tagInfo = requestedTags && requestedTags.length > 0
145
+ ? ` (filtered by tags: ${requestedTags.join(', ')}, ${allServers.length} total)`
146
+ : '';
147
+ const oauthCount = oauthRequiredServers.length;
148
+ secureLogger.debug(`MCP Availability: ${availableServers.length}/${relevantServers.length} ready, ` +
149
+ `${loadingServers.length} loading, ${unavailableServers.length} failed, ` +
150
+ `${oauthCount} OAuth required${tagInfo}`);
151
+ // Decide whether to proceed based on availability
152
+ if (relevantServers.length === 0) {
153
+ // No servers configured - proceed normally
154
+ next();
155
+ return;
156
+ }
157
+ if (allServersReady) {
158
+ // All servers ready - proceed normally
159
+ next();
160
+ return;
161
+ }
162
+ if (!hasPartialAvailability) {
163
+ // No servers available - return error with detailed information
164
+ logger.warn('No MCP servers available for request');
165
+ // Create detailed error message including specific server failures
166
+ const failureDetails = unavailableServers
167
+ .map((name) => {
168
+ const detail = serverDetails[name];
169
+ if (detail.error) {
170
+ return `${name}: ${detail.error} (retries: ${detail.retryCount || 0})`;
171
+ }
172
+ return `${name}: ${detail.state}`;
173
+ })
174
+ .join(', ');
175
+ const detailedMessage = unavailableServers.length > 0
176
+ ? `No MCP servers are currently available. Failed servers: ${failureDetails}`
177
+ : 'No MCP servers are currently available';
178
+ res.status(503).json({
179
+ error: 'service_unavailable',
180
+ message: detailedMessage,
181
+ details: {
182
+ total: relevantServers.length,
183
+ available: availableServers.length,
184
+ loading: loadingServers.length,
185
+ failed: unavailableServers.length,
186
+ oauthRequired: oauthRequiredServers.length,
187
+ availableList: availableServers,
188
+ loadingList: loadingServers,
189
+ failedList: unavailableServers,
190
+ oauthRequiredList: sanitizeOAuthServerList(oauthRequiredServers),
191
+ },
192
+ serverDetails,
193
+ loading: {
194
+ isComplete: stateTracker.isLoadingComplete(),
195
+ summary: loadingManager.getSummary(),
196
+ },
197
+ timestamp: new Date().toISOString(),
198
+ });
199
+ return;
200
+ }
201
+ if (opts.allowPartialAvailability) {
202
+ // Some servers available - proceed with warning
203
+ logger.info(`Proceeding with partial MCP availability: ${availableServers.length}/${relevantServers.length} servers ready`);
204
+ // Add warning headers
205
+ res.setHeader('X-MCP-Partial-Availability', 'true');
206
+ res.setHeader('X-MCP-Available-Count', availableServers.length.toString());
207
+ res.setHeader('X-MCP-Total-Count', relevantServers.length.toString());
208
+ if (loadingServers.length > 0) {
209
+ res.setHeader('X-MCP-Loading-Count', loadingServers.length.toString());
210
+ }
211
+ next();
212
+ return;
213
+ }
214
+ else {
215
+ // Partial availability not allowed - return error with detailed information
216
+ logger.warn('Partial MCP availability not allowed - blocking request');
217
+ const primaryReason = loadingServers.length > 0 ? 'loading' : 'unavailable';
218
+ let detailedMessage = primaryReason === 'loading' ? opts.loadingMessage : opts.unavailableMessage;
219
+ // Add specific error details for unavailable servers
220
+ if (unavailableServers.length > 0) {
221
+ const failureDetails = unavailableServers
222
+ .map((name) => {
223
+ const detail = serverDetails[name];
224
+ if (detail.error) {
225
+ return `${name}: ${detail.error} (retries: ${detail.retryCount || 0})`;
226
+ }
227
+ return `${name}: ${detail.state}`;
228
+ })
229
+ .join(', ');
230
+ detailedMessage += `. Failed servers: ${failureDetails}`;
231
+ }
232
+ // Add loading server details
233
+ if (loadingServers.length > 0) {
234
+ const loadingDetails = loadingServers
235
+ .map((name) => {
236
+ const detail = serverDetails[name];
237
+ const retryInfo = detail.retryCount && detail.retryCount > 0 ? ` (retry ${detail.retryCount})` : '';
238
+ return `${name}: ${detail.state}${retryInfo}`;
239
+ })
240
+ .join(', ');
241
+ detailedMessage +=
242
+ primaryReason === 'loading'
243
+ ? `. Loading servers: ${loadingDetails}`
244
+ : ` Currently loading: ${loadingDetails}`;
245
+ }
246
+ res.status(primaryReason === 'loading' ? 202 : 503).json({
247
+ error: primaryReason === 'loading' ? 'servers_loading' : 'servers_unavailable',
248
+ message: detailedMessage,
249
+ details: {
250
+ total: relevantServers.length,
251
+ available: availableServers.length,
252
+ loading: loadingServers.length,
253
+ failed: unavailableServers.length,
254
+ oauthRequired: oauthRequiredServers.length,
255
+ availableList: availableServers,
256
+ loadingList: loadingServers,
257
+ failedList: unavailableServers,
258
+ oauthRequiredList: sanitizeOAuthServerList(oauthRequiredServers),
259
+ },
260
+ serverDetails,
261
+ loading: {
262
+ isComplete: stateTracker.isLoadingComplete(),
263
+ summary: loadingManager.getSummary(),
264
+ },
265
+ retryAfter: primaryReason === 'loading' ? 30 : undefined, // Suggest retry in 30 seconds for loading
266
+ timestamp: new Date().toISOString(),
267
+ });
268
+ return;
269
+ }
270
+ }
271
+ catch (error) {
272
+ logger.error('MCP availability check failed:', error);
273
+ // On error, proceed normally to avoid blocking requests
274
+ // This ensures the system remains functional even if availability checking fails
275
+ next();
276
+ }
277
+ };
278
+ }
279
+ /**
280
+ * Utility function to get MCP availability info from request
281
+ */
282
+ export function getMcpAvailability(req) {
283
+ return req.mcpAvailability;
284
+ }
285
+ /**
286
+ * Utility function to check if all MCP servers are ready
287
+ */
288
+ export function areAllMcpServersReady(req) {
289
+ const availability = getMcpAvailability(req);
290
+ return availability?.allServersReady ?? true; // Assume ready if no availability info
291
+ }
292
+ /**
293
+ * Utility function to get list of available MCP servers
294
+ */
295
+ export function getAvailableMcpServers(req) {
296
+ const availability = getMcpAvailability(req);
297
+ return availability?.availableServers ?? [];
298
+ }
299
+ /**
300
+ * Utility function to get list of loading MCP servers
301
+ */
302
+ export function getLoadingMcpServers(req) {
303
+ const availability = getMcpAvailability(req);
304
+ return availability?.loadingServers ?? [];
305
+ }
306
+ //# sourceMappingURL=mcpAvailabilityMiddleware.js.map