@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,85 @@
1
+ /**
2
+ * Security Manager - Permission-Based Sandbox for MCP Operations
3
+ * Implements the research blueprint's security-by-design principles
4
+ */
5
+ import type { ExecutionContext } from "./contracts/mcp-contract.js";
6
+ /**
7
+ * Security levels for plugin execution
8
+ */
9
+ export type SecurityLevel = "strict" | "moderate" | "permissive";
10
+ /**
11
+ * Permission types supported by the security system
12
+ */
13
+ export interface Permission {
14
+ type: "fs" | "net" | "process" | "env";
15
+ action: string;
16
+ resource: string;
17
+ }
18
+ /**
19
+ * Security Manager implementing permission-based sandbox
20
+ */
21
+ export declare class SecurityManager {
22
+ private securityLevel;
23
+ private allowedBasePaths;
24
+ private deniedPaths;
25
+ constructor(securityLevel?: SecurityLevel);
26
+ /**
27
+ * Initialize default security boundaries based on level
28
+ */
29
+ private initializeSecurityBoundaries;
30
+ /**
31
+ * Validate permissions array from manifest
32
+ */
33
+ validatePermissions(permissions: string[]): boolean;
34
+ /**
35
+ * Parse permission string into structured format
36
+ */
37
+ private parsePermission;
38
+ /**
39
+ * Check if a permission is allowed based on security level
40
+ */
41
+ private isPermissionAllowed;
42
+ /**
43
+ * Validate filesystem permissions
44
+ */
45
+ private isFileSystemPermissionAllowed;
46
+ /**
47
+ * Check if filesystem action is allowed
48
+ */
49
+ private isFileSystemActionAllowed;
50
+ /**
51
+ * Validate network permissions
52
+ */
53
+ private isNetworkPermissionAllowed;
54
+ /**
55
+ * Validate process permissions
56
+ */
57
+ private isProcessPermissionAllowed;
58
+ /**
59
+ * Validate environment permissions
60
+ */
61
+ private isEnvironmentPermissionAllowed;
62
+ /**
63
+ * Create a secure filesystem interface for ExecutionContext
64
+ */
65
+ createSecureFS(grantedPermissions: string[], basePath?: string): {
66
+ readFile(filePath: string, encoding?: string): Promise<string | Buffer>;
67
+ writeFile(filePath: string, content: string | Buffer): Promise<void>;
68
+ readdir(dirPath: string): Promise<string[]>;
69
+ stat(filePath: string): Promise<any>;
70
+ mkdir(dirPath: string, options?: any): Promise<void>;
71
+ exists(filePath: string): Promise<boolean>;
72
+ };
73
+ /**
74
+ * Check filesystem permission against granted permissions
75
+ */
76
+ private checkFileSystemPermission;
77
+ /**
78
+ * Check if permission matches wildcard pattern
79
+ */
80
+ private matchesWildcardPermission;
81
+ /**
82
+ * Create execution context with security sandbox
83
+ */
84
+ createExecutionContext(sessionId: string, userId: string, grantedPermissions: string[], basePath?: string): ExecutionContext;
85
+ }
@@ -0,0 +1,344 @@
1
+ /**
2
+ * Security Manager - Permission-Based Sandbox for MCP Operations
3
+ * Implements the research blueprint's security-by-design principles
4
+ */
5
+ import * as fs from "fs/promises";
6
+ import * as path from "path";
7
+ import { mcpLogger } from "./logging.js";
8
+ /**
9
+ * Security Manager implementing permission-based sandbox
10
+ */
11
+ export class SecurityManager {
12
+ securityLevel;
13
+ allowedBasePaths;
14
+ deniedPaths;
15
+ constructor(securityLevel = "moderate") {
16
+ this.securityLevel = securityLevel;
17
+ this.allowedBasePaths = new Set();
18
+ this.deniedPaths = new Set();
19
+ // Initialize default security boundaries
20
+ this.initializeSecurityBoundaries();
21
+ }
22
+ /**
23
+ * Initialize default security boundaries based on level
24
+ */
25
+ initializeSecurityBoundaries() {
26
+ const cwd = process.cwd();
27
+ switch (this.securityLevel) {
28
+ case "strict":
29
+ // Only allow current working directory
30
+ this.allowedBasePaths.add(cwd);
31
+ this.deniedPaths.add(path.join(cwd, "node_modules"));
32
+ this.deniedPaths.add("/etc");
33
+ this.deniedPaths.add("/usr");
34
+ this.deniedPaths.add("/var");
35
+ break;
36
+ case "moderate":
37
+ // Allow project directory and some system reads
38
+ this.allowedBasePaths.add(cwd);
39
+ this.allowedBasePaths.add(path.join(process.env.HOME || "/", "Downloads"));
40
+ this.deniedPaths.add("/etc/passwd");
41
+ this.deniedPaths.add("/etc/shadow");
42
+ break;
43
+ case "permissive":
44
+ // Allow broader access with minimal restrictions
45
+ this.allowedBasePaths.add("/");
46
+ this.deniedPaths.add("/etc/passwd");
47
+ this.deniedPaths.add("/etc/shadow");
48
+ break;
49
+ }
50
+ }
51
+ /**
52
+ * Validate permissions array from manifest
53
+ */
54
+ validatePermissions(permissions) {
55
+ try {
56
+ for (const permission of permissions) {
57
+ const parsed = this.parsePermission(permission);
58
+ if (!this.isPermissionAllowed(parsed)) {
59
+ mcpLogger.warn(`[SecurityManager] Permission denied: ${permission}`);
60
+ return false;
61
+ }
62
+ }
63
+ return true;
64
+ }
65
+ catch (error) {
66
+ mcpLogger.error("[SecurityManager] Permission validation failed:", error);
67
+ return false;
68
+ }
69
+ }
70
+ /**
71
+ * Parse permission string into structured format
72
+ */
73
+ parsePermission(permission) {
74
+ const parts = permission.split(":");
75
+ if (parts.length !== 3) {
76
+ throw new Error(`Invalid permission format: ${permission}`);
77
+ }
78
+ return {
79
+ type: parts[0],
80
+ action: parts[1],
81
+ resource: parts[2],
82
+ };
83
+ }
84
+ /**
85
+ * Check if a permission is allowed based on security level
86
+ */
87
+ isPermissionAllowed(permission) {
88
+ switch (permission.type) {
89
+ case "fs":
90
+ return this.isFileSystemPermissionAllowed(permission);
91
+ case "net":
92
+ return this.isNetworkPermissionAllowed(permission);
93
+ case "process":
94
+ return this.isProcessPermissionAllowed(permission);
95
+ case "env":
96
+ return this.isEnvironmentPermissionAllowed(permission);
97
+ default:
98
+ return false;
99
+ }
100
+ }
101
+ /**
102
+ * Validate filesystem permissions
103
+ */
104
+ isFileSystemPermissionAllowed(permission) {
105
+ const { action, resource } = permission;
106
+ const resolvedPath = path.resolve(resource);
107
+ // Check if path is explicitly denied
108
+ for (const deniedPath of this.deniedPaths) {
109
+ if (resolvedPath.startsWith(deniedPath)) {
110
+ return false;
111
+ }
112
+ }
113
+ // Check if path is within allowed base paths
114
+ for (const basePath of this.allowedBasePaths) {
115
+ if (resolvedPath.startsWith(basePath)) {
116
+ return this.isFileSystemActionAllowed(action);
117
+ }
118
+ }
119
+ return false;
120
+ }
121
+ /**
122
+ * Check if filesystem action is allowed
123
+ */
124
+ isFileSystemActionAllowed(action) {
125
+ const allowedActions = {
126
+ strict: ["read"],
127
+ moderate: ["read", "write"],
128
+ permissive: ["read", "write", "delete", "execute"],
129
+ };
130
+ return allowedActions[this.securityLevel].includes(action);
131
+ }
132
+ /**
133
+ * Validate network permissions
134
+ */
135
+ isNetworkPermissionAllowed(permission) {
136
+ if (this.securityLevel === "strict") {
137
+ return false; // No network access in strict mode
138
+ }
139
+ const { resource } = permission;
140
+ // Only allow HTTPS in moderate mode
141
+ if (this.securityLevel === "moderate") {
142
+ return resource.startsWith("https://");
143
+ }
144
+ // Permissive allows both HTTP and HTTPS
145
+ return resource.startsWith("http://") || resource.startsWith("https://");
146
+ }
147
+ /**
148
+ * Validate process permissions
149
+ */
150
+ isProcessPermissionAllowed(permission) {
151
+ // Only permissive mode allows process operations
152
+ return this.securityLevel === "permissive";
153
+ }
154
+ /**
155
+ * Validate environment permissions
156
+ */
157
+ isEnvironmentPermissionAllowed(permission) {
158
+ const { action, resource } = permission;
159
+ // Reading environment variables is generally safe
160
+ if (action === "read") {
161
+ return true;
162
+ }
163
+ // Writing environment variables requires higher permissions
164
+ return this.securityLevel === "permissive";
165
+ }
166
+ /**
167
+ * Create a secure filesystem interface for ExecutionContext
168
+ */
169
+ createSecureFS(grantedPermissions, basePath) {
170
+ const self = this;
171
+ const CWD = process.cwd();
172
+ const resolveSecurePath = (p) => {
173
+ // Resolve the path. If basePath is provided, use it, otherwise use the current working directory.
174
+ const resolved = path.resolve(basePath || CWD, p);
175
+ // If a basePath is specified, ensure the resolved path is within that base path.
176
+ // This is a security measure to prevent path traversal attacks (e.g., using '../').
177
+ if (basePath) {
178
+ const relative = path.relative(path.resolve(basePath), resolved);
179
+ if (relative.startsWith("..") || path.isAbsolute(relative)) {
180
+ throw new Error(`Path traversal detected. Attempted to access ${resolved} which is outside of the allowed base path ${basePath}`);
181
+ }
182
+ }
183
+ return resolved;
184
+ };
185
+ return {
186
+ async readFile(filePath, encoding) {
187
+ const resolvedPath = resolveSecurePath(filePath);
188
+ self.checkFileSystemPermission("read", resolvedPath, grantedPermissions, basePath);
189
+ try {
190
+ return await fs.readFile(resolvedPath, encoding);
191
+ }
192
+ catch (error) {
193
+ mcpLogger.error(`[SecurityManager] Failed to read file ${filePath}:`, error);
194
+ throw error;
195
+ }
196
+ },
197
+ async writeFile(filePath, content) {
198
+ const resolvedPath = resolveSecurePath(filePath);
199
+ self.checkFileSystemPermission("write", resolvedPath, grantedPermissions, basePath);
200
+ try {
201
+ // Ensure directory exists
202
+ await fs.mkdir(path.dirname(resolvedPath), { recursive: true });
203
+ await fs.writeFile(resolvedPath, content);
204
+ }
205
+ catch (error) {
206
+ mcpLogger.error(`[SecurityManager] Failed to write file ${filePath}:`, error);
207
+ throw error;
208
+ }
209
+ },
210
+ async readdir(dirPath) {
211
+ const resolvedPath = resolveSecurePath(dirPath);
212
+ self.checkFileSystemPermission("read", resolvedPath, grantedPermissions, basePath);
213
+ try {
214
+ return await fs.readdir(resolvedPath);
215
+ }
216
+ catch (error) {
217
+ mcpLogger.error(`[SecurityManager] Failed to read directory ${dirPath}:`, error);
218
+ throw error;
219
+ }
220
+ },
221
+ async stat(filePath) {
222
+ const resolvedPath = resolveSecurePath(filePath);
223
+ self.checkFileSystemPermission("read", resolvedPath, grantedPermissions, basePath);
224
+ try {
225
+ return await fs.stat(resolvedPath);
226
+ }
227
+ catch (error) {
228
+ mcpLogger.error(`[SecurityManager] Failed to stat ${filePath}:`, error);
229
+ throw error;
230
+ }
231
+ },
232
+ async mkdir(dirPath, options) {
233
+ const resolvedPath = resolveSecurePath(dirPath);
234
+ self.checkFileSystemPermission("write", resolvedPath, grantedPermissions, basePath);
235
+ try {
236
+ await fs.mkdir(resolvedPath, options);
237
+ }
238
+ catch (error) {
239
+ mcpLogger.error(`[SecurityManager] Failed to create directory ${dirPath}:`, error);
240
+ throw error;
241
+ }
242
+ },
243
+ async exists(filePath) {
244
+ const resolvedPath = resolveSecurePath(filePath);
245
+ self.checkFileSystemPermission("read", resolvedPath, grantedPermissions, basePath);
246
+ try {
247
+ await fs.access(resolvedPath);
248
+ return true;
249
+ }
250
+ catch {
251
+ return false;
252
+ }
253
+ },
254
+ };
255
+ }
256
+ /**
257
+ * Check filesystem permission against granted permissions
258
+ */
259
+ checkFileSystemPermission(action, filePath, grantedPermissions, basePath) {
260
+ const requiredPermission = `fs:${action}:${filePath}`;
261
+ for (const permissionString of grantedPermissions) {
262
+ const parsedPermission = this.parsePermission(permissionString);
263
+ if (parsedPermission.type === "fs" &&
264
+ (parsedPermission.action === action ||
265
+ parsedPermission.action === "read-write")) {
266
+ // Handle relative paths with wildcards properly
267
+ let grantedPath;
268
+ if (!path.isAbsolute(parsedPermission.resource)) {
269
+ // For relative paths, resolve them relative to basePath if provided
270
+ if (basePath) {
271
+ // Handle wildcard patterns specially
272
+ if (parsedPermission.resource.includes("*")) {
273
+ // For patterns like './**/*', convert to absolute pattern
274
+ const resolvedBase = path.resolve(basePath);
275
+ if (parsedPermission.resource.startsWith("./")) {
276
+ grantedPath = path.join(resolvedBase, parsedPermission.resource.substring(2));
277
+ }
278
+ else {
279
+ grantedPath = path.join(resolvedBase, parsedPermission.resource);
280
+ }
281
+ }
282
+ else {
283
+ grantedPath = path.resolve(basePath, parsedPermission.resource);
284
+ }
285
+ }
286
+ else {
287
+ grantedPath = path.resolve(parsedPermission.resource);
288
+ }
289
+ }
290
+ else {
291
+ grantedPath = parsedPermission.resource;
292
+ }
293
+ if (this.matchesWildcardPermission(filePath, grantedPath)) {
294
+ return; // Permission granted
295
+ }
296
+ }
297
+ }
298
+ throw new Error(`Permission denied: ${requiredPermission}`);
299
+ }
300
+ /**
301
+ * Check if permission matches wildcard pattern
302
+ */
303
+ matchesWildcardPermission(required, granted) {
304
+ // Handle patterns that end with /** or /**/* (recursive directory access)
305
+ if (granted.endsWith("/**") || granted.endsWith("/**/*")) {
306
+ const basePath = granted.endsWith("/**/*")
307
+ ? granted.slice(0, -5) // Remove /**/*
308
+ : granted.slice(0, -3); // Remove /**
309
+ // Check if required path is the base path itself or a subdirectory/file within it.
310
+ return required === basePath || required.startsWith(basePath + "/");
311
+ }
312
+ if (!granted.includes("*")) {
313
+ return required === granted;
314
+ }
315
+ // Convert wildcard to regex for other cases
316
+ const regexPattern = granted
317
+ .replace(/[.+?^${}()|[\]\\]/g, "\\$&") // Escape special regex characters
318
+ .replace(/\*\*/g, ".*") // This is a greedy match, use with caution
319
+ .replace(/\*/g, "[^/]*"); // Handle single wildcard (any characters except slashes)
320
+ const regex = new RegExp(`^${regexPattern}$`);
321
+ return regex.test(required);
322
+ }
323
+ /**
324
+ * Create execution context with security sandbox
325
+ */
326
+ createExecutionContext(sessionId, userId, grantedPermissions, basePath) {
327
+ return {
328
+ sessionId,
329
+ userId,
330
+ grantedPermissions,
331
+ secureFS: this.createSecureFS(grantedPermissions, basePath),
332
+ path: {
333
+ join: path.join,
334
+ resolve: path.resolve,
335
+ relative: path.relative,
336
+ dirname: path.dirname,
337
+ basename: path.basename,
338
+ },
339
+ log: (level, message, data) => {
340
+ mcpLogger[level](`[ExecutionContext:${sessionId}] ${message}`, data);
341
+ },
342
+ };
343
+ }
344
+ }
@@ -30,13 +30,13 @@ export declare const workflowToolSchemas: {
30
30
  includeAsyncTests: z.ZodDefault<z.ZodBoolean>;
31
31
  }, "strip", z.ZodTypeAny, {
32
32
  codeFunction: string;
33
- testTypes: ("unit" | "integration" | "edge-cases" | "performance" | "security")[];
33
+ testTypes: ("integration" | "unit" | "edge-cases" | "performance" | "security")[];
34
34
  framework: "jest" | "mocha" | "vitest" | "pytest" | "unittest" | "rspec";
35
35
  coverageTarget: number;
36
36
  includeAsyncTests: boolean;
37
37
  }, {
38
38
  codeFunction: string;
39
- testTypes?: ("unit" | "integration" | "edge-cases" | "performance" | "security")[] | undefined;
39
+ testTypes?: ("integration" | "unit" | "edge-cases" | "performance" | "security")[] | undefined;
40
40
  framework?: "jest" | "mocha" | "vitest" | "pytest" | "unittest" | "rspec" | undefined;
41
41
  coverageTarget?: number | undefined;
42
42
  includeAsyncTests?: boolean | undefined;
@@ -18,26 +18,16 @@ export declare class MCPToolIntegration {
18
18
  /**
19
19
  * Get all available tools
20
20
  */
21
- getAvailableTools(): {
22
- name: string;
23
- qualifiedName: string;
24
- description: string;
25
- server: string;
26
- serverTitle: string;
27
- category?: string;
28
- serverCategory?: string;
29
- permissions?: string[];
30
- isImplemented?: boolean;
31
- }[];
21
+ getAvailableTools(): Promise<import("./tool-registry.js").ToolInfo[]>;
32
22
  /**
33
23
  * Find tools that match a query
34
24
  */
35
- findTools(query: string): Array<{
25
+ findTools(query: string): Promise<Array<{
36
26
  name: string;
37
27
  description: string;
38
28
  serverId: string;
39
29
  relevance: number;
40
- }>;
30
+ }>>;
41
31
  /**
42
32
  * Execute a tool by name
43
33
  */
@@ -45,7 +35,7 @@ export declare class MCPToolIntegration {
45
35
  /**
46
36
  * Enhance AI prompt with tool context
47
37
  */
48
- createToolAwarePrompt(userPrompt: string): string;
38
+ createToolAwarePrompt(userPrompt: string): Promise<string>;
49
39
  /**
50
40
  * Analyze AI response for tool usage requests
51
41
  */
@@ -4,7 +4,7 @@
4
4
  */
5
5
  import { mcpConfig } from "./config.js";
6
6
  import { logger } from "../utils/logger.js";
7
- import { MCPToolRegistry } from "./registry.js";
7
+ import { MCPToolRegistry } from "./tool-registry.js";
8
8
  /**
9
9
  * Tool Integration System
10
10
  * Provides natural language tool discovery and execution
@@ -16,9 +16,34 @@ export class MCPToolIntegration {
16
16
  this.registry = new MCPToolRegistry();
17
17
  this.context = {
18
18
  sessionId: context?.sessionId || `session-${Date.now()}`,
19
- userId: context?.userId,
20
- aiProvider: context?.aiProvider,
19
+ userId: context?.userId || "anonymous",
20
+ aiProvider: context?.aiProvider || "unknown",
21
21
  ...context,
22
+ // Ensure secureFS is properly typed
23
+ secureFS: context?.secureFS || {
24
+ readFile: async () => {
25
+ throw new Error("secureFS not configured");
26
+ },
27
+ writeFile: async () => {
28
+ throw new Error("secureFS not configured");
29
+ },
30
+ readdir: async () => {
31
+ throw new Error("secureFS not configured");
32
+ },
33
+ stat: async () => {
34
+ throw new Error("secureFS not configured");
35
+ },
36
+ mkdir: async () => {
37
+ throw new Error("secureFS not configured");
38
+ },
39
+ exists: async () => false,
40
+ rmdir: async () => {
41
+ throw new Error("secureFS not configured");
42
+ },
43
+ unlink: async () => {
44
+ throw new Error("secureFS not configured");
45
+ },
46
+ },
22
47
  };
23
48
  // Initialize with all active servers
24
49
  this.initializeTools();
@@ -29,11 +54,12 @@ export class MCPToolIntegration {
29
54
  async initializeTools() {
30
55
  const servers = await mcpConfig.getServers();
31
56
  for (const server of servers) {
32
- await this.registry.registerServer(server);
57
+ await this.registry.registerServer(server.id || server.name || "unknown", server);
33
58
  }
59
+ const tools = await this.registry.listTools();
34
60
  logger.debug("[Tool Integration] Initialized with servers:", {
35
61
  serverCount: servers.length,
36
- toolCount: this.registry.listTools().length,
62
+ toolCount: tools.length,
37
63
  });
38
64
  }
39
65
  /**
@@ -45,8 +71,8 @@ export class MCPToolIntegration {
45
71
  /**
46
72
  * Find tools that match a query
47
73
  */
48
- findTools(query) {
49
- const allTools = this.registry.listTools();
74
+ async findTools(query) {
75
+ const allTools = await this.registry.listTools();
50
76
  const queryLower = query.toLowerCase();
51
77
  const results = [];
52
78
  for (const toolInfo of allTools) {
@@ -56,18 +82,18 @@ export class MCPToolIntegration {
56
82
  relevance += 10;
57
83
  }
58
84
  // Check tool description
59
- if (toolInfo.description.toLowerCase().includes(queryLower)) {
85
+ if (toolInfo.description?.toLowerCase().includes(queryLower)) {
60
86
  relevance += 5;
61
87
  }
62
- // Check category if present
63
- if (toolInfo.category?.toLowerCase().includes(queryLower)) {
64
- relevance += 3;
65
- }
88
+ // Check category if present (category might not exist on ToolInfo)
89
+ // if (toolInfo.category?.toLowerCase().includes(queryLower)) {
90
+ // relevance += 3;
91
+ // }
66
92
  if (relevance > 0) {
67
93
  results.push({
68
94
  name: toolInfo.name,
69
- description: toolInfo.description,
70
- serverId: toolInfo.server,
95
+ description: toolInfo.description || "No description available",
96
+ serverId: toolInfo.server || "unknown",
71
97
  relevance,
72
98
  });
73
99
  }
@@ -82,11 +108,7 @@ export class MCPToolIntegration {
82
108
  try {
83
109
  // If serverId is provided, use qualified name
84
110
  const qualifiedName = serverId ? `${serverId}.${toolName}` : toolName;
85
- const result = await this.registry.executeTool(qualifiedName, params, this.context, {
86
- validateInput: true,
87
- validatePermissions: true,
88
- trackMetrics: true,
89
- });
111
+ const result = await this.registry.executeTool(qualifiedName, params, this.context);
90
112
  return result;
91
113
  }
92
114
  catch (error) {
@@ -105,8 +127,8 @@ export class MCPToolIntegration {
105
127
  /**
106
128
  * Enhance AI prompt with tool context
107
129
  */
108
- createToolAwarePrompt(userPrompt) {
109
- const tools = this.getAvailableTools();
130
+ async createToolAwarePrompt(userPrompt) {
131
+ const tools = await this.getAvailableTools();
110
132
  const toolDescriptions = tools
111
133
  .map((t) => `- ${t.name}: ${t.description}`)
112
134
  .join("\n");
@@ -0,0 +1,66 @@
1
+ /**
2
+ * MCP Tool Registry - Extended Registry with Tool Management
3
+ */
4
+ import type { ExecutionContext } from "./contracts/mcp-contract.js";
5
+ import type { ToolResult } from "./factory.js";
6
+ import { MCPRegistry } from "./registry.js";
7
+ export interface ToolInfo {
8
+ id: string;
9
+ name: string;
10
+ description?: string;
11
+ inputSchema?: any;
12
+ outputSchema?: any;
13
+ serverId: string;
14
+ source: "manual" | "auto" | "default";
15
+ isImplemented?: boolean;
16
+ server?: string;
17
+ }
18
+ export type ToolExecutionResult = ToolResult;
19
+ export declare class MCPToolRegistry extends MCPRegistry {
20
+ private tools;
21
+ private toolExecutionStats;
22
+ /**
23
+ * Register a server with its tools
24
+ */
25
+ registerServer(serverId: string, serverInfo: any): Promise<void>;
26
+ /**
27
+ * Unregister a server and its tools
28
+ */
29
+ unregisterServer(serverId: string): Promise<void>;
30
+ /**
31
+ * Execute a tool
32
+ */
33
+ executeTool(toolName: string, args: any, context: ExecutionContext): Promise<ToolExecutionResult>;
34
+ /**
35
+ * List all available tools
36
+ */
37
+ listTools(): Promise<ToolInfo[]>;
38
+ /**
39
+ * Get tool information
40
+ */
41
+ getToolInfo(toolName: string): ToolInfo | undefined;
42
+ /**
43
+ * Update execution statistics
44
+ */
45
+ private updateStats;
46
+ /**
47
+ * Get tool execution statistics
48
+ */
49
+ getToolStats(toolName?: string): any;
50
+ /**
51
+ * Get tool execution statistics
52
+ */
53
+ getStats(): Promise<any>;
54
+ /**
55
+ * Clear all tools and stats
56
+ */
57
+ clear(): void;
58
+ }
59
+ export declare const toolRegistry: MCPToolRegistry;
60
+ export declare const defaultToolRegistry: MCPToolRegistry;
61
+ export interface ToolExecutionOptions {
62
+ preferredSource?: string;
63
+ fallbackEnabled?: boolean;
64
+ validateBeforeExecution?: boolean;
65
+ timeoutMs?: number;
66
+ }