@juspay/neurolink 5.1.0 → 5.3.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 (190) hide show
  1. package/CHANGELOG.md +21 -9
  2. package/README.md +123 -126
  3. package/dist/agent/direct-tools.d.ts +6 -6
  4. package/dist/cli/commands/config.d.ts +3 -3
  5. package/dist/cli/commands/mcp.js +8 -7
  6. package/dist/cli/factories/command-factory.d.ts +4 -0
  7. package/dist/cli/factories/command-factory.js +63 -8
  8. package/dist/cli/index.js +87 -140
  9. package/dist/core/base-provider.d.ts +423 -0
  10. package/dist/core/base-provider.js +376 -0
  11. package/dist/core/constants.d.ts +2 -1
  12. package/dist/core/constants.js +2 -1
  13. package/dist/core/dynamic-models.d.ts +6 -6
  14. package/dist/core/evaluation.d.ts +19 -80
  15. package/dist/core/evaluation.js +185 -484
  16. package/dist/core/factory.d.ts +3 -3
  17. package/dist/core/factory.js +31 -91
  18. package/dist/core/service-registry.d.ts +47 -0
  19. package/dist/core/service-registry.js +112 -0
  20. package/dist/core/types.d.ts +8 -1
  21. package/dist/factories/compatibility-factory.js +1 -1
  22. package/dist/factories/provider-factory.d.ts +72 -0
  23. package/dist/factories/provider-factory.js +144 -0
  24. package/dist/factories/provider-registry.d.ts +38 -0
  25. package/dist/factories/provider-registry.js +107 -0
  26. package/dist/index.d.ts +4 -3
  27. package/dist/index.js +2 -4
  28. package/dist/lib/agent/direct-tools.d.ts +6 -6
  29. package/dist/lib/core/base-provider.d.ts +423 -0
  30. package/dist/lib/core/base-provider.js +376 -0
  31. package/dist/lib/core/constants.d.ts +2 -1
  32. package/dist/lib/core/constants.js +2 -1
  33. package/dist/lib/core/dynamic-models.d.ts +6 -6
  34. package/dist/lib/core/evaluation.d.ts +19 -80
  35. package/dist/lib/core/evaluation.js +185 -484
  36. package/dist/lib/core/factory.d.ts +3 -3
  37. package/dist/lib/core/factory.js +30 -91
  38. package/dist/lib/core/service-registry.d.ts +47 -0
  39. package/dist/lib/core/service-registry.js +112 -0
  40. package/dist/lib/core/types.d.ts +8 -1
  41. package/dist/lib/factories/compatibility-factory.js +1 -1
  42. package/dist/lib/factories/provider-factory.d.ts +72 -0
  43. package/dist/lib/factories/provider-factory.js +144 -0
  44. package/dist/lib/factories/provider-registry.d.ts +38 -0
  45. package/dist/lib/factories/provider-registry.js +107 -0
  46. package/dist/lib/index.d.ts +4 -3
  47. package/dist/lib/index.js +2 -4
  48. package/dist/lib/mcp/client.d.ts +1 -0
  49. package/dist/lib/mcp/client.js +1 -0
  50. package/dist/lib/mcp/config.js +28 -3
  51. package/dist/lib/mcp/context-manager.d.ts +1 -0
  52. package/dist/lib/mcp/context-manager.js +8 -4
  53. package/dist/lib/mcp/function-calling.d.ts +13 -0
  54. package/dist/lib/mcp/function-calling.js +134 -35
  55. package/dist/lib/mcp/initialize-tools.d.ts +1 -1
  56. package/dist/lib/mcp/initialize-tools.js +45 -1
  57. package/dist/lib/mcp/initialize.js +16 -6
  58. package/dist/lib/mcp/neurolink-mcp-client.d.ts +1 -0
  59. package/dist/lib/mcp/neurolink-mcp-client.js +21 -5
  60. package/dist/lib/mcp/servers/agent/direct-tools-server.d.ts +8 -0
  61. package/dist/lib/mcp/servers/agent/direct-tools-server.js +109 -0
  62. package/dist/lib/mcp/servers/ai-providers/ai-core-server.js +3 -1
  63. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  64. package/dist/lib/mcp/unified-registry.d.ts +4 -0
  65. package/dist/lib/mcp/unified-registry.js +42 -9
  66. package/dist/lib/neurolink.d.ts +156 -117
  67. package/dist/lib/neurolink.js +619 -404
  68. package/dist/lib/providers/amazon-bedrock.d.ts +32 -0
  69. package/dist/lib/providers/amazon-bedrock.js +143 -0
  70. package/dist/lib/providers/analytics-helper.js +7 -4
  71. package/dist/lib/providers/anthropic-baseprovider.d.ts +23 -0
  72. package/dist/lib/providers/anthropic-baseprovider.js +114 -0
  73. package/dist/lib/providers/anthropic.d.ts +19 -43
  74. package/dist/lib/providers/anthropic.js +82 -306
  75. package/dist/lib/providers/azure-openai.d.ts +20 -0
  76. package/dist/lib/providers/azure-openai.js +89 -0
  77. package/dist/lib/providers/function-calling-provider.d.ts +64 -2
  78. package/dist/lib/providers/function-calling-provider.js +208 -9
  79. package/dist/lib/providers/google-ai-studio.d.ts +23 -0
  80. package/dist/lib/providers/google-ai-studio.js +107 -0
  81. package/dist/lib/providers/google-vertex.d.ts +47 -0
  82. package/dist/lib/providers/google-vertex.js +205 -0
  83. package/dist/lib/providers/huggingFace.d.ts +32 -25
  84. package/dist/lib/providers/huggingFace.js +97 -431
  85. package/dist/lib/providers/index.d.ts +9 -9
  86. package/dist/lib/providers/index.js +9 -9
  87. package/dist/lib/providers/mcp-provider.js +24 -5
  88. package/dist/lib/providers/mistral.d.ts +42 -0
  89. package/dist/lib/providers/mistral.js +160 -0
  90. package/dist/lib/providers/ollama.d.ts +52 -36
  91. package/dist/lib/providers/ollama.js +297 -520
  92. package/dist/lib/providers/openAI.d.ts +19 -18
  93. package/dist/lib/providers/openAI.js +76 -275
  94. package/dist/lib/sdk/tool-extension.d.ts +181 -0
  95. package/dist/lib/sdk/tool-extension.js +283 -0
  96. package/dist/lib/sdk/tool-registration.d.ts +95 -0
  97. package/dist/lib/sdk/tool-registration.js +167 -0
  98. package/dist/lib/services/streaming/streaming-manager.js +11 -10
  99. package/dist/lib/services/websocket/websocket-server.js +12 -11
  100. package/dist/lib/telemetry/telemetry-service.js +8 -7
  101. package/dist/lib/types/generate-types.d.ts +1 -0
  102. package/dist/lib/types/mcp-types.d.ts +116 -0
  103. package/dist/lib/types/mcp-types.js +5 -0
  104. package/dist/lib/types/stream-types.d.ts +30 -18
  105. package/dist/lib/types/universal-provider-options.d.ts +87 -0
  106. package/dist/lib/types/universal-provider-options.js +53 -0
  107. package/dist/mcp/client.d.ts +1 -0
  108. package/dist/mcp/client.js +1 -0
  109. package/dist/mcp/config.js +28 -3
  110. package/dist/mcp/context-manager.d.ts +1 -0
  111. package/dist/mcp/context-manager.js +8 -4
  112. package/dist/mcp/function-calling.d.ts +13 -0
  113. package/dist/mcp/function-calling.js +134 -35
  114. package/dist/mcp/initialize-tools.d.ts +1 -1
  115. package/dist/mcp/initialize-tools.js +45 -1
  116. package/dist/mcp/initialize.js +16 -6
  117. package/dist/mcp/neurolink-mcp-client.d.ts +1 -0
  118. package/dist/mcp/neurolink-mcp-client.js +21 -5
  119. package/dist/mcp/servers/agent/direct-tools-server.d.ts +8 -0
  120. package/dist/mcp/servers/agent/direct-tools-server.js +109 -0
  121. package/dist/mcp/servers/ai-providers/ai-core-server.js +3 -1
  122. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  123. package/dist/mcp/unified-registry.d.ts +4 -0
  124. package/dist/mcp/unified-registry.js +42 -9
  125. package/dist/neurolink.d.ts +156 -117
  126. package/dist/neurolink.js +619 -404
  127. package/dist/providers/amazon-bedrock.d.ts +32 -0
  128. package/dist/providers/amazon-bedrock.js +143 -0
  129. package/dist/providers/analytics-helper.js +7 -4
  130. package/dist/providers/anthropic-baseprovider.d.ts +23 -0
  131. package/dist/providers/anthropic-baseprovider.js +114 -0
  132. package/dist/providers/anthropic.d.ts +19 -43
  133. package/dist/providers/anthropic.js +81 -305
  134. package/dist/providers/azure-openai.d.ts +20 -0
  135. package/dist/providers/azure-openai.js +89 -0
  136. package/dist/providers/function-calling-provider.d.ts +64 -2
  137. package/dist/providers/function-calling-provider.js +208 -9
  138. package/dist/providers/google-ai-studio.d.ts +23 -0
  139. package/dist/providers/google-ai-studio.js +108 -0
  140. package/dist/providers/google-vertex.d.ts +47 -0
  141. package/dist/providers/google-vertex.js +205 -0
  142. package/dist/providers/huggingFace.d.ts +32 -25
  143. package/dist/providers/huggingFace.js +96 -430
  144. package/dist/providers/index.d.ts +9 -9
  145. package/dist/providers/index.js +9 -9
  146. package/dist/providers/mcp-provider.js +24 -5
  147. package/dist/providers/mistral.d.ts +42 -0
  148. package/dist/providers/mistral.js +160 -0
  149. package/dist/providers/ollama.d.ts +52 -36
  150. package/dist/providers/ollama.js +297 -519
  151. package/dist/providers/openAI.d.ts +19 -18
  152. package/dist/providers/openAI.js +76 -276
  153. package/dist/sdk/tool-extension.d.ts +181 -0
  154. package/dist/sdk/tool-extension.js +283 -0
  155. package/dist/sdk/tool-registration.d.ts +95 -0
  156. package/dist/sdk/tool-registration.js +168 -0
  157. package/dist/services/streaming/streaming-manager.js +11 -10
  158. package/dist/services/websocket/websocket-server.js +12 -11
  159. package/dist/telemetry/telemetry-service.js +8 -7
  160. package/dist/types/generate-types.d.ts +1 -0
  161. package/dist/types/mcp-types.d.ts +116 -0
  162. package/dist/types/mcp-types.js +5 -0
  163. package/dist/types/stream-types.d.ts +30 -18
  164. package/dist/types/universal-provider-options.d.ts +87 -0
  165. package/dist/types/universal-provider-options.js +53 -0
  166. package/package.json +12 -5
  167. package/dist/lib/providers/agent-enhanced-provider.d.ts +0 -93
  168. package/dist/lib/providers/agent-enhanced-provider.js +0 -605
  169. package/dist/lib/providers/amazonBedrock.d.ts +0 -28
  170. package/dist/lib/providers/amazonBedrock.js +0 -364
  171. package/dist/lib/providers/azureOpenAI.d.ts +0 -42
  172. package/dist/lib/providers/azureOpenAI.js +0 -347
  173. package/dist/lib/providers/googleAIStudio.d.ts +0 -42
  174. package/dist/lib/providers/googleAIStudio.js +0 -364
  175. package/dist/lib/providers/googleVertexAI.d.ts +0 -34
  176. package/dist/lib/providers/googleVertexAI.js +0 -547
  177. package/dist/lib/providers/mistralAI.d.ts +0 -37
  178. package/dist/lib/providers/mistralAI.js +0 -325
  179. package/dist/providers/agent-enhanced-provider.d.ts +0 -93
  180. package/dist/providers/agent-enhanced-provider.js +0 -606
  181. package/dist/providers/amazonBedrock.d.ts +0 -28
  182. package/dist/providers/amazonBedrock.js +0 -364
  183. package/dist/providers/azureOpenAI.d.ts +0 -42
  184. package/dist/providers/azureOpenAI.js +0 -348
  185. package/dist/providers/googleAIStudio.d.ts +0 -42
  186. package/dist/providers/googleAIStudio.js +0 -364
  187. package/dist/providers/googleVertexAI.d.ts +0 -34
  188. package/dist/providers/googleVertexAI.js +0 -547
  189. package/dist/providers/mistralAI.d.ts +0 -37
  190. package/dist/providers/mistralAI.js +0 -325
