contextguard 0.1.8 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +23 -17
  2. package/README.md +157 -109
  3. package/dist/agent.d.ts +24 -0
  4. package/dist/agent.js +376 -0
  5. package/dist/cli.d.ts +11 -0
  6. package/dist/cli.js +298 -0
  7. package/dist/config.d.ts +23 -0
  8. package/dist/config.js +56 -0
  9. package/dist/database.d.ts +116 -0
  10. package/dist/database.js +291 -0
  11. package/dist/index.d.ts +16 -0
  12. package/dist/index.js +18 -0
  13. package/dist/init.d.ts +7 -0
  14. package/dist/init.js +178 -0
  15. package/dist/lib/supabase-client.d.ts +27 -0
  16. package/dist/lib/supabase-client.js +97 -0
  17. package/dist/logger.d.ts +36 -0
  18. package/dist/logger.js +145 -0
  19. package/dist/mcp-security-wrapper.d.ts +84 -0
  20. package/dist/mcp-security-wrapper.js +389 -147
  21. package/dist/mcp-traceability-integration.d.ts +118 -0
  22. package/dist/mcp-traceability-integration.js +302 -0
  23. package/dist/policy.d.ts +30 -0
  24. package/dist/policy.js +273 -0
  25. package/dist/premium-features.d.ts +364 -0
  26. package/dist/premium-features.js +950 -0
  27. package/dist/security-logger.d.ts +45 -0
  28. package/dist/security-logger.js +125 -0
  29. package/dist/security-policy.d.ts +55 -0
  30. package/dist/security-policy.js +140 -0
  31. package/dist/semantic-detector.d.ts +21 -0
  32. package/dist/semantic-detector.js +49 -0
  33. package/dist/sse-proxy.d.ts +21 -0
  34. package/dist/sse-proxy.js +276 -0
  35. package/dist/supabase-client.d.ts +27 -0
  36. package/dist/supabase-client.js +89 -0
  37. package/dist/types/database.types.d.ts +220 -0
  38. package/dist/types/database.types.js +8 -0
  39. package/dist/types/mcp.d.ts +27 -0
  40. package/dist/types/mcp.js +15 -0
  41. package/dist/types/types.d.ts +65 -0
  42. package/dist/types/types.js +8 -0
  43. package/dist/types.d.ts +84 -0
  44. package/dist/types.js +8 -0
  45. package/dist/wrapper.d.ts +115 -0
  46. package/dist/wrapper.js +417 -0
  47. package/package.json +35 -11
  48. package/.github/ISSUE_TEMPLATE/bug_report.md +0 -57
  49. package/CONTRIBUTING.md +0 -532
  50. package/SECURITY.md +0 -254
  51. package/assets/demo.mp4 +0 -0
  52. package/eslint.config.mts +0 -23
  53. package/examples/config/config.json +0 -19
  54. package/examples/mcp-server/demo.js +0 -228
  55. package/examples/mcp-server/package-lock.json +0 -978
  56. package/examples/mcp-server/package.json +0 -16
  57. package/examples/mcp-server/pnpm-lock.yaml +0 -745
  58. package/src/mcp-security-wrapper.ts +0 -570
  59. package/test/test-server.ts +0 -295
  60. package/tsconfig.json +0 -16
