@privacyscrubber/mcp-server 2.4.5 → 2.4.7
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/README.md +14 -7
- package/index.js +578 -171
- package/install.js +94 -3
- package/manifest.json +8 -10
- package/package.json +1 -3
- package/pii-masking-run.js +427 -45
- package/ps-license-manager.cjs +1 -1
- package/ps-pii-engine.cjs +1 -1
- package/scrubber-core.cjs +1 -1
- package/server.json +3 -3
- package/ps-license-manager.js +0 -11
- package/ps-pii-engine.js +0 -11
package/install.js
CHANGED
|
@@ -234,6 +234,8 @@ export function parseArgs(rawArgs = process.argv.slice(2)) {
|
|
|
234
234
|
dryRun: false,
|
|
235
235
|
remove: false,
|
|
236
236
|
all: false,
|
|
237
|
+
rules: false,
|
|
238
|
+
hooks: false,
|
|
237
239
|
targets: [],
|
|
238
240
|
help: false
|
|
239
241
|
};
|
|
@@ -242,6 +244,8 @@ export function parseArgs(rawArgs = process.argv.slice(2)) {
|
|
|
242
244
|
if (arg === '--dry-run') options.dryRun = true;
|
|
243
245
|
else if (arg === '--remove' || arg === '--uninstall') options.remove = true;
|
|
244
246
|
else if (arg === '--all') options.all = true;
|
|
247
|
+
else if (arg === '--rules') options.rules = true;
|
|
248
|
+
else if (arg === '--hooks') options.hooks = true;
|
|
245
249
|
else if (arg === '--claude') options.targets.push('claude');
|
|
246
250
|
else if (arg === '--claude-code') options.targets.push('claude-code', 'claude-code-project');
|
|
247
251
|
else if (arg === '--cursor') options.targets.push('cursor', 'cursor-storage', 'cursor-workspace');
|
|
@@ -249,7 +253,11 @@ export function parseArgs(rawArgs = process.argv.slice(2)) {
|
|
|
249
253
|
else if (arg === '--zed') options.targets.push('zed');
|
|
250
254
|
else if (arg === '--windsurf') options.targets.push('windsurf');
|
|
251
255
|
else if (arg === '--cline') options.targets.push('cline', 'roo');
|
|
252
|
-
else if (arg === '--workspace')
|
|
256
|
+
else if (arg === '--workspace') {
|
|
257
|
+
options.targets.push('cursor-workspace', 'claude-code-project', 'vscode');
|
|
258
|
+
options.rules = true;
|
|
259
|
+
options.hooks = true;
|
|
260
|
+
}
|
|
253
261
|
else if (arg === '--help' || arg === '-h') options.help = true;
|
|
254
262
|
}
|
|
255
263
|
|
|
@@ -327,7 +335,8 @@ Options:
|
|
|
327
335
|
--zed Configure Zed IDE (~/.config/zed/settings.json)
|
|
328
336
|
--windsurf Configure Windsurf only
|
|
329
337
|
--cline Configure Cline / Roo-Code only
|
|
330
|
-
--workspace Configure workspace paths (.cursor, .mcp.json, .vscode)
|
|
338
|
+
--workspace Configure workspace paths (.cursor, .mcp.json, .vscode) & agent rules
|
|
339
|
+
--rules Scaffold native AI agent rules (.cursor/rules/privacyscrubber.mdc, AGENTS.md)
|
|
331
340
|
--dry-run Preview configuration changes without writing files
|
|
332
341
|
--remove Remove PrivacyScrubber from all target client configurations
|
|
333
342
|
-h, --help Display this help guide
|
|
@@ -400,12 +409,94 @@ Options:
|
|
|
400
409
|
console.log('');
|
|
401
410
|
}
|
|
402
411
|
|
|
412
|
+
if (options.rules && !options.remove) {
|
|
413
|
+
const cwd = process.cwd();
|
|
414
|
+
const mdcPath = path.join(cwd, '.cursor', 'rules', 'privacyscrubber.mdc');
|
|
415
|
+
const agentsMdPath = path.join(cwd, 'AGENTS.md');
|
|
416
|
+
const ruleBody = [
|
|
417
|
+
'# PrivacyScrubber Zero-Trust Agentic Guard (ZTDS)',
|
|
418
|
+
'1. Never read `.env`, `*secret*`, `*credentials*`, `*.pem`, `*.key`, or database dumps with native `read_file` / `cat`. Call `guard_read_file` or `sanitize_file`.',
|
|
419
|
+
'2. Route shell commands that may print credentials or PII through `guard_exec`, and inspect git diffs via `guard_git_diff`.',
|
|
420
|
+
'3. Keep tokens like `[API_KEY_1]`, `[EMAIL_1]` intact during reasoning. Restore final answers via `reveal_text` or write to disk via `guard_apply_patch`.'
|
|
421
|
+
].join('\n');
|
|
422
|
+
const mdcContent = `---\ndescription: PrivacyScrubber Zero-Trust Data Sanitization (ZTDS) — Mandatory PII & Secret Guard\nglobs: "**/*"\nalwaysApply: true\n---\n\n${ruleBody}\n`;
|
|
423
|
+
|
|
424
|
+
if (options.dryRun) {
|
|
425
|
+
console.log(`[DRY-RUN OK]: Would scaffold agent rules in ${mdcPath} and ${agentsMdPath}\n`);
|
|
426
|
+
} else {
|
|
427
|
+
try {
|
|
428
|
+
fs.mkdirSync(path.dirname(mdcPath), { recursive: true });
|
|
429
|
+
if (!fs.existsSync(mdcPath) || !fs.readFileSync(mdcPath, 'utf8').includes('PrivacyScrubber Zero-Trust Agentic Guard')) {
|
|
430
|
+
fs.writeFileSync(mdcPath, mdcContent, 'utf8');
|
|
431
|
+
console.log(`[RULES] Created ${mdcPath}`);
|
|
432
|
+
}
|
|
433
|
+
if (!fs.existsSync(agentsMdPath)) {
|
|
434
|
+
fs.writeFileSync(agentsMdPath, ruleBody + '\n', 'utf8');
|
|
435
|
+
console.log(`[RULES] Created ${agentsMdPath}`);
|
|
436
|
+
} else {
|
|
437
|
+
const existingAgents = fs.readFileSync(agentsMdPath, 'utf8');
|
|
438
|
+
if (!existingAgents.includes('PrivacyScrubber Zero-Trust Agentic Guard')) {
|
|
439
|
+
fs.writeFileSync(agentsMdPath, existingAgents.trimEnd() + '\n\n' + ruleBody + '\n', 'utf8');
|
|
440
|
+
console.log(`[RULES] Updated ${agentsMdPath}`);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
} catch (_) {}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
if (options.hooks && !options.remove) {
|
|
448
|
+
const cwd = process.cwd();
|
|
449
|
+
const cursorHooksPath = path.join(cwd, '.cursor', 'hooks.json');
|
|
450
|
+
const claudeSettingsPath = path.join(cwd, '.claude', 'settings.json');
|
|
451
|
+
const hookCmd = 'npx -y @privacyscrubber/mcp-server --hook';
|
|
452
|
+
|
|
453
|
+
if (options.dryRun) {
|
|
454
|
+
console.log(`[DRY-RUN OK]: Would scaffold IDE lifecycle hooks in ${cursorHooksPath} and ${claudeSettingsPath}\n`);
|
|
455
|
+
} else {
|
|
456
|
+
try {
|
|
457
|
+
fs.mkdirSync(path.dirname(cursorHooksPath), { recursive: true });
|
|
458
|
+
let cursorHooks = { version: 1, hooks: {} };
|
|
459
|
+
if (fs.existsSync(cursorHooksPath)) {
|
|
460
|
+
try { cursorHooks = JSON.parse(fs.readFileSync(cursorHooksPath, 'utf8')); } catch (_) {}
|
|
461
|
+
}
|
|
462
|
+
if (!cursorHooks.hooks || typeof cursorHooks.hooks !== 'object') cursorHooks.hooks = {};
|
|
463
|
+
for (const ev of ['beforeReadFile', 'beforeShellExecution']) {
|
|
464
|
+
if (!Array.isArray(cursorHooks.hooks[ev])) cursorHooks.hooks[ev] = [];
|
|
465
|
+
if (!cursorHooks.hooks[ev].some(h => h && h.command && h.command.includes('privacyscrubber'))) {
|
|
466
|
+
cursorHooks.hooks[ev].push({ command: hookCmd });
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
fs.writeFileSync(cursorHooksPath, JSON.stringify(cursorHooks, null, 2) + '\n', 'utf8');
|
|
470
|
+
console.log(`[HOOKS] Configured ${cursorHooksPath}`);
|
|
471
|
+
|
|
472
|
+
fs.mkdirSync(path.dirname(claudeSettingsPath), { recursive: true });
|
|
473
|
+
let claudeSettings = {};
|
|
474
|
+
if (fs.existsSync(claudeSettingsPath)) {
|
|
475
|
+
try { claudeSettings = JSON.parse(fs.readFileSync(claudeSettingsPath, 'utf8')); } catch (_) {}
|
|
476
|
+
}
|
|
477
|
+
if (!claudeSettings.hooks || typeof claudeSettings.hooks !== 'object') claudeSettings.hooks = {};
|
|
478
|
+
if (!Array.isArray(claudeSettings.hooks.PreToolUse)) claudeSettings.hooks.PreToolUse = [];
|
|
479
|
+
const hasClaudeHook = claudeSettings.hooks.PreToolUse.some(entry =>
|
|
480
|
+
Array.isArray(entry?.hooks) && entry.hooks.some(h => h && h.command && h.command.includes('privacyscrubber'))
|
|
481
|
+
);
|
|
482
|
+
if (!hasClaudeHook) {
|
|
483
|
+
claudeSettings.hooks.PreToolUse.push({
|
|
484
|
+
matcher: 'Read|Bash',
|
|
485
|
+
hooks: [{ type: 'command', command: hookCmd }]
|
|
486
|
+
});
|
|
487
|
+
}
|
|
488
|
+
fs.writeFileSync(claudeSettingsPath, JSON.stringify(claudeSettings, null, 2) + '\n', 'utf8');
|
|
489
|
+
console.log(`[HOOKS] Configured ${claudeSettingsPath}`);
|
|
490
|
+
} catch (_) {}
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
403
494
|
console.log('--------------------------------------------------');
|
|
404
495
|
if (configuredCount > 0) {
|
|
405
496
|
console.log(`[SUMMARY] ${options.remove ? 'Cleaned' : 'Configured'} ${configuredCount} AI client(s) successfully.`);
|
|
406
497
|
if (!options.remove) {
|
|
407
498
|
console.log('Next step: Restart your AI IDE or Claude Desktop to activate PrivacyScrubber.');
|
|
408
|
-
console.log('\x1b[36m💼 B2B 7-Day Free Trial (TEAMS/SDK): npx @privacyscrubber/mcp-server trial\x1b[0m');
|
|
499
|
+
console.log('\x1b[36m💼 B2B 7-Day Free Trial (TEAMS $99/mo · SDK $299/mo): npx @privacyscrubber/mcp-server trial | https://privacyscrubber.com/pricing/?tier=teams&trial=true&utm_source=mcp_install\x1b[0m');
|
|
409
500
|
console.log('\x1b[36m📋 Generate CISO Procurement Memo: npx @privacyscrubber/mcp-server memo\x1b[0m');
|
|
410
501
|
console.log('\x1b[33m⭐ Enjoying zero-trust privacy? Star the repo on GitHub: https://github.com/moxno/privacyscrubber-mcp\x1b[0m');
|
|
411
502
|
console.log('\x1b[90m One-click CLI: gh repo star moxno/privacyscrubber-mcp && gh repo star moxno/ztds.ai\x1b[0m');
|
package/manifest.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"manifest_version": "0.3",
|
|
3
3
|
"name": "privacyscrubber/pii-masking-mcp",
|
|
4
|
-
"version": "2.4.
|
|
4
|
+
"version": "2.4.7",
|
|
5
5
|
"description": "CISO-Approved Zero-Trust PII & Secrets Redaction MCP Server for Cursor, Windsurf, and Claude Desktop. Prevent API leaks and comply with HIPAA/SOC 2 locally.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "PrivacyScrubber",
|
|
@@ -30,21 +30,17 @@
|
|
|
30
30
|
"description": "STEP 3: Call this last. Restores masked tokens back with original private data from the local volatile RAM-only session map."
|
|
31
31
|
},
|
|
32
32
|
{
|
|
33
|
-
"name": "
|
|
34
|
-
"description": "STEP
|
|
33
|
+
"name": "stream_reveal_text",
|
|
34
|
+
"description": "STEP 3 (Streaming): Real-time streaming token detokenizer for LLM Server-Sent Events (SSE) and stdio chunk pipelines."
|
|
35
35
|
},
|
|
36
36
|
{
|
|
37
|
-
"name": "
|
|
38
|
-
"description": "
|
|
37
|
+
"name": "audit_context",
|
|
38
|
+
"description": "STEP 0 (Pre-Flight): Non-destructive security inspection of raw prompts or document chunks before sending to LLMs. Evaluates PII, secrets, risk severity, and triggered regulatory frameworks."
|
|
39
39
|
},
|
|
40
40
|
{
|
|
41
41
|
"name": "sanitize_file",
|
|
42
42
|
"description": "Reads a local file, sanitizes its contents using the selected profile, and outputs the safe version for AI analysis. Securely keeps original identifiers in memory."
|
|
43
43
|
},
|
|
44
|
-
{
|
|
45
|
-
"name": "scrub_file",
|
|
46
|
-
"description": "Alias for sanitize_file."
|
|
47
|
-
},
|
|
48
44
|
{
|
|
49
45
|
"name": "audit_directory_for_pii",
|
|
50
46
|
"description": "Scans a local directory for leaks of secrets, keys, and PII. Returns a structured security summary report."
|
|
@@ -116,7 +112,9 @@
|
|
|
116
112
|
{
|
|
117
113
|
"name": "generate_procurement_memo",
|
|
118
114
|
"description": "Zero-Trust Enterprise Procurement: Generates an executive-ready Procurement & ROI Memorandum for CISOs, DPOs, and VP of Engineering."
|
|
119
|
-
}
|
|
115
|
+
}
|
|
116
|
+
],
|
|
117
|
+
"prompts": [
|
|
120
118
|
{
|
|
121
119
|
"name": "secure_ai_workflow",
|
|
122
120
|
"description": "Zero-Trust Data Sanitization workflow instruction to automatically scrub PII before processing data."
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@privacyscrubber/mcp-server",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.7",
|
|
4
4
|
"mcpName": "io.github.moxno/privacyscrubber-mcp",
|
|
5
5
|
"description": "CISO-Approved Zero-Trust PII & Secrets Redaction MCP Server for Cursor, Windsurf, and Claude Desktop. Prevent API leaks and comply with HIPAA/SOC 2 locally.",
|
|
6
6
|
"main": "index.js",
|
|
@@ -13,10 +13,8 @@
|
|
|
13
13
|
"install.js",
|
|
14
14
|
"pii-masking-run.js",
|
|
15
15
|
"scrubber-core.cjs",
|
|
16
|
-
"ps-license-manager.js",
|
|
17
16
|
"ps-license-manager.cjs",
|
|
18
17
|
"ps-pii-engine.cjs",
|
|
19
|
-
"ps-pii-engine.js",
|
|
20
18
|
"config-schema.json",
|
|
21
19
|
"smithery.yaml",
|
|
22
20
|
"server.json",
|