@@ -8,6 +8,100 @@ import { z } from "zod";
8
8
  import { unifiedRegistry } from "./unified-registry.js";
9
9
  import { createExecutionContext } from "./context-manager.js";
10
10
  import { mcpLogger } from "./logging.js";
11
+ /**
12
+ * Parses neurolink-specific function name patterns to extract the server ID and tool name.
13
+ *
14
+ * @param {string[]} parts - An array of strings representing parts of a function name,
15
+ * typically obtained by splitting the function name on underscores.
16
+ * @returns {{ serverId: string; toolName: string } | null} An object containing the `serverId`
17
+ * and `toolName` if the input matches a neurolink-specific pattern, or `null` if no match is found.
18
+ *
19
+ * @example
20
+ * // Returns { serverId: "neurolink_ai_core", toolName: "generate" }
21
+ * parseNeuroLinkPattern(["neurolink", "ai", "core", "generate"]);
22
+ *
23
+ * @example
24
+ * // Returns { serverId: "neurolink_utility", toolName: "format_number" }
25
+ * parseNeuroLinkPattern(["neurolink", "utility", "format_number"]);
26
+ *
27
+ * @example
28
+ * // Returns null
29
+ * parseNeuroLinkPattern(["other", "pattern"]);
30
+ */
31
+ function parseNeuroLinkPattern(parts) {
32
+ if (parts.length >= 3 &&
33
+ parts[0] === "neurolink" &&
34
+ (parts[1] === "ai" || parts[1] === "utility")) {
35
+ // neurolink_ai_core_generate -> serverId: "neurolink_ai_core", toolName: "generate"
36
+ // neurolink_utility_format_number -> serverId: "neurolink_utility", toolName: "format_number"
37
+ if (parts[1] === "ai" && parts[2] === "core") {
38
+ return {
39
+ serverId: "neurolink_ai_core",
40
+ toolName: parts.slice(3).join("_"),
41
+ };
42
+ }
43
+ else if (parts[1] === "utility") {
44
+ return {
45
+ serverId: "neurolink_utility",
46
+ toolName: parts.slice(2).join("_"),
47
+ };
48
+ }
49
+ }
50
+ return null;
51
+ }
52
+ /**
53
+ * Parse underscore-separated function name format
54
+ */
55
+ function parseUnderscoreFormat(functionName) {
56
+ const parts = functionName.split("_");
57
+ if (parts.length >= 2) {
58
+ // Try neurolink-specific patterns first
59
+ const neurolinkResult = parseNeuroLinkPattern(parts);
60
+ if (neurolinkResult) {
61
+ return neurolinkResult;
62
+ }
63
+ // Default underscore parsing
64
+ return {
65
+ serverId: parts[0],
66
+ toolName: parts.slice(1).join("_"),
67
+ };
68
+ }
69
+ return null;
70
+ }
71
+ /**
72
+ * Parse dot-separated function name format (legacy support)
73
+ */
74
+ function parseDotFormat(functionName) {
75
+ const parts = functionName.split(".");
76
+ if (parts.length >= 2) {
77
+ return {
78
+ serverId: parts[0],
79
+ toolName: parts.slice(1).join("."),
80
+ };
81
+ }
82
+ return null;
83
+ }
84
+ /**
85
+ * Parse function name to extract server ID and tool name
86
+ * Handles various naming patterns including neurolink server patterns
87
+ */
88
+ function parseFunctionName(functionName) {
89
+ // Try underscore format first (most common)
90
+ const underscoreResult = parseUnderscoreFormat(functionName);
91
+ if (underscoreResult) {
92
+ return underscoreResult;
93
+ }
94
+ // Fallback to dot format for backward compatibility
95
+ const dotResult = parseDotFormat(functionName);
96
+ if (dotResult) {
97
+ return dotResult;
98
+ }
99
+ // Final fallback - return as-is with unknown server
100
+ return {
101
+ serverId: "unknown",
102
+ toolName: functionName,
103
+ };
104
+ }
11
105
  /**
12
106
  * Convert MCP tool to AI SDK function definition
13
107
  */