package/dist/init.js ADDED
@@ -0,0 +1,178 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Amir Mironi
4
+ *
5
+ * contextguard init — automatically patch claude_desktop_config.json
6
+ * so that every MCP server is wrapped with ContextGuard.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.runInit = runInit;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const os = __importStar(require("os"));
46
+ // ── Config file detection ────────────────────────────────────────────────────
47
+ function findConfigPath() {
48
+ const home = os.homedir();
49
+ let candidates = [];
50
+ switch (process.platform) {
51
+ case "darwin":
52
+ candidates = [
53
+ path.join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json"),
54
+ ];
55
+ break;
56
+ case "win32":
57
+ candidates = [
58
+ path.join(process.env.APPDATA ?? path.join(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json"),
59
+ ];
60
+ break;
61
+ default: // Linux
62
+ candidates = [
63
+ path.join(home, ".config", "Claude", "claude_desktop_config.json"),
64
+ path.join(home, ".config", "claude", "claude_desktop_config.json"),
65
+ ];
66
+ }
67
+ return candidates.find((p) => fs.existsSync(p)) ?? null;
68
+ }
69
+ // ── Wrapping helpers ─────────────────────────────────────────────────────────
70
+ function isAlreadyWrapped(server) {
71
+ if (server.command === "npx" && server.args?.[1] === "contextguard") {
72
+ return true;
73
+ }
74
+ if (server.command === "contextguard") {
75
+ return true;
76
+ }
77
+ return false;
78
+ }
79
+ /**
80
+ * Wrap an MCP server entry:
81
+ * { command, args } → { command: "npx", args: ["-y", "contextguard", "--", <original command+args>] }
82
+ */
83
+ function wrapServer(server, apiKey) {
84
+ const originalCmd = [server.command, ...(server.args ?? [])];
85
+ return {
86
+ command: "npx",
87
+ args: ["-y", "contextguard", "--", ...originalCmd],
88
+ env: {
89
+ ...server.env,
90
+ CONTEXTGUARD_API_KEY: apiKey,
91
+ },
92
+ };
93
+ }
94
+ function parseInitArgs(argv) {
95
+ let apiKey = "";
96
+ let configPath;
97
+ let dryRun = false;
98
+ for (let i = 0; i < argv.length; i++) {
99
+ const arg = argv[i];
100
+ if ((arg === "--api-key" || arg === "-k") && argv[i + 1]) {
101
+ apiKey = argv[++i];
102
+ }
103
+ else if ((arg === "--config" || arg === "-c") && argv[i + 1]) {
104
+ configPath = argv[++i];
105
+ }
106
+ else if (arg === "--dry-run") {
107
+ dryRun = true;
108
+ }
109
+ }
110
+ return { apiKey, configPath, dryRun };
111
+ }
112
+ // ── Main ─────────────────────────────────────────────────────────────────────
113
+ function runInit(argv) {
114
+ const { apiKey, configPath: customPath, dryRun } = parseInitArgs(argv);
115
+ if (!apiKey) {
116
+ console.error("\n❌ Missing required argument: --api-key <key>\n" +
117
+ " Get your key from the ContextGuard dashboard → Settings → API Keys\n");
118
+ process.exit(1);
119
+ }
120
+ // Locate config
121
+ const configPath = customPath ?? findConfigPath();
122
+ if (!configPath) {
123
+ console.error("\n❌ Could not find claude_desktop_config.json.\n" +
124
+ " Is Claude Desktop installed? Or specify the path with --config <path>\n");
125
+ process.exit(1);
126
+ }
127
+ console.log(`\n🔍 Config found: ${configPath}`);
128
+ // Read and parse
129
+ let config;
130
+ try {
131
+ config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
132
+ }
133
+ catch (err) {
134
+ console.error(`\n❌ Failed to parse config: ${configPath}`);
135
+ console.error(` Error: ${err instanceof Error ? err.message : String(err)}\n`);
136
+ process.exit(1);
137
+ }
138
+ const servers = { ...(config.mcpServers ?? {}) };
139
+ const names = Object.keys(servers);
140
+ if (names.length === 0) {
141
+ console.log("\n⚠️ No MCP servers found in config — nothing to wrap.\n");
142
+ process.exit(0);
143
+ }
144
+ console.log(`\n📋 Found ${names.length} MCP server(s):\n`);
145
+ let wrapped = 0;
146
+ let skipped = 0;
147
+ for (const [name, server] of Object.entries(servers)) {
148
+ if (isAlreadyWrapped(server)) {
149
+ console.log(` ⏭ ${name} (already wrapped, skipping)`);
150
+ skipped++;
151
+ }
152
+ else {
153
+ servers[name] = wrapServer(server, apiKey);
154
+ console.log(` ✅ ${name} → wrapped`);
155
+ wrapped++;
156
+ }
157
+ }
158
+ console.log(`\n📝 ${wrapped} wrapped, ${skipped} already configured.\n`);
159
+ if (wrapped === 0) {
160
+ console.log("✨ Nothing to do — all servers are already protected.\n");
161
+ process.exit(0);
162
+ }
163
+ const updated = { ...config, mcpServers: servers };
164
+ if (dryRun) {
165
+ console.log("⚠️ --dry-run: no changes written. Preview:\n");
166
+ console.log(JSON.stringify(updated, null, 2));
167
+ process.exit(0);
168
+ }
169
+ // Backup
170
+ const backupPath = configPath + ".bak";
171
+ fs.copyFileSync(configPath, backupPath);
172
+ console.log(`💾 Backup saved: ${backupPath}`);
173
+ // Write
174
+ fs.writeFileSync(configPath, JSON.stringify(updated, null, 2) + "\n", "utf-8");
175
+ console.log(`✅ Config updated: ${configPath}`);
176
+ console.log("\n🚀 Done! Restart Claude Desktop to activate ContextGuard.\n" +
177
+ " Dashboard: https://contextguard.dev/dashboard\n");
178
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Copyright (c) 2026 Amir Mironi
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import type { AgentPolicyRow, SecurityEventRow } from "../types/database.types";
8
+ /**
9
+ * Supabase configuration
10
+ */
11
+ export interface SupabaseConfig {
12
+ url: string;
13
+ serviceKey: string;
14
+ agentId?: string;
15
+ }
16
+ /**
17
+ * Supabase client for agent-dashboard communication
18
+ */
19
+ export interface SupabaseClient {
20
+ reportEvent: (event: SecurityEventRow) => Promise<void>;
21
+ fetchPolicy: (agentId: string) => Promise<AgentPolicyRow | null>;
22
+ updateAgentStatus: (agentId: string, status: string) => Promise<void>;
23
+ }
24
+ /**
25
+ * Create a Supabase client
26
+ */
27
+ export declare const createSupabaseClient: (config: SupabaseConfig) => SupabaseClient;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Amir Mironi
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.createSupabaseClient = void 0;
10
+ const supabase_js_1 = require("@supabase/supabase-js");
11
+ /**
12
+ * Create a Supabase client
13
+ */
14
+ const createSupabaseClient = (config) => {
15
+ const { url, serviceKey } = config;
16
+ // Create Supabase client using the official SDK
17
+ const supabase = (0, supabase_js_1.createClient)(url, serviceKey, {
18
+ auth: {
19
+ persistSession: false,
20
+ autoRefreshToken: false,
21
+ },
22
+ });
23
+ return {
24
+ /**
25
+ * Report a security event to Supabase
26
+ */
27
+ reportEvent: async (event) => {
28
+ try {
29
+ const eventData = {
30
+ agent_id: config.agentId || "unknown",
31
+ event_type: event.event_type,
32
+ severity: event.severity,
33
+ details: event.details,
34
+ session_id: event.session_id,
35
+ timestamp: event.timestamp,
36
+ };
37
+ const { error } = await supabase
38
+ .from("events")
39
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
40
+ .insert(eventData);
41
+ if (error) {
42
+ console.error("Failed to report event to Supabase:", error);
43
+ }
44
+ }
45
+ catch (error) {
46
+ console.error("Failed to report event to Supabase:", error);
47
+ // Don't throw - we don't want to break the agent if reporting fails
48
+ }
49
+ },
50
+ /**
51
+ * Fetch policy configuration for an agent
52
+ */
53
+ fetchPolicy: async (agentId) => {
54
+ try {
55
+ const { data, error } = await supabase
56
+ .from("policies")
57
+ .select("*")
58
+ .eq("agent_id", agentId)
59
+ .single();
60
+ if (error) {
61
+ console.error("Failed to fetch policy from Supabase:", error);
62
+ return null;
63
+ }
64
+ return data || null;
65
+ }
66
+ catch (error) {
67
+ console.error("Failed to fetch policy from Supabase:", error);
68
+ return null;
69
+ }
70
+ },
71
+ /**
72
+ * Update agent status
73
+ */
74
+ updateAgentStatus: async (agentId, status) => {
75
+ try {
76
+ const statusData = {
77
+ agent_id: agentId,
78
+ status: status,
79
+ last_heartbeat: new Date().toISOString(),
80
+ };
81
+ const { error } = await supabase
82
+ .from("agents")
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ .upsert(statusData, {
85
+ onConflict: "agent_id",
86
+ });
87
+ if (error) {
88
+ console.error("Failed to update agent status:", error);
89
+ }
90
+ }
91
+ catch (error) {
92
+ console.error("Failed to update agent status:", error);
93
+ }
94
+ },
95
+ };
96
+ };
97
+ exports.createSupabaseClient = createSupabaseClient;
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Copyright (c) 2026 Amir Mironi
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+ import { SupabaseClient } from "./lib/supabase-client";
8
+ import { SecurityEventRow, SecuritySeverity } from "./types/database.types";
9
+ /**
10
+ * Security statistics interface
11
+ */
12
+ export interface SecurityStatistics {
13
+ totalEvents: number;
14
+ eventsByType: Record<string, number>;
15
+ eventsBySeverity: Record<string, number>;
16
+ recentEvents: SecurityEventRow[];
17
+ }
18
+ /**
19
+ * Logger interface
20
+ */
21
+ export interface Logger {
22
+ logEvent: (eventType: string, severity: SecuritySeverity, details: Record<string, unknown>, sessionId: string) => void;
23
+ getStatistics: () => SecurityStatistics;
24
+ clearEvents: () => void;
25
+ getAllEvents: () => SecurityEventRow[];
26
+ }
27
+ /**
28
+ * Create a security event logger
29
+ * @param logFile - Path to log file
30
+ * @param supabaseClient - Optional Supabase client for remote logging
31
+ * @param agentId - Agent identifier for event attribution
32
+ * @param alertWebhook - Optional webhook URL for HIGH/CRITICAL alerts
33
+ * @param alertOnSeverity - Severity levels that trigger webhook alerts
34
+ * @returns Logger functions
35
+ */
36
+ export declare const createLogger: (logFile?: string, supabaseClient?: SupabaseClient, agentId?: string, alertWebhook?: string, alertOnSeverity?: string[]) => Logger;
package/dist/logger.js ADDED
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) 2026 Amir Mironi
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.createLogger = void 0;
43
+ const fs = __importStar(require("fs"));
44
+ const MAX_STORED_EVENTS = 1000;
45
+ /**
46
+ * Count events by a specific field
47
+ */
48
+ const countByField = (events, field) => {
49
+ const counts = {};
50
+ for (const event of events) {
51
+ const value = String(event[field]);
52
+ counts[value] = (counts[value] || 0) + 1;
53
+ }
54
+ return counts;
55
+ };
56
+ const fireWebhookAlert = (webhookUrl, event) => {
57
+ fetch(webhookUrl, {
58
+ method: "POST",
59
+ headers: { "Content-Type": "application/json" },
60
+ body: JSON.stringify({
61
+ text: `[ContextGuard] ${event.severity} — ${event.event_type}`,
62
+ agent_id: event.agent_id,
63
+ session_id: event.session_id,
64
+ details: event.details,
65
+ timestamp: event.timestamp,
66
+ }),
67
+ }).catch((err) => {
68
+ console.error("Failed to fire webhook alert:", err);
69
+ });
70
+ };
71
+ /**
72
+ * Create a security event logger
73
+ * @param logFile - Path to log file
74
+ * @param supabaseClient - Optional Supabase client for remote logging
75
+ * @param agentId - Agent identifier for event attribution
76
+ * @param alertWebhook - Optional webhook URL for HIGH/CRITICAL alerts
77
+ * @param alertOnSeverity - Severity levels that trigger webhook alerts
78
+ * @returns Logger functions
79
+ */
80
+ const createLogger = (logFile = "mcp_security.log", supabaseClient, agentId = "", alertWebhook, alertOnSeverity = ["HIGH", "CRITICAL"]) => {
81
+ let events = [];
82
+ return {
83
+ /**
84
+ * Log a security event
85
+ */
86
+ logEvent: (eventType, severity, details, sessionId) => {
87
+ const event = {
88
+ timestamp: new Date().toISOString(),
89
+ event_type: eventType,
90
+ severity,
91
+ details,
92
+ session_id: sessionId,
93
+ agent_id: agentId,
94
+ created_at: new Date().toISOString(),
95
+ id: "",
96
+ };
97
+ events.push(event);
98
+ // Keep only recent events in memory
99
+ if (events.length > MAX_STORED_EVENTS) {
100
+ events = events.slice(-MAX_STORED_EVENTS);
101
+ }
102
+ // Write to log file
103
+ try {
104
+ fs.appendFileSync(logFile, JSON.stringify(event) + "\n");
105
+ }
106
+ catch (error) {
107
+ console.error("Failed to write to log file:", error);
108
+ }
109
+ // Alert on high/critical severity
110
+ if (severity === "HIGH" || severity === "CRITICAL") {
111
+ console.error(`[SECURITY ALERT] ${eventType}: ${JSON.stringify(details)}`);
112
+ }
113
+ // Fire webhook alert if configured and severity matches
114
+ if (alertWebhook && alertOnSeverity.includes(severity)) {
115
+ fireWebhookAlert(alertWebhook, event);
116
+ }
117
+ // Report to Supabase if client is provided
118
+ if (supabaseClient) {
119
+ supabaseClient.reportEvent(event).catch((err) => {
120
+ console.error("Failed to report event to Supabase:", err);
121
+ });
122
+ }
123
+ },
124
+ /**
125
+ * Get security statistics
126
+ */
127
+ getStatistics: () => ({
128
+ totalEvents: events.length,
129
+ eventsByType: countByField(events, "event_type"),
130
+ eventsBySeverity: countByField(events, "severity"),
131
+ recentEvents: events.slice(-10),
132
+ }),
133
+ /**
134
+ * Clear all logged events
135
+ */
136
+ clearEvents: () => {
137
+ events = [];
138
+ },
139
+ /**
140
+ * Get all events
141
+ */
142
+ getAllEvents: () => [...events],
143
+ };
144
+ };
145
+ exports.createLogger = createLogger;
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Copyright (c) 2026 Amir Mironi
4
+ *
5
+ * This source code is licensed under the MIT license found in the
6
+ * LICENSE file in the root directory of this source tree.
7
+ */
8
+ interface SecurityConfig {
9
+ maxToolCallsPerMinute?: number;
10
+ enablePromptInjectionDetection?: boolean;
11
+ enableSensitiveDataDetection?: boolean;
12
+ enablePathTraversalPrevention?: boolean;
13
+ mode?: "monitor" | "block";
14
+ blockedPatterns?: string[];
15
+ allowedFilePaths?: string[];
16
+ alertThreshold?: number;
17
+ logPath?: string;
18
+ logLevel?: "debug" | "info" | "warn" | "error";
19
+ transport?: "stdio" | "sse" | "http";
20
+ port?: number;
21
+ targetUrl?: string;
22
+ }
23
+ interface SecurityEvent {
24
+ timestamp: string;
25
+ eventType: string;
26
+ severity: "LOW" | "MEDIUM" | "HIGH" | "CRITICAL";
27
+ details: Record<string, unknown>;
28
+ sessionId: string;
29
+ }
30
+ declare class SecurityPolicy {
31
+ private config;
32
+ private sensitiveDataPatterns;
33
+ private promptInjectionPatterns;
34
+ constructor(config: SecurityConfig);
35
+ get isBlockingMode(): boolean;
36
+ get rawConfig(): Required<SecurityConfig>;
37
+ checkPromptInjection(text: string): string[];
38
+ checkSensitiveData(text: string): string[];
39
+ checkFileAccess(filePath: string): string[];
40
+ checkRateLimit(timestamps: number[]): boolean;
41
+ }
42
+ declare class SecurityLogger {
43
+ private logFile;
44
+ private events;
45
+ constructor(logFile?: string);
46
+ logEvent(eventType: string, severity: SecurityEvent["severity"], details: Record<string, unknown>, sessionId: string): void;
47
+ getStatistics(): Record<string, unknown>;
48
+ private countByField;
49
+ }
50
+ declare class MCPSecurityWrapper {
51
+ private serverCommand;
52
+ private policy;
53
+ private logger;
54
+ private process;
55
+ private toolCallTimestamps;
56
+ private sessionId;
57
+ private clientMessageBuffer;
58
+ private serverMessageBuffer;
59
+ constructor(serverCommand: string[], policy: SecurityPolicy, logger: SecurityLogger);
60
+ start(): Promise<void>;
61
+ private handleClientInput;
62
+ private processClientMessage;
63
+ /** Returns violations + whether to block (block only if mode==="block") */
64
+ private inspectOutbound;
65
+ private handleServerOutput;
66
+ }
67
+ /**
68
+ * SSE proxy: listens on `port`, forwards every request to `targetUrl`,
69
+ * scanning both request body (outbound) and response body (inbound).
70
+ *
71
+ * Supports:
72
+ * - Standard JSON-RPC over HTTP POST (MCP HTTP transport)
73
+ * - Server-Sent Events streams (MCP SSE transport)
74
+ */
75
+ declare class MCPSSEProxy {
76
+ private policy;
77
+ private logger;
78
+ private sessionId;
79
+ private toolCallTimestamps;
80
+ constructor(policy: SecurityPolicy, logger: SecurityLogger);
81
+ start(port: number, targetUrl: string): void;
82
+ private inspectOutbound;
83
+ }
84
+ export { MCPSecurityWrapper, MCPSSEProxy, SecurityPolicy, SecurityLogger };