sovr-mcp-proxy 7.0.0 → 7.2.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.
@@ -0,0 +1,256 @@
1
+ /**
2
+ * SOVR MCP Proxy Interceptor — Universal Tool Call Interception
3
+ *
4
+ * P1-1: SOVR sits between the MCP client (LLM) and the MCP server (tools),
5
+ * intercepting ALL tool calls regardless of transport (stdio/SSE/HTTP).
6
+ *
7
+ * Architecture:
8
+ * [LLM Client] → [SOVR Proxy] → [Upstream MCP Server]
9
+ * ↓
10
+ * [Policy Engine]
11
+ * [Audit Trail]
12
+ * [Rate Limiter]
13
+ * [Semantic Analyzer]
14
+ *
15
+ * Unlike Tool Replacement (which replaces tools), this module transparently
16
+ * proxies ALL tools and applies policies at the protocol level.
17
+ */
18
+ interface InterceptorConfig {
19
+ /** Policy mode: block | warn | audit-only */
20
+ mode: 'block' | 'warn' | 'audit';
21
+ /** Maximum concurrent tool calls */
22
+ maxConcurrent: number;
23
+ /** Per-tool rate limits (calls per minute) */
24
+ rateLimits: Record<string, number>;
25
+ /** Global rate limit (calls per minute) */
26
+ globalRateLimit: number;
27
+ /** Tool-specific policies */
28
+ toolPolicies: ToolPolicy[];
29
+ /** Enable semantic analysis for tool arguments */
30
+ enableSemanticAnalysis: boolean;
31
+ /** Callback for human approval */
32
+ onApprovalRequired?: (request: InterceptedCall) => Promise<ApprovalResult>;
33
+ /** Callback for audit events */
34
+ onAuditEvent?: (event: AuditEvent) => void;
35
+ /** Timeout for upstream tool calls (ms) */
36
+ upstreamTimeout: number;
37
+ /** Max retries for transient failures */
38
+ maxRetries: number;
39
+ }
40
+ interface ToolPolicy {
41
+ /** Tool name pattern (glob) */
42
+ toolPattern: string;
43
+ /** Action to take */
44
+ action: 'allow' | 'block' | 'require-approval' | 'rate-limit' | 'transform';
45
+ /** Conditions for this policy */
46
+ conditions?: PolicyCondition[];
47
+ /** Argument transformations (for 'transform' action) */
48
+ transforms?: ArgumentTransform[];
49
+ /** Priority (higher = evaluated first) */
50
+ priority: number;
51
+ /** Human-readable description */
52
+ description: string;
53
+ }
54
+ interface PolicyCondition {
55
+ /** Field path in tool arguments (dot notation) */
56
+ field: string;
57
+ /** Operator */
58
+ operator: 'contains' | 'matches' | 'equals' | 'gt' | 'lt' | 'exists' | 'not-exists';
59
+ /** Value to compare against */
60
+ value: string | number | boolean;
61
+ }
62
+ interface ArgumentTransform {
63
+ /** Field path to transform */
64
+ field: string;
65
+ /** Transform type */
66
+ type: 'redact' | 'mask' | 'replace' | 'remove';
67
+ /** Replacement value (for 'replace') */
68
+ replacement?: string;
69
+ }
70
+ interface InterceptedCall {
71
+ /** Unique call ID */
72
+ id: string;
73
+ /** Timestamp */
74
+ timestamp: number;
75
+ /** Tool name */
76
+ toolName: string;
77
+ /** Original arguments */
78
+ arguments: Record<string, unknown>;
79
+ /** Matched policies */
80
+ matchedPolicies: ToolPolicy[];
81
+ /** Decision */
82
+ decision: InterceptDecision;
83
+ /** Semantic analysis result (if enabled) */
84
+ semanticResult?: SemanticAnalysisResult;
85
+ }
86
+ interface InterceptDecision {
87
+ /** Final action */
88
+ action: 'allow' | 'block' | 'require-approval' | 'transform';
89
+ /** Reason for decision */
90
+ reason: string;
91
+ /** Policy that triggered this decision */
92
+ triggeringPolicy?: ToolPolicy;
93
+ /** Risk score (0-100) */
94
+ riskScore: number;
95
+ /** Transformed arguments (if action is 'transform') */
96
+ transformedArguments?: Record<string, unknown>;
97
+ }
98
+ interface SemanticAnalysisResult {
99
+ /** Detected intent */
100
+ intent: string;
101
+ /** Risk category */
102
+ riskCategory: 'safe' | 'suspicious' | 'dangerous' | 'critical';
103
+ /** Confidence (0-1) */
104
+ confidence: number;
105
+ /** Explanation */
106
+ explanation: string;
107
+ }
108
+ interface ApprovalResult {
109
+ approved: boolean;
110
+ approver?: string;
111
+ reason?: string;
112
+ timestamp: number;
113
+ }
114
+ interface AuditEvent {
115
+ id: string;
116
+ timestamp: number;
117
+ type: 'intercept' | 'allow' | 'block' | 'approval-requested' | 'approval-granted' | 'approval-denied' | 'error' | 'rate-limited';
118
+ toolName: string;
119
+ arguments: Record<string, unknown>;
120
+ decision: InterceptDecision;
121
+ duration?: number;
122
+ error?: string;
123
+ upstreamResult?: unknown;
124
+ }
125
+ interface InterceptorStats {
126
+ totalCalls: number;
127
+ allowed: number;
128
+ blocked: number;
129
+ approvalRequested: number;
130
+ rateLimited: number;
131
+ errors: number;
132
+ avgLatencyMs: number;
133
+ callsByTool: Record<string, number>;
134
+ blocksByPolicy: Record<string, number>;
135
+ riskDistribution: {
136
+ safe: number;
137
+ suspicious: number;
138
+ dangerous: number;
139
+ critical: number;
140
+ };
141
+ }
142
+ declare class McpProxyInterceptor {
143
+ private config;
144
+ private rateLimiter;
145
+ private stats;
146
+ private auditLog;
147
+ private maxAuditLogSize;
148
+ private activeCalls;
149
+ private cleanupInterval;
150
+ constructor(config?: Partial<InterceptorConfig>);
151
+ /**
152
+ * Intercept a tool call — the core entry point.
153
+ * Returns the decision and optionally transformed arguments.
154
+ */
155
+ intercept(toolName: string, args: Record<string, unknown>): Promise<InterceptedCall>;
156
+ /**
157
+ * Wrap an upstream tool call with interception.
158
+ * If allowed, executes the upstream function; if blocked, returns error.
159
+ */
160
+ wrapToolCall<T>(toolName: string, args: Record<string, unknown>, upstream: (args: Record<string, unknown>) => Promise<T>): Promise<{
161
+ result?: T;
162
+ intercepted: InterceptedCall;
163
+ error?: string;
164
+ }>;
165
+ /** Get current statistics */
166
+ getStats(): InterceptorStats;
167
+ /** Get recent audit log */
168
+ getAuditLog(limit?: number): AuditEvent[];
169
+ /** Export audit log as CSV */
170
+ exportAuditCSV(): string;
171
+ /** Add a policy at runtime */
172
+ addPolicy(policy: ToolPolicy): void;
173
+ /** Remove policies matching a pattern */
174
+ removePolicies(toolPattern: string): number;
175
+ /** Reset statistics */
176
+ resetStats(): void;
177
+ /** Cleanup resources */
178
+ destroy(): void;
179
+ private emitAudit;
180
+ private trimAuditLog;
181
+ }
182
+ declare const PRESET_POLICIES: {
183
+ /** Block all destructive file operations */
184
+ noDestructiveFiles: {
185
+ toolPattern: string;
186
+ action: "block";
187
+ conditions: {
188
+ field: string;
189
+ operator: "matches";
190
+ value: string;
191
+ }[];
192
+ priority: number;
193
+ description: string;
194
+ };
195
+ /** Block all database write operations */
196
+ readOnlyDatabase: {
197
+ toolPattern: string;
198
+ action: "block";
199
+ conditions: {
200
+ field: string;
201
+ operator: "matches";
202
+ value: string;
203
+ }[];
204
+ priority: number;
205
+ description: string;
206
+ };
207
+ /** Require approval for payment operations */
208
+ approvePayments: {
209
+ toolPattern: string;
210
+ action: "require-approval";
211
+ priority: number;
212
+ description: string;
213
+ };
214
+ /** Redact secrets in tool arguments */
215
+ redactSecrets: {
216
+ toolPattern: string;
217
+ action: "transform";
218
+ conditions: {
219
+ field: string;
220
+ operator: "matches";
221
+ value: string;
222
+ }[];
223
+ transforms: ({
224
+ field: string;
225
+ type: "redact";
226
+ } | {
227
+ field: string;
228
+ type: "mask";
229
+ })[];
230
+ priority: number;
231
+ description: string;
232
+ };
233
+ /** Rate limit shell commands */
234
+ rateLimitShell: {
235
+ toolPattern: string;
236
+ action: "rate-limit";
237
+ priority: number;
238
+ description: string;
239
+ };
240
+ /** Allow read-only operations */
241
+ allowReadOnly: {
242
+ toolPattern: string;
243
+ action: "allow";
244
+ conditions: {
245
+ field: string;
246
+ operator: "matches";
247
+ value: string;
248
+ }[];
249
+ priority: number;
250
+ description: string;
251
+ };
252
+ };
253
+ /** Create a pre-configured interceptor with common security policies */
254
+ declare function createSecureInterceptor(overrides?: Partial<InterceptorConfig>): McpProxyInterceptor;
255
+
256
+ export { type ApprovalResult, type ArgumentTransform, type AuditEvent, type InterceptDecision, type InterceptedCall, type InterceptorConfig, type InterceptorStats, McpProxyInterceptor, PRESET_POLICIES, type PolicyCondition, type SemanticAnalysisResult, type ToolPolicy, createSecureInterceptor };