@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,256 @@
1
+ import { EventEmitter } from 'events';
2
+ import { CapabilityAggregator } from './capabilityAggregator.js';
3
+ import { NotificationManager } from '../notifications/notificationManager.js';
4
+ import { AgentConfigManager } from '../server/agentConfig.js';
5
+ import logger from '../../logger/logger.js';
6
+ /**
7
+ * Orchestrates the async loading system by coordinating CapabilityAggregator,
8
+ * NotificationManager, and LoadingStateTracker events.
9
+ *
10
+ * This class handles the complete flow:
11
+ * 1. MCP server becomes ready
12
+ * 2. Capability aggregation detects changes
13
+ * 3. Notifications are sent to clients about new capabilities
14
+ *
15
+ * @example
16
+ * ```typescript
17
+ * const orchestrator = new AsyncLoadingOrchestrator(
18
+ * outboundConnections,
19
+ * inboundConnection,
20
+ * loadingManager
21
+ * );
22
+ * orchestrator.initialize();
23
+ * ```
24
+ */
25
+ export class AsyncLoadingOrchestrator extends EventEmitter {
26
+ capabilityAggregator;
27
+ notificationManager = null;
28
+ loadingManager;
29
+ serverManager;
30
+ agentConfig;
31
+ isInitialized = false;
32
+ isShuttingDown = false;
33
+ constructor(outboundConnections, serverManager, loadingManager) {
34
+ super();
35
+ this.loadingManager = loadingManager;
36
+ this.serverManager = serverManager;
37
+ this.agentConfig = AgentConfigManager.getInstance();
38
+ // Create capability aggregator
39
+ this.capabilityAggregator = new CapabilityAggregator(outboundConnections);
40
+ this.setMaxListeners(20);
41
+ }
42
+ /**
43
+ * Initialize the orchestrator and wire up event handlers
44
+ */
45
+ initialize() {
46
+ if (this.isInitialized) {
47
+ logger.warn('AsyncLoadingOrchestrator already initialized');
48
+ return;
49
+ }
50
+ if (!this.agentConfig.isAsyncLoadingEnabled()) {
51
+ logger.info('Async loading disabled - AsyncLoadingOrchestrator skipping initialization');
52
+ return;
53
+ }
54
+ logger.info('Initializing AsyncLoadingOrchestrator...');
55
+ // Wire up the event chain: LoadingManager -> CapabilityAggregator
56
+ this.setupEventChain();
57
+ this.isInitialized = true;
58
+ logger.info('AsyncLoadingOrchestrator initialized successfully');
59
+ this.emit('orchestrator-ready');
60
+ }
61
+ /**
62
+ * Initialize notification manager when inbound connection is available
63
+ */
64
+ initializeNotifications(inboundConnection) {
65
+ if (this.notificationManager) {
66
+ logger.warn('NotificationManager already initialized');
67
+ return;
68
+ }
69
+ if (!this.agentConfig.isAsyncLoadingEnabled()) {
70
+ return;
71
+ }
72
+ // Create notification manager with config from agent settings
73
+ const notificationConfig = {
74
+ batchNotifications: this.agentConfig.isBatchNotificationsEnabled(),
75
+ batchDelayMs: this.agentConfig.getBatchDelayMs(),
76
+ notifyOnServerReady: this.agentConfig.isNotifyOnServerReadyEnabled(),
77
+ };
78
+ this.notificationManager = new NotificationManager(inboundConnection, notificationConfig);
79
+ // Wire up notification events
80
+ this.setupNotificationEvents();
81
+ logger.info('AsyncLoadingOrchestrator notification manager initialized');
82
+ }
83
+ /**
84
+ * Set up the event handling chain for capability tracking
85
+ */
86
+ setupEventChain() {
87
+ // 1. Listen for server readiness from LoadingManager
88
+ this.loadingManager.on('server-loaded', (serverName, _result) => {
89
+ if (this.isShuttingDown)
90
+ return;
91
+ logger.debug(`Server ${serverName} became ready, updating capabilities`);
92
+ this.handleServerReady(serverName);
93
+ });
94
+ // 2. Listen for capability changes from CapabilityAggregator
95
+ this.capabilityAggregator.on('capabilities-changed', (changes) => {
96
+ if (this.isShuttingDown)
97
+ return;
98
+ logger.debug('Capabilities changed, processing notifications');
99
+ this.handleCapabilityChanges(changes);
100
+ });
101
+ logger.debug('Event chain setup completed');
102
+ }
103
+ /**
104
+ * Set up notification event handlers
105
+ */
106
+ setupNotificationEvents() {
107
+ if (!this.notificationManager) {
108
+ return;
109
+ }
110
+ // 3. Listen for notification events from NotificationManager
111
+ this.notificationManager.on('batch-sent', (notifications, clientCount) => {
112
+ if (this.isShuttingDown)
113
+ return;
114
+ logger.info(`Sent listChanged notifications to ${clientCount} clients: [${notifications.join(', ')}]`);
115
+ this.emit('notifications-sent', notifications);
116
+ });
117
+ this.notificationManager.on('notification-failed', (type, error) => {
118
+ logger.error(`Failed to send ${type} listChanged notification: ${error.message}`);
119
+ });
120
+ logger.debug('Notification event handlers setup completed');
121
+ }
122
+ /**
123
+ * Handle a server becoming ready by updating capabilities
124
+ */
125
+ async handleServerReady(serverName) {
126
+ try {
127
+ // Update capability aggregation
128
+ const changes = await this.capabilityAggregator.updateCapabilities();
129
+ if (changes.hasChanges) {
130
+ logger.info(`Server ${serverName} ready: ${changes.current.tools.length} tools, ${changes.current.resources.length} resources, ${changes.current.prompts.length} prompts now available`);
131
+ this.emit('server-capabilities-updated', serverName, changes);
132
+ }
133
+ else {
134
+ logger.debug(`Server ${serverName} ready but no capability changes detected`);
135
+ }
136
+ }
137
+ catch (error) {
138
+ logger.error(`Failed to update capabilities after ${serverName} became ready: ${error}`);
139
+ }
140
+ }
141
+ /**
142
+ * Handle capability changes by sending notifications
143
+ */
144
+ handleCapabilityChanges(changes) {
145
+ if (!changes.hasChanges) {
146
+ return;
147
+ }
148
+ // Send notifications to clients if notification manager is available
149
+ if (this.notificationManager) {
150
+ this.notificationManager.handleCapabilityChanges(changes);
151
+ }
152
+ else {
153
+ logger.debug('Capability changes detected but no notification manager available yet');
154
+ }
155
+ // Log the changes for visibility
156
+ const summary = this.capabilityAggregator.getCapabilitiesSummary();
157
+ logger.info(`Capability update complete: ${summary}`);
158
+ }
159
+ /**
160
+ * Get the capability aggregator instance
161
+ */
162
+ getCapabilityAggregator() {
163
+ return this.capabilityAggregator;
164
+ }
165
+ /**
166
+ * Get the notification manager instance
167
+ */
168
+ getNotificationManager() {
169
+ return this.notificationManager;
170
+ }
171
+ /**
172
+ * Check if the orchestrator is initialized
173
+ */
174
+ isReady() {
175
+ return this.isInitialized;
176
+ }
177
+ /**
178
+ * Force refresh capabilities and send notifications if needed
179
+ */
180
+ async refreshCapabilities() {
181
+ if (!this.isInitialized || this.isShuttingDown) {
182
+ logger.warn('Cannot refresh capabilities - orchestrator not ready');
183
+ return;
184
+ }
185
+ try {
186
+ logger.info('Manually refreshing capabilities...');
187
+ const changes = await this.capabilityAggregator.updateCapabilities();
188
+ if (changes.hasChanges) {
189
+ this.handleCapabilityChanges(changes);
190
+ logger.info('Manual capability refresh completed with changes');
191
+ }
192
+ else {
193
+ logger.info('Manual capability refresh completed - no changes detected');
194
+ }
195
+ }
196
+ catch (error) {
197
+ logger.error(`Failed to refresh capabilities: ${error}`);
198
+ }
199
+ }
200
+ /**
201
+ * Update configuration at runtime
202
+ */
203
+ updateConfig() {
204
+ if (!this.isInitialized) {
205
+ return;
206
+ }
207
+ if (this.notificationManager) {
208
+ const notificationConfig = {
209
+ batchNotifications: this.agentConfig.isBatchNotificationsEnabled(),
210
+ batchDelayMs: this.agentConfig.getBatchDelayMs(),
211
+ notifyOnServerReady: this.agentConfig.isNotifyOnServerReadyEnabled(),
212
+ };
213
+ this.notificationManager.updateConfig(notificationConfig);
214
+ logger.debug('AsyncLoadingOrchestrator configuration updated');
215
+ }
216
+ }
217
+ /**
218
+ * Get status summary for monitoring
219
+ */
220
+ getStatusSummary() {
221
+ if (!this.isInitialized) {
222
+ return 'not-initialized';
223
+ }
224
+ const capabilities = this.capabilityAggregator.getCapabilitiesSummary();
225
+ const notifications = this.notificationManager ? this.notificationManager.getStatusSummary() : 'not-initialized';
226
+ return `capabilities: ${capabilities}, notifications: ${notifications}`;
227
+ }
228
+ /**
229
+ * Shutdown the orchestrator
230
+ */
231
+ shutdown() {
232
+ if (this.isShuttingDown) {
233
+ return;
234
+ }
235
+ this.isShuttingDown = true;
236
+ logger.info('Shutting down AsyncLoadingOrchestrator...');
237
+ try {
238
+ // Flush any pending notifications
239
+ if (this.notificationManager) {
240
+ this.notificationManager.flushPendingNotifications();
241
+ this.notificationManager.shutdown();
242
+ }
243
+ // Remove all listeners
244
+ this.removeAllListeners();
245
+ this.capabilityAggregator.removeAllListeners();
246
+ if (this.notificationManager) {
247
+ this.notificationManager.removeAllListeners();
248
+ }
249
+ logger.info('AsyncLoadingOrchestrator shutdown complete');
250
+ }
251
+ catch (error) {
252
+ logger.error(`Error during AsyncLoadingOrchestrator shutdown: ${error}`);
253
+ }
254
+ }
255
+ }
256
+ //# sourceMappingURL=asyncLoadingOrchestrator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asyncLoadingOrchestrator.js","sourceRoot":"","sources":["../../../src/core/capabilities/asyncLoadingOrchestrator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,114 @@
1
+ import { EventEmitter } from 'events';
2
+ import { Tool, Resource, Prompt } from '@modelcontextprotocol/sdk/types.js';
3
+ import { OutboundConnections } from '../types/index.js';
4
+ /**
5
+ * Represents a snapshot of aggregated capabilities from all ready servers
6
+ */
7
+ export interface AggregatedCapabilities {
8
+ readonly tools: Tool[];
9
+ readonly resources: Resource[];
10
+ readonly prompts: Prompt[];
11
+ readonly readyServers: string[];
12
+ readonly timestamp: Date;
13
+ }
14
+ /**
15
+ * Represents changes between two capability snapshots
16
+ */
17
+ export interface CapabilityChanges {
18
+ readonly hasChanges: boolean;
19
+ readonly toolsChanged: boolean;
20
+ readonly resourcesChanged: boolean;
21
+ readonly promptsChanged: boolean;
22
+ readonly addedServers: string[];
23
+ readonly removedServers: string[];
24
+ readonly previous: AggregatedCapabilities;
25
+ readonly current: AggregatedCapabilities;
26
+ }
27
+ /**
28
+ * Events emitted by CapabilityAggregator
29
+ */
30
+ export interface CapabilityAggregatorEvents {
31
+ 'capabilities-changed': (changes: CapabilityChanges) => void;
32
+ 'server-capabilities-ready': (serverName: string, capabilities: AggregatedCapabilities) => void;
33
+ }
34
+ /**
35
+ * Aggregates and tracks capabilities (tools, resources, prompts) from all ready MCP servers.
36
+ * Detects changes when servers come online or go offline and emits events for notification.
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const aggregator = new CapabilityAggregator(outboundConnections);
41
+ * aggregator.on('capabilities-changed', (changes) => {
42
+ * if (changes.toolsChanged) {
43
+ * // Send ToolListChangedNotification to clients
44
+ * }
45
+ * });
46
+ *
47
+ * // When server comes online
48
+ * aggregator.updateCapabilities();
49
+ * ```
50
+ */
51
+ export declare class CapabilityAggregator extends EventEmitter {
52
+ private outboundConns;
53
+ private currentCapabilities;
54
+ private isInitialized;
55
+ constructor(outboundConnections: OutboundConnections);
56
+ /**
57
+ * Create an empty capabilities snapshot
58
+ */
59
+ private createEmptyCapabilities;
60
+ /**
61
+ * Get current aggregated capabilities
62
+ */
63
+ getCurrentCapabilities(): AggregatedCapabilities;
64
+ /**
65
+ * Update capabilities by querying all ready servers
66
+ * This should be called when server states change
67
+ */
68
+ updateCapabilities(): Promise<CapabilityChanges>;
69
+ /**
70
+ * Force refresh capabilities from all servers
71
+ */
72
+ refreshCapabilities(): Promise<AggregatedCapabilities>;
73
+ /**
74
+ * Aggregate capabilities from all ready servers
75
+ */
76
+ private aggregateFromReadyServers;
77
+ /**
78
+ * Safely list tools from a server
79
+ */
80
+ private safeListTools;
81
+ /**
82
+ * Safely list resources from a server
83
+ */
84
+ private safeListResources;
85
+ /**
86
+ * Safely list prompts from a server
87
+ */
88
+ private safeListPrompts;
89
+ /**
90
+ * Detect changes between two capability snapshots
91
+ */
92
+ private detectChanges;
93
+ /**
94
+ * Check if two arrays are equal (shallow comparison)
95
+ */
96
+ private arraysEqual;
97
+ /**
98
+ * Remove duplicate tools based on name
99
+ */
100
+ private deduplicateTools;
101
+ /**
102
+ * Remove duplicate resources based on URI
103
+ */
104
+ private deduplicateResources;
105
+ /**
106
+ * Remove duplicate prompts based on name
107
+ */
108
+ private deduplicatePrompts;
109
+ /**
110
+ * Get summary of current capabilities for logging
111
+ */
112
+ getCapabilitiesSummary(): string;
113
+ }
114
+ //# sourceMappingURL=capabilityAggregator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilityAggregator.d.ts","sourceRoot":"","sources":["../../../src/core/capabilities/capabilityAggregator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAIL,IAAI,EACJ,QAAQ,EACR,MAAM,EACP,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,mBAAmB,EAAgB,MAAM,mBAAmB,CAAC;AAGtE;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC3B,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,SAAS,EAAE,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC;IAC7B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,CAAC;IAChC,QAAQ,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC;IAClC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;IAC1C,QAAQ,CAAC,OAAO,EAAE,sBAAsB,CAAC;CAC1C;AAED;;GAEG;AACH,MAAM,WAAW,0BAA0B;IACzC,sBAAsB,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;IAC7D,2BAA2B,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,sBAAsB,KAAK,IAAI,CAAC;CACjG;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,OAAO,CAAC,aAAa,CAAsB;IAC3C,OAAO,CAAC,mBAAmB,CAAyB;IACpD,OAAO,CAAC,aAAa,CAAkB;gBAE3B,mBAAmB,EAAE,mBAAmB;IAOpD;;OAEG;IACH,OAAO,CAAC,uBAAuB;IAU/B;;OAEG;IACI,sBAAsB,IAAI,sBAAsB;IAIvD;;;OAGG;IACU,kBAAkB,IAAI,OAAO,CAAC,iBAAiB,CAAC;IAsB7D;;OAEG;IACU,mBAAmB,IAAI,OAAO,CAAC,sBAAsB,CAAC;IAKnE;;OAEG;YACW,yBAAyB;IAkDvC;;OAEG;YACW,aAAa;IAS3B;;OAEG;YACW,iBAAiB;IAS/B;;OAEG;YACW,eAAe;IAS7B;;OAEG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,CAAC,WAAW;IAInB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAYxB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAY5B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAY1B;;OAEG;IACI,sBAAsB,IAAI,MAAM;CAIxC"}
@@ -0,0 +1,234 @@
1
+ import { EventEmitter } from 'events';
2
+ import { ClientStatus } from '../types/index.js';
3
+ import logger from '../../logger/logger.js';
4
+ /**
5
+ * Aggregates and tracks capabilities (tools, resources, prompts) from all ready MCP servers.
6
+ * Detects changes when servers come online or go offline and emits events for notification.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * const aggregator = new CapabilityAggregator(outboundConnections);
11
+ * aggregator.on('capabilities-changed', (changes) => {
12
+ * if (changes.toolsChanged) {
13
+ * // Send ToolListChangedNotification to clients
14
+ * }
15
+ * });
16
+ *
17
+ * // When server comes online
18
+ * aggregator.updateCapabilities();
19
+ * ```
20
+ */
21
+ export class CapabilityAggregator extends EventEmitter {
22
+ outboundConns;
23
+ currentCapabilities;
24
+ isInitialized = false;
25
+ constructor(outboundConnections) {
26
+ super();
27
+ this.outboundConns = outboundConnections;
28
+ this.currentCapabilities = this.createEmptyCapabilities();
29
+ this.setMaxListeners(50);
30
+ }
31
+ /**
32
+ * Create an empty capabilities snapshot
33
+ */
34
+ createEmptyCapabilities() {
35
+ return {
36
+ tools: [],
37
+ resources: [],
38
+ prompts: [],
39
+ readyServers: [],
40
+ timestamp: new Date(),
41
+ };
42
+ }
43
+ /**
44
+ * Get current aggregated capabilities
45
+ */
46
+ getCurrentCapabilities() {
47
+ return this.currentCapabilities;
48
+ }
49
+ /**
50
+ * Update capabilities by querying all ready servers
51
+ * This should be called when server states change
52
+ */
53
+ async updateCapabilities() {
54
+ const previousCapabilities = this.currentCapabilities;
55
+ const newCapabilities = await this.aggregateFromReadyServers();
56
+ const changes = this.detectChanges(previousCapabilities, newCapabilities);
57
+ this.currentCapabilities = newCapabilities;
58
+ if (!this.isInitialized) {
59
+ this.isInitialized = true;
60
+ logger.debug('CapabilityAggregator initialized with capabilities from ready servers');
61
+ }
62
+ if (changes.hasChanges) {
63
+ logger.info(`Capabilities changed: tools=${changes.toolsChanged}, resources=${changes.resourcesChanged}, prompts=${changes.promptsChanged}`);
64
+ this.emit('capabilities-changed', changes);
65
+ }
66
+ return changes;
67
+ }
68
+ /**
69
+ * Force refresh capabilities from all servers
70
+ */
71
+ async refreshCapabilities() {
72
+ const changes = await this.updateCapabilities();
73
+ return changes.current;
74
+ }
75
+ /**
76
+ * Aggregate capabilities from all ready servers
77
+ */
78
+ async aggregateFromReadyServers() {
79
+ const readyServers = [];
80
+ const allTools = [];
81
+ const allResources = [];
82
+ const allPrompts = [];
83
+ for (const [serverName, connection] of this.outboundConns.entries()) {
84
+ if (connection.status !== ClientStatus.Connected || !connection.client.transport) {
85
+ continue;
86
+ }
87
+ try {
88
+ readyServers.push(serverName);
89
+ // Fetch tools, resources, and prompts in parallel
90
+ const [toolsResult, resourcesResult, promptsResult] = await Promise.allSettled([
91
+ this.safeListTools(serverName, connection.client),
92
+ this.safeListResources(serverName, connection.client),
93
+ this.safeListPrompts(serverName, connection.client),
94
+ ]);
95
+ // Process tools
96
+ if (toolsResult.status === 'fulfilled' && toolsResult.value.tools) {
97
+ allTools.push(...toolsResult.value.tools);
98
+ }
99
+ // Process resources
100
+ if (resourcesResult.status === 'fulfilled' && resourcesResult.value.resources) {
101
+ allResources.push(...resourcesResult.value.resources);
102
+ }
103
+ // Process prompts
104
+ if (promptsResult.status === 'fulfilled' && promptsResult.value.prompts) {
105
+ allPrompts.push(...promptsResult.value.prompts);
106
+ }
107
+ }
108
+ catch (error) {
109
+ logger.warn(`Failed to aggregate capabilities from ${serverName}: ${error}`);
110
+ // Continue with other servers
111
+ }
112
+ }
113
+ return {
114
+ tools: this.deduplicateTools(allTools),
115
+ resources: this.deduplicateResources(allResources),
116
+ prompts: this.deduplicatePrompts(allPrompts),
117
+ readyServers: readyServers.sort(),
118
+ timestamp: new Date(),
119
+ };
120
+ }
121
+ /**
122
+ * Safely list tools from a server
123
+ */
124
+ async safeListTools(serverName, client) {
125
+ try {
126
+ return await client.listTools();
127
+ }
128
+ catch (error) {
129
+ logger.debug(`Failed to list tools from ${serverName}: ${error}`);
130
+ return { tools: [] };
131
+ }
132
+ }
133
+ /**
134
+ * Safely list resources from a server
135
+ */
136
+ async safeListResources(serverName, client) {
137
+ try {
138
+ return await client.listResources();
139
+ }
140
+ catch (error) {
141
+ logger.debug(`Failed to list resources from ${serverName}: ${error}`);
142
+ return { resources: [] };
143
+ }
144
+ }
145
+ /**
146
+ * Safely list prompts from a server
147
+ */
148
+ async safeListPrompts(serverName, client) {
149
+ try {
150
+ return await client.listPrompts();
151
+ }
152
+ catch (error) {
153
+ logger.debug(`Failed to list prompts from ${serverName}: ${error}`);
154
+ return { prompts: [] };
155
+ }
156
+ }
157
+ /**
158
+ * Detect changes between two capability snapshots
159
+ */
160
+ detectChanges(previous, current) {
161
+ const toolsChanged = !this.arraysEqual(previous.tools.map((t) => t.name).sort(), current.tools.map((t) => t.name).sort());
162
+ const resourcesChanged = !this.arraysEqual(previous.resources.map((r) => r.uri).sort(), current.resources.map((r) => r.uri).sort());
163
+ const promptsChanged = !this.arraysEqual(previous.prompts.map((p) => p.name).sort(), current.prompts.map((p) => p.name).sort());
164
+ const addedServers = current.readyServers.filter((s) => !previous.readyServers.includes(s));
165
+ const removedServers = previous.readyServers.filter((s) => !current.readyServers.includes(s));
166
+ const hasChanges = toolsChanged || resourcesChanged || promptsChanged || addedServers.length > 0 || removedServers.length > 0;
167
+ return {
168
+ hasChanges,
169
+ toolsChanged,
170
+ resourcesChanged,
171
+ promptsChanged,
172
+ addedServers,
173
+ removedServers,
174
+ previous,
175
+ current,
176
+ };
177
+ }
178
+ /**
179
+ * Check if two arrays are equal (shallow comparison)
180
+ */
181
+ arraysEqual(a, b) {
182
+ return a.length === b.length && a.every((val, index) => val === b[index]);
183
+ }
184
+ /**
185
+ * Remove duplicate tools based on name
186
+ */
187
+ deduplicateTools(tools) {
188
+ const seen = new Set();
189
+ return tools.filter((tool) => {
190
+ if (seen.has(tool.name)) {
191
+ logger.debug(`Duplicate tool name detected: ${tool.name}`);
192
+ return false;
193
+ }
194
+ seen.add(tool.name);
195
+ return true;
196
+ });
197
+ }
198
+ /**
199
+ * Remove duplicate resources based on URI
200
+ */
201
+ deduplicateResources(resources) {
202
+ const seen = new Set();
203
+ return resources.filter((resource) => {
204
+ if (seen.has(resource.uri)) {
205
+ logger.debug(`Duplicate resource URI detected: ${resource.uri}`);
206
+ return false;
207
+ }
208
+ seen.add(resource.uri);
209
+ return true;
210
+ });
211
+ }
212
+ /**
213
+ * Remove duplicate prompts based on name
214
+ */
215
+ deduplicatePrompts(prompts) {
216
+ const seen = new Set();
217
+ return prompts.filter((prompt) => {
218
+ if (seen.has(prompt.name)) {
219
+ logger.debug(`Duplicate prompt name detected: ${prompt.name}`);
220
+ return false;
221
+ }
222
+ seen.add(prompt.name);
223
+ return true;
224
+ });
225
+ }
226
+ /**
227
+ * Get summary of current capabilities for logging
228
+ */
229
+ getCapabilitiesSummary() {
230
+ const caps = this.currentCapabilities;
231
+ return `${caps.tools.length} tools, ${caps.resources.length} resources, ${caps.prompts.length} prompts from ${caps.readyServers.length} servers`;
232
+ }
233
+ }
234
+ //# sourceMappingURL=capabilityAggregator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capabilityAggregator.js","sourceRoot":"","sources":["../../../src/core/capabilities/capabilityAggregator.ts"],"names":[],"mappings":"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"}
@@ -45,6 +45,35 @@ export declare class ClientManager {
45
45
  * @returns Map of all outbound connections
46
46
  */
47
47
  getClients(): OutboundConnections;
48
+ /**
49
+ * Creates a single client for async loading (used by McpLoadingManager)
50
+ * @param name The name of the client
51
+ * @param transport The transport to connect to
52
+ * @param abortSignal Optional AbortSignal to cancel the operation
53
+ * @returns Promise that resolves when client is connected
54
+ */
55
+ createSingleClient(name: string, transport: AuthProviderTransport, abortSignal?: AbortSignal): Promise<void>;
56
+ /**
57
+ * Internal method to create and connect a single client
58
+ */
59
+ private createSingleClientInternal;
60
+ /**
61
+ * Initialize clients storage without connecting (for async loading)
62
+ * @param transports Record of transport instances
63
+ * @returns Empty connections map (to be populated by async loading)
64
+ */
65
+ initializeClientsAsync(transports: Record<string, AuthProviderTransport>): OutboundConnections;
66
+ /**
67
+ * Get transport by name (used by loading manager for retries)
68
+ * @param name The transport name
69
+ * @returns The transport instance or undefined
70
+ */
71
+ getTransport(name: string): AuthProviderTransport | undefined;
72
+ /**
73
+ * Get all transport names
74
+ * @returns Array of transport names
75
+ */
76
+ getTransportNames(): string[];
48
77
  /**
49
78
  * Executes a client operation with error handling and retry logic
50
79
  * @param clientName The name of the client to use