@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.
- package/CHANGELOG.md +16 -6
- package/dist/agent/direct-tools.js +6 -5
- package/dist/cli/commands/config.d.ts +13 -13
- package/dist/cli/index.js +3 -9
- package/dist/config/configManager.js +11 -10
- package/dist/core/analytics.d.ts +11 -1
- package/dist/core/analytics.js +2 -2
- package/dist/core/base-provider.js +4 -18
- package/dist/core/dynamic-models.d.ts +8 -8
- package/dist/core/factory.js +3 -11
- package/dist/index.d.ts +2 -4
- package/dist/index.js +2 -11
- package/dist/lib/agent/direct-tools.js +6 -5
- package/dist/lib/config/configManager.js +11 -10
- package/dist/lib/core/analytics.d.ts +11 -1
- package/dist/lib/core/analytics.js +2 -2
- package/dist/lib/core/base-provider.js +4 -18
- package/dist/lib/core/dynamic-models.d.ts +8 -8
- package/dist/lib/core/factory.js +3 -11
- package/dist/lib/index.d.ts +2 -4
- package/dist/lib/index.js +2 -11
- package/dist/lib/mcp/factory.d.ts +1 -1
- package/dist/lib/mcp/index.d.ts +9 -21
- package/dist/lib/mcp/index.js +16 -57
- package/dist/lib/mcp/registry.js +1 -1
- package/dist/lib/mcp/servers/ai-providers/ai-analysis-tools.js +2 -1
- package/dist/lib/mcp/tool-registry.js +1 -1
- package/dist/lib/neurolink.d.ts +1 -9
- package/dist/lib/neurolink.js +22 -71
- package/dist/lib/providers/amazon-bedrock.js +5 -16
- package/dist/lib/providers/anthropic-baseprovider.js +3 -21
- package/dist/lib/providers/anthropic.js +4 -7
- package/dist/lib/providers/azure-openai.js +6 -3
- package/dist/lib/providers/google-vertex.js +5 -9
- package/dist/lib/providers/huggingFace.js +5 -10
- package/dist/lib/providers/mistral.js +5 -8
- package/dist/lib/providers/openAI.js +4 -7
- package/dist/lib/telemetry/index.js +2 -1
- package/dist/lib/utils/logger.d.ts +62 -2
- package/dist/lib/utils/logger.js +174 -9
- package/dist/lib/utils/providerConfig.d.ts +117 -0
- package/dist/lib/utils/providerConfig.js +353 -0
- package/dist/lib/utils/providerUtils.d.ts +2 -1
- package/dist/lib/utils/providerUtils.js +53 -36
- package/dist/lib/utils/timeout.d.ts +72 -1
- package/dist/lib/utils/timeout.js +203 -2
- package/dist/mcp/factory.d.ts +1 -1
- package/dist/mcp/index.d.ts +9 -21
- package/dist/mcp/index.js +16 -57
- package/dist/mcp/registry.js +1 -1
- package/dist/mcp/servers/ai-providers/ai-analysis-tools.js +2 -1
- package/dist/mcp/tool-registry.js +1 -1
- package/dist/neurolink.d.ts +1 -9
- package/dist/neurolink.js +22 -71
- package/dist/providers/amazon-bedrock.js +5 -16
- package/dist/providers/anthropic-baseprovider.js +3 -21
- package/dist/providers/anthropic.js +4 -7
- package/dist/providers/azure-openai.js +6 -3
- package/dist/providers/google-vertex.js +5 -9
- package/dist/providers/huggingFace.js +5 -10
- package/dist/providers/mistral.js +5 -8
- package/dist/providers/openAI.js +4 -7
- package/dist/telemetry/index.js +2 -1
- package/dist/utils/logger.d.ts +62 -2
- package/dist/utils/logger.js +174 -9
- package/dist/utils/providerConfig.d.ts +117 -0
- package/dist/utils/providerConfig.js +353 -0
- package/dist/utils/providerUtils.d.ts +2 -1
- package/dist/utils/providerUtils.js +53 -36
- package/dist/utils/timeout.d.ts +72 -1
- package/dist/utils/timeout.js +203 -2
- package/package.json +1 -1
- package/dist/chat/client-utils.d.ts +0 -95
- package/dist/chat/client-utils.js +0 -315
- package/dist/chat/index.d.ts +0 -24
- package/dist/chat/index.js +0 -33
- package/dist/chat/session-storage.d.ts +0 -77
- package/dist/chat/session-storage.js +0 -233
- package/dist/chat/session.d.ts +0 -96
- package/dist/chat/session.js +0 -257
- package/dist/chat/sse-handler.d.ts +0 -49
- package/dist/chat/sse-handler.js +0 -259
- package/dist/chat/types.d.ts +0 -74
- package/dist/chat/types.js +0 -5
- package/dist/chat/websocket-chat-handler.d.ts +0 -37
- package/dist/chat/websocket-chat-handler.js +0 -262
- package/dist/cli/commands/mcp.d.ts +0 -20
- package/dist/cli/commands/mcp.js +0 -1272
- package/dist/core/defaults.d.ts +0 -19
- package/dist/core/defaults.js +0 -29
- package/dist/core/evaluation-config.d.ts +0 -29
- package/dist/core/evaluation-config.js +0 -144
- package/dist/factories/compatibility-factory.d.ts +0 -35
- package/dist/factories/compatibility-factory.js +0 -71
- package/dist/factories/provider-generate-factory.d.ts +0 -20
- package/dist/factories/provider-generate-factory.js +0 -93
- package/dist/lib/chat/client-utils.d.ts +0 -95
- package/dist/lib/chat/client-utils.js +0 -315
- package/dist/lib/chat/index.d.ts +0 -24
- package/dist/lib/chat/index.js +0 -33
- package/dist/lib/chat/session-storage.d.ts +0 -77
- package/dist/lib/chat/session-storage.js +0 -233
- package/dist/lib/chat/session.d.ts +0 -96
- package/dist/lib/chat/session.js +0 -257
- package/dist/lib/chat/sse-handler.d.ts +0 -49
- package/dist/lib/chat/sse-handler.js +0 -259
- package/dist/lib/chat/types.d.ts +0 -74
- package/dist/lib/chat/types.js +0 -5
- package/dist/lib/chat/websocket-chat-handler.d.ts +0 -37
- package/dist/lib/chat/websocket-chat-handler.js +0 -262
- package/dist/lib/core/defaults.d.ts +0 -19
- package/dist/lib/core/defaults.js +0 -29
- package/dist/lib/core/evaluation-config.d.ts +0 -29
- package/dist/lib/core/evaluation-config.js +0 -144
- package/dist/lib/factories/compatibility-factory.d.ts +0 -35
- package/dist/lib/factories/compatibility-factory.js +0 -71
- package/dist/lib/factories/provider-generate-factory.d.ts +0 -20
- package/dist/lib/factories/provider-generate-factory.js +0 -93
- package/dist/lib/mcp/adapters/plugin-bridge.d.ts +0 -40
- package/dist/lib/mcp/adapters/plugin-bridge.js +0 -89
- package/dist/lib/mcp/auto-discovery.d.ts +0 -62
- package/dist/lib/mcp/auto-discovery.js +0 -149
- package/dist/lib/mcp/client.d.ts +0 -68
- package/dist/lib/mcp/client.js +0 -248
- package/dist/lib/mcp/config.d.ts +0 -31
- package/dist/lib/mcp/config.js +0 -99
- package/dist/lib/mcp/context-manager.d.ts +0 -171
- package/dist/lib/mcp/context-manager.js +0 -362
- package/dist/lib/mcp/contracts/mcp-contract.d.ts +0 -169
- package/dist/lib/mcp/contracts/mcp-contract.js +0 -58
- package/dist/lib/mcp/core/plugin-manager.d.ts +0 -46
- package/dist/lib/mcp/core/plugin-manager.js +0 -110
- package/dist/lib/mcp/demo/plugin-demo.d.ts +0 -20
- package/dist/lib/mcp/demo/plugin-demo.js +0 -118
- package/dist/lib/mcp/dynamic-chain-executor.d.ts +0 -225
- package/dist/lib/mcp/dynamic-chain-executor.js +0 -489
- package/dist/lib/mcp/dynamic-orchestrator.d.ts +0 -115
- package/dist/lib/mcp/dynamic-orchestrator.js +0 -351
- package/dist/lib/mcp/ecosystem.d.ts +0 -75
- package/dist/lib/mcp/ecosystem.js +0 -161
- package/dist/lib/mcp/error-manager.d.ts +0 -254
- package/dist/lib/mcp/error-manager.js +0 -501
- package/dist/lib/mcp/error-recovery.d.ts +0 -159
- package/dist/lib/mcp/error-recovery.js +0 -405
- package/dist/lib/mcp/external-client.d.ts +0 -88
- package/dist/lib/mcp/external-client.js +0 -331
- package/dist/lib/mcp/external-manager.d.ts +0 -112
- package/dist/lib/mcp/external-manager.js +0 -308
- package/dist/lib/mcp/function-calling.d.ts +0 -65
- package/dist/lib/mcp/function-calling.js +0 -642
- package/dist/lib/mcp/health-monitor.d.ts +0 -257
- package/dist/lib/mcp/health-monitor.js +0 -630
- package/dist/lib/mcp/initialize-tools.d.ts +0 -29
- package/dist/lib/mcp/initialize-tools.js +0 -261
- package/dist/lib/mcp/initialize.d.ts +0 -18
- package/dist/lib/mcp/initialize.js +0 -62
- package/dist/lib/mcp/logging.d.ts +0 -38
- package/dist/lib/mcp/logging.js +0 -100
- package/dist/lib/mcp/manager.d.ts +0 -68
- package/dist/lib/mcp/manager.js +0 -176
- package/dist/lib/mcp/neurolink-mcp-client.d.ts +0 -97
- package/dist/lib/mcp/neurolink-mcp-client.js +0 -462
- package/dist/lib/mcp/orchestrator.d.ts +0 -302
- package/dist/lib/mcp/orchestrator.js +0 -703
- package/dist/lib/mcp/plugin-manager.d.ts +0 -98
- package/dist/lib/mcp/plugin-manager.js +0 -296
- package/dist/lib/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
- package/dist/lib/mcp/plugins/core/filesystem-mcp.js +0 -142
- package/dist/lib/mcp/plugins/filesystem-mcp.d.ts +0 -37
- package/dist/lib/mcp/plugins/filesystem-mcp.js +0 -54
- package/dist/lib/mcp/security-manager.d.ts +0 -87
- package/dist/lib/mcp/security-manager.js +0 -344
- package/dist/lib/mcp/semaphore-manager.d.ts +0 -137
- package/dist/lib/mcp/semaphore-manager.js +0 -329
- package/dist/lib/mcp/session-manager.d.ts +0 -187
- package/dist/lib/mcp/session-manager.js +0 -400
- package/dist/lib/mcp/session-persistence.d.ts +0 -93
- package/dist/lib/mcp/session-persistence.js +0 -301
- package/dist/lib/mcp/tool-integration.d.ts +0 -58
- package/dist/lib/mcp/tool-integration.js +0 -203
- package/dist/lib/mcp/transport-manager.d.ts +0 -154
- package/dist/lib/mcp/transport-manager.js +0 -334
- package/dist/lib/mcp/unified-mcp.d.ts +0 -133
- package/dist/lib/mcp/unified-mcp.js +0 -251
- package/dist/lib/mcp/unified-registry.d.ts +0 -165
- package/dist/lib/mcp/unified-registry.js +0 -538
- package/dist/lib/providers/analytics-helper.d.ts +0 -38
- package/dist/lib/providers/analytics-helper.js +0 -216
- package/dist/lib/providers/function-calling-provider.d.ts +0 -142
- package/dist/lib/providers/function-calling-provider.js +0 -630
- package/dist/lib/providers/mcp-provider.d.ts +0 -75
- package/dist/lib/providers/mcp-provider.js +0 -283
- package/dist/lib/providers/timeout-wrapper.d.ts +0 -40
- package/dist/lib/providers/timeout-wrapper.js +0 -100
- package/dist/lib/sdk/tool-extension.d.ts +0 -181
- package/dist/lib/sdk/tool-extension.js +0 -284
- package/dist/lib/services/streaming/streaming-manager.d.ts +0 -29
- package/dist/lib/services/streaming/streaming-manager.js +0 -245
- package/dist/lib/services/types.d.ts +0 -156
- package/dist/lib/services/types.js +0 -2
- package/dist/lib/services/websocket/websocket-server.d.ts +0 -34
- package/dist/lib/services/websocket/websocket-server.js +0 -305
- package/dist/lib/utils/provider-validation.d.ts +0 -36
- package/dist/lib/utils/provider-validation.js +0 -625
- package/dist/lib/utils/providerUtils-fixed.d.ts +0 -8
- package/dist/lib/utils/providerUtils-fixed.js +0 -94
- package/dist/lib/utils/streaming-utils.d.ts +0 -79
- package/dist/lib/utils/streaming-utils.js +0 -198
- package/dist/lib/utils/timeout-manager.d.ts +0 -75
- package/dist/lib/utils/timeout-manager.js +0 -244
- package/dist/mcp/adapters/plugin-bridge.d.ts +0 -40
- package/dist/mcp/adapters/plugin-bridge.js +0 -89
- package/dist/mcp/auto-discovery.d.ts +0 -62
- package/dist/mcp/auto-discovery.js +0 -149
- package/dist/mcp/client.d.ts +0 -68
- package/dist/mcp/client.js +0 -248
- package/dist/mcp/config.d.ts +0 -31
- package/dist/mcp/config.js +0 -99
- package/dist/mcp/context-manager.d.ts +0 -171
- package/dist/mcp/context-manager.js +0 -362
- package/dist/mcp/contracts/mcp-contract.d.ts +0 -169
- package/dist/mcp/contracts/mcp-contract.js +0 -58
- package/dist/mcp/core/plugin-manager.d.ts +0 -46
- package/dist/mcp/core/plugin-manager.js +0 -110
- package/dist/mcp/demo/plugin-demo.d.ts +0 -20
- package/dist/mcp/demo/plugin-demo.js +0 -118
- package/dist/mcp/dynamic-chain-executor.d.ts +0 -225
- package/dist/mcp/dynamic-chain-executor.js +0 -489
- package/dist/mcp/dynamic-orchestrator.d.ts +0 -115
- package/dist/mcp/dynamic-orchestrator.js +0 -351
- package/dist/mcp/ecosystem.d.ts +0 -75
- package/dist/mcp/ecosystem.js +0 -162
- package/dist/mcp/error-manager.d.ts +0 -254
- package/dist/mcp/error-manager.js +0 -501
- package/dist/mcp/error-recovery.d.ts +0 -159
- package/dist/mcp/error-recovery.js +0 -405
- package/dist/mcp/external-client.d.ts +0 -88
- package/dist/mcp/external-client.js +0 -331
- package/dist/mcp/external-manager.d.ts +0 -112
- package/dist/mcp/external-manager.js +0 -308
- package/dist/mcp/function-calling.d.ts +0 -65
- package/dist/mcp/function-calling.js +0 -642
- package/dist/mcp/health-monitor.d.ts +0 -257
- package/dist/mcp/health-monitor.js +0 -630
- package/dist/mcp/initialize-tools.d.ts +0 -29
- package/dist/mcp/initialize-tools.js +0 -262
- package/dist/mcp/initialize.d.ts +0 -18
- package/dist/mcp/initialize.js +0 -62
- package/dist/mcp/logging.d.ts +0 -38
- package/dist/mcp/logging.js +0 -100
- package/dist/mcp/manager.d.ts +0 -68
- package/dist/mcp/manager.js +0 -176
- package/dist/mcp/neurolink-mcp-client.d.ts +0 -97
- package/dist/mcp/neurolink-mcp-client.js +0 -462
- package/dist/mcp/orchestrator.d.ts +0 -302
- package/dist/mcp/orchestrator.js +0 -703
- package/dist/mcp/plugin-manager.d.ts +0 -98
- package/dist/mcp/plugin-manager.js +0 -297
- package/dist/mcp/plugins/core/filesystem-mcp.d.ts +0 -36
- package/dist/mcp/plugins/core/filesystem-mcp.js +0 -142
- package/dist/mcp/plugins/core/neurolink-mcp.json +0 -17
- package/dist/mcp/plugins/filesystem-mcp.d.ts +0 -37
- package/dist/mcp/plugins/filesystem-mcp.js +0 -54
- package/dist/mcp/security-manager.d.ts +0 -87
- package/dist/mcp/security-manager.js +0 -344
- package/dist/mcp/semaphore-manager.d.ts +0 -137
- package/dist/mcp/semaphore-manager.js +0 -329
- package/dist/mcp/session-manager.d.ts +0 -187
- package/dist/mcp/session-manager.js +0 -400
- package/dist/mcp/session-persistence.d.ts +0 -93
- package/dist/mcp/session-persistence.js +0 -302
- package/dist/mcp/tool-integration.d.ts +0 -58
- package/dist/mcp/tool-integration.js +0 -203
- package/dist/mcp/transport-manager.d.ts +0 -154
- package/dist/mcp/transport-manager.js +0 -335
- package/dist/mcp/unified-mcp.d.ts +0 -133
- package/dist/mcp/unified-mcp.js +0 -251
- package/dist/mcp/unified-registry.d.ts +0 -165
- package/dist/mcp/unified-registry.js +0 -539
- package/dist/providers/analytics-helper.d.ts +0 -38
- package/dist/providers/analytics-helper.js +0 -216
- package/dist/providers/function-calling-provider.d.ts +0 -142
- package/dist/providers/function-calling-provider.js +0 -630
- package/dist/providers/mcp-provider.d.ts +0 -75
- package/dist/providers/mcp-provider.js +0 -283
- package/dist/providers/timeout-wrapper.d.ts +0 -40
- package/dist/providers/timeout-wrapper.js +0 -100
- package/dist/sdk/tool-extension.d.ts +0 -181
- package/dist/sdk/tool-extension.js +0 -284
- package/dist/services/streaming/streaming-manager.d.ts +0 -29
- package/dist/services/streaming/streaming-manager.js +0 -245
- package/dist/services/types.d.ts +0 -156
- package/dist/services/types.js +0 -2
- package/dist/services/websocket/websocket-server.d.ts +0 -34
- package/dist/services/websocket/websocket-server.js +0 -306
- package/dist/utils/provider-validation.d.ts +0 -36
- package/dist/utils/provider-validation.js +0 -625
- package/dist/utils/providerUtils-fixed.d.ts +0 -8
- package/dist/utils/providerUtils-fixed.js +0 -94
- package/dist/utils/streaming-utils.d.ts +0 -79
- package/dist/utils/streaming-utils.js +0 -198
- package/dist/utils/timeout-manager.d.ts +0 -75
- package/dist/utils/timeout-manager.js +0 -244
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Security Manager - Permission-Based Sandbox for MCP Operations
|
|
3
|
-
* Implements the research blueprint's security-by-design principles
|
|
4
|
-
*/
|
|
5
|
-
import type { Stats } from "fs";
|
|
6
|
-
import type { UnknownRecord } from "../types/common.js";
|
|
7
|
-
import type { ExecutionContext } from "./contracts/mcp-contract.js";
|
|
8
|
-
/**
|
|
9
|
-
* Security levels for plugin execution
|
|
10
|
-
*/
|
|
11
|
-
export type SecurityLevel = "strict" | "moderate" | "permissive";
|
|
12
|
-
/**
|
|
13
|
-
* Permission types supported by the security system
|
|
14
|
-
*/
|
|
15
|
-
export interface Permission {
|
|
16
|
-
type: "fs" | "net" | "process" | "env";
|
|
17
|
-
action: string;
|
|
18
|
-
resource: string;
|
|
19
|
-
}
|
|
20
|
-
/**
|
|
21
|
-
* Security Manager implementing permission-based sandbox
|
|
22
|
-
*/
|
|
23
|
-
export declare class SecurityManager {
|
|
24
|
-
private securityLevel;
|
|
25
|
-
private allowedBasePaths;
|
|
26
|
-
private deniedPaths;
|
|
27
|
-
constructor(securityLevel?: SecurityLevel);
|
|
28
|
-
/**
|
|
29
|
-
* Initialize default security boundaries based on level
|
|
30
|
-
*/
|
|
31
|
-
private initializeSecurityBoundaries;
|
|
32
|
-
/**
|
|
33
|
-
* Validate permissions array from manifest
|
|
34
|
-
*/
|
|
35
|
-
validatePermissions(permissions: string[]): boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Parse permission string into structured format
|
|
38
|
-
*/
|
|
39
|
-
private parsePermission;
|
|
40
|
-
/**
|
|
41
|
-
* Check if a permission is allowed based on security level
|
|
42
|
-
*/
|
|
43
|
-
private isPermissionAllowed;
|
|
44
|
-
/**
|
|
45
|
-
* Validate filesystem permissions
|
|
46
|
-
*/
|
|
47
|
-
private isFileSystemPermissionAllowed;
|
|
48
|
-
/**
|
|
49
|
-
* Check if filesystem action is allowed
|
|
50
|
-
*/
|
|
51
|
-
private isFileSystemActionAllowed;
|
|
52
|
-
/**
|
|
53
|
-
* Validate network permissions
|
|
54
|
-
*/
|
|
55
|
-
private isNetworkPermissionAllowed;
|
|
56
|
-
/**
|
|
57
|
-
* Validate process permissions
|
|
58
|
-
*/
|
|
59
|
-
private isProcessPermissionAllowed;
|
|
60
|
-
/**
|
|
61
|
-
* Validate environment permissions
|
|
62
|
-
*/
|
|
63
|
-
private isEnvironmentPermissionAllowed;
|
|
64
|
-
/**
|
|
65
|
-
* Create a secure filesystem interface for ExecutionContext
|
|
66
|
-
*/
|
|
67
|
-
createSecureFS(grantedPermissions: string[], basePath?: string): {
|
|
68
|
-
readFile(filePath: string, encoding?: string): Promise<string | Buffer>;
|
|
69
|
-
writeFile(filePath: string, content: string | Buffer): Promise<void>;
|
|
70
|
-
readdir(dirPath: string): Promise<string[]>;
|
|
71
|
-
stat(filePath: string): Promise<Stats>;
|
|
72
|
-
mkdir(dirPath: string, options?: UnknownRecord): Promise<void>;
|
|
73
|
-
exists(filePath: string): Promise<boolean>;
|
|
74
|
-
};
|
|
75
|
-
/**
|
|
76
|
-
* Check filesystem permission against granted permissions
|
|
77
|
-
*/
|
|
78
|
-
private checkFileSystemPermission;
|
|
79
|
-
/**
|
|
80
|
-
* Check if permission matches wildcard pattern
|
|
81
|
-
*/
|
|
82
|
-
private matchesWildcardPermission;
|
|
83
|
-
/**
|
|
84
|
-
* Create execution context with security sandbox
|
|
85
|
-
*/
|
|
86
|
-
createExecutionContext(sessionId: string, userId: string, grantedPermissions: string[], basePath?: string): ExecutionContext;
|
|
87
|
-
}
|
|
@@ -1,344 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* NeuroLink MCP Semaphore Manager
|
|
3
|
-
* Prevents race conditions in concurrent tool executions using a robust semaphore pattern
|
|
4
|
-
* Based on proven patterns from 1MCP reference implementation
|
|
5
|
-
*/
|
|
6
|
-
import type { NeuroLinkExecutionContext } from "./factory.js";
|
|
7
|
-
/**
|
|
8
|
-
* Semaphore operation result
|
|
9
|
-
*/
|
|
10
|
-
export interface SemaphoreResult<T> {
|
|
11
|
-
success: boolean;
|
|
12
|
-
result?: T;
|
|
13
|
-
error?: Error;
|
|
14
|
-
waitTime: number;
|
|
15
|
-
executionTime: number;
|
|
16
|
-
queueDepth: number;
|
|
17
|
-
}
|
|
18
|
-
/**
|
|
19
|
-
* Semaphore statistics
|
|
20
|
-
*/
|
|
21
|
-
export interface SemaphoreStats {
|
|
22
|
-
activeOperations: number;
|
|
23
|
-
queuedOperations: number;
|
|
24
|
-
totalOperations: number;
|
|
25
|
-
totalWaitTime: number;
|
|
26
|
-
averageWaitTime: number;
|
|
27
|
-
peakQueueDepth: number;
|
|
28
|
-
lastActivity: number;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Semaphore Manager for concurrent operation control
|
|
32
|
-
* Implements the proven semaphore pattern from 1MCP to prevent race conditions
|
|
33
|
-
*/
|
|
34
|
-
export declare class SemaphoreManager {
|
|
35
|
-
private locks;
|
|
36
|
-
private queues;
|
|
37
|
-
private stats;
|
|
38
|
-
private globalStats;
|
|
39
|
-
/**
|
|
40
|
-
* Acquire a semaphore and execute an operation
|
|
41
|
-
* Ensures exclusive access to resources identified by the key
|
|
42
|
-
*
|
|
43
|
-
* @param key Unique identifier for the resource
|
|
44
|
-
* @param operation Async operation to execute with exclusive access
|
|
45
|
-
* @param context Optional execution context for enhanced tracking
|
|
46
|
-
* @returns Result of the operation with timing metrics
|
|
47
|
-
*/
|
|
48
|
-
acquire<T>(key: string, operation: () => Promise<T>, context?: NeuroLinkExecutionContext): Promise<SemaphoreResult<T>>;
|
|
49
|
-
/**
|
|
50
|
-
* Try to acquire a semaphore without waiting
|
|
51
|
-
* Returns immediately if the resource is locked
|
|
52
|
-
*
|
|
53
|
-
* @param key Unique identifier for the resource
|
|
54
|
-
* @param operation Async operation to execute if lock is available
|
|
55
|
-
* @param context Optional execution context
|
|
56
|
-
* @returns Result of the operation or null if resource is locked
|
|
57
|
-
*/
|
|
58
|
-
tryAcquire<T>(key: string, operation: () => Promise<T>, context?: NeuroLinkExecutionContext): Promise<SemaphoreResult<T> | null>;
|
|
59
|
-
/**
|
|
60
|
-
* Check if a resource is currently locked
|
|
61
|
-
*
|
|
62
|
-
* @param key Resource identifier
|
|
63
|
-
* @returns True if the resource is locked
|
|
64
|
-
*/
|
|
65
|
-
isLocked(key: string): boolean;
|
|
66
|
-
/**
|
|
67
|
-
* Get the current queue depth for a resource
|
|
68
|
-
*
|
|
69
|
-
* @param key Resource identifier
|
|
70
|
-
* @returns Number of operations waiting for this resource
|
|
71
|
-
*/
|
|
72
|
-
getQueueDepth(key: string): number;
|
|
73
|
-
/**
|
|
74
|
-
* Get statistics for a specific resource or global stats
|
|
75
|
-
*
|
|
76
|
-
* @param key Optional resource identifier
|
|
77
|
-
* @returns Semaphore statistics
|
|
78
|
-
*/
|
|
79
|
-
getStats(key?: string): SemaphoreStats;
|
|
80
|
-
/**
|
|
81
|
-
* Clear all semaphores (use with caution)
|
|
82
|
-
* This will reject all pending operations
|
|
83
|
-
*/
|
|
84
|
-
clearAll(): void;
|
|
85
|
-
/**
|
|
86
|
-
* Update queue depth statistics
|
|
87
|
-
*
|
|
88
|
-
* @private
|
|
89
|
-
*/
|
|
90
|
-
private updateQueueDepth;
|
|
91
|
-
/**
|
|
92
|
-
* Increment active operations counter
|
|
93
|
-
*
|
|
94
|
-
* @private
|
|
95
|
-
*/
|
|
96
|
-
private incrementActiveOperations;
|
|
97
|
-
/**
|
|
98
|
-
* Decrement active operations counter
|
|
99
|
-
*
|
|
100
|
-
* @private
|
|
101
|
-
*/
|
|
102
|
-
private decrementActiveOperations;
|
|
103
|
-
/**
|
|
104
|
-
* Update timing statistics
|
|
105
|
-
*
|
|
106
|
-
* @private
|
|
107
|
-
*/
|
|
108
|
-
private updateStats;
|
|
109
|
-
/**
|
|
110
|
-
* Create empty statistics object
|
|
111
|
-
*
|
|
112
|
-
* @private
|
|
113
|
-
*/
|
|
114
|
-
private createEmptyStats;
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Default semaphore manager instance
|
|
118
|
-
*/
|
|
119
|
-
export declare const defaultSemaphoreManager: SemaphoreManager;
|
|
120
|
-
/**
|
|
121
|
-
* Utility function to acquire semaphore with default manager
|
|
122
|
-
*
|
|
123
|
-
* @param key Resource identifier
|
|
124
|
-
* @param operation Operation to execute
|
|
125
|
-
* @param context Optional execution context
|
|
126
|
-
* @returns Operation result with metrics
|
|
127
|
-
*/
|
|
128
|
-
export declare function acquireSemaphore<T>(key: string, operation: () => Promise<T>, context?: NeuroLinkExecutionContext): Promise<SemaphoreResult<T>>;
|
|
129
|
-
/**
|
|
130
|
-
* Utility function to try acquiring semaphore without waiting
|
|
131
|
-
*
|
|
132
|
-
* @param key Resource identifier
|
|
133
|
-
* @param operation Operation to execute
|
|
134
|
-
* @param context Optional execution context
|
|
135
|
-
* @returns Operation result or null if locked
|
|
136
|
-
*/
|
|
137
|
-
export declare function tryAcquireSemaphore<T>(key: string, operation: () => Promise<T>, context?: NeuroLinkExecutionContext): Promise<SemaphoreResult<T> | null>;
|