@juspay/neurolink 7.13.0 → 7.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +89 -25
  3. package/dist/agent/directTools.d.ts +3 -3
  4. package/dist/agent/directTools.js +1 -1
  5. package/dist/cli/commands/mcp.js +67 -207
  6. package/dist/cli/factories/commandFactory.js +7 -1
  7. package/dist/cli/utils/interactiveSetup.js +1 -1
  8. package/dist/config/conversationMemoryConfig.js +2 -1
  9. package/dist/context/ContextManager.js +15 -4
  10. package/dist/context/config.js +5 -1
  11. package/dist/context/utils.js +1 -1
  12. package/dist/core/baseProvider.d.ts +11 -30
  13. package/dist/core/baseProvider.js +268 -42
  14. package/dist/core/conversationMemoryManager.js +3 -2
  15. package/dist/core/dynamicModels.d.ts +14 -14
  16. package/dist/core/dynamicModels.js +1 -1
  17. package/dist/core/evaluation.js +1 -1
  18. package/dist/core/factory.js +1 -1
  19. package/dist/factories/providerFactory.js +5 -11
  20. package/dist/factories/providerRegistry.js +2 -2
  21. package/dist/index.d.ts +5 -4
  22. package/dist/index.js +1 -1
  23. package/dist/lib/agent/directTools.js +1 -1
  24. package/dist/lib/config/conversationMemoryConfig.js +2 -1
  25. package/dist/lib/context/ContextManager.js +15 -4
  26. package/dist/lib/context/config.js +5 -1
  27. package/dist/lib/context/utils.js +1 -1
  28. package/dist/lib/core/baseProvider.d.ts +11 -30
  29. package/dist/lib/core/baseProvider.js +268 -42
  30. package/dist/lib/core/conversationMemoryManager.js +3 -2
  31. package/dist/lib/core/dynamicModels.js +1 -1
  32. package/dist/lib/core/evaluation.js +1 -1
  33. package/dist/lib/core/factory.js +1 -1
  34. package/dist/lib/factories/providerFactory.js +5 -11
  35. package/dist/lib/factories/providerRegistry.js +2 -2
  36. package/dist/lib/index.d.ts +5 -4
  37. package/dist/lib/index.js +1 -1
  38. package/dist/lib/mcp/externalServerManager.d.ts +148 -0
  39. package/dist/lib/mcp/externalServerManager.js +1038 -0
  40. package/dist/lib/mcp/mcpCircuitBreaker.d.ts +184 -0
  41. package/dist/lib/mcp/mcpCircuitBreaker.js +338 -0
  42. package/dist/lib/mcp/mcpClientFactory.d.ts +105 -0
  43. package/dist/lib/mcp/mcpClientFactory.js +421 -0
  44. package/dist/lib/mcp/toolDiscoveryService.d.ts +193 -0
  45. package/dist/lib/mcp/toolDiscoveryService.js +646 -0
  46. package/dist/lib/mcp/toolRegistry.d.ts +15 -11
  47. package/dist/lib/mcp/toolRegistry.js +118 -55
  48. package/dist/lib/models/modelResolver.js +1 -1
  49. package/dist/lib/neurolink.d.ts +139 -43
  50. package/dist/lib/neurolink.js +604 -174
  51. package/dist/lib/providers/googleVertex.d.ts +7 -1
  52. package/dist/lib/providers/googleVertex.js +34 -7
  53. package/dist/lib/providers/huggingFace.js +1 -1
  54. package/dist/lib/providers/mistral.js +3 -3
  55. package/dist/lib/providers/ollama.js +1 -1
  56. package/dist/lib/providers/openAI.d.ts +3 -2
  57. package/dist/lib/providers/openAI.js +2 -2
  58. package/dist/lib/providers/openaiCompatible.d.ts +1 -1
  59. package/dist/lib/providers/openaiCompatible.js +2 -2
  60. package/dist/lib/providers/sagemaker/config.js +1 -1
  61. package/dist/lib/sdk/toolRegistration.d.ts +4 -13
  62. package/dist/lib/sdk/toolRegistration.js +19 -66
  63. package/dist/lib/types/cli.d.ts +0 -1
  64. package/dist/lib/types/cli.js +0 -1
  65. package/dist/lib/types/common.d.ts +1 -2
  66. package/dist/lib/types/common.js +0 -1
  67. package/dist/lib/types/contextTypes.d.ts +1 -1
  68. package/dist/lib/types/contextTypes.js +3 -3
  69. package/dist/lib/types/externalMcp.d.ts +288 -0
  70. package/dist/lib/types/externalMcp.js +7 -0
  71. package/dist/lib/types/generateTypes.d.ts +0 -1
  72. package/dist/lib/types/index.d.ts +2 -2
  73. package/dist/lib/types/index.js +0 -1
  74. package/dist/lib/types/mcpTypes.d.ts +53 -99
  75. package/dist/lib/types/providers.d.ts +0 -1
  76. package/dist/lib/types/providers.js +0 -1
  77. package/dist/lib/types/tools.d.ts +2 -2
  78. package/dist/lib/types/tools.js +2 -2
  79. package/dist/lib/utils/factoryProcessing.js +1 -1
  80. package/dist/lib/utils/mcpDefaults.d.ts +54 -0
  81. package/dist/lib/utils/mcpDefaults.js +125 -0
  82. package/dist/lib/utils/providerConfig.d.ts +1 -1
  83. package/dist/lib/utils/providerConfig.js +2 -2
  84. package/dist/lib/utils/providerHealth.js +6 -6
  85. package/dist/mcp/externalServerManager.d.ts +148 -0
  86. package/dist/mcp/externalServerManager.js +1038 -0
  87. package/dist/mcp/mcpCircuitBreaker.d.ts +184 -0
  88. package/dist/mcp/mcpCircuitBreaker.js +338 -0
  89. package/dist/mcp/mcpClientFactory.d.ts +105 -0
  90. package/dist/mcp/mcpClientFactory.js +421 -0
  91. package/dist/mcp/toolDiscoveryService.d.ts +193 -0
  92. package/dist/mcp/toolDiscoveryService.js +646 -0
  93. package/dist/mcp/toolRegistry.d.ts +15 -11
  94. package/dist/mcp/toolRegistry.js +118 -55
  95. package/dist/models/modelResolver.js +1 -1
  96. package/dist/neurolink.d.ts +139 -43
  97. package/dist/neurolink.js +604 -174
  98. package/dist/providers/googleVertex.d.ts +7 -1
  99. package/dist/providers/googleVertex.js +34 -7
  100. package/dist/providers/huggingFace.js +1 -1
  101. package/dist/providers/mistral.js +3 -3
  102. package/dist/providers/ollama.js +1 -1
  103. package/dist/providers/openAI.d.ts +3 -2
  104. package/dist/providers/openAI.js +2 -2
  105. package/dist/providers/openaiCompatible.d.ts +1 -1
  106. package/dist/providers/openaiCompatible.js +2 -2
  107. package/dist/providers/sagemaker/config.js +1 -1
  108. package/dist/sdk/toolRegistration.d.ts +4 -13
  109. package/dist/sdk/toolRegistration.js +19 -66
  110. package/dist/types/cli.d.ts +0 -1
  111. package/dist/types/cli.js +0 -1
  112. package/dist/types/common.d.ts +1 -2
  113. package/dist/types/common.js +0 -1
  114. package/dist/types/contextTypes.d.ts +1 -1
  115. package/dist/types/contextTypes.js +3 -3
  116. package/dist/types/externalMcp.d.ts +288 -0
  117. package/dist/types/externalMcp.js +7 -0
  118. package/dist/types/generateTypes.d.ts +0 -1
  119. package/dist/types/index.d.ts +2 -2
  120. package/dist/types/index.js +0 -1
  121. package/dist/types/mcpTypes.d.ts +53 -99
  122. package/dist/types/providers.d.ts +0 -1
  123. package/dist/types/providers.js +0 -1
  124. package/dist/types/tools.d.ts +2 -2
  125. package/dist/types/tools.js +2 -2
  126. package/dist/utils/factoryProcessing.js +1 -1
  127. package/dist/utils/mcpDefaults.d.ts +54 -0
  128. package/dist/utils/mcpDefaults.js +125 -0
  129. package/dist/utils/providerConfig.d.ts +1 -1
  130. package/dist/utils/providerConfig.js +2 -2
  131. package/dist/utils/providerHealth.js +6 -6
  132. package/package.json +1 -1