@@ -55,10 +149,11 @@ export function mcpToolToAISDKTool(tool, serverId) {
55
149
  export async function getAvailableFunctionTools() {
56
150
  const functionTag = "getAvailableFunctionTools";
57
151
  const tools = [];
152
+ const toolsObject = {};
58
153
  const toolMap = new Map();
59
154
  try {
60
155
  // Add overall timeout for the entire function
61
- const overallTimeoutMs = 5000; // 5 seconds max for everything
156
+ const overallTimeoutMs = process.env.NODE_ENV === "test" ? 30000 : 15000; // 30s for tests, 15s for production
62
157
  let overallTimeoutId;
63
158
  const overallTimeoutPromise = new Promise((_, reject) => {
64
159
  overallTimeoutId = setTimeout(() => {
@@ -281,6 +376,8 @@ export async function getAvailableFunctionTools() {
281
376
  },
282
377
  });
283
378
  tools.push(aiTool);
379
+ // Store tool with proper name association
380
+ toolsObject[functionName] = aiTool;
284
381
  // Store mapping for execution - CRITICAL: Use sanitized functionName as key
285
382
  toolMap.set(functionName, {
286
383
  serverId: typeof toolInfo.serverId === "string"
@@ -302,7 +399,7 @@ export async function getAvailableFunctionTools() {
302
399
  if (overallTimeoutId) {
303
400
  clearTimeout(overallTimeoutId);
304
401
  }
305
- return { tools, toolMap };
402
+ return { tools, toolsObject, toolMap };
306
403
  }
307
404
  catch (error) {
308
405
  if (overallTimeoutId) {
@@ -315,7 +412,7 @@ export async function getAvailableFunctionTools() {
315
412
  }
316
413
  catch (error) {
317
414
  mcpLogger.error(`[${functionTag}] Error getting function tools:`, error);
318
- return { tools: [], toolMap: new Map() };
415
+ return { tools: [], toolsObject: {}, toolMap: new Map() };
319
416
  }
320
417
  }
321
418
  /**
@@ -345,38 +442,12 @@ export async function executeFunctionCall(functionName, parameters, context) {
345
442
  });
346
443
  }
347
444
  // Parse server and tool name from function name
348
- // First try underscore format (sanitized), then fallback to dot format
349
- let parts = functionName.split("_");
350
- let serverId = "unknown";
351
- let toolName = functionName;
352
- if (parts.length >= 2) {
353
- // Handle underscore format (sanitized names)
354
- const firstPart = parts[0];
355
- if (firstPart && typeof firstPart === "string" && firstPart.length > 0) {
356
- serverId = firstPart;
357
- }
358
- else {
359
- serverId = "unknown";
360
- }
361
- toolName = parts.slice(1).join("_"); // Rejoin in case tool name had underscores
362
- }
363
- else {
364
- // Fallback to dot format for backward compatibility
365
- parts = functionName.split(".");
366
- if (parts.length === 2) {
367
- const parsedServerId = parts[0];
368
- const parsedToolName = parts[1];
369
- if (parsedServerId && parsedToolName) {
370
- serverId = parsedServerId;
371
- toolName = parsedToolName;
372
- }
373
- }
374
- else {
375
- // Can't parse - try executing as-is through unified registry
376
- mcpLogger.debug(`[${functionTag}] Cannot parse function name format: ${functionName}, trying unified registry`);
377
- const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
378
- return result;
379
- }
445
+ const { serverId, toolName } = parseFunctionName(functionName);
446
+ if (serverId === "unknown") {
447
+ // Can't parse - try executing as-is through unified registry
448
+ mcpLogger.debug(`[${functionTag}] Cannot parse function name format: ${functionName}, trying unified registry`);
449
+ const result = await unifiedRegistry.executeTool(functionName, actualParameters, finalContext);
450
+ return result;
380
451
  }
381
452
  // Handle built-in NeuroLink servers directly
382
453
  if (serverId === "neurolink-utility" ||
@@ -541,3 +612,31 @@ export async function isFunctionCallingAvailable() {
541
612
  return false;
542
613
  }
543
614
  }
615
+ /**
616
+ * Utility function to create a named tool object for debugging
617
+ */
618
+ export function createNamedTool(name, toolDef) {
619
+ return {
620
+ name,
621
+ description: toolDef.description,
622
+ parameters: toolDef.parameters,
623
+ execute: toolDef.execute,
624
+ };
625
+ }
626
+ /**
627
+ * Get tools with proper name properties for debugging
628
+ */
629
+ export async function getToolsWithNames() {
630
+ try {
631
+ const { toolsObject } = await getAvailableFunctionTools();
632
+ const namedTools = {};
633
+ for (const [name, tool] of Object.entries(toolsObject)) {
634
+ namedTools[name] = createNamedTool(name, tool);
635
+ }
636
+ return namedTools;
637
+ }
638
+ catch (error) {
639
+ mcpLogger.warn("[getToolsWithNames] Failed to get tools with names:", error);
640
+ return {};
641
+ }
642
+ }
@@ -13,7 +13,7 @@ export declare const initializeMCPTools: (sessionId: string, client: NeuroLinkMC
13
13
  * Get all available tools across all servers
14
14
  * Useful for documentation and discovery
15
15
  */
16
- export declare function getAllAvailableTools(): Promise<Array<{
16
+ export declare function getAllAvailableTools(inMemoryServers?: Map<string, any>): Promise<Array<{
17
17
  serverId: string;
18
18
  serverTitle: string;
19
19
  toolName: string;
@@ -140,8 +140,52 @@ export const initializeMCPTools = async (sessionId, client, context) => {
140
140
  * Get all available tools across all servers
141
141
  * Useful for documentation and discovery
142
142
  */
143
- export async function getAllAvailableTools() {
143
+ export async function getAllAvailableTools(inMemoryServers) {
144
144
  const tools = [];
145
+ // Add in-memory server tools first
146
+ if (inMemoryServers) {
147
+ for (const [serverId, serverConfig] of inMemoryServers) {
148
+ const server = serverConfig.server;
149
+ if (server && server.tools) {
150
+ // Handle both Map and object formats
151
+ const toolEntries = server.tools instanceof Map
152
+ ? Array.from(server.tools.entries())
153
+ : Object.entries(server.tools || {});
154
+ for (const [toolName, toolInfo] of toolEntries) {
155
+ const prefix = `${serverId}_`;
156
+ const finalToolName = toolName.length > 64 - prefix.length
157
+ ? toolName.substring(0, 64 - prefix.length)
158
+ : toolName;
159
+ const namespacedName = sanitizeToolName(`${prefix}${finalToolName}`);
160
+ // Handle different tool info structures
161
+ let description = `Tool from ${serverId}`;
162
+ let isImplemented = true;
163
+ if (toolInfo) {
164
+ // Check if it's a tool info object with description
165
+ if (typeof toolInfo.description === "string") {
166
+ description = toolInfo.description;
167
+ }
168
+ else if (typeof toolInfo === "function") {
169
+ // It's a raw function, no description available
170
+ description = `${toolName} from ${serverId}`;
171
+ }
172
+ // Check implementation status
173
+ if (typeof toolInfo.isImplemented === "boolean") {
174
+ isImplemented = toolInfo.isImplemented;
175
+ }
176
+ }
177
+ tools.push({
178
+ serverId,
179
+ serverTitle: server.title || serverId,
180
+ toolName,
181
+ namespacedName,
182
+ description,
183
+ isImplemented,
184
+ });
185
+ }
186
+ }
187
+ }
188
+ }
145
189
  const servers = await mcpConfig.getServers();
146
190
  servers.forEach((server) => {
147
191
  Object.entries(server.tools).forEach(([toolName, tool]) => {
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { toolRegistry, defaultToolRegistry, } from "./tool-registry.js";
7
7
  import { mcpLogger } from "./logging.js";
8
+ import { ServiceRegistry } from "../core/service-registry.js";
8
9
  let isInitialized = false;
9
10
  /**
10
11
  * Initialize NeuroLink MCP system by registering built-in servers
@@ -15,19 +16,28 @@ export async function initializeNeuroLinkMCP(targetRegistry) {
15
16
  }
16
17
  mcpLogger.debug("Initializing built-in MCP servers...");
17
18
  try {
19
+ // First, register AIProviderFactory in ServiceRegistry to break circular dependencies
20
+ ServiceRegistry.register("AIProviderFactory", async () => {
21
+ const { AIProviderFactory } = await import("../core/factory.js");
22
+ return AIProviderFactory;
23
+ });
24
+ mcpLogger.debug("Registered AIProviderFactory in ServiceRegistry");
18
25
  // Import utility server dynamically to avoid circular dependencies
19
- // Note: AI core server temporarily disabled due to circular dependency issues
20
26
  const { utilityServer } = await import("./servers/utilities/utility-server.js");
21
27
  // Register built-in NeuroLink servers with specified registry (or default)
22
28
  const registry = targetRegistry || toolRegistry;
23
29
  await registry.registerServer(utilityServer.id, utilityServer);
24
30
  mcpLogger.debug(`Registered neurolink-utility server with built-in tools in ${targetRegistry ? "target" : "default"} registry`);
25
- // TODO: Re-enable AI core server once circular dependencies are resolved
26
- // const { aiCoreServer } = await import('./servers/ai-providers/ai-core-server.js');
27
- // await registry.registerServer(aiCoreServer.id, aiCoreServer);
28
- // mcpLogger.debug('Registered neurolink-ai-core server with AI tools');
31
+ // Now safe to import and register AI core server
32
+ const { aiCoreServer } = await import("./servers/ai-providers/ai-core-server.js");
33
+ await registry.registerServer(aiCoreServer.id, aiCoreServer);
34
+ mcpLogger.debug("Registered neurolink-ai-core server with AI tools");
35
+ // Register direct tools server
36
+ const { directToolsServer } = await import("./servers/agent/direct-tools-server.js");
37
+ await registry.registerServer(directToolsServer.id, directToolsServer);
38
+ mcpLogger.debug("Registered neurolink-direct server with direct tools");
29
39
  const stats = await registry.getStats();
30
- mcpLogger.info(`Initialization complete: ${stats.totalServers} server, ${stats.totalTools} tools available`);
40
+ mcpLogger.info(`Initialization complete: ${stats.totalServers} servers, ${stats.totalTools} tools available`);
31
41
  isInitialized = true;
32
42
  }
33
43
  catch (error) {
@@ -70,6 +70,7 @@ export declare class NeuroLinkMCPClient extends EventEmitter {
70
70
  * Get registered tools
71
71
  */
72
72
  getTools(): Record<string, {
73
+ name: string;
73
74
  description?: string;
74
75
  inputSchema?: unknown;
75
76
  }>;
@@ -244,11 +244,26 @@ Response (JSON array only):`;
244
244
  exists: async () => false,
245
245
  },
246
246
  path: {
247
- join: (...paths) => require("path").join(...paths),
248
- resolve: (...paths) => require("path").resolve(...paths),
249
- relative: (from, to) => require("path").relative(from, to),
250
- dirname: (path) => require("path").dirname(path),
251
- basename: (path, ext) => require("path").basename(path, ext),
247
+ join: (...paths) => {
248
+ const pathModule = require("path");
249
+ return pathModule.join(...paths);
250
+ },
251
+ resolve: (...paths) => {
252
+ const pathModule = require("path");
253
+ return pathModule.resolve(...paths);
254
+ },
255
+ relative: (from, to) => {
256
+ const pathModule = require("path");
257
+ return pathModule.relative(from, to);
258
+ },
259
+ dirname: (pathArg) => {
260
+ const pathModule = require("path");
261
+ return pathModule.dirname(pathArg);
262
+ },
263
+ basename: (pathArg, ext) => {
264
+ const pathModule = require("path");
265
+ return pathModule.basename(pathArg, ext);
266
+ },
252
267
  },
253
268
  grantedPermissions: [],
254
269
  log: console.log,
@@ -409,6 +424,7 @@ Please provide a natural response based on the tool results.`;
409
424
  const tools = {};
410
425
  for (const [name, tool] of this.tools) {
411
426
  tools[name] = {
427
+ name: name, // Include the tool name as a property
412
428
  description: tool.description,
413
429
  inputSchema: tool.inputSchema,
414
430
  };
@@ -0,0 +1,8 @@
1
+ /**
2
+ * NeuroLink Direct Tools Server
3
+ * Wraps the agent direct tools as an MCP server for proper registration
4
+ */
5
+ /**
6
+ * Direct Tools Server - Agent direct tools for immediate use
7
+ */
8
+ export declare const directToolsServer: import("../../factory.js").NeuroLinkMCPServer;
@@ -0,0 +1,109 @@
1
+ /**
2
+ * NeuroLink Direct Tools Server
3
+ * Wraps the agent direct tools as an MCP server for proper registration
4
+ */
5
+ import { createMCPServer } from "../../factory.js";
6
+ import { directAgentTools } from "../../../agent/direct-tools.js";
7
+ import { logger } from "../../../utils/logger.js";
8
+ /**
9
+ * Direct Tools Server - Agent direct tools for immediate use
10
+ */
11
+ export const directToolsServer = createMCPServer({
12
+ id: "neurolink-direct",
13
+ title: "NeuroLink Direct Tools Server",
14
+ description: "Provides direct agent tools for immediate execution",
15
+ category: "integrations",
16
+ version: "1.0.0",
17
+ });
18
+ /**
19
+ * Wrap each direct tool and register it with the server
20
+ */
21
+ Object.entries(directAgentTools).forEach(([toolName, toolDef]) => {
22
+ // The toolDef is a Vercel AI SDK Tool object
23
+ // Extract properties from the Tool object
24
+ const toolSpec = toolDef._spec || toolDef;
25
+ const description = toolSpec.description || `Direct tool: ${toolName}`;
26
+ const inputSchema = toolSpec.parameters;
27
+ const execute = toolSpec.execute;
28
+ directToolsServer.registerTool({
29
+ name: toolName,
30
+ description: description,
31
+ category: getToolCategory(toolName),
32
+ inputSchema: inputSchema,
33
+ isImplemented: true,
34
+ execute: async (params, context) => {
35
+ const startTime = Date.now();
36
+ try {
37
+ logger.debug(`[Direct Tools] Executing ${toolName} with params:`, params);
38
+ // Execute the direct tool
39
+ const result = await execute(params);
40
+ // Convert direct tool result to ToolResult format
41
+ if (result.success) {
42
+ return {
43
+ success: true,
44
+ data: result,
45
+ usage: {
46
+ executionTime: Date.now() - startTime,
47
+ },
48
+ metadata: {
49
+ toolName,
50
+ serverId: "neurolink-direct",
51
+ sessionId: context.sessionId,
52
+ },
53
+ };
54
+ }
55
+ else {
56
+ return {
57
+ success: false,
58
+ data: null,
59
+ error: result.error || "Unknown error",
60
+ usage: {
61
+ executionTime: Date.now() - startTime,
62
+ },
63
+ metadata: {
64
+ toolName,
65
+ serverId: "neurolink-direct",
66
+ sessionId: context.sessionId,
67
+ },
68
+ };
69
+ }
70
+ }
71
+ catch (error) {
72
+ logger.error(`[Direct Tools] Error executing ${toolName}:`, error);
73
+ return {
74
+ success: false,
75
+ data: null,
76
+ error: error instanceof Error ? error.message : String(error),
77
+ usage: {
78
+ executionTime: Date.now() - startTime,
79
+ },
80
+ metadata: {
81
+ toolName,
82
+ serverId: "neurolink-direct",
83
+ sessionId: context.sessionId,
84
+ },
85
+ };
86
+ }
87
+ },
88
+ });
89
+ });
90
+ /**
91
+ * Get tool category based on tool name
92
+ */
93
+ function getToolCategory(toolName) {
94
+ switch (toolName) {
95
+ case "getCurrentTime":
96
+ return "time";
97
+ case "calculateMath":
98
+ return "math";
99
+ case "readFile":
100
+ case "writeFile":
101
+ case "listDirectory":
102
+ case "searchFiles":
103
+ return "filesystem";
104
+ default:
105
+ return "utility";
106
+ }
107
+ }
108
+ // Log successful registration
109
+ logger.info(`[Direct Tools] Registered ${Object.keys(directAgentTools).length} direct tools`);
@@ -5,7 +5,7 @@
5
5
  */
6
6
  import { z } from "zod";
7
7
  import { createMCPServer } from "../../factory.js";
8
- import { AIProviderFactory } from "../../../core/factory.js";
8
+ import { ServiceRegistry } from "../../../core/service-registry.js";
9
9
  import { getBestProvider, getAvailableProviders, } from "../../../utils/providerUtils.js";
10
10
  import { logger } from "../../../utils/logger.js";
11
11
  import { analyzeAIUsageTool, benchmarkProviderPerformanceTool, optimizePromptParametersTool, } from "./ai-analysis-tools.js";
@@ -86,6 +86,8 @@ aiCoreServer.registerTool({
86
86
  logger.debug(`[AI-Core] Starting text generation: "${params.prompt.substring(0, 50)}..."`);
87
87
  // Use existing AIProviderFactory with best provider selection
88
88
  const selectedProvider = params.provider || (await getBestProvider(params.provider));
89
+ // Get AIProviderFactory from ServiceRegistry to avoid circular dependency
90
+ const AIProviderFactory = await ServiceRegistry.get("AIProviderFactory");
89
91
  const provider = await AIProviderFactory.createBestProvider(selectedProvider);
90
92
  // Generate text using existing NeuroLink patterns
91
93
  const result = await provider.generate({
@@ -88,14 +88,14 @@ export declare const workflowToolSchemas: {
88
88
  }, "strip", z.ZodTypeAny, {
89
89
  aiOutput: string;
90
90
  expectedBehavior: string;
91
- outputType: "text" | "code" | "conversation" | "structured-data";
91
+ outputType: "text" | "code" | "structured-data" | "conversation";
92
92
  includeFixSuggestions: boolean;
93
93
  context?: string | undefined;
94
94
  }, {
95
95
  aiOutput: string;
96
96
  expectedBehavior: string;
97
97
  context?: string | undefined;
98
- outputType?: "text" | "code" | "conversation" | "structured-data" | undefined;
98
+ outputType?: "text" | "code" | "structured-data" | "conversation" | undefined;
99
99
  includeFixSuggestions?: boolean | undefined;
100
100
  }>;
101
101
  };
@@ -26,6 +26,10 @@ export declare class UnifiedMCPRegistry extends MCPToolRegistry {
26
26
  * Load servers from .mcp-config.json
27
27
  */
28
28
  private loadManualConfig;
29
+ /**
30
+ * Connect to manually configured servers
31
+ */
32
+ private connectManualServers;
29
33
  /**
30
34
  * Enable or disable auto-discovery
31
35
  */
@@ -4,7 +4,7 @@
4
4
  import { MCPRegistry } from "./registry.js";
5
5
  import { discoverMCPServers, autoRegisterMCPServers, } from "./auto-discovery.js";
6
6
  import { unifiedRegistryLogger } from "./logging.js";
7
- import { MCPToolRegistry, } from "./tool-registry.js";
7
+ import { MCPToolRegistry, defaultToolRegistry, } from "./tool-registry.js";
8
8
  import { TransportManager, TransportConfigSchema, } from "./transport-manager.js";
9
9
  import { Client } from "@modelcontextprotocol/sdk/client/index.js";
10
10
  import { ErrorManager } from "./error-manager.js";
@@ -31,8 +31,18 @@ export class UnifiedMCPRegistry extends MCPToolRegistry {
31
31
  */
32
32
  async initialize(options = {}) {
33
33
  unifiedRegistryLogger.info("Initializing unified MCP registry...");
34
- // Load manual configuration first
35
- await this.loadManualConfig();
34
+ // Import ProviderRegistry to check options
35
+ const { ProviderRegistry } = await import("../factories/provider-registry.js");
36
+ const registryOptions = ProviderRegistry.getOptions();
37
+ // Only load manual config if explicitly enabled (CLI mode)
38
+ if (registryOptions.enableManualMCP) {
39
+ unifiedRegistryLogger.info("Manual MCP config enabled - loading .mcp-config.json");
40
+ await this.loadManualConfig();
41
+ await this.connectManualServers();
42
+ }
43
+ else {
44
+ unifiedRegistryLogger.debug("Manual MCP config disabled - skipping .mcp-config.json");
45
+ }
36
46
  if (this.autoDiscoveryEnabled) {
37
47
  const result = await autoRegisterMCPServers(options);
38
48
  unifiedRegistryLogger.info(`Auto-discovery complete: ${result.registered} registered, ${result.failed} failed`);
@@ -96,6 +106,29 @@ export class UnifiedMCPRegistry extends MCPToolRegistry {
96
106
  unifiedRegistryLogger.error("Failed to load manual config:", error instanceof Error ? error.message : String(error));
97
107
  }
98
108
  }
109
+ /**
110
+ * Connect to manually configured servers
111
+ */
112
+ async connectManualServers() {
113
+ for (const [serverId, serverConfig] of this.manualServers.entries()) {
114
+ try {
115
+ unifiedRegistryLogger.info(`Connecting to manual server: ${serverId}`);
116
+ // Use addExternalServer method which properly establishes connections
117
+ await this.addExternalServer(serverId, {
118
+ type: "stdio",
119
+ command: serverConfig.command || "npx",
120
+ args: serverConfig.args || [],
121
+ env: serverConfig.env,
122
+ });
123
+ unifiedRegistryLogger.info(`Successfully connected manual server: ${serverId}`);
124
+ }
125
+ catch (error) {
126
+ unifiedRegistryLogger.error(`Failed to connect manual server ${serverId}:`, error instanceof Error ? error.message : String(error));
127
+ // Remove from available servers if connection fails
128
+ this.availableServers.delete(serverId);
129
+ }
130
+ }
131
+ }
99
132
  /**
100
133
  * Enable or disable auto-discovery
101
134
  */
@@ -142,8 +175,8 @@ export class UnifiedMCPRegistry extends MCPToolRegistry {
142
175
  async listAllTools() {
143
176
  const allTools = [];
144
177
  try {
145
- // FIXED: Get built-in tools from base registry
146
- const builtInTools = await super.listTools();
178
+ // FIXED: Get built-in tools from defaultToolRegistry where they are actually registered
179
+ const builtInTools = await defaultToolRegistry.listTools();
147
180
  allTools.push(...builtInTools.map((tool) => ({
148
181
  ...tool,
149
182
  id: tool.name,
@@ -151,7 +184,7 @@ export class UnifiedMCPRegistry extends MCPToolRegistry {
151
184
  source: "built-in",
152
185
  isExternal: false,
153
186
  })));
154
- unifiedRegistryLogger.debug(`Found ${builtInTools.length} built-in tools`);
187
+ unifiedRegistryLogger.debug(`Found ${builtInTools.length} built-in tools from defaultToolRegistry`);
155
188
  }
156
189
  catch (error) {
157
190
  unifiedRegistryLogger.warn("Failed to get built-in tools:", error);
@@ -195,10 +228,10 @@ export class UnifiedMCPRegistry extends MCPToolRegistry {
195
228
  */
196
229
  async executeTool(toolName, args, context) {
197
230
  unifiedRegistryLogger.info(`Executing tool: ${toolName}`);
198
- // STEP 1: Try built-in tools first
231
+ // STEP 1: Try built-in tools first from defaultToolRegistry
199
232
  try {
200
- const result = await super.executeTool(toolName, args, context);
201
- unifiedRegistryLogger.info(`Tool ${toolName} executed successfully via built-in registry`);
233
+ const result = await defaultToolRegistry.executeTool(toolName, args, context);
234
+ unifiedRegistryLogger.info(`Tool ${toolName} executed successfully via defaultToolRegistry`);
202
235
  return result;
203
236
  }
204
237
  catch (builtInError) {