@juspay/neurolink 1.10.0 → 1.11.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 (144) hide show
  1. package/CHANGELOG.md +36 -33
  2. package/README.md +16 -0
  3. package/dist/agent/direct-tools.d.ts +9 -9
  4. package/dist/cli/commands/agent-generate.d.ts +1 -2
  5. package/dist/cli/commands/agent-generate.js +5 -8
  6. package/dist/cli/commands/config.d.ts +2 -2
  7. package/dist/cli/commands/config.js +1 -1
  8. package/dist/cli/commands/mcp.js +91 -100
  9. package/dist/cli/commands/ollama.d.ts +2 -7
  10. package/dist/cli/commands/ollama.js +5 -8
  11. package/dist/cli/index.js +185 -276
  12. package/dist/core/factory.js +9 -10
  13. package/dist/index.d.ts +23 -0
  14. package/dist/index.js +35 -0
  15. package/dist/lib/agent/direct-tools.d.ts +9 -9
  16. package/dist/lib/core/factory.js +9 -10
  17. package/dist/lib/index.d.ts +23 -0
  18. package/dist/lib/index.js +35 -0
  19. package/dist/lib/mcp/adapters/plugin-bridge.d.ts +39 -0
  20. package/dist/lib/mcp/adapters/plugin-bridge.js +82 -0
  21. package/dist/lib/mcp/auto-discovery.d.ts +38 -96
  22. package/dist/lib/mcp/auto-discovery.js +100 -744
  23. package/dist/lib/mcp/client.js +4 -4
  24. package/dist/lib/mcp/context-manager.js +72 -1
  25. package/dist/lib/mcp/contracts/mcp-contract.d.ts +162 -0
  26. package/dist/lib/mcp/contracts/mcp-contract.js +58 -0
  27. package/dist/lib/mcp/core/plugin-manager.d.ts +45 -0
  28. package/dist/lib/mcp/core/plugin-manager.js +110 -0
  29. package/dist/lib/mcp/demo/plugin-demo.d.ts +20 -0
  30. package/dist/lib/mcp/demo/plugin-demo.js +116 -0
  31. package/dist/lib/mcp/ecosystem.d.ts +75 -0
  32. package/dist/lib/mcp/ecosystem.js +161 -0
  33. package/dist/lib/mcp/external-client.d.ts +88 -0
  34. package/dist/lib/mcp/external-client.js +323 -0
  35. package/dist/lib/mcp/external-manager.d.ts +112 -0
  36. package/dist/lib/mcp/external-manager.js +302 -0
  37. package/dist/lib/mcp/factory.d.ts +4 -4
  38. package/dist/lib/mcp/function-calling.js +59 -34
  39. package/dist/lib/mcp/index.d.ts +39 -184
  40. package/dist/lib/mcp/index.js +72 -150
  41. package/dist/lib/mcp/initialize.js +5 -5
  42. package/dist/lib/mcp/logging.d.ts +27 -60
  43. package/dist/lib/mcp/logging.js +77 -165
  44. package/dist/lib/mcp/neurolink-mcp-client.js +31 -3
  45. package/dist/lib/mcp/orchestrator.d.ts +1 -1
  46. package/dist/lib/mcp/orchestrator.js +13 -12
  47. package/dist/lib/mcp/plugin-manager.d.ts +98 -0
  48. package/dist/lib/mcp/plugin-manager.js +294 -0
  49. package/dist/lib/mcp/plugins/core/filesystem-mcp.d.ts +35 -0
  50. package/dist/lib/mcp/plugins/core/filesystem-mcp.js +139 -0
  51. package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +36 -0
  52. package/dist/lib/mcp/plugins/filesystem-mcp.js +54 -0
  53. package/dist/lib/mcp/registry.d.ts +27 -176
  54. package/dist/lib/mcp/registry.js +31 -372
  55. package/dist/lib/mcp/security-manager.d.ts +85 -0
  56. package/dist/lib/mcp/security-manager.js +344 -0
  57. package/dist/lib/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  58. package/dist/lib/mcp/tool-integration.d.ts +4 -14
  59. package/dist/lib/mcp/tool-integration.js +43 -21
  60. package/dist/lib/mcp/tool-registry.d.ts +66 -0
  61. package/dist/lib/mcp/tool-registry.js +160 -0
  62. package/dist/lib/mcp/unified-mcp.d.ts +123 -0
  63. package/dist/lib/mcp/unified-mcp.js +246 -0
  64. package/dist/lib/mcp/unified-registry.d.ts +42 -229
  65. package/dist/lib/mcp/unified-registry.js +96 -1346
  66. package/dist/lib/neurolink.d.ts +3 -4
  67. package/dist/lib/neurolink.js +17 -18
  68. package/dist/lib/providers/agent-enhanced-provider.js +2 -2
  69. package/dist/lib/providers/amazonBedrock.js +2 -2
  70. package/dist/lib/providers/anthropic.js +3 -3
  71. package/dist/lib/providers/azureOpenAI.js +3 -3
  72. package/dist/lib/providers/function-calling-provider.js +34 -25
  73. package/dist/lib/providers/googleAIStudio.js +3 -3
  74. package/dist/lib/providers/googleVertexAI.js +2 -2
  75. package/dist/lib/providers/huggingFace.js +2 -2
  76. package/dist/lib/providers/mcp-provider.js +33 -5
  77. package/dist/lib/providers/mistralAI.js +2 -2
  78. package/dist/lib/providers/ollama.js +2 -2
  79. package/dist/lib/providers/openAI.js +2 -2
  80. package/dist/lib/utils/providerUtils-fixed.js +9 -9
  81. package/dist/mcp/adapters/plugin-bridge.d.ts +39 -0
  82. package/dist/mcp/adapters/plugin-bridge.js +82 -0
  83. package/dist/mcp/auto-discovery.d.ts +38 -96
  84. package/dist/mcp/auto-discovery.js +100 -745
  85. package/dist/mcp/client.js +4 -4
  86. package/dist/mcp/context-manager.js +72 -1
  87. package/dist/mcp/contracts/mcp-contract.d.ts +162 -0
  88. package/dist/mcp/contracts/mcp-contract.js +58 -0
  89. package/dist/mcp/core/plugin-manager.d.ts +45 -0
  90. package/dist/mcp/core/plugin-manager.js +110 -0
  91. package/dist/mcp/demo/plugin-demo.d.ts +20 -0
  92. package/dist/mcp/demo/plugin-demo.js +116 -0
  93. package/dist/mcp/ecosystem.d.ts +75 -0
  94. package/dist/mcp/ecosystem.js +162 -0
  95. package/dist/mcp/external-client.d.ts +88 -0
  96. package/dist/mcp/external-client.js +323 -0
  97. package/dist/mcp/external-manager.d.ts +112 -0
  98. package/dist/mcp/external-manager.js +302 -0
  99. package/dist/mcp/factory.d.ts +4 -4
  100. package/dist/mcp/function-calling.js +59 -34
  101. package/dist/mcp/index.d.ts +39 -184
  102. package/dist/mcp/index.js +72 -150
  103. package/dist/mcp/initialize.js +5 -5
  104. package/dist/mcp/logging.d.ts +27 -60
  105. package/dist/mcp/logging.js +77 -165
  106. package/dist/mcp/neurolink-mcp-client.js +31 -3
  107. package/dist/mcp/orchestrator.d.ts +1 -1
  108. package/dist/mcp/orchestrator.js +13 -12
  109. package/dist/mcp/plugin-manager.d.ts +98 -0
  110. package/dist/mcp/plugin-manager.js +295 -0
  111. package/dist/mcp/plugins/core/filesystem-mcp.d.ts +35 -0
  112. package/dist/mcp/plugins/core/filesystem-mcp.js +139 -0
  113. package/dist/mcp/plugins/core/neurolink-mcp.json +17 -0
  114. package/dist/mcp/plugins/filesystem-mcp.d.ts +36 -0
  115. package/dist/mcp/plugins/filesystem-mcp.js +54 -0
  116. package/dist/mcp/registry.d.ts +27 -176
  117. package/dist/mcp/registry.js +31 -372
  118. package/dist/mcp/security-manager.d.ts +85 -0
  119. package/dist/mcp/security-manager.js +344 -0
  120. package/dist/mcp/servers/ai-providers/ai-workflow-tools.d.ts +2 -2
  121. package/dist/mcp/tool-integration.d.ts +4 -14
  122. package/dist/mcp/tool-integration.js +43 -21
  123. package/dist/mcp/tool-registry.d.ts +66 -0
  124. package/dist/mcp/tool-registry.js +160 -0
  125. package/dist/mcp/unified-mcp.d.ts +123 -0
  126. package/dist/mcp/unified-mcp.js +246 -0
  127. package/dist/mcp/unified-registry.d.ts +42 -229
  128. package/dist/mcp/unified-registry.js +96 -1345
  129. package/dist/neurolink.d.ts +3 -4
  130. package/dist/neurolink.js +17 -18
  131. package/dist/providers/agent-enhanced-provider.js +2 -2
  132. package/dist/providers/amazonBedrock.js +2 -2
  133. package/dist/providers/anthropic.js +3 -3
  134. package/dist/providers/azureOpenAI.js +3 -3
  135. package/dist/providers/function-calling-provider.js +34 -25
  136. package/dist/providers/googleAIStudio.js +3 -3
  137. package/dist/providers/googleVertexAI.js +2 -2
  138. package/dist/providers/huggingFace.js +2 -2
  139. package/dist/providers/mcp-provider.js +33 -5
  140. package/dist/providers/mistralAI.js +2 -2
  141. package/dist/providers/ollama.js +2 -2
  142. package/dist/providers/openAI.js +2 -2
  143. package/dist/utils/providerUtils-fixed.js +9 -9
  144. package/package.json +1 -1