@@ -0,0 +1,421 @@
1
+ /**
2
+ * MCP Client Factory
3
+ * Creates and manages MCP clients for external servers
4
+ * Supports stdio, SSE, and WebSocket transports
5
+ */
6
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
7
+ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
8
+ import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
9
+ import { WebSocketClientTransport } from "@modelcontextprotocol/sdk/client/websocket.js";
10
+ import { spawn } from "child_process";
11
+ import { mcpLogger } from "../utils/logger.js";
12
+ import { globalCircuitBreakerManager, } from "./mcpCircuitBreaker.js";
13
+ /**
14
+ * MCPClientFactory
15
+ * Factory class for creating MCP clients with different transports
16
+ */
17
+ export class MCPClientFactory {
18
+ static NEUROLINK_IMPLEMENTATION = {
19
+ name: "neurolink-sdk",
20
+ version: "1.0.0",
21
+ };
22
+ static DEFAULT_CAPABILITIES = {
23
+ tools: {},
24
+ resources: {},
25
+ prompts: {},
26
+ sampling: {},
27
+ roots: {
28
+ listChanged: false,
29
+ },
30
+ };
31
+ /**
32
+ * Create an MCP client for the given server configuration
33
+ */
34
+ static async createClient(config, timeout = 10000) {
35
+ const startTime = Date.now();
36
+ try {
37
+ mcpLogger.info(`[MCPClientFactory] Creating client for ${config.id}`, {
38
+ transport: config.transport,
39
+ command: config.command,
40
+ });
41
+ // Create circuit breaker for this server
42
+ const circuitBreaker = globalCircuitBreakerManager.getBreaker(`mcp-client-${config.id}`, {
43
+ failureThreshold: 3,
44
+ resetTimeout: 30000,
45
+ operationTimeout: timeout,
46
+ });
47
+ // Create client with circuit breaker protection
48
+ const result = await circuitBreaker.execute(async () => {
49
+ return await this.createClientInternal(config, timeout);
50
+ });
51
+ mcpLogger.info(`[MCPClientFactory] Client created successfully for ${config.id}`, {
52
+ duration: Date.now() - startTime,
53
+ capabilities: result.capabilities,
54
+ });
55
+ return {
56
+ ...result,
57
+ success: true,
58
+ duration: Date.now() - startTime,
59
+ };
60
+ }
61
+ catch (error) {
62
+ const errorMessage = error instanceof Error ? error.message : String(error);
63
+ mcpLogger.error(`[MCPClientFactory] Failed to create client for ${config.id}:`, error);
64
+ return {
65
+ success: false,
66
+ error: errorMessage,
67
+ duration: Date.now() - startTime,
68
+ };
69
+ }
70
+ }
71
+ /**
72
+ * Internal client creation logic
73
+ */
74
+ static async createClientInternal(config, timeout) {
75
+ // Create transport
76
+ const { transport, process } = await this.createTransport(config);
77
+ try {
78
+ // Create client
79
+ const client = new Client(this.NEUROLINK_IMPLEMENTATION, {
80
+ capabilities: this.DEFAULT_CAPABILITIES,
81
+ });
82
+ // Connect with timeout
83
+ await Promise.race([
84
+ client.connect(transport),
85
+ this.createTimeoutPromise(timeout, `Client connection timeout for ${config.id}`),
86
+ ]);
87
+ // Perform handshake to get server capabilities
88
+ const serverCapabilities = await this.performHandshake(client, timeout);
89
+ mcpLogger.debug(`[MCPClientFactory] Handshake completed for ${config.id}`, {
90
+ capabilities: serverCapabilities,
91
+ });
92
+ return {
93
+ client,
94
+ transport,
95
+ process,
96
+ capabilities: serverCapabilities,
97
+ };
98
+ }
99
+ catch (error) {
100
+ // Clean up on failure
101
+ try {
102
+ await transport.close();
103
+ }
104
+ catch (closeError) {
105
+ mcpLogger.debug(`[MCPClientFactory] Error closing transport during cleanup:`, closeError);
106
+ }
107
+ if (process && !process.killed) {
108
+ process.kill("SIGTERM");
109
+ }
110
+ throw error;
111
+ }
112
+ }
113
+ /**
114
+ * Create transport based on configuration
115
+ */
116
+ static async createTransport(config) {
117
+ switch (config.transport) {
118
+ case "stdio":
119
+ return this.createStdioTransport(config);
120
+ case "sse":
121
+ return this.createSSETransport(config);
122
+ case "websocket":
123
+ return this.createWebSocketTransport(config);
124
+ default:
125
+ throw new Error(`Unsupported transport type: ${config.transport}`);
126
+ }
127
+ }
128
+ /**
129
+ * Create stdio transport with process spawning
130
+ */
131
+ static async createStdioTransport(config) {
132
+ mcpLogger.debug(`[MCPClientFactory] Creating stdio transport for ${config.id}`, {
133
+ command: config.command,
134
+ args: config.args,
135
+ });
136
+ // Validate command is present
137
+ if (!config.command) {
138
+ throw new Error(`Command is required for stdio transport`);
139
+ }
140
+ // Spawn the process
141
+ const childProcess = spawn(config.command, config.args || [], {
142
+ stdio: ["pipe", "pipe", "pipe"],
143
+ env: {
144
+ ...process.env,
145
+ ...config.env,
146
+ },
147
+ cwd: config.cwd,
148
+ });
149
+ // Handle process errors
150
+ const processErrorPromise = new Promise((_, reject) => {
151
+ childProcess.on("error", (error) => {
152
+ reject(new Error(`Process spawn error: ${error.message}`));
153
+ });
154
+ childProcess.on("exit", (code, signal) => {
155
+ if (code !== 0) {
156
+ reject(new Error(`Process exited with code ${code}, signal ${signal}`));
157
+ }
158
+ });
159
+ });
160
+ // Wait for process to be ready or fail
161
+ await Promise.race([
162
+ new Promise((resolve) => setTimeout(resolve, 1000)), // Give process time to start
163
+ processErrorPromise,
164
+ ]);
165
+ // Check if process is still running
166
+ if (childProcess.killed ||
167
+ childProcess.exitCode !== null) {
168
+ throw new Error("Process failed to start or exited immediately");
169
+ }
170
+ // Create transport
171
+ const transport = new StdioClientTransport({
172
+ command: config.command,
173
+ args: config.args || [],
174
+ env: Object.fromEntries(Object.entries({
175
+ ...process.env,
176
+ ...config.env,
177
+ }).filter(([, value]) => value !== undefined)),
178
+ cwd: config.cwd,
179
+ });
180
+ return { transport, process: childProcess };
181
+ }
182
+ /**
183
+ * Create SSE transport
184
+ */
185
+ static async createSSETransport(config) {
186
+ if (!config.url) {
187
+ throw new Error("URL is required for SSE transport");
188
+ }
189
+ mcpLogger.debug(`[MCPClientFactory] Creating SSE transport for ${config.id}`, {
190
+ url: config.url,
191
+ });
192
+ try {
193
+ const url = new URL(config.url);
194
+ const transport = new SSEClientTransport(url);
195
+ return { transport };
196
+ }
197
+ catch (error) {
198
+ throw new Error(`Invalid SSE URL: ${error instanceof Error ? error.message : String(error)}`);
199
+ }
200
+ }
201
+ /**
202
+ * Create WebSocket transport
203
+ */
204
+ static async createWebSocketTransport(config) {
205
+ if (!config.url) {
206
+ throw new Error("URL is required for WebSocket transport");
207
+ }
208
+ mcpLogger.debug(`[MCPClientFactory] Creating WebSocket transport for ${config.id}`, {
209
+ url: config.url,
210
+ });
211
+ try {
212
+ const url = new URL(config.url);
213
+ const transport = new WebSocketClientTransport(url);
214
+ return { transport };
215
+ }
216
+ catch (error) {
217
+ throw new Error(`Invalid WebSocket URL: ${error instanceof Error ? error.message : String(error)}`);
218
+ }
219
+ }
220
+ /**
221
+ * Perform MCP handshake and get server capabilities
222
+ */
223
+ static async performHandshake(client, timeout) {
224
+ try {
225
+ // The MCP SDK handles the handshake automatically during connect()
226
+ // We can request server info to verify the connection
227
+ const serverInfo = await Promise.race([
228
+ this.getServerInfo(client),
229
+ this.createTimeoutPromise(timeout, "Handshake timeout"),
230
+ ]);
231
+ // Extract capabilities from server info
232
+ return this.extractCapabilities(serverInfo);
233
+ }
234
+ catch (error) {
235
+ mcpLogger.warn("[MCPClientFactory] Handshake failed, but connection may still be valid:", error);
236
+ // Return default capabilities if handshake fails
237
+ // The connection might still work for basic operations
238
+ return this.DEFAULT_CAPABILITIES;
239
+ }
240
+ }
241
+ /**
242
+ * Get server information
243
+ */
244
+ static async getServerInfo(client) {
245
+ try {
246
+ // Try to list tools to verify server is responding
247
+ const toolsResult = await client.listTools();
248
+ return {
249
+ tools: toolsResult.tools || [],
250
+ capabilities: this.DEFAULT_CAPABILITIES,
251
+ };
252
+ }
253
+ catch (error) {
254
+ // If listing tools fails, try a simpler ping
255
+ mcpLogger.debug("[MCPClientFactory] Tool listing failed, server may not support tools yet");
256
+ return {
257
+ tools: [],
258
+ capabilities: this.DEFAULT_CAPABILITIES,
259
+ };
260
+ }
261
+ }
262
+ /**
263
+ * Extract capabilities from server info
264
+ */
265
+ static extractCapabilities(serverInfo) {
266
+ // For now, return default capabilities
267
+ // This can be enhanced when MCP servers provide more detailed capability info
268
+ return {
269
+ ...this.DEFAULT_CAPABILITIES,
270
+ tools: serverInfo.tools ? {} : undefined,
271
+ };
272
+ }
273
+ /**
274
+ * Create a timeout promise
275
+ */
276
+ static createTimeoutPromise(timeout, message) {
277
+ return new Promise((_, reject) => {
278
+ setTimeout(() => {
279
+ reject(new Error(message));
280
+ }, timeout);
281
+ });
282
+ }
283
+ /**
284
+ * Close an MCP client and clean up resources
285
+ */
286
+ static async closeClient(client, transport, process) {
287
+ const errors = [];
288
+ // Close client
289
+ try {
290
+ await client.close();
291
+ }
292
+ catch (error) {
293
+ errors.push(`Client close error: ${error instanceof Error ? error.message : String(error)}`);
294
+ }
295
+ // Close transport
296
+ try {
297
+ await transport.close();
298
+ }
299
+ catch (error) {
300
+ errors.push(`Transport close error: ${error instanceof Error ? error.message : String(error)}`);
301
+ }
302
+ // Kill process if exists
303
+ if (process && !process.killed) {
304
+ try {
305
+ process.kill("SIGTERM");
306
+ // Force kill after 5 seconds
307
+ setTimeout(() => {
308
+ if (!process.killed) {
309
+ mcpLogger.warn("[MCPClientFactory] Force killing process");
310
+ process.kill("SIGKILL");
311
+ }
312
+ }, 5000);
313
+ }
314
+ catch (error) {
315
+ errors.push(`Process kill error: ${error instanceof Error ? error.message : String(error)}`);
316
+ }
317
+ }
318
+ if (errors.length > 0) {
319
+ mcpLogger.warn("[MCPClientFactory] Errors during client cleanup:", errors);
320
+ }
321
+ }
322
+ /**
323
+ * Test connection to an MCP server
324
+ */
325
+ static async testConnection(config, timeout = 5000) {
326
+ let client;
327
+ let transport;
328
+ let process;
329
+ try {
330
+ const result = await this.createClient(config, timeout);
331
+ if (!result.success) {
332
+ return { success: false, error: result.error };
333
+ }
334
+ client = result.client;
335
+ transport = result.transport;
336
+ process = result.process;
337
+ // Try to list tools as a connectivity test
338
+ if (client) {
339
+ try {
340
+ await client.listTools();
341
+ }
342
+ catch (error) {
343
+ // Tool listing failure doesn't necessarily mean connection failure
344
+ mcpLogger.debug("[MCPClientFactory] Tool listing failed during test, but connection may be valid");
345
+ }
346
+ }
347
+ return {
348
+ success: true,
349
+ capabilities: result.capabilities,
350
+ };
351
+ }
352
+ catch (error) {
353
+ return {
354
+ success: false,
355
+ error: error instanceof Error ? error.message : String(error),
356
+ };
357
+ }
358
+ finally {
359
+ // Clean up test connection
360
+ if (client && transport) {
361
+ try {
362
+ await this.closeClient(client, transport, process);
363
+ }
364
+ catch (error) {
365
+ mcpLogger.debug("[MCPClientFactory] Error cleaning up test connection:", error);
366
+ }
367
+ }
368
+ }
369
+ }
370
+ /**
371
+ * Validate MCP server configuration for client creation
372
+ */
373
+ static validateClientConfig(config) {
374
+ const errors = [];
375
+ // Basic validation
376
+ if (!config.command) {
377
+ errors.push("Command is required");
378
+ }
379
+ if (!config.transport) {
380
+ errors.push("Transport is required");
381
+ }
382
+ if (!["stdio", "sse", "websocket"].includes(config.transport)) {
383
+ errors.push("Transport must be stdio, sse, or websocket");
384
+ }
385
+ // Transport-specific validation
386
+ if (config.transport === "sse" || config.transport === "websocket") {
387
+ if (!config.url) {
388
+ errors.push(`URL is required for ${config.transport} transport`);
389
+ }
390
+ else {
391
+ try {
392
+ new URL(config.url);
393
+ }
394
+ catch {
395
+ errors.push(`Invalid URL for ${config.transport} transport`);
396
+ }
397
+ }
398
+ }
399
+ if (config.transport === "stdio") {
400
+ if (!Array.isArray(config.args)) {
401
+ errors.push("Args array is required for stdio transport");
402
+ }
403
+ }
404
+ return {
405
+ isValid: errors.length === 0,
406
+ errors,
407
+ };
408
+ }
409
+ /**
410
+ * Get supported transport types
411
+ */
412
+ static getSupportedTransports() {
413
+ return ["stdio", "sse", "websocket"];
414
+ }
415
+ /**
416
+ * Get default client capabilities
417
+ */
418
+ static getDefaultCapabilities() {
419
+ return { ...this.DEFAULT_CAPABILITIES };
420
+ }
421
+ }
@@ -0,0 +1,193 @@
1
+ /**
2
+ * Tool Discovery Service
3
+ * Automatically discovers and registers tools from external MCP servers
4
+ * Handles tool validation, transformation, and lifecycle management
5
+ */
6
+ import { EventEmitter } from "events";
7
+ import type { Client } from "@modelcontextprotocol/sdk/client/index.js";
8
+ import type { ExternalMCPToolInfo, ExternalMCPToolResult, ExternalMCPToolContext } from "../types/externalMcp.js";
9
+ import type { JsonObject } from "../types/common.js";
10
+ /**
11
+ * Tool discovery result
12
+ */
13
+ export interface ToolDiscoveryResult {
14
+ /** Whether discovery was successful */
15
+ success: boolean;
16
+ /** Number of tools discovered */
17
+ toolCount: number;
18
+ /** Discovered tools */
19
+ tools: ExternalMCPToolInfo[];
20
+ /** Error message if failed */
21
+ error?: string;
22
+ /** Discovery duration in milliseconds */
23
+ duration: number;
24
+ /** Server ID */
25
+ serverId: string;
26
+ }
27
+ /**
28
+ * Tool execution options
29
+ */
30
+ export interface ToolExecutionOptions {
31
+ /** Execution timeout in milliseconds */
32
+ timeout?: number;
33
+ /** Additional context for execution */
34
+ context?: Partial<ExternalMCPToolContext>;
35
+ /** Whether to validate input parameters */
36
+ validateInput?: boolean;
37
+ /** Whether to validate output */
38
+ validateOutput?: boolean;
39
+ }
40
+ /**
41
+ * Tool validation result
42
+ */
43
+ export interface ToolValidationResult {
44
+ /** Whether the tool is valid */
45
+ isValid: boolean;
46
+ /** Validation errors */
47
+ errors: string[];
48
+ /** Validation warnings */
49
+ warnings: string[];
50
+ /** Tool metadata */
51
+ metadata?: {
52
+ category?: string;
53
+ complexity?: "simple" | "moderate" | "complex";
54
+ requiresAuth?: boolean;
55
+ isDeprecated?: boolean;
56
+ };
57
+ }
58
+ /**
59
+ * Tool registry events
60
+ */
61
+ export interface ToolRegistryEvents {
62
+ toolRegistered: {
63
+ serverId: string;
64
+ toolName: string;
65
+ toolInfo: ExternalMCPToolInfo;
66
+ timestamp: Date;
67
+ };
68
+ toolUnregistered: {
69
+ serverId: string;
70
+ toolName: string;
71
+ timestamp: Date;
72
+ };
73
+ toolUpdated: {
74
+ serverId: string;
75
+ toolName: string;
76
+ oldInfo: ExternalMCPToolInfo;
77
+ newInfo: ExternalMCPToolInfo;
78
+ timestamp: Date;
79
+ };
80
+ discoveryCompleted: {
81
+ serverId: string;
82
+ toolCount: number;
83
+ duration: number;
84
+ timestamp: Date;
85
+ };
86
+ discoveryFailed: {
87
+ serverId: string;
88
+ error: string;
89
+ timestamp: Date;
90
+ };
91
+ }
92
+ /**
93
+ * ToolDiscoveryService
94
+ * Handles automatic tool discovery and registration from external MCP servers
95
+ */
96
+ export declare class ToolDiscoveryService extends EventEmitter {
97
+ private serverToolStorage;
98
+ private toolRegistry;
99
+ private serverTools;
100
+ private discoveryInProgress;
101
+ constructor();
102
+ /**
103
+ * Discover tools from an external MCP server
104
+ */
105
+ discoverTools(serverId: string, client: Client, timeout?: number): Promise<ToolDiscoveryResult>;
106
+ /**
107
+ * Perform the actual tool discovery
108
+ */
109
+ private performToolDiscovery;
110
+ /**
111
+ * Register discovered tools
112
+ */
113
+ private registerDiscoveredTools;
114
+ /**
115
+ * Create tool info from MCP tool definition
116
+ */
117
+ private createToolInfo;
118
+ /**
119
+ * Infer tool category from tool definition
120
+ */
121
+ private inferToolCategory;
122
+ /**
123
+ * Validate a tool
124
+ */
125
+ private validateTool;
126
+ /**
127
+ * Infer tool complexity
128
+ */
129
+ private inferComplexity;
130
+ /**
131
+ * Infer if tool requires authentication
132
+ */
133
+ private inferAuthRequirement;
134
+ /**
135
+ * Execute a tool
136
+ */
137
+ executeTool(toolName: string, serverId: string, client: Client, parameters: JsonObject, options?: ToolExecutionOptions): Promise<ExternalMCPToolResult>;
138
+ /**
139
+ * Validate tool parameters
140
+ */
141
+ private validateToolParameters;
142
+ /**
143
+ * Validate parameter type
144
+ */
145
+ private validateParameterType;
146
+ /**
147
+ * Validate tool output
148
+ */
149
+ private validateToolOutput;
150
+ /**
151
+ * Update tool statistics
152
+ */
153
+ private updateToolStats;
154
+ /**
155
+ * Get tool by name and server
156
+ */
157
+ getTool(toolName: string, serverId: string): ExternalMCPToolInfo | undefined;
158
+ /**
159
+ * Get all tools for a server
160
+ */
161
+ getServerTools(serverId: string): ExternalMCPToolInfo[];
162
+ /**
163
+ * Get all registered tools
164
+ */
165
+ getAllTools(): ExternalMCPToolInfo[];
166
+ /**
167
+ * Clear tools for a server
168
+ */
169
+ clearServerTools(serverId: string): void;
170
+ /**
171
+ * Update tool availability
172
+ */
173
+ updateToolAvailability(toolName: string, serverId: string, isAvailable: boolean): void;
174
+ /**
175
+ * Create tool key for registry
176
+ */
177
+ private createToolKey;
178
+ /**
179
+ * Create timeout promise
180
+ */
181
+ private createTimeoutPromise;
182
+ /**
183
+ * Get discovery statistics
184
+ */
185
+ getStatistics(): {
186
+ totalTools: number;
187
+ availableTools: number;
188
+ unavailableTools: number;
189
+ totalServers: number;
190
+ toolsByServer: Record<string, number>;
191
+ toolsByCategory: Record<string, number>;
192
+ };
193
+ }