@juspay/neurolink 8.28.0 → 8.30.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 (83) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +23 -2
  3. package/dist/adapters/video/vertexVideoHandler.d.ts +12 -2
  4. package/dist/adapters/video/vertexVideoHandler.js +12 -2
  5. package/dist/core/baseProvider.d.ts +19 -0
  6. package/dist/core/baseProvider.js +174 -0
  7. package/dist/index.d.ts +3 -3
  8. package/dist/index.js +7 -1
  9. package/dist/lib/adapters/video/vertexVideoHandler.d.ts +12 -2
  10. package/dist/lib/adapters/video/vertexVideoHandler.js +12 -2
  11. package/dist/lib/core/baseProvider.d.ts +19 -0
  12. package/dist/lib/core/baseProvider.js +174 -0
  13. package/dist/lib/index.d.ts +3 -3
  14. package/dist/lib/index.js +7 -1
  15. package/dist/lib/mcp/auth/index.d.ts +6 -0
  16. package/dist/lib/mcp/auth/index.js +12 -0
  17. package/dist/lib/mcp/auth/oauthClientProvider.d.ts +93 -0
  18. package/dist/lib/mcp/auth/oauthClientProvider.js +326 -0
  19. package/dist/lib/mcp/auth/tokenStorage.d.ts +56 -0
  20. package/dist/lib/mcp/auth/tokenStorage.js +135 -0
  21. package/dist/lib/mcp/externalServerManager.d.ts +5 -1
  22. package/dist/lib/mcp/externalServerManager.js +84 -22
  23. package/dist/lib/mcp/httpRateLimiter.d.ts +152 -0
  24. package/dist/lib/mcp/httpRateLimiter.js +365 -0
  25. package/dist/lib/mcp/httpRetryHandler.d.ts +62 -0
  26. package/dist/lib/mcp/httpRetryHandler.js +154 -0
  27. package/dist/lib/mcp/index.d.ts +5 -0
  28. package/dist/lib/mcp/index.js +8 -0
  29. package/dist/lib/mcp/mcpClientFactory.d.ts +25 -2
  30. package/dist/lib/mcp/mcpClientFactory.js +206 -10
  31. package/dist/lib/mcp/toolRegistry.d.ts +1 -2
  32. package/dist/lib/mcp/toolRegistry.js +1 -5
  33. package/dist/lib/neurolink.js +3 -0
  34. package/dist/lib/providers/amazonBedrock.js +4 -1
  35. package/dist/lib/providers/ollama.js +4 -1
  36. package/dist/lib/sdk/toolRegistration.d.ts +3 -25
  37. package/dist/lib/types/cli.d.ts +42 -42
  38. package/dist/lib/types/externalMcp.d.ts +55 -3
  39. package/dist/lib/types/externalMcp.js +0 -1
  40. package/dist/lib/types/generateTypes.d.ts +37 -0
  41. package/dist/lib/types/hitlTypes.d.ts +38 -0
  42. package/dist/lib/types/index.d.ts +6 -8
  43. package/dist/lib/types/index.js +4 -4
  44. package/dist/lib/types/mcpTypes.d.ts +235 -27
  45. package/dist/lib/types/providers.d.ts +16 -16
  46. package/dist/lib/types/sdkTypes.d.ts +2 -2
  47. package/dist/lib/types/tools.d.ts +42 -3
  48. package/dist/lib/types/utilities.d.ts +19 -0
  49. package/dist/mcp/auth/index.d.ts +6 -0
  50. package/dist/mcp/auth/index.js +11 -0
  51. package/dist/mcp/auth/oauthClientProvider.d.ts +93 -0
  52. package/dist/mcp/auth/oauthClientProvider.js +325 -0
  53. package/dist/mcp/auth/tokenStorage.d.ts +56 -0
  54. package/dist/mcp/auth/tokenStorage.js +134 -0
  55. package/dist/mcp/externalServerManager.d.ts +5 -1
  56. package/dist/mcp/externalServerManager.js +84 -22
  57. package/dist/mcp/httpRateLimiter.d.ts +152 -0
  58. package/dist/mcp/httpRateLimiter.js +364 -0
  59. package/dist/mcp/httpRetryHandler.d.ts +62 -0
  60. package/dist/mcp/httpRetryHandler.js +153 -0
  61. package/dist/mcp/index.d.ts +5 -0
  62. package/dist/mcp/index.js +8 -0
  63. package/dist/mcp/mcpClientFactory.d.ts +25 -2
  64. package/dist/mcp/mcpClientFactory.js +206 -10
  65. package/dist/mcp/toolRegistry.d.ts +1 -2
  66. package/dist/mcp/toolRegistry.js +1 -5
  67. package/dist/neurolink.js +3 -0
  68. package/dist/providers/amazonBedrock.js +4 -1
  69. package/dist/providers/ollama.js +4 -1
  70. package/dist/sdk/toolRegistration.d.ts +3 -25
  71. package/dist/types/cli.d.ts +42 -42
  72. package/dist/types/externalMcp.d.ts +55 -3
  73. package/dist/types/externalMcp.js +0 -1
  74. package/dist/types/generateTypes.d.ts +37 -0
  75. package/dist/types/hitlTypes.d.ts +38 -0
  76. package/dist/types/index.d.ts +6 -8
  77. package/dist/types/index.js +4 -4
  78. package/dist/types/mcpTypes.d.ts +235 -27
  79. package/dist/types/providers.d.ts +16 -16
  80. package/dist/types/sdkTypes.d.ts +2 -2
  81. package/dist/types/tools.d.ts +42 -3
  82. package/dist/types/utilities.d.ts +19 -0
  83. package/package.json +2 -1
