@juspay/neurolink 6.1.0 โ†’ 6.2.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 (303) hide show
  1. package/CHANGELOG.md +16 -6
  2. package/dist/agent/direct-tools.js +6 -5
  3. package/dist/cli/commands/config.d.ts +13 -13
  4. package/dist/cli/index.js +3 -9
  5. package/dist/config/configManager.js +11 -10
  6. package/dist/core/analytics.d.ts +11 -1
  7. package/dist/core/analytics.js +2 -2
  8. package/dist/core/base-provider.js +4 -18
  9. package/dist/core/dynamic-models.d.ts +8 -8
  10. package/dist/core/factory.js +3 -11
  11. package/dist/index.d.ts +2 -4
  12. package/dist/index.js +2 -11
  13. package/dist/lib/agent/direct-tools.js +6 -5
  14. package/dist/lib/config/configManager.js +11 -10
  15. package/dist/lib/core/analytics.d.ts +11 -1
  16. package/dist/lib/core/analytics.js +2 -2
  17. package/dist/lib/core/base-provider.js +4 -18
  18. package/dist/lib/core/dynamic-models.d.ts +8 -8
  19. package/dist/lib/core/factory.js +3 -11
  20. package/dist/lib/index.d.ts +2 -4
  21. package/dist/lib/index.js +2 -11
  22. package/dist/lib/mcp/factory.d.ts +1 -1
  23. package/dist/lib/mcp/index.d.ts +9 -21
  24. package/dist/lib/mcp/index.js +16 -57
  25. package/dist/lib/mcp/registry.js +1 -1
  26. package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +2 -1
  27. package/dist/lib/mcp/tool-registry.js +1 -1
  28. package/dist/lib/neurolink.d.ts +1 -9
  29. package/dist/lib/neurolink.js +22 -71
  30. package/dist/lib/providers/amazon-bedrock.js +5 -16
  31. package/dist/lib/providers/anthropic-baseprovider.js +3 -21
  32. package/dist/lib/providers/anthropic.js +4 -7
  33. package/dist/lib/providers/azure-openai.js +6 -3
  34. package/dist/lib/providers/google-vertex.js +5 -9
  35. package/dist/lib/providers/huggingFace.js +5 -10
  36. package/dist/lib/providers/mistral.js +5 -8
  37. package/dist/lib/providers/openAI.js +4 -7
  38. package/dist/lib/telemetry/index.js +2 -1
  39. package/dist/lib/utils/logger.d.ts +62 -2
  40. package/dist/lib/utils/logger.js +174 -9
  41. package/dist/lib/utils/providerConfig.d.ts +117 -0
  42. package/dist/lib/utils/providerConfig.js +353 -0
  43. package/dist/lib/utils/providerUtils.d.ts +2 -1
  44. package/dist/lib/utils/providerUtils.js +53 -36
  45. package/dist/lib/utils/timeout.d.ts +72 -1
  46. package/dist/lib/utils/timeout.js +203 -2
  47. package/dist/mcp/factory.d.ts +1 -1
  48. package/dist/mcp/index.d.ts +9 -21
  49. package/dist/mcp/index.js +16 -57
  50. package/dist/mcp/registry.js +1 -1
  51. package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +2 -1
  52. package/dist/mcp/tool-registry.js +1 -1
  53. package/dist/neurolink.d.ts +1 -9
  54. package/dist/neurolink.js +22 -71
  55. package/dist/providers/amazon-bedrock.js +5 -16
  56. package/dist/providers/anthropic-baseprovider.js +3 -21
  57. package/dist/providers/anthropic.js +4 -7
  58. package/dist/providers/azure-openai.js +6 -3
  59. package/dist/providers/google-vertex.js +5 -9
  60. package/dist/providers/huggingFace.js +5 -10
  61. package/dist/providers/mistral.js +5 -8
  62. package/dist/providers/openAI.js +4 -7
  63. package/dist/telemetry/index.js +2 -1
  64. package/dist/utils/logger.d.ts +62 -2
  65. package/dist/utils/logger.js +174 -9
  66. package/dist/utils/providerConfig.d.ts +117 -0
  67. package/dist/utils/providerConfig.js +353 -0
  68. package/dist/utils/providerUtils.d.ts +2 -1
  69. package/dist/utils/providerUtils.js +53 -36
  70. package/dist/utils/timeout.d.ts +72 -1
  71. package/dist/utils/timeout.js +203 -2
  72. package/package.json +1 -1
  73. package/dist/chat/client-utils.d.ts +0 -95
  74. package/dist/chat/client-utils.js +0 -315
  75. package/dist/chat/index.d.ts +0 -24
  76. package/dist/chat/index.js +0 -33
  77. package/dist/chat/session-storage.d.ts +0 -77
  78. package/dist/chat/session-storage.js +0 -233
  79. package/dist/chat/session.d.ts +0 -96
  80. package/dist/chat/session.js +0 -257
  81. package/dist/chat/sse-handler.d.ts +0 -49
  82. package/dist/chat/sse-handler.js +0 -259
  83. package/dist/chat/types.d.ts +0 -74
  84. package/dist/chat/types.js +0 -5
  85. package/dist/chat/websocket-chat-handler.d.ts +0 -37
  86. package/dist/chat/websocket-chat-handler.js +0 -262
  87. package/dist/cli/commands/mcp.d.ts +0 -20
  88. package/dist/cli/commands/mcp.js +0 -1272
  89. package/dist/core/defaults.d.ts +0 -19
  90. package/dist/core/defaults.js +0 -29
  91. package/dist/core/evaluation-config.d.ts +0 -29
  92. package/dist/core/evaluation-config.js +0 -144
  93. package/dist/factories/compatibility-factory.d.ts +0 -35
  94. package/dist/factories/compatibility-factory.js +0 -71
  95. package/dist/factories/provider-generate-factory.d.ts +0 -20
  96. package/dist/factories/provider-generate-factory.js +0 -93
  97. package/dist/lib/chat/client-utils.d.ts +0 -95
  98. package/dist/lib/chat/client-utils.js +0 -315
  99. package/dist/lib/chat/index.d.ts +0 -24
  100. package/dist/lib/chat/index.js +0 -33
  101. package/dist/lib/chat/session-storage.d.ts +0 -77
  102. package/dist/lib/chat/session-storage.js +0 -233
  103. package/dist/lib/chat/session.d.ts +0 -96
  104. package/dist/lib/chat/session.js +0 -257
  105. package/dist/lib/chat/sse-handler.d.ts +0 -49
  106. package/dist/lib/chat/sse-handler.js +0 -259
  107. package/dist/lib/chat/types.d.ts +0 -74
  108. package/dist/lib/chat/types.js +0 -5
  109. package/dist/lib/chat/websocket-chat-handler.d.ts +0 -37
  110. package/dist/lib/chat/websocket-chat-handler.js +0 -262
  111. package/dist/lib/core/defaults.d.ts +0 -19
  112. package/dist/lib/core/defaults.js +0 -29
  113. package/dist/lib/core/evaluation-config.d.ts +0 -29
  114. package/dist/lib/core/evaluation-config.js +0 -144
  115. package/dist/lib/factories/compatibility-factory.d.ts +0 -35
  116. package/dist/lib/factories/compatibility-factory.js +0 -71
  117. package/dist/lib/factories/provider-generate-factory.d.ts +0 -20
  118. package/dist/lib/factories/provider-generate-factory.js +0 -93
  119. package/dist/lib/mcp/adapters/plugin-bridge.d.ts +0 -40
  120. package/dist/lib/mcp/adapters/plugin-bridge.js +0 -89
  121. package/dist/lib/mcp/auto-discovery.d.ts +0 -62
  122. package/dist/lib/mcp/auto-discovery.js +0 -149
  123. package/dist/lib/mcp/client.d.ts +0 -68
  124. package/dist/lib/mcp/client.js +0 -248
  125. package/dist/lib/mcp/config.d.ts +0 -31
  126. package/dist/lib/mcp/config.js +0 -99
  127. package/dist/lib/mcp/context-manager.d.ts +0 -171
  128. package/dist/lib/mcp/context-manager.js +0 -362
  129. package/dist/lib/mcp/contracts/mcp-contract.d.ts +0 -169
  130. package/dist/lib/mcp/contracts/mcp-contract.js +0 -58
  131. package/dist/lib/mcp/core/plugin-manager.d.ts +0 -46
  132. package/dist/lib/mcp/core/plugin-manager.js +0 -110
  133. package/dist/lib/mcp/demo/plugin-demo.d.ts +0 -20
  134. package/dist/lib/mcp/demo/plugin-demo.js +0 -118
  135. package/dist/lib/mcp/dynamic-chain-executor.d.ts +0 -225
  136. package/dist/lib/mcp/dynamic-chain-executor.js +0 -489
  137. package/dist/lib/mcp/dynamic-orchestrator.d.ts +0 -115
  138. package/dist/lib/mcp/dynamic-orchestrator.js +0 -351
  139. package/dist/lib/mcp/ecosystem.d.ts +0 -75
  140. package/dist/lib/mcp/ecosystem.js +0 -161
  141. package/dist/lib/mcp/error-manager.d.ts +0 -254
  142. package/dist/lib/mcp/error-manager.js +0 -501
  143. package/dist/lib/mcp/error-recovery.d.ts +0 -159
  144. package/dist/lib/mcp/error-recovery.js +0 -405
  145. package/dist/lib/mcp/external-client.d.ts +0 -88
  146. package/dist/lib/mcp/external-client.js +0 -331
  147. package/dist/lib/mcp/external-manager.d.ts +0 -112
  148. package/dist/lib/mcp/external-manager.js +0 -308
  149. package/dist/lib/mcp/function-calling.d.ts +0 -65
  150. package/dist/lib/mcp/function-calling.js +0 -642
  151. package/dist/lib/mcp/health-monitor.d.ts +0 -257
  152. package/dist/lib/mcp/health-monitor.js +0 -630
  153. package/dist/lib/mcp/initialize-tools.d.ts +0 -29
  154. package/dist/lib/mcp/initialize-tools.js +0 -261
  155. package/dist/lib/mcp/initialize.d.ts +0 -18
  156. package/dist/lib/mcp/initialize.js +0 -62
  157. package/dist/lib/mcp/logging.d.ts +0 -38
  158. package/dist/lib/mcp/logging.js +0 -100
  159. package/dist/lib/mcp/manager.d.ts +0 -68
  160. package/dist/lib/mcp/manager.js +0 -176
  161. package/dist/lib/mcp/neurolink-mcp-client.d.ts +0 -97
  162. package/dist/lib/mcp/neurolink-mcp-client.js +0 -462
  163. package/dist/lib/mcp/orchestrator.d.ts +0 -302
  164. package/dist/lib/mcp/orchestrator.js +0 -703
  165. package/dist/lib/mcp/plugin-manager.d.ts +0 -98
  166. package/dist/lib/mcp/plugin-manager.js +0 -296
  167. package/dist/lib/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
  168. package/dist/lib/mcp/plugins/core/filesystem-mcp.js +0 -142
  169. package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +0 -37
  170. package/dist/lib/mcp/plugins/filesystem-mcp.js +0 -54
  171. package/dist/lib/mcp/security-manager.d.ts +0 -87
  172. package/dist/lib/mcp/security-manager.js +0 -344
  173. package/dist/lib/mcp/semaphore-manager.d.ts +0 -137
  174. package/dist/lib/mcp/semaphore-manager.js +0 -329
  175. package/dist/lib/mcp/session-manager.d.ts +0 -187
  176. package/dist/lib/mcp/session-manager.js +0 -400
  177. package/dist/lib/mcp/session-persistence.d.ts +0 -93
  178. package/dist/lib/mcp/session-persistence.js +0 -301
  179. package/dist/lib/mcp/tool-integration.d.ts +0 -58
  180. package/dist/lib/mcp/tool-integration.js +0 -203
  181. package/dist/lib/mcp/transport-manager.d.ts +0 -154
  182. package/dist/lib/mcp/transport-manager.js +0 -334
  183. package/dist/lib/mcp/unified-mcp.d.ts +0 -133
  184. package/dist/lib/mcp/unified-mcp.js +0 -251
  185. package/dist/lib/mcp/unified-registry.d.ts +0 -165
  186. package/dist/lib/mcp/unified-registry.js +0 -538
  187. package/dist/lib/providers/analytics-helper.d.ts +0 -38
  188. package/dist/lib/providers/analytics-helper.js +0 -216
  189. package/dist/lib/providers/function-calling-provider.d.ts +0 -142
  190. package/dist/lib/providers/function-calling-provider.js +0 -630
  191. package/dist/lib/providers/mcp-provider.d.ts +0 -75
  192. package/dist/lib/providers/mcp-provider.js +0 -283
  193. package/dist/lib/providers/timeout-wrapper.d.ts +0 -40
  194. package/dist/lib/providers/timeout-wrapper.js +0 -100
  195. package/dist/lib/sdk/tool-extension.d.ts +0 -181
  196. package/dist/lib/sdk/tool-extension.js +0 -284
  197. package/dist/lib/services/streaming/streaming-manager.d.ts +0 -29
  198. package/dist/lib/services/streaming/streaming-manager.js +0 -245
  199. package/dist/lib/services/types.d.ts +0 -156
  200. package/dist/lib/services/types.js +0 -2
  201. package/dist/lib/services/websocket/websocket-server.d.ts +0 -34
  202. package/dist/lib/services/websocket/websocket-server.js +0 -305
  203. package/dist/lib/utils/provider-validation.d.ts +0 -36
  204. package/dist/lib/utils/provider-validation.js +0 -625
  205. package/dist/lib/utils/providerUtils-fixed.d.ts +0 -8
  206. package/dist/lib/utils/providerUtils-fixed.js +0 -94
  207. package/dist/lib/utils/streaming-utils.d.ts +0 -79
  208. package/dist/lib/utils/streaming-utils.js +0 -198
  209. package/dist/lib/utils/timeout-manager.d.ts +0 -75
  210. package/dist/lib/utils/timeout-manager.js +0 -244
  211. package/dist/mcp/adapters/plugin-bridge.d.ts +0 -40
  212. package/dist/mcp/adapters/plugin-bridge.js +0 -89
  213. package/dist/mcp/auto-discovery.d.ts +0 -62
  214. package/dist/mcp/auto-discovery.js +0 -149
  215. package/dist/mcp/client.d.ts +0 -68
  216. package/dist/mcp/client.js +0 -248
  217. package/dist/mcp/config.d.ts +0 -31
  218. package/dist/mcp/config.js +0 -99
  219. package/dist/mcp/context-manager.d.ts +0 -171
  220. package/dist/mcp/context-manager.js +0 -362
  221. package/dist/mcp/contracts/mcp-contract.d.ts +0 -169
  222. package/dist/mcp/contracts/mcp-contract.js +0 -58
  223. package/dist/mcp/core/plugin-manager.d.ts +0 -46
  224. package/dist/mcp/core/plugin-manager.js +0 -110
  225. package/dist/mcp/demo/plugin-demo.d.ts +0 -20
  226. package/dist/mcp/demo/plugin-demo.js +0 -118
  227. package/dist/mcp/dynamic-chain-executor.d.ts +0 -225
  228. package/dist/mcp/dynamic-chain-executor.js +0 -489
  229. package/dist/mcp/dynamic-orchestrator.d.ts +0 -115
  230. package/dist/mcp/dynamic-orchestrator.js +0 -351
  231. package/dist/mcp/ecosystem.d.ts +0 -75
  232. package/dist/mcp/ecosystem.js +0 -162
  233. package/dist/mcp/error-manager.d.ts +0 -254
  234. package/dist/mcp/error-manager.js +0 -501
  235. package/dist/mcp/error-recovery.d.ts +0 -159
  236. package/dist/mcp/error-recovery.js +0 -405
  237. package/dist/mcp/external-client.d.ts +0 -88
  238. package/dist/mcp/external-client.js +0 -331
  239. package/dist/mcp/external-manager.d.ts +0 -112
  240. package/dist/mcp/external-manager.js +0 -308
  241. package/dist/mcp/function-calling.d.ts +0 -65
  242. package/dist/mcp/function-calling.js +0 -642
  243. package/dist/mcp/health-monitor.d.ts +0 -257
  244. package/dist/mcp/health-monitor.js +0 -630
  245. package/dist/mcp/initialize-tools.d.ts +0 -29
  246. package/dist/mcp/initialize-tools.js +0 -262
  247. package/dist/mcp/initialize.d.ts +0 -18
  248. package/dist/mcp/initialize.js +0 -62
  249. package/dist/mcp/logging.d.ts +0 -38
  250. package/dist/mcp/logging.js +0 -100
  251. package/dist/mcp/manager.d.ts +0 -68
  252. package/dist/mcp/manager.js +0 -176
  253. package/dist/mcp/neurolink-mcp-client.d.ts +0 -97
  254. package/dist/mcp/neurolink-mcp-client.js +0 -462
  255. package/dist/mcp/orchestrator.d.ts +0 -302
  256. package/dist/mcp/orchestrator.js +0 -703
  257. package/dist/mcp/plugin-manager.d.ts +0 -98
  258. package/dist/mcp/plugin-manager.js +0 -297
  259. package/dist/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
  260. package/dist/mcp/plugins/core/filesystem-mcp.js +0 -142
  261. package/dist/mcp/plugins/core/neurolink-mcp.json +0 -17
  262. package/dist/mcp/plugins/filesystem-mcp.d.ts +0 -37
  263. package/dist/mcp/plugins/filesystem-mcp.js +0 -54
  264. package/dist/mcp/security-manager.d.ts +0 -87
  265. package/dist/mcp/security-manager.js +0 -344
  266. package/dist/mcp/semaphore-manager.d.ts +0 -137
  267. package/dist/mcp/semaphore-manager.js +0 -329
  268. package/dist/mcp/session-manager.d.ts +0 -187
  269. package/dist/mcp/session-manager.js +0 -400
  270. package/dist/mcp/session-persistence.d.ts +0 -93
  271. package/dist/mcp/session-persistence.js +0 -302
  272. package/dist/mcp/tool-integration.d.ts +0 -58
  273. package/dist/mcp/tool-integration.js +0 -203
  274. package/dist/mcp/transport-manager.d.ts +0 -154
  275. package/dist/mcp/transport-manager.js +0 -335
  276. package/dist/mcp/unified-mcp.d.ts +0 -133
  277. package/dist/mcp/unified-mcp.js +0 -251
  278. package/dist/mcp/unified-registry.d.ts +0 -165
  279. package/dist/mcp/unified-registry.js +0 -539
  280. package/dist/providers/analytics-helper.d.ts +0 -38
  281. package/dist/providers/analytics-helper.js +0 -216
  282. package/dist/providers/function-calling-provider.d.ts +0 -142
  283. package/dist/providers/function-calling-provider.js +0 -630
  284. package/dist/providers/mcp-provider.d.ts +0 -75
  285. package/dist/providers/mcp-provider.js +0 -283
  286. package/dist/providers/timeout-wrapper.d.ts +0 -40
  287. package/dist/providers/timeout-wrapper.js +0 -100
  288. package/dist/sdk/tool-extension.d.ts +0 -181
  289. package/dist/sdk/tool-extension.js +0 -284
  290. package/dist/services/streaming/streaming-manager.d.ts +0 -29
  291. package/dist/services/streaming/streaming-manager.js +0 -245
  292. package/dist/services/types.d.ts +0 -156
  293. package/dist/services/types.js +0 -2
  294. package/dist/services/websocket/websocket-server.d.ts +0 -34
  295. package/dist/services/websocket/websocket-server.js +0 -306
  296. package/dist/utils/provider-validation.d.ts +0 -36
  297. package/dist/utils/provider-validation.js +0 -625
  298. package/dist/utils/providerUtils-fixed.d.ts +0 -8
  299. package/dist/utils/providerUtils-fixed.js +0 -94
  300. package/dist/utils/streaming-utils.d.ts +0 -79
  301. package/dist/utils/streaming-utils.js +0 -198
  302. package/dist/utils/timeout-manager.d.ts +0 -75
  303. package/dist/utils/timeout-manager.js +0 -244
