@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
@@ -0,0 +1,156 @@
1
+ import { EventEmitter } from 'events';
2
+ import { OutboundConnections, AuthProviderTransport } from '../types/index.js';
3
+ import { ClientManager } from '../client/clientManager.js';
4
+ import { LoadingStateTracker, LoadingSummary } from './loadingStateTracker.js';
5
+ /**
6
+ * Configuration options for MCP loading behavior
7
+ */
8
+ export interface McpLoadingConfig {
9
+ /** Maximum time to wait for each server (ms) */
10
+ readonly serverTimeoutMs: number;
11
+ /** Maximum number of retry attempts per server */
12
+ readonly maxRetries: number;
13
+ /** Initial delay between retries (ms) */
14
+ readonly retryDelayMs: number;
15
+ /** Maximum number of servers to initialize concurrently */
16
+ readonly maxConcurrentLoads: number;
17
+ /** Whether to continue loading other servers if some fail */
18
+ readonly continueOnFailure: boolean;
19
+ /** Whether to enable background retry for failed servers */
20
+ readonly enableBackgroundRetry: boolean;
21
+ /** Interval for background retry attempts (ms) */
22
+ readonly backgroundRetryIntervalMs: number;
23
+ }
24
+ /**
25
+ * Default configuration for MCP loading
26
+ */
27
+ export declare const DEFAULT_LOADING_CONFIG: McpLoadingConfig;
28
+ /**
29
+ * Result of loading a specific server
30
+ */
31
+ interface ServerLoadResult {
32
+ readonly name: string;
33
+ readonly success: boolean;
34
+ readonly error?: Error;
35
+ readonly duration: number;
36
+ readonly retryCount: number;
37
+ }
38
+ /**
39
+ * Events emitted by McpLoadingManager
40
+ */
41
+ export interface McpLoadingEvents {
42
+ 'loading-started': (serverNames: string[]) => void;
43
+ 'server-loading': (name: string) => void;
44
+ 'server-loaded': (name: string, result: ServerLoadResult) => void;
45
+ 'server-failed': (name: string, result: ServerLoadResult) => void;
46
+ 'oauth-required': (name: string, authUrl?: string) => void;
47
+ 'loading-progress': (summary: LoadingSummary) => void;
48
+ 'loading-complete': (summary: LoadingSummary) => void;
49
+ 'background-retry': (name: string, attempt: number) => void;
50
+ }
51
+ /**
52
+ * Manages asynchronous loading of MCP servers without blocking HTTP server startup
53
+ *
54
+ * This manager coordinates the initialization of multiple MCP servers in parallel,
55
+ * provides real-time status updates, and handles retries and error recovery.
56
+ * The HTTP server can start immediately while this manager loads servers in the background.
57
+ *
58
+ * @example
59
+ * ```typescript
60
+ * const manager = new McpLoadingManager(clientManager, config);
61
+ * manager.on('loading-complete', (summary) => {
62
+ * console.log(`${summary.ready}/${summary.totalServers} servers ready`);
63
+ * });
64
+ *
65
+ * // Start loading asynchronously
66
+ * const loadingPromise = manager.startAsyncLoading(transports);
67
+ *
68
+ * // HTTP server can start immediately
69
+ * const expressServer = new ExpressServer(serverManager);
70
+ * expressServer.start();
71
+ *
72
+ * // Optionally wait for loading to complete
73
+ * await loadingPromise;
74
+ * ```
75
+ */
76
+ export declare class McpLoadingManager extends EventEmitter {
77
+ private clientManager;
78
+ private config;
79
+ private stateTracker;
80
+ private loadingSemaphore;
81
+ private backgroundRetryTimer?;
82
+ private isShuttingDown;
83
+ private abortControllers;
84
+ constructor(clientManager: ClientManager, config?: Partial<McpLoadingConfig>);
85
+ /**
86
+ * Start asynchronous loading of MCP servers
87
+ * Returns immediately, loading happens in background
88
+ */
89
+ startAsyncLoading(transports: Record<string, AuthProviderTransport>): Promise<OutboundConnections>;
90
+ /**
91
+ * Load servers with concurrency control
92
+ */
93
+ private loadServersWithConcurrency;
94
+ /**
95
+ * Load a single server with retry logic
96
+ */
97
+ private loadSingleServer;
98
+ /**
99
+ * Create client with timeout and cancellation support
100
+ */
101
+ private createClientWithTimeout;
102
+ /**
103
+ * Set up background retry for failed servers
104
+ */
105
+ private setupBackgroundRetry;
106
+ /**
107
+ * Perform background retry for failed servers
108
+ */
109
+ private performBackgroundRetry;
110
+ /**
111
+ * Get current loading state tracker
112
+ */
113
+ getStateTracker(): LoadingStateTracker;
114
+ /**
115
+ * Get current loading summary
116
+ */
117
+ getSummary(): LoadingSummary;
118
+ /**
119
+ * Check if a specific server is ready
120
+ */
121
+ isServerReady(name: string): boolean;
122
+ /**
123
+ * Get list of ready servers
124
+ */
125
+ getReadyServers(): string[];
126
+ /**
127
+ * Get list of failed servers
128
+ */
129
+ getFailedServers(): string[];
130
+ /**
131
+ * Cancel loading of a specific server
132
+ */
133
+ cancelServerLoading(serverName: string): void;
134
+ /**
135
+ * Cancel loading of multiple servers
136
+ */
137
+ cancelServersLoading(serverNames: string[]): void;
138
+ /**
139
+ * Cancel all currently loading servers
140
+ */
141
+ cancelAllLoading(): void;
142
+ /**
143
+ * Get list of servers that are currently being loaded and can be cancelled
144
+ */
145
+ getCancellableServers(): string[];
146
+ /**
147
+ * Shutdown the loading manager
148
+ */
149
+ shutdown(): void;
150
+ /**
151
+ * Utility method for sleeping
152
+ */
153
+ private sleep;
154
+ }
155
+ export {};
156
+ //# sourceMappingURL=mcpLoadingManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpLoadingManager.d.ts","sourceRoot":"","sources":["../../../src/core/loading/mcpLoadingManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,352 @@
1
+ import { EventEmitter } from 'events';
2
+ import { LoadingStateTracker, LoadingState } from './loadingStateTracker.js';
3
+ import logger from '../../logger/logger.js';
4
+ /**
5
+ * Default configuration for MCP loading
6
+ */
7
+ export const DEFAULT_LOADING_CONFIG = {
8
+ serverTimeoutMs: 30000, // 30 seconds per server
9
+ maxRetries: 3,
10
+ retryDelayMs: 2000, // 2 seconds initial delay
11
+ maxConcurrentLoads: 5, // Load 5 servers at once
12
+ continueOnFailure: true,
13
+ enableBackgroundRetry: true,
14
+ backgroundRetryIntervalMs: 60000, // Retry every minute
15
+ };
16
+ /**
17
+ * Manages asynchronous loading of MCP servers without blocking HTTP server startup
18
+ *
19
+ * This manager coordinates the initialization of multiple MCP servers in parallel,
20
+ * provides real-time status updates, and handles retries and error recovery.
21
+ * The HTTP server can start immediately while this manager loads servers in the background.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * const manager = new McpLoadingManager(clientManager, config);
26
+ * manager.on('loading-complete', (summary) => {
27
+ * console.log(`${summary.ready}/${summary.totalServers} servers ready`);
28
+ * });
29
+ *
30
+ * // Start loading asynchronously
31
+ * const loadingPromise = manager.startAsyncLoading(transports);
32
+ *
33
+ * // HTTP server can start immediately
34
+ * const expressServer = new ExpressServer(serverManager);
35
+ * expressServer.start();
36
+ *
37
+ * // Optionally wait for loading to complete
38
+ * await loadingPromise;
39
+ * ```
40
+ */
41
+ export class McpLoadingManager extends EventEmitter {
42
+ clientManager;
43
+ config;
44
+ stateTracker;
45
+ loadingSemaphore = new Map();
46
+ backgroundRetryTimer;
47
+ isShuttingDown = false;
48
+ abortControllers = new Map();
49
+ constructor(clientManager, config = {}) {
50
+ super();
51
+ this.clientManager = clientManager;
52
+ this.config = { ...DEFAULT_LOADING_CONFIG, ...config };
53
+ this.stateTracker = new LoadingStateTracker();
54
+ // Forward state tracker events
55
+ this.stateTracker.on('server-state-changed', (name, info) => {
56
+ if (info.state === LoadingState.Ready) {
57
+ this.emit('server-loaded', name, {
58
+ name,
59
+ success: true,
60
+ duration: info.duration || 0,
61
+ retryCount: info.retryCount,
62
+ });
63
+ }
64
+ else if (info.state === LoadingState.Failed) {
65
+ this.emit('server-failed', name, {
66
+ name,
67
+ success: false,
68
+ error: info.error,
69
+ duration: info.duration || 0,
70
+ retryCount: info.retryCount,
71
+ });
72
+ }
73
+ else if (info.state === LoadingState.AwaitingOAuth) {
74
+ this.emit('oauth-required', name, info.authorizationUrl);
75
+ }
76
+ });
77
+ this.stateTracker.on('loading-progress', (summary) => {
78
+ this.emit('loading-progress', summary);
79
+ });
80
+ this.stateTracker.on('loading-complete', (summary) => {
81
+ this.emit('loading-complete', summary);
82
+ this.setupBackgroundRetry();
83
+ });
84
+ this.setMaxListeners(100); // Allow many listeners
85
+ }
86
+ /**
87
+ * Start asynchronous loading of MCP servers
88
+ * Returns immediately, loading happens in background
89
+ */
90
+ async startAsyncLoading(transports) {
91
+ const serverNames = Object.keys(transports);
92
+ if (serverNames.length === 0) {
93
+ logger.info('No MCP servers to load');
94
+ return new Map();
95
+ }
96
+ logger.info(`Starting async loading of ${serverNames.length} MCP servers`);
97
+ this.stateTracker.startLoading(serverNames);
98
+ this.emit('loading-started', serverNames);
99
+ // Start loading servers with concurrency control
100
+ this.loadServersWithConcurrency(transports);
101
+ // Return current connections (may be empty initially)
102
+ return this.clientManager.getClients();
103
+ }
104
+ /**
105
+ * Load servers with concurrency control
106
+ */
107
+ async loadServersWithConcurrency(transports) {
108
+ const serverEntries = Object.entries(transports);
109
+ const semaphore = new Map();
110
+ // Process servers in batches based on maxConcurrentLoads
111
+ for (let i = 0; i < serverEntries.length; i += this.config.maxConcurrentLoads) {
112
+ const batch = serverEntries.slice(i, i + this.config.maxConcurrentLoads);
113
+ // Start all servers in this batch
114
+ const batchPromises = batch.map(([name, transport]) => {
115
+ const loadPromise = this.loadSingleServer(name, transport);
116
+ semaphore.set(name, loadPromise);
117
+ return loadPromise;
118
+ });
119
+ // Wait for this batch to complete before starting next batch
120
+ await Promise.allSettled(batchPromises);
121
+ // Clean up completed promises
122
+ for (const [name] of batch) {
123
+ semaphore.delete(name);
124
+ }
125
+ if (this.isShuttingDown) {
126
+ logger.info('Loading cancelled due to shutdown');
127
+ break;
128
+ }
129
+ }
130
+ logger.info('Initial server loading phase completed');
131
+ }
132
+ /**
133
+ * Load a single server with retry logic
134
+ */
135
+ async loadSingleServer(name, transport) {
136
+ if (this.isShuttingDown)
137
+ return;
138
+ this.emit('server-loading', name);
139
+ this.stateTracker.updateServerState(name, LoadingState.Loading, {
140
+ progress: { phase: 'initializing', message: 'Starting server connection' },
141
+ });
142
+ let lastError;
143
+ let retryCount = 0;
144
+ while (retryCount <= this.config.maxRetries && !this.isShuttingDown) {
145
+ try {
146
+ this.stateTracker.updateServerState(name, LoadingState.Loading, {
147
+ progress: {
148
+ phase: retryCount > 0 ? 'retrying' : 'connecting',
149
+ message: retryCount > 0 ? `Retry attempt ${retryCount}` : 'Connecting to server',
150
+ },
151
+ });
152
+ // Attempt to create and connect client
153
+ await this.createClientWithTimeout(name, transport);
154
+ // Success!
155
+ this.stateTracker.updateServerState(name, LoadingState.Ready);
156
+ logger.info(`Successfully loaded MCP server: ${name} (${retryCount} retries)`);
157
+ return;
158
+ }
159
+ catch (error) {
160
+ lastError = error instanceof Error ? error : new Error(String(error));
161
+ retryCount++;
162
+ this.stateTracker.incrementRetryCount(name);
163
+ // Handle OAuth case specially
164
+ if (lastError.name === 'OAuthRequiredError') {
165
+ logger.info(`OAuth required for ${name}`);
166
+ this.stateTracker.updateServerState(name, LoadingState.AwaitingOAuth, {
167
+ error: lastError,
168
+ });
169
+ return; // Don't retry OAuth errors
170
+ }
171
+ // Handle other errors
172
+ logger.warn(`Failed to load ${name} (attempt ${retryCount}): ${lastError.message}`);
173
+ if (retryCount <= this.config.maxRetries && !this.isShuttingDown) {
174
+ const delay = this.config.retryDelayMs * Math.pow(2, retryCount - 1); // Exponential backoff
175
+ logger.info(`Retrying ${name} in ${delay}ms...`);
176
+ await this.sleep(delay);
177
+ }
178
+ }
179
+ }
180
+ // All retries exhausted
181
+ this.stateTracker.updateServerState(name, LoadingState.Failed, {
182
+ error: lastError || new Error('Unknown error'),
183
+ });
184
+ if (this.config.continueOnFailure) {
185
+ logger.error(`Failed to load ${name} after ${this.config.maxRetries} retries, continuing with other servers`);
186
+ }
187
+ else {
188
+ logger.error(`Failed to load ${name}, stopping loading process`);
189
+ throw lastError;
190
+ }
191
+ }
192
+ /**
193
+ * Create client with timeout and cancellation support
194
+ */
195
+ async createClientWithTimeout(name, transport) {
196
+ // Create abort controller for this specific server loading operation
197
+ const abortController = new AbortController();
198
+ this.abortControllers.set(name, abortController);
199
+ try {
200
+ const timeoutPromise = new Promise((_, reject) => {
201
+ const timeoutId = setTimeout(() => {
202
+ abortController.abort();
203
+ reject(new Error(`Timeout loading ${name} after ${this.config.serverTimeoutMs}ms`));
204
+ }, this.config.serverTimeoutMs);
205
+ // Clear timeout if operation is aborted
206
+ abortController.signal.addEventListener('abort', () => {
207
+ clearTimeout(timeoutId);
208
+ reject(new Error(`Loading ${name} was cancelled`));
209
+ });
210
+ });
211
+ const loadPromise = this.clientManager.createSingleClient(name, transport, abortController.signal);
212
+ await Promise.race([loadPromise, timeoutPromise]);
213
+ }
214
+ finally {
215
+ // Clean up abort controller
216
+ this.abortControllers.delete(name);
217
+ }
218
+ }
219
+ /**
220
+ * Set up background retry for failed servers
221
+ */
222
+ setupBackgroundRetry() {
223
+ if (!this.config.enableBackgroundRetry || this.isShuttingDown) {
224
+ return;
225
+ }
226
+ this.backgroundRetryTimer = setInterval(() => {
227
+ this.performBackgroundRetry();
228
+ }, this.config.backgroundRetryIntervalMs);
229
+ logger.info('Background retry enabled for failed servers');
230
+ }
231
+ /**
232
+ * Perform background retry for failed servers
233
+ */
234
+ async performBackgroundRetry() {
235
+ if (this.isShuttingDown)
236
+ return;
237
+ const failedServers = this.stateTracker.getServersByState(LoadingState.Failed);
238
+ if (failedServers.length === 0) {
239
+ return;
240
+ }
241
+ logger.info(`Background retry for ${failedServers.length} failed servers`);
242
+ // Retry a subset of failed servers to avoid overwhelming the system
243
+ const serversToRetry = failedServers.slice(0, 3); // Retry max 3 at a time
244
+ for (const serverInfo of serversToRetry) {
245
+ if (this.isShuttingDown)
246
+ break;
247
+ const transport = this.clientManager.getTransport(serverInfo.name);
248
+ if (transport) {
249
+ this.emit('background-retry', serverInfo.name, serverInfo.retryCount + 1);
250
+ // Don't wait for completion, let it run in background
251
+ this.loadSingleServer(serverInfo.name, transport).catch((error) => {
252
+ logger.debug(`Background retry failed for ${serverInfo.name}: ${error.message}`);
253
+ });
254
+ }
255
+ }
256
+ }
257
+ /**
258
+ * Get current loading state tracker
259
+ */
260
+ getStateTracker() {
261
+ return this.stateTracker;
262
+ }
263
+ /**
264
+ * Get current loading summary
265
+ */
266
+ getSummary() {
267
+ return this.stateTracker.getSummary();
268
+ }
269
+ /**
270
+ * Check if a specific server is ready
271
+ */
272
+ isServerReady(name) {
273
+ const state = this.stateTracker.getServerState(name);
274
+ return state?.state === LoadingState.Ready;
275
+ }
276
+ /**
277
+ * Get list of ready servers
278
+ */
279
+ getReadyServers() {
280
+ return this.stateTracker.getServersByState(LoadingState.Ready).map((s) => s.name);
281
+ }
282
+ /**
283
+ * Get list of failed servers
284
+ */
285
+ getFailedServers() {
286
+ return this.stateTracker.getServersByState(LoadingState.Failed).map((s) => s.name);
287
+ }
288
+ /**
289
+ * Cancel loading of a specific server
290
+ */
291
+ cancelServerLoading(serverName) {
292
+ const abortController = this.abortControllers.get(serverName);
293
+ if (abortController) {
294
+ logger.info(`Cancelling loading of server: ${serverName}`);
295
+ abortController.abort();
296
+ this.stateTracker.updateServerState(serverName, LoadingState.Cancelled);
297
+ }
298
+ else {
299
+ logger.warn(`No active loading operation found for server: ${serverName}`);
300
+ }
301
+ }
302
+ /**
303
+ * Cancel loading of multiple servers
304
+ */
305
+ cancelServersLoading(serverNames) {
306
+ for (const serverName of serverNames) {
307
+ this.cancelServerLoading(serverName);
308
+ }
309
+ }
310
+ /**
311
+ * Cancel all currently loading servers
312
+ */
313
+ cancelAllLoading() {
314
+ const loadingServers = Array.from(this.abortControllers.keys());
315
+ if (loadingServers.length > 0) {
316
+ logger.info(`Cancelling loading of ${loadingServers.length} servers`);
317
+ this.cancelServersLoading(loadingServers);
318
+ }
319
+ }
320
+ /**
321
+ * Get list of servers that are currently being loaded and can be cancelled
322
+ */
323
+ getCancellableServers() {
324
+ return Array.from(this.abortControllers.keys());
325
+ }
326
+ /**
327
+ * Shutdown the loading manager
328
+ */
329
+ shutdown() {
330
+ this.isShuttingDown = true;
331
+ if (this.backgroundRetryTimer) {
332
+ clearInterval(this.backgroundRetryTimer);
333
+ this.backgroundRetryTimer = undefined;
334
+ }
335
+ // Cancel any active loading operations
336
+ this.cancelAllLoading();
337
+ // Update state for any remaining pending/loading servers
338
+ const pendingServers = this.stateTracker.getServersByState(LoadingState.Pending);
339
+ const loadingServers = this.stateTracker.getServersByState(LoadingState.Loading);
340
+ for (const server of [...pendingServers, ...loadingServers]) {
341
+ this.stateTracker.updateServerState(server.name, LoadingState.Cancelled);
342
+ }
343
+ logger.info('MCP loading manager shutdown complete');
344
+ }
345
+ /**
346
+ * Utility method for sleeping
347
+ */
348
+ sleep(ms) {
349
+ return new Promise((resolve) => setTimeout(resolve, ms));
350
+ }
351
+ }
352
+ //# sourceMappingURL=mcpLoadingManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcpLoadingManager.js","sourceRoot":"","sources":["../../../src/core/loading/mcpLoadingManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import { EventEmitter } from 'events';
2
+ import { InboundConnection } from '../types/index.js';
3
+ import { CapabilityChanges } from '../capabilities/capabilityAggregator.js';
4
+ /**
5
+ * Configuration for notification batching and behavior
6
+ */
7
+ export interface NotificationConfig {
8
+ /** Whether to enable notification batching */
9
+ readonly batchNotifications: boolean;
10
+ /** Delay in milliseconds before sending batched notifications */
11
+ readonly batchDelayMs: number;
12
+ /** Whether to notify on server readiness changes */
13
+ readonly notifyOnServerReady: boolean;
14
+ }
15
+ /**
16
+ * Default notification configuration
17
+ */
18
+ export declare const DEFAULT_NOTIFICATION_CONFIG: NotificationConfig;
19
+ /**
20
+ * Events emitted by NotificationManager
21
+ */
22
+ export interface NotificationManagerEvents {
23
+ 'notification-sent': (type: 'tools' | 'resources' | 'prompts', clientCount: number) => void;
24
+ 'notification-failed': (type: 'tools' | 'resources' | 'prompts', error: Error) => void;
25
+ 'batch-sent': (notifications: string[], clientCount: number) => void;
26
+ }
27
+ /**
28
+ * Manages sending listChanged notifications to connected clients when MCP server
29
+ * capabilities change during async loading.
30
+ *
31
+ * Features:
32
+ * - Batches multiple notification types together to reduce client spam
33
+ * - Handles client connection failures gracefully
34
+ * - Provides configurable batching delays and behavior
35
+ * - Tracks notification success/failure metrics
36
+ *
37
+ * @example
38
+ * ```typescript
39
+ * const manager = new NotificationManager(inboundConnection, config);
40
+ * manager.handleCapabilityChanges(changes);
41
+ * ```
42
+ */
43
+ export declare class NotificationManager extends EventEmitter {
44
+ private inboundConn;
45
+ private config;
46
+ private pendingNotifications;
47
+ private batchTimer;
48
+ private isShuttingDown;
49
+ constructor(inboundConnection: InboundConnection, config?: Partial<NotificationConfig>);
50
+ /**
51
+ * Handle capability changes and send appropriate notifications
52
+ */
53
+ handleCapabilityChanges(changes: CapabilityChanges): void;
54
+ /**
55
+ * Schedule notifications to be sent in a batch after a delay
56
+ */
57
+ private scheduleBatchedNotification;
58
+ /**
59
+ * Send all pending notifications as a batch
60
+ */
61
+ private sendBatchedNotifications;
62
+ /**
63
+ * Send notifications immediately without batching
64
+ */
65
+ private sendImmediateNotifications;
66
+ /**
67
+ * Send ToolListChangedNotification to client
68
+ */
69
+ private sendToolListChangedNotification;
70
+ /**
71
+ * Send ResourceListChangedNotification to client
72
+ */
73
+ private sendResourceListChangedNotification;
74
+ /**
75
+ * Send PromptListChangedNotification to client
76
+ */
77
+ private sendPromptListChangedNotification;
78
+ /**
79
+ * Send a notification to the connected client
80
+ */
81
+ private sendNotification;
82
+ /**
83
+ * Get count of connected clients (always 1 for this proxy architecture)
84
+ */
85
+ private getClientCount;
86
+ /**
87
+ * Force send any pending notifications immediately
88
+ */
89
+ flushPendingNotifications(): void;
90
+ /**
91
+ * Update configuration at runtime
92
+ */
93
+ updateConfig(newConfig: Partial<NotificationConfig>): void;
94
+ /**
95
+ * Get current configuration
96
+ */
97
+ getConfig(): NotificationConfig;
98
+ /**
99
+ * Check if notifications are enabled
100
+ */
101
+ isEnabled(): boolean;
102
+ /**
103
+ * Get summary of notification manager state
104
+ */
105
+ getStatusSummary(): string;
106
+ /**
107
+ * Shutdown the notification manager
108
+ */
109
+ shutdown(): void;
110
+ }
111
+ //# sourceMappingURL=notificationManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notificationManager.d.ts","sourceRoot":"","sources":["../../../src/core/notifications/notificationManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAMtC,OAAO,EAAE,iBAAiB,EAAgB,MAAM,mBAAmB,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,QAAQ,CAAC,kBAAkB,EAAE,OAAO,CAAC;IACrC,iEAAiE;IACjE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,oDAAoD;IACpD,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC;CACvC;AAED;;GAEG;AACH,eAAO,MAAM,2BAA2B,EAAE,kBAIzC,CAAC;AAYF;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,mBAAmB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5F,qBAAqB,EAAE,CAAC,IAAI,EAAE,OAAO,GAAG,WAAW,GAAG,SAAS,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACvF,YAAY,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC;CACtE;AAED;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,mBAAoB,SAAQ,YAAY;IACnD,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,MAAM,CAAqB;IACnC,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,cAAc,CAAkB;gBAE5B,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,GAAE,OAAO,CAAC,kBAAkB,CAAM;IAO1F;;OAEG;IACI,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAqBhE;;OAEG;IACH,OAAO,CAAC,2BAA2B;IA4BnC;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAgChC;;OAEG;IACH,OAAO,CAAC,0BAA0B;IAclC;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAOvC;;OAEG;IACH,OAAO,CAAC,mCAAmC;IAO3C;;OAEG;IACH,OAAO,CAAC,iCAAiC;IAOzC;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA4BxB;;OAEG;IACH,OAAO,CAAC,cAAc;IAItB;;OAEG;IACI,yBAAyB,IAAI,IAAI;IAOxC;;OAEG;IACI,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,IAAI;IAKjE;;OAEG;IACI,SAAS,IAAI,kBAAkB;IAItC;;OAEG;IACI,SAAS,IAAI,OAAO;IAI3B;;OAEG;IACI,gBAAgB,IAAI,MAAM;IAOjC;;OAEG;IACI,QAAQ,IAAI,IAAI;CAQxB"}