@@ -51,6 +51,7 @@ function safeMetadataConversion(metadata) {
51
51
  }
52
52
  /**
53
53
  * Type guard to validate external MCP server configuration
54
+ * Supports both stdio transport (requires command) and HTTP transport (requires url)
54
55
  */
55
56
  function isValidExternalMCPServerConfig(config) {
56
57
  if (!isNonNullObject(config)) {
@@ -66,7 +67,13 @@ function isValidExternalMCPServerConfig(config) {
66
67
  return false;
67
68
  }
68
69
  }
69
- return (typeof record.command === "string" &&
70
+ // Must have either command (for stdio) or url (for HTTP/SSE transport)
71
+ const hasCommand = typeof record.command === "string";
72
+ const hasUrl = typeof record.url === "string";
73
+ if (!hasCommand && !hasUrl) {
74
+ return false;
75
+ }
76
+ return ((record.command === undefined || typeof record.command === "string") &&
70
77
  (record.args === undefined || Array.isArray(record.args)) &&
71
78
  (record.env === undefined || isNonNullObject(record.env)) &&
72
79
  (record.transport === undefined || typeof record.transport === "string") &&
@@ -78,8 +85,17 @@ function isValidExternalMCPServerConfig(config) {
78
85
  typeof record.autoRestart === "boolean") &&
79
86
  (record.cwd === undefined || typeof record.cwd === "string") &&
80
87
  (record.url === undefined || typeof record.url === "string") &&
88
+ (record.headers === undefined || isNonNullObject(record.headers)) &&
89
+ (record.httpOptions === undefined || isNonNullObject(record.httpOptions)) &&
90
+ (record.retryConfig === undefined || isNonNullObject(record.retryConfig)) &&
91
+ (record.rateLimiting === undefined ||
92
+ isNonNullObject(record.rateLimiting)) &&
81
93
  (record.metadata === undefined || isNonNullObject(record.metadata)));
82
94
  }
95
+ /**
96
+ * ExternalServerManager
97
+ * Core class for managing external MCP servers
98
+ */
83
99
  export class ExternalServerManager extends EventEmitter {
84
100
  servers = new Map();
85
101
  config;
@@ -180,13 +196,17 @@ export class ExternalServerManager extends EventEmitter {
180
196
  const externalConfig = {
181
197
  id: serverId,
182
198
  name: serverId,
183
- description: `External MCP server: ${serverId}`,
199
+ description: typeof serverConfig.description === "string"
200
+ ? serverConfig.description
201
+ : `External MCP server: ${serverId}`,
184
202
  transport: typeof serverConfig.transport === "string"
185
203
  ? serverConfig.transport
186
204
  : "stdio",
187
205
  status: "initializing",
188
206
  tools: [],
189
- command: serverConfig.command,
207
+ command: typeof serverConfig.command === "string"
208
+ ? serverConfig.command
209
+ : undefined,
190
210
  args: Array.isArray(serverConfig.args)
191
211
  ? serverConfig.args
192
212
  : [],
@@ -211,6 +231,19 @@ export class ExternalServerManager extends EventEmitter {
211
231
  url: typeof serverConfig.url === "string"
212
232
  ? serverConfig.url
213
233
  : undefined,
234
+ // HTTP transport-specific fields
235
+ headers: isNonNullObject(serverConfig.headers)
236
+ ? serverConfig.headers
237
+ : undefined,
238
+ httpOptions: isNonNullObject(serverConfig.httpOptions)
239
+ ? serverConfig.httpOptions
240
+ : undefined,
241
+ retryConfig: isNonNullObject(serverConfig.retryConfig)
242
+ ? serverConfig.retryConfig
243
+ : undefined,
244
+ rateLimiting: isNonNullObject(serverConfig.rateLimiting)
245
+ ? serverConfig.rateLimiting
246
+ : undefined,
214
247
  blockedTools: Array.isArray(serverConfig.blockedTools)
215
248
  ? serverConfig.blockedTools
216
249
  : undefined,
@@ -294,13 +327,17 @@ export class ExternalServerManager extends EventEmitter {
294
327
  const externalConfig = {
295
328
  id: serverId,
296
329
  name: serverId,
297
- description: `External MCP server: ${serverId}`,
330
+ description: typeof serverConfig.description === "string"
331
+ ? serverConfig.description
332
+ : `External MCP server: ${serverId}`,
298
333
  transport: typeof serverConfig.transport === "string"
299
334
  ? serverConfig.transport
300
335
  : "stdio",
301
336
  status: "initializing",
302
337
  tools: [],
303
- command: serverConfig.command,
338
+ command: typeof serverConfig.command === "string"
339
+ ? serverConfig.command
340
+ : undefined,
304
341
  args: Array.isArray(serverConfig.args)
305
342
  ? serverConfig.args
306
343
  : [],
@@ -325,6 +362,19 @@ export class ExternalServerManager extends EventEmitter {
325
362
  url: typeof serverConfig.url === "string"
326
363
  ? serverConfig.url
327
364
  : undefined,
365
+ // HTTP transport-specific fields
366
+ headers: isNonNullObject(serverConfig.headers)
367
+ ? serverConfig.headers
368
+ : undefined,
369
+ httpOptions: isNonNullObject(serverConfig.httpOptions)
370
+ ? serverConfig.httpOptions
371
+ : undefined,
372
+ retryConfig: isNonNullObject(serverConfig.retryConfig)
373
+ ? serverConfig.retryConfig
374
+ : undefined,
375
+ rateLimiting: isNonNullObject(serverConfig.rateLimiting)
376
+ ? serverConfig.rateLimiting
377
+ : undefined,
328
378
  blockedTools: Array.isArray(serverConfig.blockedTools)
329
379
  ? serverConfig.blockedTools
330
380
  : undefined,
@@ -368,19 +418,26 @@ export class ExternalServerManager extends EventEmitter {
368
418
  if (!config.id || typeof config.id !== "string") {
369
419
  errors.push("Server ID is required and must be a string");
370
420
  }
371
- if (!config.command || typeof config.command !== "string") {
372
- errors.push("Command is required and must be a string");
421
+ if (!["stdio", "sse", "websocket", "http"].includes(config.transport)) {
422
+ errors.push("Transport must be one of: stdio, sse, websocket, http");
373
423
  }
374
- if (!Array.isArray(config.args)) {
375
- errors.push("Args must be an array");
376
- }
377
- if (!["stdio", "sse", "websocket"].includes(config.transport)) {
378
- errors.push("Transport must be one of: stdio, sse, websocket");
424
+ // Transport-specific validation
425
+ if (config.transport === "stdio") {
426
+ // stdio transport requires command
427
+ if (!config.command || typeof config.command !== "string") {
428
+ errors.push("Command is required and must be a string for stdio transport");
429
+ }
430
+ if (!Array.isArray(config.args)) {
431
+ errors.push("Args must be an array");
432
+ }
379
433
  }
380
- // URL validation for non-stdio transports
381
- if ((config.transport === "sse" || config.transport === "websocket") &&
382
- !config.url) {
383
- errors.push(`URL is required for ${config.transport} transport`);
434
+ else if (config.transport === "sse" ||
435
+ config.transport === "websocket" ||
436
+ config.transport === "http") {
437
+ // HTTP-based transports require URL
438
+ if (!config.url || typeof config.url !== "string") {
439
+ errors.push(`URL is required for ${config.transport} transport`);
440
+ }
384
441
  }
385
442
  // Warnings for common issues
386
443
  if (config.timeout && config.timeout < 5000) {
@@ -461,14 +518,19 @@ export class ExternalServerManager extends EventEmitter {
461
518
  command: serverInfo.command || "",
462
519
  args: serverInfo.args || [],
463
520
  env: serverInfo.env || {},
464
- timeout: serverInfo.metadata?.timeout,
465
- retries: serverInfo.metadata?.retries,
466
- healthCheckInterval: serverInfo.metadata?.healthCheckInterval,
467
- autoRestart: serverInfo.metadata?.autoRestart,
468
- cwd: serverInfo.metadata?.cwd,
469
- url: serverInfo.metadata?.url,
521
+ timeout: serverInfo.timeout,
522
+ retries: serverInfo.retries,
523
+ healthCheckInterval: serverInfo.healthCheckInterval,
524
+ autoRestart: serverInfo.autoRestart,
525
+ cwd: serverInfo.cwd,
526
+ url: serverInfo.url,
470
527
  blockedTools: serverInfo.blockedTools,
471
528
  metadata: safeMetadataConversion(serverInfo.metadata),
529
+ // HTTP transport-specific fields
530
+ headers: serverInfo.headers,
531
+ httpOptions: serverInfo.httpOptions,
532
+ retryConfig: serverInfo.retryConfig,
533
+ rateLimiting: serverInfo.rateLimiting,
472
534
  };
473
535
  const validation = this.validateConfig(tempConfig);
474
536
  if (!validation.isValid) {
@@ -0,0 +1,152 @@
1
+ /**
2
+ * HTTP Rate Limiter for MCP HTTP Transport
3
+ * Implements token bucket algorithm for rate limiting
4
+ * Provides fault tolerance and prevents server overload
5
+ */
6
+ import type { RateLimitConfig, RateLimiterStats } from "../types/mcpTypes.js";
7
+ /**
8
+ * Default rate limit configuration
9
+ * Provides sensible defaults for most MCP HTTP transport use cases
10
+ */
11
+ export declare const DEFAULT_RATE_LIMIT_CONFIG: RateLimitConfig;
12
+ /**
13
+ * HTTPRateLimiter
14
+ * Implements token bucket algorithm for rate limiting HTTP requests
15
+ *
16
+ * The token bucket algorithm works as follows:
17
+ * - Tokens are added to the bucket at a fixed rate (refillRate per second)
18
+ * - Each request consumes one token
19
+ * - If no tokens are available, the request must wait
20
+ * - Maximum tokens are capped at maxBurst to allow controlled bursting
21
+ */
22
+ export declare class HTTPRateLimiter {
23
+ private tokens;
24
+ private lastRefill;
25
+ private config;
26
+ private waitQueue;
27
+ private processingQueue;
28
+ constructor(config?: Partial<RateLimitConfig>);
29
+ /**
30
+ * Refill tokens based on elapsed time since last refill
31
+ * Tokens are added at the configured refillRate (tokens per second)
32
+ */
33
+ private refillTokens;
34
+ /**
35
+ * Acquire a token, waiting if necessary
36
+ * This is the primary method for rate-limited operations
37
+ *
38
+ * @returns Promise that resolves when a token is acquired
39
+ * @throws Error if the wait queue is too long
40
+ */
41
+ acquire(): Promise<void>;
42
+ /**
43
+ * Process the wait queue, granting tokens as they become available
44
+ */
45
+ private processQueue;
46
+ /**
47
+ * Sleep helper function
48
+ */
49
+ private sleep;
50
+ /**
51
+ * Try to acquire a token without waiting
52
+ *
53
+ * @returns true if a token was acquired, false otherwise
54
+ */
55
+ tryAcquire(): boolean;
56
+ /**
57
+ * Handle rate limit response headers from server
58
+ * Parses Retry-After header and returns wait time in milliseconds
59
+ *
60
+ * @param headers - Response headers from the server
61
+ * @returns Wait time in milliseconds, or 0 if no rate limit headers found
62
+ */
63
+ handleRateLimitResponse(headers: Headers): number;
64
+ /**
65
+ * Get the number of remaining tokens
66
+ *
67
+ * @returns Current number of available tokens
68
+ */
69
+ getRemainingTokens(): number;
70
+ /**
71
+ * Reset the rate limiter to initial state
72
+ * Useful for testing or when server indicates rate limits have been reset
73
+ */
74
+ reset(): void;
75
+ /**
76
+ * Get current rate limiter statistics
77
+ */
78
+ getStats(): RateLimiterStats;
79
+ /**
80
+ * Update configuration dynamically
81
+ * Useful when server provides rate limit information
82
+ */
83
+ updateConfig(config: Partial<RateLimitConfig>): void;
84
+ /**
85
+ * Get current configuration
86
+ */
87
+ getConfig(): Readonly<RateLimitConfig>;
88
+ }
89
+ /**
90
+ * RateLimiterManager
91
+ * Manages multiple rate limiters for different servers
92
+ * Each server can have its own rate limiting configuration
93
+ */
94
+ export declare class RateLimiterManager {
95
+ private limiters;
96
+ /**
97
+ * Get or create a rate limiter for a server
98
+ *
99
+ * @param serverId - Unique identifier for the server
100
+ * @param config - Optional configuration for the rate limiter
101
+ * @returns HTTPRateLimiter instance for the server
102
+ */
103
+ getLimiter(serverId: string, config?: Partial<RateLimitConfig>): HTTPRateLimiter;
104
+ /**
105
+ * Check if a rate limiter exists for a server
106
+ *
107
+ * @param serverId - Unique identifier for the server
108
+ * @returns true if a rate limiter exists for the server
109
+ */
110
+ hasLimiter(serverId: string): boolean;
111
+ /**
112
+ * Remove a rate limiter for a server
113
+ *
114
+ * @param serverId - Unique identifier for the server
115
+ */
116
+ removeLimiter(serverId: string): void;
117
+ /**
118
+ * Get all server IDs with active rate limiters
119
+ *
120
+ * @returns Array of server IDs
121
+ */
122
+ getServerIds(): string[];
123
+ /**
124
+ * Get statistics for all rate limiters
125
+ *
126
+ * @returns Record of server IDs to their rate limiter statistics
127
+ */
128
+ getAllStats(): Record<string, RateLimiterStats>;
129
+ /**
130
+ * Reset all rate limiters
131
+ */
132
+ resetAll(): void;
133
+ /**
134
+ * Destroy all rate limiters and clean up resources
135
+ * This should be called during application shutdown
136
+ */
137
+ destroyAll(): void;
138
+ /**
139
+ * Get health summary for all rate limiters
140
+ */
141
+ getHealthSummary(): {
142
+ totalLimiters: number;
143
+ serversWithQueuedRequests: string[];
144
+ totalQueuedRequests: number;
145
+ averageTokensAvailable: number;
146
+ };
147
+ }
148
+ /**
149
+ * Global rate limiter manager instance
150
+ * Use this for application-wide rate limiting management
151
+ */
152
+ export declare const globalRateLimiterManager: RateLimiterManager;