@@ -1,1272 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * MCP Server Management Commands
4
- * Real MCP server connectivity and management
5
- */
6
- import ora from "ora";
7
- import chalk from "chalk";
8
- import fs from "fs";
9
- import { spawn } from "child_process";
10
- import path from "path";
11
- import { discoverMCPServers } from "../../lib/mcp/auto-discovery.js";
12
- import { unifiedRegistry } from "../../lib/mcp/unified-registry.js";
13
- import { ContextManager } from "../../lib/mcp/context-manager.js";
14
- import { MCPOrchestrator } from "../../lib/mcp/orchestrator.js";
15
- import { initializeNeuroLinkMCP } from "../../lib/mcp/initialize.js";
16
- import { mcpLogger, setGlobalMCPLogLevel } from "../../lib/mcp/logging.js";
17
- // import type { LogLevel } from "../../lib/mcp/logging.js"; // Commented out as unused
18
- import { defaultTimeoutManager } from "../../lib/utils/timeout-manager.js";
19
- // Default MCP config file location
20
- const MCP_CONFIG_FILE = path.join(process.cwd(), ".mcp-config.json");
21
- // Load MCP configuration
22
- function loadMCPConfig() {
23
- if (!fs.existsSync(MCP_CONFIG_FILE)) {
24
- return { mcpServers: {} };
25
- }
26
- try {
27
- const content = fs.readFileSync(MCP_CONFIG_FILE, "utf-8");
28
- return JSON.parse(content);
29
- }
30
- catch (error) {
31
- throw new Error(`Invalid MCP config file: ${error.message}`);
32
- }
33
- }
34
- // Save MCP configuration
35
- function saveMCPConfig(config) {
36
- fs.writeFileSync(MCP_CONFIG_FILE, JSON.stringify(config, null, 2));
37
- }
38
- // Check if MCP server process is running
39
- async function checkMCPServerStatus(serverConfig) {
40
- try {
41
- if (serverConfig.transport === "stdio") {
42
- // For stdio servers, use timeout manager for proper cleanup
43
- const result = await defaultTimeoutManager.wrapMCPOperation(async () => {
44
- const child = spawn(serverConfig.command, serverConfig.args || [], {
45
- stdio: ["pipe", "pipe", "pipe"],
46
- env: { ...process.env, ...serverConfig.env },
47
- cwd: serverConfig.cwd,
48
- });
49
- return new Promise((resolve, reject) => {
50
- child.on("spawn", () => {
51
- child.kill();
52
- resolve(true);
53
- });
54
- child.on("error", (error) => {
55
- reject(error);
56
- });
57
- child.on("exit", (code) => {
58
- if (code === null) {
59
- // Process was terminated (expected for quick check)
60
- resolve(true);
61
- }
62
- else {
63
- resolve(false);
64
- }
65
- });
66
- });
67
- }, "server-status-check", 10000);
68
- return result.success && result.data === true;
69
- }
70
- else if (serverConfig.transport === "sse" && serverConfig.url) {
71
- // For SSE servers, check if URL is accessible with timeout
72
- const result = await defaultTimeoutManager.wrapMCPOperation(async () => {
73
- if (!serverConfig.url) {
74
- throw new Error("SSE URL not configured");
75
- }
76
- const response = await fetch(serverConfig.url, { method: "HEAD" });
77
- return response.ok;
78
- }, "sse-status-check", 10000);
79
- return result.success && result.data === true;
80
- }
81
- return false;
82
- }
83
- catch {
84
- return false;
85
- }
86
- }
87
- // Connect to MCP server and get capabilities
88
- async function getMCPServerCapabilities(serverConfig) {
89
- if (serverConfig.transport === "stdio") {
90
- // Use timeout manager for proper cleanup and longer timeout
91
- const result = await defaultTimeoutManager.wrapMCPOperation(async () => {
92
- const child = spawn(serverConfig.command, serverConfig.args || [], {
93
- stdio: ["pipe", "pipe", "pipe"],
94
- env: { ...process.env, ...serverConfig.env },
95
- cwd: serverConfig.cwd,
96
- });
97
- return new Promise((resolve, reject) => {
98
- let responseData = "";
99
- child.stdout?.on("data", (data) => {
100
- responseData += data.toString();
101
- // Look for JSON-RPC response
102
- try {
103
- const lines = responseData.split("\n");
104
- for (const line of lines) {
105
- if (line.trim() && line.includes('"result"')) {
106
- const response = JSON.parse(line.trim());
107
- if (response.result && response.result.capabilities) {
108
- child.kill();
109
- resolve(response.result);
110
- return;
111
- }
112
- }
113
- }
114
- }
115
- catch {
116
- // Continue parsing
117
- }
118
- });
119
- child.on("spawn", () => {
120
- // Send initialize request
121
- const initRequest = {
122
- jsonrpc: "2.0",
123
- id: 1,
124
- method: "initialize",
125
- params: {
126
- protocolVersion: "2024-11-05",
127
- capabilities: {},
128
- clientInfo: {
129
- name: "neurolink-cli",
130
- version: "1.0.0",
131
- },
132
- },
133
- };
134
- child.stdin?.write(JSON.stringify(initRequest) + "\n");
135
- });
136
- child.on("error", (error) => {
137
- reject(error);
138
- });
139
- });
140
- }, "server-capabilities-check", 15000);
141
- if (result.success) {
142
- return result.data;
143
- }
144
- else {
145
- throw result.error || new Error("Failed to get MCP server capabilities");
146
- }
147
- }
148
- throw new Error("SSE transport not yet implemented for capabilities");
149
- }
150
- // List available tools from MCP server
151
- async function listMCPServerTools(serverConfig) {
152
- if (serverConfig.transport === "stdio") {
153
- // Use timeout manager for proper cleanup and longer timeout
154
- const result = await defaultTimeoutManager.wrapMCPOperation(async () => {
155
- const child = spawn(serverConfig.command, serverConfig.args || [], {
156
- stdio: ["pipe", "pipe", "pipe"],
157
- env: { ...process.env, ...serverConfig.env },
158
- cwd: serverConfig.cwd,
159
- });
160
- return new Promise((resolve, reject) => {
161
- let responseData = "";
162
- // let initialized = false; // Commented out as unused
163
- child.stdout?.on("data", (data) => {
164
- responseData += data.toString();
165
- try {
166
- const lines = responseData.split("\n");
167
- for (const line of lines) {
168
- if (line.trim() && line.includes('"result"')) {
169
- const response = JSON.parse(line.trim());
170
- if (response.id === 1 && response.result.capabilities) {
171
- // Initialize successful, now list tools
172
- // initialized = true; // Commented out as unused
173
- const listToolsRequest = {
174
- jsonrpc: "2.0",
175
- id: 2,
176
- method: "tools/list",
177
- params: {},
178
- };
179
- child.stdin?.write(JSON.stringify(listToolsRequest) + "\n");
180
- }
181
- else if (response.id === 2 && response.result.tools) {
182
- child.kill();
183
- resolve(response.result.tools);
184
- return;
185
- }
186
- }
187
- }
188
- }
189
- catch {
190
- // Continue parsing
191
- }
192
- });
193
- child.on("spawn", () => {
194
- // Send initialize request first
195
- const initRequest = {
196
- jsonrpc: "2.0",
197
- id: 1,
198
- method: "initialize",
199
- params: {
200
- protocolVersion: "2024-11-05",
201
- capabilities: {},
202
- clientInfo: {
203
- name: "neurolink-cli",
204
- version: "1.0.0",
205
- },
206
- },
207
- };
208
- child.stdin?.write(JSON.stringify(initRequest) + "\n");
209
- });
210
- child.on("error", (error) => {
211
- reject(error);
212
- });
213
- });
214
- }, "server-tools-list", 15000);
215
- if (result.success) {
216
- return result.data || [];
217
- }
218
- else {
219
- throw result.error || new Error("Failed to list MCP server tools");
220
- }
221
- }
222
- throw new Error("SSE transport not yet implemented for tool listing");
223
- }
224
- // Execute tool on MCP server
225
- export async function executeMCPTool(serverConfig, toolName, toolParams) {
226
- if (serverConfig.transport === "stdio") {
227
- // Use timeout manager for proper cleanup and configurable timeout
228
- const result = await defaultTimeoutManager.wrapMCPOperation(async () => {
229
- const child = spawn(serverConfig.command, serverConfig.args || [], {
230
- stdio: ["pipe", "pipe", "pipe"],
231
- env: { ...process.env, ...serverConfig.env },
232
- cwd: serverConfig.cwd,
233
- });
234
- return new Promise((resolve, reject) => {
235
- let responseData = "";
236
- // let initialized = false; // Commented out as unused
237
- child.stdout?.on("data", (data) => {
238
- responseData += data.toString();
239
- try {
240
- const lines = responseData.split("\n");
241
- for (const line of lines) {
242
- if (line.trim() && line.includes('"result"')) {
243
- const response = JSON.parse(line.trim());
244
- if (response.id === 1 && response.result.capabilities) {
245
- // Initialize successful, now execute tool
246
- // initialized = true; // Commented out as unused
247
- const toolCallRequest = {
248
- jsonrpc: "2.0",
249
- id: 2,
250
- method: "tools/call",
251
- params: {
252
- name: toolName,
253
- arguments: toolParams,
254
- },
255
- };
256
- child.stdin?.write(JSON.stringify(toolCallRequest) + "\n");
257
- }
258
- else if (response.id === 2) {
259
- child.kill();
260
- if (response.result) {
261
- resolve(response.result);
262
- }
263
- else if (response.error) {
264
- reject(new Error(`MCP Error: ${response.error.message || "Unknown error"}`));
265
- }
266
- else {
267
- reject(new Error("Unknown MCP response format"));
268
- }
269
- return;
270
- }
271
- }
272
- else if (line.trim() && line.includes('"error"')) {
273
- const response = JSON.parse(line.trim());
274
- if (response.error) {
275
- child.kill();
276
- reject(new Error(`MCP Error: ${response.error.message || "Unknown error"}`));
277
- return;
278
- }
279
- }
280
- }
281
- }
282
- catch {
283
- // Continue parsing
284
- }
285
- });
286
- child.stderr?.on("data", (data) => {
287
- console.error(chalk.red(`MCP Server Error: ${data.toString()}`));
288
- });
289
- child.on("spawn", () => {
290
- // Send initialize request first
291
- const initRequest = {
292
- jsonrpc: "2.0",
293
- id: 1,
294
- method: "initialize",
295
- params: {
296
- protocolVersion: "2024-11-05",
297
- capabilities: {},
298
- clientInfo: {
299
- name: "neurolink-cli",
300
- version: "1.0.0",
301
- },
302
- },
303
- };
304
- child.stdin?.write(JSON.stringify(initRequest) + "\n");
305
- });
306
- child.on("error", (error) => {
307
- reject(error);
308
- });
309
- });
310
- }, "tool-execution", 30000);
311
- if (result.success) {
312
- return result.data || null;
313
- }
314
- else {
315
- throw result.error || new Error("Failed to execute MCP tool");
316
- }
317
- }
318
- throw new Error("SSE transport not yet implemented for tool execution");
319
- }
320
- /**
321
- * Display discovery results in table format
322
- */
323
- function _displayTable(discoveryResult) {
324
- console.log(chalk.green(`\n๐Ÿ“‹ Found ${discoveryResult.discovered.length} MCP servers:`));
325
- console.log(chalk.gray("โ”€".repeat(80)));
326
- discoveryResult.discovered.forEach((server, index) => {
327
- const source = server.source;
328
- const sourceIcon = getSourceIcon(source?.tool);
329
- const typeColor = source?.type === "global"
330
- ? chalk.blue
331
- : source?.type === "workspace"
332
- ? chalk.green
333
- : chalk.gray;
334
- console.log(`${chalk.white(`${index + 1}.`)} ${sourceIcon} ${chalk.cyan(server.id)}`);
335
- console.log(` ${chalk.gray("Title:")} ${server.title}`);
336
- console.log(` ${chalk.gray("Source:")} ${source?.tool} ${typeColor(`(${source?.type})`)}`);
337
- console.log(` ${chalk.gray("Command:")} ${server.command} ${server.args?.join(" ") || ""}`);
338
- console.log(` ${chalk.gray("Config:")} ${server.configPath}`);
339
- if (server.env && Object.keys(server.env).length > 0) {
340
- console.log(` ${chalk.gray("Environment:")} ${Object.keys(server.env).length} variable(s)`);
341
- }
342
- console.log();
343
- });
344
- // Display statistics
345
- console.log(chalk.blue("๐Ÿ“Š Discovery Statistics:"));
346
- console.log(` ${chalk.gray("Execution time:")} ${discoveryResult.stats.executionTime}ms`);
347
- console.log(` ${chalk.gray("Config files found:")} ${discoveryResult.stats.configFilesFound}`);
348
- console.log(` ${chalk.gray("Servers discovered:")} ${discoveryResult.stats.serversDiscovered}`);
349
- console.log(` ${chalk.gray("Duplicates removed:")} ${discoveryResult.stats.duplicatesRemoved}`);
350
- // Display sources
351
- if (discoveryResult.sources.length > 0) {
352
- console.log(chalk.blue("\n๐ŸŽฏ Search Sources:"));
353
- const sourcesByTool = discoveryResult.sources.reduce((acc, source) => {
354
- const tool = String(source.tool || "unknown");
355
- acc[tool] = (Number(acc[tool]) || 0) + 1;
356
- return acc;
357
- }, {});
358
- Object.entries(sourcesByTool).forEach(([tool, count]) => {
359
- const icon = getSourceIcon(tool);
360
- console.log(` ${icon} ${tool}: ${count} location(s)`);
361
- });
362
- }
363
- }
364
- /**
365
- * Display discovery results in summary format
366
- */
367
- function _displaySummary(discoveryResult) {
368
- console.log(chalk.green(`\n๐Ÿ“Š Discovery Summary`));
369
- console.log(chalk.gray("==================="));
370
- console.log(`${chalk.cyan("Total servers found:")} ${discoveryResult.discovered.length}`);
371
- console.log(`${chalk.cyan("Execution time:")} ${discoveryResult.stats.executionTime}ms`);
372
- console.log(`${chalk.cyan("Config files found:")} ${discoveryResult.stats.configFilesFound}`);
373
- console.log(`${chalk.cyan("Duplicates removed:")} ${discoveryResult.stats.duplicatesRemoved}`);
374
- // Group by source tool
375
- const serversByTool = discoveryResult.discovered.reduce((acc, server) => {
376
- const tool = String(server.source?.tool || "unknown");
377
- acc[tool] = (Number(acc[tool]) || 0) + 1;
378
- return acc;
379
- }, {});
380
- if (Object.keys(serversByTool).length > 0) {
381
- console.log(chalk.blue("\n๐Ÿ”ง Servers by Tool:"));
382
- Object.entries(serversByTool).forEach(([tool, count]) => {
383
- const icon = getSourceIcon(tool);
384
- console.log(` ${icon} ${tool}: ${count} server(s)`);
385
- });
386
- }
387
- // Group by type
388
- const serversByType = discoveryResult.discovered.reduce((acc, server) => {
389
- const type = String(server.source?.type || "unknown");
390
- acc[type] = (Number(acc[type]) || 0) + 1;
391
- return acc;
392
- }, {});
393
- if (Object.keys(serversByType).length > 0) {
394
- console.log(chalk.blue("\n๐Ÿ“ Servers by Type:"));
395
- Object.entries(serversByType).forEach(([type, count]) => {
396
- const typeColor = type === "global"
397
- ? chalk.blue
398
- : type === "workspace"
399
- ? chalk.green
400
- : chalk.gray;
401
- console.log(` ${typeColor(`${type}:`)} ${count} server(s)`);
402
- });
403
- }
404
- }
405
- /**
406
- * Get icon for source tool
407
- */
408
- function getSourceIcon(tool) {
409
- const icons = {
410
- "Claude Desktop": "๐Ÿค–",
411
- "VS Code": "๐Ÿ“",
412
- Cursor: "๐Ÿ–ฑ๏ธ",
413
- Windsurf: "๐Ÿ„",
414
- "Roo Code": "๐Ÿฆ˜",
415
- Generic: "โš™๏ธ",
416
- "Cline AI Coder": "๐Ÿ”ง",
417
- "Continue Dev": "๐Ÿ”„",
418
- Aider: "๐Ÿ› ๏ธ",
419
- };
420
- return icons[tool] || "๐Ÿ”ง";
421
- }
422
- /**
423
- * Get icon for source type
424
- */
425
- function getSourceTypeIcon(sourceType) {
426
- const icons = {
427
- manual: "๐Ÿ“",
428
- auto: "๐Ÿ”",
429
- default: "โš™๏ธ",
430
- };
431
- return icons[sourceType] || "โ“";
432
- }
433
- /**
434
- * Get icon for server status
435
- */
436
- function _getStatusIcon(status) {
437
- const icons = {
438
- available: "โœ…",
439
- unavailable: "โŒ",
440
- unknown: "โ“",
441
- };
442
- return icons[status] || "โ“";
443
- }
444
- // Export the tool execution function for use in other parts of the CLI
445
- export async function mcpExecuteTool(serverName, toolName, toolParams) {
446
- // First try unified registry (includes built-in NeuroLink servers)
447
- try {
448
- await unifiedRegistry.initialize();
449
- const orchestrator = new MCPOrchestrator(unifiedRegistry);
450
- const result = await orchestrator.executeTool(toolName, toolParams, {
451
- sessionId: `cli-${Date.now()}`,
452
- userId: "cli-user",
453
- aiProvider: "unified-mcp",
454
- }, {
455
- preferredSource: "default", // Try built-in servers first
456
- fallbackEnabled: true,
457
- validateBeforeExecution: true,
458
- timeoutMs: 30000,
459
- });
460
- if (result.success) {
461
- return result.data;
462
- }
463
- }
464
- catch (error) {
465
- mcpLogger.debug("[mcpExecuteTool] Unified registry failed, trying manual config:", {
466
- error: error instanceof Error ? error.message : String(error),
467
- serverName,
468
- toolName: toolName,
469
- });
470
- }
471
- // Fallback to manual configuration (legacy behavior)
472
- const config = loadMCPConfig();
473
- const serverConfig = config.mcpServers[serverName];
474
- if (!serverConfig) {
475
- throw new Error(`MCP server '${serverName}' not found`);
476
- }
477
- const result = await executeMCPTool(serverConfig, toolName, toolParams);
478
- mcpLogger.debug("[mcpExecuteTool] Tool executed via manual config:", {
479
- serverName,
480
- toolName,
481
- hasResult: !!result,
482
- resultType: typeof result,
483
- });
484
- // Extract the text content from MCP result format
485
- if (result &&
486
- result.content &&
487
- Array.isArray(result.content)) {
488
- const textContent = result.content.find((item) => item.type === "text");
489
- if (textContent) {
490
- return JSON.parse(textContent.text);
491
- }
492
- }
493
- return result;
494
- }
495
- // MCP Commands for yargs
496
- export function addMCPCommands(yargs) {
497
- return yargs.command("mcp <subcommand>", "Manage MCP (Model Context Protocol) servers", (yargsBuilder) => {
498
- yargsBuilder
499
- .usage("Usage: $0 mcp <subcommand> [options]")
500
- // List MCP servers
501
- .command("list", "List configured MCP servers", (y) => y
502
- .usage("Usage: $0 mcp list [options]")
503
- .option("status", {
504
- type: "boolean",
505
- description: "Check server status",
506
- })
507
- .example("$0 mcp list", "List all MCP servers")
508
- .example("$0 mcp list --status", "List servers with status check"), async (argv) => {
509
- const config = loadMCPConfig();
510
- const servers = Object.entries(config.mcpServers);
511
- if (servers.length === 0) {
512
- console.log(chalk.yellow("๐Ÿ“ญ No MCP servers configured"));
513
- console.log(chalk.blue("๐Ÿ’ก Add a server with: neurolink mcp add <name> <command>"));
514
- return;
515
- }
516
- console.log(chalk.blue(`๐Ÿ“‹ Configured MCP servers (${servers.length}):\n`));
517
- for (const [name, serverConfig] of servers) {
518
- console.log(chalk.bold(`๐Ÿ”ง ${name}`));
519
- console.log(` Command: ${serverConfig.command} ${(serverConfig.args || []).join(" ")}`);
520
- console.log(` Transport: ${serverConfig.transport}`);
521
- if (argv.status) {
522
- const spinner = ora(`Checking ${name}...`).start();
523
- try {
524
- const isRunning = await checkMCPServerStatus(serverConfig);
525
- if (isRunning) {
526
- spinner.succeed(`${name}: ${chalk.green("โœ… Available")}`);
527
- }
528
- else {
529
- spinner.fail(`${name}: ${chalk.red("โŒ Not available")}`);
530
- }
531
- }
532
- catch (error) {
533
- spinner.fail(`${name}: ${chalk.red("โŒ Error")} - ${error.message}`);
534
- }
535
- }
536
- console.log(); // Empty line
537
- }
538
- })
539
- // Add MCP server
540
- .command("add <name> <command>", "Add a new MCP server", (y) => y
541
- .usage("Usage: $0 mcp add <name> <command> [options]")
542
- .positional("name", {
543
- type: "string",
544
- description: "Server name",
545
- demandOption: true,
546
- })
547
- .positional("command", {
548
- type: "string",
549
- description: "Command to run server",
550
- demandOption: true,
551
- })
552
- .option("args", {
553
- type: "array",
554
- description: "Command arguments",
555
- })
556
- .option("transport", {
557
- choices: ["stdio", "sse"],
558
- default: "stdio",
559
- description: "Transport type",
560
- })
561
- .option("url", {
562
- type: "string",
563
- description: "URL for SSE transport",
564
- })
565
- .option("env", {
566
- type: "string",
567
- description: "Environment variables (JSON)",
568
- })
569
- .option("cwd", {
570
- type: "string",
571
- description: "Working directory",
572
- })
573
- .example('$0 mcp add filesystem "npx @modelcontextprotocol/server-filesystem"', "Add filesystem server")
574
- .example('$0 mcp add github "npx @modelcontextprotocol/server-github"', "Add GitHub server"), async (argv) => {
575
- const config = loadMCPConfig();
576
- const serverConfig = {
577
- name: argv.name,
578
- command: argv.command,
579
- args: argv.args || [],
580
- transport: argv.transport,
581
- url: argv.url,
582
- cwd: argv.cwd,
583
- };
584
- if (argv.env) {
585
- try {
586
- serverConfig.env = JSON.parse(argv.env);
587
- }
588
- catch (error) {
589
- console.error(chalk.red("โŒ Invalid JSON for environment variables"));
590
- process.exit(1);
591
- }
592
- }
593
- config.mcpServers[argv.name] = serverConfig;
594
- saveMCPConfig(config);
595
- console.log(chalk.green(`โœ… Added MCP server: ${argv.name}`));
596
- console.log(chalk.blue(`๐Ÿ’ก Test it with: neurolink mcp test ${argv.name}`));
597
- })
598
- // Remove MCP server
599
- .command("remove <name>", "Remove an MCP server", (y) => y
600
- .usage("Usage: $0 mcp remove <name>")
601
- .positional("name", {
602
- type: "string",
603
- description: "Server name to remove",
604
- demandOption: true,
605
- })
606
- .example("$0 mcp remove filesystem", "Remove filesystem server"), async (argv) => {
607
- const config = loadMCPConfig();
608
- if (!config.mcpServers[argv.name]) {
609
- console.error(chalk.red(`โŒ MCP server '${argv.name}' not found`));
610
- process.exit(1);
611
- }
612
- delete config.mcpServers[argv.name];
613
- saveMCPConfig(config);
614
- console.log(chalk.green(`โœ… Removed MCP server: ${argv.name}`));
615
- })
616
- // Test MCP server
617
- .command("test <name>", "Test connection to an MCP server", (y) => y
618
- .usage("Usage: $0 mcp test <name>")
619
- .positional("name", {
620
- type: "string",
621
- description: "Server name to test",
622
- demandOption: true,
623
- })
624
- .example("$0 mcp test filesystem", "Test filesystem server"), async (argv) => {
625
- const config = loadMCPConfig();
626
- const serverConfig = config.mcpServers[argv.name];
627
- if (!serverConfig) {
628
- console.error(chalk.red(`โŒ MCP server '${argv.name}' not found`));
629
- process.exit(1);
630
- }
631
- console.log(chalk.blue(`๐Ÿ” Testing MCP server: ${argv.name}\n`));
632
- const spinner = ora("Connecting...").start();
633
- try {
634
- // Test basic connectivity
635
- const isRunning = await checkMCPServerStatus(serverConfig);
636
- if (!isRunning) {
637
- spinner.fail(chalk.red("โŒ Server not available"));
638
- return;
639
- }
640
- spinner.text = "Getting capabilities...";
641
- const capabilities = await getMCPServerCapabilities(serverConfig);
642
- spinner.text = "Listing tools...";
643
- const tools = await listMCPServerTools(serverConfig);
644
- spinner.succeed(chalk.green("โœ… Connection successful!"));
645
- console.log(chalk.blue("\n๐Ÿ“‹ Server Capabilities:"));
646
- console.log(` Protocol Version: ${capabilities.protocolVersion || "Unknown"}`);
647
- if (capabilities.tools) {
648
- console.log(` Tools: โœ… Supported`);
649
- }
650
- if (capabilities.resources) {
651
- console.log(` Resources: โœ… Supported`);
652
- }
653
- console.log(chalk.blue("\n๐Ÿ› ๏ธ Available Tools:"));
654
- if (tools.length === 0) {
655
- console.log(" No tools available");
656
- }
657
- else {
658
- tools.forEach((tool) => {
659
- const toolObj = tool;
660
- console.log(` โ€ข ${String(toolObj.name)}: ${String(toolObj.description) || "No description"}`);
661
- });
662
- }
663
- }
664
- catch (error) {
665
- spinner.fail(chalk.red("โŒ Connection failed"));
666
- console.error(chalk.red(`Error: ${error.message}`));
667
- }
668
- })
669
- // Install popular MCP servers
670
- .command("install <server>", "Install popular MCP servers", (y) => y
671
- .usage("Usage: $0 mcp install <server>")
672
- .positional("server", {
673
- type: "string",
674
- choices: [
675
- "filesystem",
676
- "github",
677
- "postgres",
678
- "brave-search",
679
- "puppeteer",
680
- ],
681
- description: "Server to install",
682
- demandOption: true,
683
- })
684
- .example("$0 mcp install filesystem", "Install filesystem server")
685
- .example("$0 mcp install github", "Install GitHub server"), async (argv) => {
686
- const serverName = argv.server;
687
- const config = loadMCPConfig();
688
- // Pre-configured popular MCP servers
689
- const serverConfigs = {
690
- filesystem: {
691
- name: "filesystem",
692
- command: "npx",
693
- args: ["-y", "@modelcontextprotocol/server-filesystem", "/"],
694
- transport: "stdio",
695
- },
696
- github: {
697
- name: "github",
698
- command: "npx",
699
- args: ["-y", "@modelcontextprotocol/server-github"],
700
- transport: "stdio",
701
- },
702
- postgres: {
703
- name: "postgres",
704
- command: "npx",
705
- args: ["-y", "@modelcontextprotocol/server-postgres"],
706
- transport: "stdio",
707
- },
708
- "brave-search": {
709
- name: "brave-search",
710
- command: "npx",
711
- args: ["-y", "@modelcontextprotocol/server-brave-search"],
712
- transport: "stdio",
713
- },
714
- puppeteer: {
715
- name: "puppeteer",
716
- command: "npx",
717
- args: ["-y", "@modelcontextprotocol/server-puppeteer"],
718
- transport: "stdio",
719
- },
720
- };
721
- const serverConfig = serverConfigs[serverName];
722
- if (!serverConfig) {
723
- console.error(chalk.red(`โŒ Unknown server: ${serverName}`));
724
- process.exit(1);
725
- }
726
- console.log(chalk.blue(`๐Ÿ“ฆ Installing MCP server: ${serverName}`));
727
- config.mcpServers[serverName] = serverConfig;
728
- saveMCPConfig(config);
729
- console.log(chalk.green(`โœ… Installed MCP server: ${serverName}`));
730
- console.log(chalk.blue(`๐Ÿ’ก Test it with: neurolink mcp test ${serverName}`));
731
- })
732
- // Execute tool from MCP server
733
- .command("exec <server> <tool>", "Execute a tool from an MCP server", (y) => y
734
- .usage("Usage: $0 mcp exec <server> <tool> [options]")
735
- .positional("server", {
736
- type: "string",
737
- description: "Server name",
738
- demandOption: true,
739
- })
740
- .positional("tool", {
741
- type: "string",
742
- description: "Tool name",
743
- demandOption: true,
744
- })
745
- .option("params", {
746
- type: "string",
747
- description: "Tool parameters (JSON)",
748
- })
749
- .example('$0 mcp exec filesystem read_file --params \'{"path": "README.md"}\'', "Read file using filesystem server"), async (argv) => {
750
- const config = loadMCPConfig();
751
- const serverConfig = config.mcpServers[argv.server];
752
- if (!serverConfig) {
753
- console.error(chalk.red(`โŒ MCP server '${argv.server}' not found`));
754
- process.exit(1);
755
- }
756
- let params = {};
757
- if (argv.params) {
758
- try {
759
- params = JSON.parse(argv.params);
760
- }
761
- catch (error) {
762
- console.error(chalk.red("โŒ Invalid JSON for parameters"));
763
- process.exit(1);
764
- }
765
- }
766
- console.log(chalk.blue(`๐Ÿ”ง Executing tool: ${argv.tool} on server: ${argv.server}`));
767
- const spinner = ora("Executing tool...").start();
768
- try {
769
- const result = await executeMCPTool(serverConfig, argv.tool, params);
770
- spinner.succeed(chalk.green("โœ… Tool executed successfully!"));
771
- console.log(chalk.blue("\n๐Ÿ“‹ Result:"));
772
- const resultObj = result;
773
- if (resultObj.content) {
774
- // Handle different content types
775
- if (Array.isArray(resultObj.content)) {
776
- resultObj.content.forEach((item) => {
777
- if (item.type === "text") {
778
- console.log(String(item.text));
779
- }
780
- else {
781
- console.log(JSON.stringify(item, null, 2));
782
- }
783
- });
784
- }
785
- else {
786
- console.log(JSON.stringify(resultObj.content, null, 2));
787
- }
788
- }
789
- else {
790
- console.log(JSON.stringify(result, null, 2));
791
- }
792
- }
793
- catch (error) {
794
- spinner.fail(chalk.red("โŒ Tool execution failed"));
795
- console.error(chalk.red(`Error: ${error.message}`));
796
- process.exit(1);
797
- }
798
- })
799
- // Enhanced unified list command
800
- .command("list-all", "List servers from all sources (manual + auto + default)", (y) => y
801
- .usage("Usage: $0 mcp list-all [options]")
802
- .option("source", {
803
- type: "string",
804
- choices: ["manual", "auto", "default", "all"],
805
- default: "all",
806
- description: "Filter by source type",
807
- })
808
- .option("format", {
809
- type: "string",
810
- choices: ["table", "json"],
811
- default: "table",
812
- description: "Output format",
813
- })
814
- .option("refresh", {
815
- type: "boolean",
816
- description: "Force refresh auto-discovery cache",
817
- })
818
- .example("$0 mcp list-all", "List all servers from all sources")
819
- .example("$0 mcp list-all --source auto", "List only auto-discovered servers")
820
- .example("$0 mcp list-all --refresh", "Refresh auto-discovery and list all"), async (argv) => {
821
- console.log(chalk.blue("๐ŸŒ NeuroLink Unified MCP Registry"));
822
- console.log(chalk.gray("==================================="));
823
- const spinner = ora("Initializing NeuroLink MCP...").start();
824
- try {
825
- // Initialize built-in NeuroLink servers first - register in unified registry
826
- await initializeNeuroLinkMCP(unifiedRegistry);
827
- // Initialize unified registry
828
- spinner.text = "Initializing unified registry...";
829
- await unifiedRegistry.initialize();
830
- // Force refresh if requested
831
- if (argv.refresh) {
832
- spinner.text = "Refreshing auto-discovery...";
833
- await unifiedRegistry.refresh();
834
- }
835
- spinner.succeed(chalk.green("Registry initialized!"));
836
- // Get servers based on source filter
837
- const servers = unifiedRegistry.list();
838
- const filteredServers = argv.source === "all"
839
- ? servers
840
- : servers.filter((s) => s.source === argv.source);
841
- if (filteredServers.length === 0) {
842
- console.log(chalk.yellow(`\n๐Ÿ“ญ No servers found from source: ${argv.source}`));
843
- return;
844
- }
845
- if (argv.format === "json") {
846
- console.log(JSON.stringify(filteredServers, null, 2));
847
- return;
848
- }
849
- // Table format
850
- console.log(chalk.green(`\n๐Ÿ“‹ Found ${filteredServers.length} servers:`));
851
- console.log(chalk.gray("โ”€".repeat(80)));
852
- filteredServers.forEach((server, index) => {
853
- const sourceIcon = getSourceTypeIcon(String(server.source || "unknown"));
854
- console.log(`${chalk.white(`${index + 1}.`)} ${sourceIcon} ${chalk.cyan(server.metadata.name)}`);
855
- console.log(` ${chalk.gray("Version:")} ${String(server.metadata.version || "unknown")}`);
856
- console.log(` ${chalk.gray("Source:")} ${server.source}`);
857
- console.log(` ${chalk.gray("Entry:")} ${server.entryPath}`);
858
- if (server.metadata.description) {
859
- console.log(` ${chalk.gray("Description:")} ${server.metadata.description}`);
860
- }
861
- // Add spacing between entries
862
- if (index < filteredServers.length - 1) {
863
- console.log();
864
- }
865
- });
866
- // Display statistics
867
- const stats = await unifiedRegistry.getDetailedStats();
868
- console.log(chalk.blue("๐Ÿ“Š Registry Statistics:"));
869
- console.log(` ${chalk.gray("Total plugins:")} ${stats.total}`);
870
- console.log(` ${chalk.gray("Manual servers:")} ${stats.manual?.servers || 0}`);
871
- console.log(` ${chalk.gray("Auto-discovered:")} ${stats.auto?.servers || 0}`);
872
- console.log(` ${chalk.gray("Total tools:")} ${stats.tools || 0}`);
873
- }
874
- catch (error) {
875
- spinner.fail(chalk.red("Registry initialization failed"));
876
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
877
- process.exit(1);
878
- }
879
- })
880
- // Enhanced tool execution with unified registry
881
- .command("run <tool>", "Execute a tool using unified registry (auto-fallback)", (y) => y
882
- .usage("Usage: $0 mcp run <tool> [options]")
883
- .positional("tool", {
884
- type: "string",
885
- description: "Tool name to execute",
886
- demandOption: true,
887
- })
888
- .option("params", {
889
- type: "string",
890
- description: "Tool parameters (JSON)",
891
- })
892
- .option("source", {
893
- type: "string",
894
- choices: ["manual", "auto", "default"],
895
- description: "Preferred source (with fallback)",
896
- })
897
- .option("no-fallback", {
898
- type: "boolean",
899
- description: "Disable fallback to other sources",
900
- })
901
- .example('$0 mcp run generate --params \'{"prompt": "Hello world"}\'', "Run tool with fallback")
902
- .example('$0 mcp run read_file --params \'{"path": "README.md"}\' --source manual', "Prefer manual config"), async (argv) => {
903
- console.log(chalk.blue(`๐Ÿš€ Executing tool: ${argv.tool}`));
904
- const spinner = ora("Initializing NeuroLink MCP...").start();
905
- try {
906
- // Initialize built-in NeuroLink servers first - register in unified registry
907
- await initializeNeuroLinkMCP(unifiedRegistry);
908
- // Initialize unified registry
909
- spinner.text = "Initializing unified registry...";
910
- await unifiedRegistry.initialize();
911
- let params = {};
912
- if (argv.params) {
913
- try {
914
- params = JSON.parse(argv.params);
915
- }
916
- catch (error) {
917
- spinner.fail(chalk.red("โŒ Invalid JSON for parameters"));
918
- process.exit(1);
919
- }
920
- }
921
- // Create execution context
922
- const contextManager = new ContextManager();
923
- const context = contextManager.createContext({
924
- sessionId: `cli-${Date.now()}`,
925
- userId: "cli-user",
926
- aiProvider: "unified-mcp",
927
- });
928
- const executionOptions = {
929
- preferredSource: argv.source,
930
- fallbackEnabled: !argv["no-fallback"],
931
- validateBeforeExecution: true,
932
- timeoutMs: 30000,
933
- };
934
- spinner.text = "Executing tool...";
935
- const orchestrator = new MCPOrchestrator(unifiedRegistry);
936
- const result = await orchestrator.executeTool(argv.tool, params, {
937
- sessionId: `cli-${Date.now()}`,
938
- userId: "cli-user",
939
- }, executionOptions);
940
- if (result.success) {
941
- spinner.succeed(chalk.green("โœ… Tool executed successfully!"));
942
- console.log(chalk.blue("\n๐Ÿ“‹ Result:"));
943
- if (result.data) {
944
- console.log(JSON.stringify(result.data, null, 2));
945
- }
946
- else {
947
- console.log("No data returned");
948
- }
949
- if (result.metadata) {
950
- console.log(chalk.gray("\n๐Ÿ”ง Execution Details:"));
951
- console.log(` Tool: ${result.metadata.toolName}`);
952
- console.log(` Server: ${result.metadata.serverId || "unknown"}`);
953
- console.log(` Execution time: ${result.metadata.executionTime}ms`);
954
- console.log(` Session: ${result.metadata.sessionId}`);
955
- }
956
- }
957
- else {
958
- spinner.fail(chalk.red("โŒ Tool execution failed"));
959
- console.error(chalk.red(`Error: ${result.error}`));
960
- process.exit(1);
961
- }
962
- }
963
- catch (error) {
964
- spinner.fail(chalk.red("โŒ Execution failed"));
965
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
966
- process.exit(1);
967
- }
968
- })
969
- // Configuration management commands
970
- .command("config <action>", "Manage unified registry configuration", (y) => y
971
- .usage("Usage: $0 mcp config <action> [options]")
972
- .command("show", "Show current configuration", {}, async () => {
973
- try {
974
- await unifiedRegistry.initialize();
975
- console.log(chalk.blue("๐Ÿ”ง Unified Registry Configuration"));
976
- console.log(chalk.gray("================================"));
977
- const stats = await unifiedRegistry.getDetailedStats();
978
- console.log(`Total servers: ${stats.total}`);
979
- console.log("\nBy Source:");
980
- Object.entries(stats.bySource).forEach(([source, count]) => {
981
- console.log(` ${source}: ${count}`);
982
- });
983
- console.log("\nBy Type:");
984
- Object.entries(stats.byType).forEach(([type, count]) => {
985
- console.log(` ${type}: ${count}`);
986
- });
987
- }
988
- catch (error) {
989
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
990
- process.exit(1);
991
- }
992
- })
993
- .command("enable-auto-discovery", "Enable auto-discovery", {}, async () => {
994
- try {
995
- await unifiedRegistry.initialize();
996
- unifiedRegistry.setAutoDiscovery(true);
997
- console.log(chalk.green("โœ… Auto-discovery enabled"));
998
- }
999
- catch (error) {
1000
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
1001
- process.exit(1);
1002
- }
1003
- })
1004
- .command("disable-auto-discovery", "Disable auto-discovery", {}, async () => {
1005
- try {
1006
- await unifiedRegistry.initialize();
1007
- unifiedRegistry.setAutoDiscovery(false);
1008
- console.log(chalk.green("โœ… Auto-discovery disabled"));
1009
- }
1010
- catch (error) {
1011
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
1012
- process.exit(1);
1013
- }
1014
- })
1015
- .command("set-sources <sources>", "Set preferred auto-discovery sources", (y) => y.positional("sources", {
1016
- type: "string",
1017
- description: "Comma-separated source list",
1018
- demandOption: true,
1019
- }), async (argv) => {
1020
- try {
1021
- await unifiedRegistry.initialize();
1022
- const sources = argv.sources
1023
- .split(",")
1024
- .map((s) => s.trim());
1025
- // Note: Source preference configuration not yet implemented
1026
- console.log(chalk.yellow(`โš ๏ธ Source preference configuration not yet implemented`));
1027
- console.log(chalk.blue(` Requested sources: ${sources.join(", ")}`));
1028
- }
1029
- catch (error) {
1030
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
1031
- process.exit(1);
1032
- }
1033
- })
1034
- .command("set-log-level <level>", "Set MCP logging verbosity", (y) => y.positional("level", {
1035
- type: "string",
1036
- choices: ["silent", "error", "warn", "info", "debug"],
1037
- description: "Log level to set",
1038
- demandOption: true,
1039
- }), async (argv) => {
1040
- try {
1041
- const level = argv.level;
1042
- // Note: LogLevel is a type, not an enum
1043
- // 'silent' is not a valid LogLevel, default to 'error' for minimal output
1044
- const logLevel = level === "silent"
1045
- ? "error" // Use 'error' for minimal output
1046
- : level === "error"
1047
- ? "error"
1048
- : level === "warn"
1049
- ? "warn"
1050
- : level === "info"
1051
- ? "info"
1052
- : "debug";
1053
- setGlobalMCPLogLevel(logLevel);
1054
- console.log(chalk.green(`โœ… MCP log level set to: ${level}`));
1055
- console.log(chalk.gray("This affects auto-discovery, registry operations, and tool execution logging"));
1056
- }
1057
- catch (error) {
1058
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
1059
- process.exit(1);
1060
- }
1061
- })
1062
- .example("$0 mcp config show", "Show current configuration")
1063
- .example("$0 mcp config enable-auto-discovery", "Enable auto-discovery")
1064
- .example('$0 mcp config set-sources "claude,vscode,cursor"', "Set preferred sources")
1065
- .example("$0 mcp config set-log-level debug", "Enable debug logging for troubleshooting"))
1066
- // Discover MCP servers from all AI tools
1067
- .command(["discover [options]", "d [options]"], "Discover MCP servers from all AI development tools", (y) => y
1068
- .usage("Usage: $0 mcp discover [options]")
1069
- .option("format", {
1070
- alias: "f",
1071
- type: "string",
1072
- choices: ["table", "json", "yaml", "summary"],
1073
- default: "table",
1074
- description: "Output format",
1075
- })
1076
- .option("include-inactive", {
1077
- type: "boolean",
1078
- default: true,
1079
- description: "Include servers that may not be currently active",
1080
- })
1081
- .option("preferred-tools", {
1082
- type: "string",
1083
- description: "Prioritize specific tools (comma-separated)",
1084
- })
1085
- .option("workspace-only", {
1086
- type: "boolean",
1087
- description: "Search only workspace/project configurations",
1088
- })
1089
- .option("global-only", {
1090
- type: "boolean",
1091
- description: "Search only global configurations",
1092
- })
1093
- .example("$0 mcp discover", "Discover all MCP servers")
1094
- .example("$0 mcp d --format json", "Export as JSON (using alias)")
1095
- .example('$0 mcp discover --preferred-tools "claude,cursor"', "Prioritize specific tools"), async (argv) => {
1096
- console.log(chalk.blue("๐Ÿ” NeuroLink MCP Server Discovery"));
1097
- console.log(chalk.gray("====================================="));
1098
- const options = {
1099
- includeDevPlugins: argv["include-inactive"],
1100
- // Additional search paths if needed
1101
- searchPaths: [
1102
- "./src/lib/mcp/plugins",
1103
- "./neurolink-mcp",
1104
- "./node_modules",
1105
- ],
1106
- };
1107
- const spinner = ora("Discovering MCP servers...").start();
1108
- try {
1109
- mcpLogger.debug("[MCP Discovery] Starting server discovery:", {
1110
- includeDevPlugins: options.includeDevPlugins,
1111
- searchPaths: options.searchPaths,
1112
- });
1113
- const discoveredPlugins = await discoverMCPServers(options);
1114
- mcpLogger.info("[MCP Discovery] Discovery completed:", {
1115
- pluginsFound: discoveredPlugins.length,
1116
- });
1117
- spinner.succeed(chalk.green("Discovery completed!"));
1118
- if (discoveredPlugins.length === 0) {
1119
- console.log(chalk.yellow("\n๐Ÿ“ญ No MCP servers found"));
1120
- console.log(chalk.gray("\n๐Ÿ’ก Tips for finding MCP servers:"));
1121
- console.log(chalk.gray(" โ€ข Make sure you have Claude Desktop, VS Code, or Cursor with MCP configurations"));
1122
- console.log(chalk.gray(" โ€ข Check that MCP configuration files exist in their expected locations"));
1123
- console.log(chalk.gray(" โ€ข Run with 'neurolink mcp discover' to search all locations"));
1124
- return;
1125
- }
1126
- // Display results based on format
1127
- if (argv.format === "json") {
1128
- console.log(JSON.stringify(discoveredPlugins, null, 2));
1129
- return;
1130
- }
1131
- if (argv.format === "yaml") {
1132
- // Simple YAML output
1133
- console.log("discovered:");
1134
- discoveredPlugins.forEach((plugin) => {
1135
- console.log(` - name: ${plugin.metadata.name}`);
1136
- console.log(` version: ${plugin.metadata.version}`);
1137
- console.log(` source: ${plugin.source}`);
1138
- console.log(` entryPath: ${plugin.entryPath}`);
1139
- if (plugin.metadata.description) {
1140
- console.log(` description: ${plugin.metadata.description}`);
1141
- }
1142
- });
1143
- return;
1144
- }
1145
- // Default format - show simple list
1146
- console.log(chalk.green(`\n๐Ÿ“‹ Found ${discoveredPlugins.length} MCP plugins:`));
1147
- console.log(chalk.gray("โ”€".repeat(80)));
1148
- discoveredPlugins.forEach((plugin, index) => {
1149
- console.log(`${chalk.white(`${index + 1}.`)} ${chalk.cyan(plugin.metadata.name)} v${plugin.metadata.version}`);
1150
- console.log(` ${chalk.gray("Source:")} ${plugin.source}`);
1151
- console.log(` ${chalk.gray("Entry:")} ${plugin.entryPath}`);
1152
- if (plugin.metadata.description) {
1153
- console.log(` ${chalk.gray("Description:")} ${plugin.metadata.description}`);
1154
- }
1155
- console.log();
1156
- });
1157
- }
1158
- catch (error) {
1159
- mcpLogger.error("[MCP Discovery] Discovery failed:", {
1160
- error: error instanceof Error ? error.message : String(error),
1161
- options,
1162
- });
1163
- spinner.fail(chalk.red("Discovery failed"));
1164
- console.error(chalk.red(`Error: ${error instanceof Error ? error.message : String(error)}`));
1165
- process.exit(1);
1166
- }
1167
- })
1168
- // Add debug command for tool registry diagnostics
1169
- .command("debug", "Debug MCP tool registry state and diagnose issues", (yargs) => {
1170
- return yargs.option("verbose", {
1171
- type: "boolean",
1172
- default: false,
1173
- description: "Show detailed debug information",
1174
- });
1175
- }, async (argv) => {
1176
- console.log(chalk.blue("๐Ÿ” MCP Tool Registry Debug"));
1177
- console.log(chalk.gray("=============================\n"));
1178
- try {
1179
- // Initialize built-in servers
1180
- console.log(chalk.cyan("๐Ÿ”ง Initializing Built-in Servers..."));
1181
- await initializeNeuroLinkMCP(unifiedRegistry);
1182
- // Initialize unified registry
1183
- console.log(chalk.cyan("๐ŸŒ Initializing Unified Registry..."));
1184
- await unifiedRegistry.initialize();
1185
- const registry = unifiedRegistry;
1186
- // Check built-in tools
1187
- console.log(chalk.green("\n๐Ÿ“ฆ Built-in Tools:"));
1188
- const builtInTools = await registry.listTools();
1189
- if (builtInTools.length === 0) {
1190
- console.log(chalk.red(" โŒ No built-in tools found"));
1191
- }
1192
- else {
1193
- builtInTools.forEach((tool) => {
1194
- console.log(` โœ… ${String(tool.name)} (${String(tool.serverId) || "unknown server"})`);
1195
- if (argv.verbose && tool.description) {
1196
- console.log(` โ””โ”€ ${String(tool.description)}`);
1197
- }
1198
- });
1199
- }
1200
- // Check external servers
1201
- console.log(chalk.green("\n๐ŸŒ External Servers:"));
1202
- const allTools = await registry.listAllTools();
1203
- const externalTools = allTools.filter((t) => Boolean(t.isExternal));
1204
- if (externalTools.length === 0) {
1205
- console.log(chalk.yellow(" โš ๏ธ No external servers connected"));
1206
- }
1207
- else {
1208
- const serverGroups = externalTools.reduce((acc, tool) => {
1209
- const server = String(tool.serverId) || "unknown";
1210
- if (!acc[server]) {
1211
- acc[server] = [];
1212
- }
1213
- acc[server].push(tool);
1214
- return acc;
1215
- }, {});
1216
- Object.entries(serverGroups).forEach(([server, tools]) => {
1217
- console.log(` ๐Ÿ”ง ${server} (${tools.length} tools)`);
1218
- if (argv.verbose) {
1219
- tools.forEach((tool) => {
1220
- console.log(` โ””โ”€ ${String(tool.name)}`);
1221
- });
1222
- }
1223
- });
1224
- }
1225
- // Test specific tool execution
1226
- console.log(chalk.green("\n๐Ÿงช Testing 'get-current-time' Tool:"));
1227
- try {
1228
- const result = await registry.executeTool("get-current-time");
1229
- console.log(chalk.green(" โœ… Success:"));
1230
- if (argv.verbose) {
1231
- console.log(JSON.stringify(result, null, 4));
1232
- }
1233
- else {
1234
- console.log(` โ””โ”€ Tool executed successfully`);
1235
- }
1236
- }
1237
- catch (error) {
1238
- const errorMessage = error instanceof Error ? error.message : String(error);
1239
- console.log(chalk.red(" โŒ Failed:"));
1240
- console.log(` โ””โ”€ ${errorMessage}`);
1241
- if (argv.verbose) {
1242
- console.log(chalk.gray("\n๐Ÿ“‹ Debug Details:"));
1243
- console.log(` Error Type: ${error instanceof Error ? error.constructor.name : typeof error}`);
1244
- console.log(` Stack: ${error instanceof Error && error.stack ? error.stack : "No stack trace available"}`);
1245
- }
1246
- }
1247
- // Summary
1248
- console.log(chalk.green(`\n๐Ÿ“Š Summary:`));
1249
- console.log(` Built-in tools: ${builtInTools.length}`);
1250
- console.log(` External tools: ${externalTools.length}`);
1251
- console.log(` Total tools: ${allTools.length}`);
1252
- }
1253
- catch (error) {
1254
- const errorMessage = error instanceof Error ? error.message : String(error);
1255
- console.error(chalk.red("โŒ Debug failed:"));
1256
- console.error(` ${errorMessage}`);
1257
- if (argv.verbose) {
1258
- console.error(error instanceof Error && error.stack
1259
- ? error.stack
1260
- : "No stack trace available");
1261
- }
1262
- process.exit(1);
1263
- }
1264
- })
1265
- .demandCommand(1, "Please specify an MCP subcommand")
1266
- .example("$0 mcp list", "List configured MCP servers")
1267
- .example("$0 mcp discover", "Discover MCP servers from all tools")
1268
- .example("$0 mcp debug", "Debug tool registry state")
1269
- .example("$0 mcp install filesystem", "Install filesystem MCP server")
1270
- .example("$0 mcp test filesystem", "Test filesystem server connection");
1271
- });
1272
- }