@@ -0,0 +1,295 @@
1
+ /**
2
+ * PluginManager - Central Orchestrator for MCP Lifecycle
3
+ * Implements generic factory pattern with manifest-based discovery
4
+ * Based on research blueprint for extensible plugin architecture
5
+ */
6
+ import * as fs from "fs/promises";
7
+ import * as path from "path";
8
+ import { fileURLToPath } from "url";
9
+ import { dirname } from "path";
10
+ // ES Module compatibility
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+ import { MCP } from "./contracts/mcp-contract.js";
14
+ import { SecurityManager } from "./security-manager.js";
15
+ import { mcpLogger } from "./logging.js";
16
+ /**
17
+ * Central Plugin Manager implementing the research blueprint
18
+ */
19
+ export class PluginManager {
20
+ static instance;
21
+ mcpConstructors = new Map();
22
+ mcpInstances = new Map();
23
+ discoveredMCPs = new Map();
24
+ securityManager;
25
+ initialized = false;
26
+ config;
27
+ constructor(config = {}) {
28
+ this.config = {
29
+ enableDiscovery: true,
30
+ pluginDirectories: [],
31
+ securityLevel: "moderate",
32
+ maxPlugins: 50,
33
+ ...config,
34
+ };
35
+ this.securityManager = new SecurityManager(this.config.securityLevel);
36
+ }
37
+ /**
38
+ * Get the singleton instance
39
+ */
40
+ static getInstance(config) {
41
+ if (!PluginManager.instance) {
42
+ PluginManager.instance = new PluginManager(config);
43
+ }
44
+ return PluginManager.instance;
45
+ }
46
+ /**
47
+ * Initialize the plugin manager with discovery
48
+ */
49
+ async initialize() {
50
+ if (this.initialized) {
51
+ return;
52
+ }
53
+ mcpLogger.info("[PluginManager] Initializing plugin discovery...");
54
+ if (this.config.enableDiscovery) {
55
+ await this.discoverPlugins();
56
+ }
57
+ this.initialized = true;
58
+ mcpLogger.info(`[PluginManager] Initialized with ${this.discoveredMCPs.size} discovered plugins`);
59
+ }
60
+ /**
61
+ * Discover plugins following research blueprint priority:
62
+ * 1. Core plugins (bundled)
63
+ * 2. Project plugins (./neurolink-mcp/)
64
+ * 3. Installed plugins (node_modules)
65
+ */
66
+ async discoverPlugins() {
67
+ const functionTag = "PluginManager.discoverPlugins";
68
+ try {
69
+ // 1. Discover core plugins
70
+ await this.discoverCorePlugins();
71
+ // 2. Discover project plugins
72
+ await this.discoverProjectPlugins();
73
+ // 3. Discover installed plugins
74
+ await this.discoverInstalledPlugins();
75
+ mcpLogger.debug(`[${functionTag}] Discovery completed`, {
76
+ total: this.discoveredMCPs.size,
77
+ bySource: this.getDiscoveryStats(),
78
+ });
79
+ }
80
+ catch (error) {
81
+ mcpLogger.error(`[${functionTag}] Discovery failed:`, error);
82
+ }
83
+ }
84
+ /**
85
+ * Discover core plugins bundled with NeuroLink
86
+ */
87
+ async discoverCorePlugins() {
88
+ // Correctly resolve path from 'dist' to 'src'
89
+ const corePluginsPath = path.resolve(__dirname, "../../src/lib/mcp/plugins/core");
90
+ await this.discoverPluginsInDirectory(corePluginsPath, "core");
91
+ }
92
+ /**
93
+ * Discover project-local plugins
94
+ */
95
+ async discoverProjectPlugins() {
96
+ const projectPluginsPath = path.join(process.cwd(), "neurolink-mcp");
97
+ await this.discoverPluginsInDirectory(projectPluginsPath, "project");
98
+ }
99
+ /**
100
+ * Discover installed plugins from node_modules
101
+ */
102
+ async discoverInstalledPlugins() {
103
+ const nodeModulesPath = path.join(process.cwd(), "node_modules");
104
+ try {
105
+ const packages = await fs.readdir(nodeModulesPath);
106
+ for (const pkg of packages) {
107
+ if (pkg.startsWith(".")) {
108
+ continue;
109
+ }
110
+ const packagePath = path.join(nodeModulesPath, pkg);
111
+ const packageJsonPath = path.join(packagePath, "package.json");
112
+ try {
113
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, "utf-8"));
114
+ // Check for neurolink-mcp keyword
115
+ if (packageJson.keywords?.includes("neurolink-mcp")) {
116
+ await this.discoverPluginsInDirectory(packagePath, "installed");
117
+ }
118
+ }
119
+ catch {
120
+ // Skip invalid packages
121
+ }
122
+ }
123
+ }
124
+ catch {
125
+ // node_modules doesn't exist or not accessible
126
+ }
127
+ }
128
+ /**
129
+ * Discover plugins in a specific directory
130
+ */
131
+ async discoverPluginsInDirectory(dirPath, source) {
132
+ try {
133
+ const manifestPath = path.join(dirPath, "neurolink-mcp.json");
134
+ const manifestExists = await fs
135
+ .access(manifestPath)
136
+ .then(() => true)
137
+ .catch(() => false);
138
+ if (!manifestExists) {
139
+ return;
140
+ }
141
+ const manifest = JSON.parse(await fs.readFile(manifestPath, "utf-8"));
142
+ // Validate manifest
143
+ if (!this.validateManifest(manifest)) {
144
+ mcpLogger.warn(`[PluginManager] Invalid manifest in ${dirPath}`);
145
+ return;
146
+ }
147
+ // Now we know manifest is MCPMetadata due to type guard
148
+ const validatedManifest = manifest;
149
+ const entryPath = path
150
+ .resolve(dirPath, validatedManifest.main)
151
+ .replace(`${process.cwd()}/src/lib`, `${process.cwd()}/dist`);
152
+ this.discoveredMCPs.set(validatedManifest.name, {
153
+ metadata: validatedManifest,
154
+ entryPath,
155
+ source,
156
+ constructor: undefined, // Will be loaded on demand
157
+ });
158
+ mcpLogger.debug(`[PluginManager] Discovered ${validatedManifest.name} from ${source}`);
159
+ }
160
+ catch (error) {
161
+ mcpLogger.debug(`[PluginManager] Failed to discover plugin in ${dirPath}:`, error);
162
+ }
163
+ }
164
+ /**
165
+ * Validate manifest structure
166
+ */
167
+ validateManifest(manifest) {
168
+ if (!manifest || typeof manifest !== "object") {
169
+ return false;
170
+ }
171
+ const obj = manifest;
172
+ return (typeof obj.name === "string" &&
173
+ typeof obj.version === "string" &&
174
+ typeof obj.main === "string" &&
175
+ obj.engine?.neurolink &&
176
+ typeof obj.description === "string" &&
177
+ Array.isArray(obj.permissions));
178
+ }
179
+ /**
180
+ * Generic Factory Method - Creates type-safe MCP instances
181
+ * Core implementation of the research blueprint
182
+ */
183
+ async createInstance(name, config) {
184
+ const functionTag = "PluginManager.createInstance";
185
+ if (!this.initialized) {
186
+ await this.initialize();
187
+ }
188
+ // Check if already instantiated
189
+ const existingInstance = this.mcpInstances.get(name);
190
+ if (existingInstance) {
191
+ mcpLogger.debug(`[${functionTag}] Returning existing instance of ${name}`);
192
+ return existingInstance;
193
+ }
194
+ // Get constructor (load if necessary)
195
+ const Constructor = await this.getConstructor(name);
196
+ if (!Constructor) {
197
+ throw new Error(`MCP with name "${name}" is not registered or failed validation.`);
198
+ }
199
+ // Security check
200
+ const discovered = this.discoveredMCPs.get(name);
201
+ if (discovered &&
202
+ !this.securityManager.validatePermissions(discovered.metadata.permissions)) {
203
+ throw new Error(`Security validation failed for MCP "${name}"`);
204
+ }
205
+ try {
206
+ // Instantiate the class
207
+ const instance = new Constructor();
208
+ // Initialize with config
209
+ await instance.initialize(config);
210
+ // Store instance
211
+ this.mcpInstances.set(name, instance);
212
+ mcpLogger.info(`[${functionTag}] Created and initialized ${name}`);
213
+ return instance;
214
+ }
215
+ catch (error) {
216
+ mcpLogger.error(`[${functionTag}] Failed to create instance of ${name}:`, error);
217
+ throw error;
218
+ }
219
+ }
220
+ /**
221
+ * Get or load constructor for an MCP
222
+ */
223
+ async getConstructor(name) {
224
+ // Check if already loaded
225
+ const existingConstructor = this.mcpConstructors.get(name);
226
+ if (existingConstructor) {
227
+ return existingConstructor;
228
+ }
229
+ // Load from discovered plugins
230
+ const discovered = this.discoveredMCPs.get(name);
231
+ if (!discovered) {
232
+ return null;
233
+ }
234
+ try {
235
+ // Dynamic import of the plugin
236
+ const module = await import(discovered.entryPath);
237
+ const Constructor = module.default || module[discovered.metadata.name];
238
+ if (typeof Constructor !== "function") {
239
+ throw new Error(`Invalid export from ${discovered.entryPath}`);
240
+ }
241
+ // Store constructor
242
+ this.mcpConstructors.set(name, Constructor);
243
+ return Constructor;
244
+ }
245
+ catch (error) {
246
+ mcpLogger.error(`[PluginManager] Failed to load ${name} from ${discovered.entryPath}:`, error);
247
+ return null;
248
+ }
249
+ }
250
+ /**
251
+ * List all discovered MCPs
252
+ */
253
+ listDiscovered() {
254
+ return Array.from(this.discoveredMCPs.values()).map((d) => d.metadata);
255
+ }
256
+ /**
257
+ * Get metadata for a specific MCP
258
+ */
259
+ getMetadata(name) {
260
+ const discovered = this.discoveredMCPs.get(name);
261
+ return discovered ? discovered.metadata : null;
262
+ }
263
+ /**
264
+ * Get discovery statistics
265
+ */
266
+ getDiscoveryStats() {
267
+ const stats = { core: 0, project: 0, installed: 0 };
268
+ for (const discovered of this.discoveredMCPs.values()) {
269
+ stats[discovered.source]++;
270
+ }
271
+ return stats;
272
+ }
273
+ /**
274
+ * Dispose of all instances and cleanup
275
+ */
276
+ async dispose() {
277
+ mcpLogger.info("[PluginManager] Disposing all MCP instances...");
278
+ for (const [name, instance] of this.mcpInstances) {
279
+ try {
280
+ await instance.dispose();
281
+ mcpLogger.debug(`[PluginManager] Disposed ${name}`);
282
+ }
283
+ catch (error) {
284
+ mcpLogger.error(`[PluginManager] Failed to dispose ${name}:`, error);
285
+ }
286
+ }
287
+ this.mcpInstances.clear();
288
+ this.mcpConstructors.clear();
289
+ this.initialized = false;
290
+ }
291
+ }
292
+ /**
293
+ * Export singleton instance getter
294
+ */
295
+ export const pluginManager = PluginManager.getInstance();
@@ -0,0 +1,35 @@
1
+ /**
2
+ * FileSystemMCP - Proof of Concept Plugin
3
+ * Demonstrates the research blueprint implementation
4
+ */
5
+ import { MCP } from "../../contracts/mcp-contract.js";
6
+ import type { MCPMetadata, ExecutionContext } from "../../contracts/mcp-contract.js";
7
+ interface FileSystemConfig {
8
+ basePath: string;
9
+ allowedExtensions?: string[];
10
+ }
11
+ interface FileSystemArgs {
12
+ operation: "readFile" | "writeFile" | "listFiles" | "createDir";
13
+ path: string;
14
+ content?: string;
15
+ options?: any;
16
+ }
17
+ interface FileSystemResult {
18
+ success: boolean;
19
+ data?: any;
20
+ error?: string;
21
+ }
22
+ /**
23
+ * FileSystem MCP implementing the abstract contract
24
+ */
25
+ export declare class FileSystemMCP extends MCP<FileSystemConfig, FileSystemArgs, FileSystemResult> {
26
+ readonly metadata: MCPMetadata;
27
+ initialize(config: FileSystemConfig): Promise<void>;
28
+ execute(context: ExecutionContext, args: FileSystemArgs): Promise<FileSystemResult>;
29
+ private readFile;
30
+ private writeFile;
31
+ private listFiles;
32
+ private createDirectory;
33
+ dispose(): Promise<void>;
34
+ }
35
+ export default FileSystemMCP;
@@ -0,0 +1,139 @@
1
+ /**
2
+ * FileSystemMCP - Proof of Concept Plugin
3
+ * Demonstrates the research blueprint implementation
4
+ */
5
+ import { MCP } from "../../contracts/mcp-contract.js";
6
+ import * as path from "path";
7
+ /**
8
+ * FileSystem MCP implementing the abstract contract
9
+ */
10
+ export class FileSystemMCP extends MCP {
11
+ metadata = {
12
+ name: "@neurolink-mcp/filesystem",
13
+ version: "1.0.0",
14
+ main: "./filesystem-mcp.js",
15
+ engine: {
16
+ neurolink: ">=1.9.0 <2.0.0",
17
+ },
18
+ description: "Provides secure file system operations for NeuroLink agents",
19
+ permissions: [
20
+ "fs:read:./**/*",
21
+ "fs:write:./output/**/*",
22
+ "fs:write:./temp/**/*",
23
+ ],
24
+ };
25
+ async initialize(config) {
26
+ if (!config.basePath) {
27
+ throw new Error("basePath is required in FileSystemMCP configuration");
28
+ }
29
+ this.config = {
30
+ allowedExtensions: [".txt", ".json", ".md", ".js", ".ts"],
31
+ ...config,
32
+ };
33
+ this.initialized = true;
34
+ }
35
+ async execute(context, args) {
36
+ this.log(context, "info", "Executing FileSystemMCP", { args });
37
+ this.log(context, "info", "Executing FileSystemMCP", { args });
38
+ this.log(context, "info", "Executing FileSystemMCP", { args });
39
+ this.ensureInitialized();
40
+ try {
41
+ if (!args.path) {
42
+ // This is a configuration call, not an operation
43
+ return { success: true, data: { configured: true } };
44
+ }
45
+ const fullPath = path.isAbsolute(args.path)
46
+ ? args.path
47
+ : context.path.join(this.config.basePath, args.path);
48
+ switch (args.operation) {
49
+ case "readFile":
50
+ return await this.readFile(context, fullPath);
51
+ case "writeFile":
52
+ return await this.writeFile(context, fullPath, args.content);
53
+ case "listFiles":
54
+ return await this.listFiles(context, fullPath);
55
+ case "createDir":
56
+ return await this.createDirectory(context, fullPath);
57
+ default:
58
+ throw new Error(`Unsupported operation: ${args.operation}`);
59
+ }
60
+ }
61
+ catch (error) {
62
+ this.log(context, "error", "Operation failed", {
63
+ operation: args.operation,
64
+ error,
65
+ });
66
+ return {
67
+ success: false,
68
+ error: error instanceof Error ? error.message : String(error),
69
+ };
70
+ }
71
+ }
72
+ async readFile(context, filePath) {
73
+ const content = await context.secureFS.readFile(filePath, "utf-8");
74
+ const stats = await context.secureFS.stat(filePath);
75
+ return {
76
+ success: true,
77
+ data: {
78
+ content,
79
+ size: stats.size,
80
+ lastModified: stats.mtime,
81
+ path: filePath,
82
+ },
83
+ };
84
+ }
85
+ async writeFile(context, filePath, content) {
86
+ await context.secureFS.writeFile(filePath, content);
87
+ return {
88
+ success: true,
89
+ data: {
90
+ path: filePath,
91
+ size: content.length,
92
+ written: true,
93
+ },
94
+ };
95
+ }
96
+ async listFiles(context, dirPath) {
97
+ const items = await context.secureFS.readdir(dirPath);
98
+ const itemDetails = [];
99
+ for (const item of items) {
100
+ const itemPath = context.path.join(dirPath, item);
101
+ try {
102
+ const stats = await context.secureFS.stat(itemPath);
103
+ itemDetails.push({
104
+ name: item,
105
+ type: stats.isDirectory() ? "directory" : "file",
106
+ size: stats.isFile() ? stats.size : undefined,
107
+ lastModified: stats.mtime,
108
+ });
109
+ }
110
+ catch {
111
+ // Skip inaccessible items
112
+ }
113
+ }
114
+ return {
115
+ success: true,
116
+ data: {
117
+ path: dirPath,
118
+ items: itemDetails,
119
+ count: itemDetails.length,
120
+ },
121
+ };
122
+ }
123
+ async createDirectory(context, dirPath) {
124
+ await context.secureFS.mkdir(dirPath, { recursive: true });
125
+ return {
126
+ success: true,
127
+ data: {
128
+ path: dirPath,
129
+ created: true,
130
+ },
131
+ };
132
+ }
133
+ async dispose() {
134
+ this.initialized = false;
135
+ this.config = undefined;
136
+ }
137
+ }
138
+ // Export as default for dynamic import
139
+ export default FileSystemMCP;
@@ -0,0 +1,17 @@
1
+ {
2
+ "name": "@neurolink-mcp/filesystem",
3
+ "version": "1.0.0",
4
+ "main": "./filesystem-mcp.js",
5
+ "description": "Provides secure file system operations for NeuroLink agents",
6
+ "author": "NeuroLink Team",
7
+ "license": "MIT",
8
+ "engine": {
9
+ "neurolink": ">=1.9.0 <2.0.0"
10
+ },
11
+ "permissions": [
12
+ "fs:read:./**/*",
13
+ "fs:write:./output/**/*",
14
+ "fs:write:./temp/**/*"
15
+ ],
16
+ "keywords": ["filesystem", "file", "mcp", "plugin"]
17
+ }
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Enhanced FileSystem MCP Plugin
3
+ * Implements the new MCP contract with security sandbox
4
+ * Based on research document recommendations
5
+ */
6
+ import { MCP, MCPMetadata, ExecutionContext } from "../contracts/mcp-contract.js";
7
+ /**
8
+ * FileSystem MCP Configuration
9
+ */
10
+ export interface FileSystemConfig {
11
+ basePath: string;
12
+ allowedExtensions?: string[];
13
+ maxFileSize?: number;
14
+ readOnly?: boolean;
15
+ }
16
+ /**
17
+ * FileSystem Operation Arguments
18
+ */
19
+ export interface FileSystemArgs {
20
+ operation: "readFile" | "writeFile" | "listFiles" | "getFileInfo";
21
+ path: string;
22
+ content?: string;
23
+ encoding?: string;
24
+ }
25
+ /**
26
+ * Enhanced FileSystem MCP Plugin
27
+ */
28
+ export declare class FileSystemMCP extends MCP<FileSystemConfig> {
29
+ config: FileSystemConfig;
30
+ readonly metadata: MCPMetadata;
31
+ initialize(config: FileSystemConfig): Promise<void>;
32
+ execute(context: ExecutionContext, args: FileSystemArgs): Promise<any>;
33
+ private resolvePath;
34
+ dispose(): Promise<void>;
35
+ }
36
+ export declare function createFileSystemMCP(): FileSystemMCP;
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Enhanced FileSystem MCP Plugin
3
+ * Implements the new MCP contract with security sandbox
4
+ * Based on research document recommendations
5
+ */
6
+ import path from "path";
7
+ import { MCP, MCPMetadata, ExecutionContext, MCPCategory, } from "../contracts/mcp-contract.js";
8
+ /**
9
+ * Enhanced FileSystem MCP Plugin
10
+ */
11
+ export class FileSystemMCP extends MCP {
12
+ metadata = {
13
+ name: "@neurolink-mcp/filesystem",
14
+ version: "1.0.0",
15
+ main: "./dist/filesystem-mcp.js",
16
+ engine: { neurolink: ">=1.9.0 <2.0.0" },
17
+ description: "Secure file system operations with permission-based access control",
18
+ permissions: ["fs:read:./**/*", "fs:write:./output/**/*"],
19
+ };
20
+ async initialize(config) {
21
+ this.config = {
22
+ allowedExtensions: [".txt", ".md", ".json", ".js", ".ts"],
23
+ maxFileSize: 10 * 1024 * 1024,
24
+ readOnly: false,
25
+ ...config,
26
+ };
27
+ }
28
+ async execute(context, args) {
29
+ const resolvedPath = this.resolvePath(args.path);
30
+ switch (args.operation) {
31
+ case "readFile":
32
+ return await context.secureFS.readFile(resolvedPath, args.encoding || "utf-8");
33
+ case "listFiles":
34
+ return await context.secureFS.readdir(resolvedPath);
35
+ case "getFileInfo":
36
+ return await context.secureFS.stat(resolvedPath);
37
+ default:
38
+ throw new Error(`Unsupported operation: ${args.operation}`);
39
+ }
40
+ }
41
+ resolvePath(inputPath) {
42
+ const resolved = path.resolve(this.config.basePath, inputPath);
43
+ if (!resolved.startsWith(this.config.basePath)) {
44
+ throw new Error(`Path outside allowed directory: ${inputPath}`);
45
+ }
46
+ return resolved;
47
+ }
48
+ async dispose() {
49
+ // Cleanup resources
50
+ }
51
+ }
52
+ export function createFileSystemMCP() {
53
+ return new FileSystemMCP();
54
+ }