@privacyscrubber/mcp-server 2.2.0 → 2.2.2
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/.well-known/mcp/server-card.json +78 -0
- package/LICENSE +21 -0
- package/README.md +25 -2
- package/index.js +119 -44
- package/manifest.json +1 -1
- package/package.json +5 -2
- package/pii-masking-run.js +207 -21
- package/ps-license-manager.cjs +257 -0
- package/ps-pii-engine.cjs +1476 -145
- package/ps-pii-engine.js +1476 -145
- package/scrubber-core.cjs +46 -1
- package/server.json +2 -2
package/scrubber-core.cjs
CHANGED
|
@@ -66,7 +66,7 @@ function scrubText(text, customRules = [], tokenLabelMap = {}, profile = 'Genera
|
|
|
66
66
|
|
|
67
67
|
// Protect system prompt from being scrubbed or counted
|
|
68
68
|
let extractedSystemPrompt = "";
|
|
69
|
-
let textToProcess = text.replace(/[\u200b\u200c\u200d\ufeff]/
|
|
69
|
+
let textToProcess = text.replace(/[\u200b\u200c\u200d\ufeff\u00ad]/gi, '');
|
|
70
70
|
|
|
71
71
|
const isSpecialized = profile && profile.toLowerCase() !== 'general';
|
|
72
72
|
|
|
@@ -119,6 +119,32 @@ function scrubText(text, customRules = [], tokenLabelMap = {}, profile = 'Genera
|
|
|
119
119
|
});
|
|
120
120
|
}
|
|
121
121
|
|
|
122
|
+
// Pre-scan input text for pre-existing tokens ([TYPE_N], <TYPE_N>, {{TYPE_N}}, __TYPE_N__)
|
|
123
|
+
// to advance counters and avoid counter collisions or overwriting literal quoted tokens
|
|
124
|
+
if (typeof textToProcess === 'string' && textToProcess) {
|
|
125
|
+
const existingTokenRegex = /(?:\[|<|\{\{|__)([A-Za-z0-9_]+)_(\d+)(?:\]|>|\}\}|__)/g;
|
|
126
|
+
let tMatch;
|
|
127
|
+
while ((tMatch = existingTokenRegex.exec(textToProcess)) !== null) {
|
|
128
|
+
const rawLabel = tMatch[1].toUpperCase();
|
|
129
|
+
const idx = parseInt(tMatch[2], 10);
|
|
130
|
+
if (!isNaN(idx)) {
|
|
131
|
+
let mappedType = rawLabel;
|
|
132
|
+
for (const [baseType, customLabel] of Object.entries(tokenLabelMap || {})) {
|
|
133
|
+
if (String(customLabel).replace(/[^A-Za-z0-9_]/g, '_').toUpperCase() === rawLabel) {
|
|
134
|
+
mappedType = baseType;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
mappedType = resolveTypeFromTokenLabel(mappedType);
|
|
139
|
+
if (counters[mappedType] !== undefined) {
|
|
140
|
+
counters[mappedType] = Math.max(counters[mappedType], idx);
|
|
141
|
+
} else {
|
|
142
|
+
customCounters[mappedType] = Math.max(customCounters[mappedType] || 0, idx);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
122
148
|
|
|
123
149
|
// Default labels
|
|
124
150
|
const labels = {
|
|
@@ -289,6 +315,15 @@ function getLabelAliases(label) {
|
|
|
289
315
|
return Array.from(aliases);
|
|
290
316
|
}
|
|
291
317
|
|
|
318
|
+
function resolveTypeFromTokenLabel(label) {
|
|
319
|
+
if (!label) return 'CUSTOM';
|
|
320
|
+
const upper = String(label).toUpperCase();
|
|
321
|
+
for (const [type, aliases] of Object.entries(LABEL_ALIASES)) {
|
|
322
|
+
if (aliases.includes(upper)) return type;
|
|
323
|
+
}
|
|
324
|
+
return upper;
|
|
325
|
+
}
|
|
326
|
+
|
|
292
327
|
function formatToken(label, index, format = 'brackets') {
|
|
293
328
|
const cleanLabel = String(label || 'PII').replace(/[^A-Za-z0-9_]/g, '_').toUpperCase();
|
|
294
329
|
switch(format) {
|
|
@@ -1090,6 +1125,16 @@ function hydrateRegex(rule) {
|
|
|
1090
1125
|
}
|
|
1091
1126
|
}
|
|
1092
1127
|
|
|
1128
|
+
// Fuse adjacent text nodes that were split across chunk boundaries during LLM streaming mutations
|
|
1129
|
+
try {
|
|
1130
|
+
const assistantContainers = document.querySelectorAll(ASSISTANT_SELECTORS);
|
|
1131
|
+
for (let i = 0; i < assistantContainers.length; i++) {
|
|
1132
|
+
if (typeof assistantContainers[i].normalize === 'function') {
|
|
1133
|
+
assistantContainers[i].normalize();
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
} catch (_) {}
|
|
1137
|
+
|
|
1093
1138
|
walkTextNodes(document.documentElement);
|
|
1094
1139
|
|
|
1095
1140
|
// TOGGLE RE-MASK: If no unmasked tokens were found on screen, but there are already revealed .ps-restored-data spans, re-mask them back to tokens
|
package/server.json
CHANGED
|
@@ -6,12 +6,12 @@
|
|
|
6
6
|
"url": "https://github.com/moxno/privacyscrubber-mcp",
|
|
7
7
|
"source": "github"
|
|
8
8
|
},
|
|
9
|
-
"version": "2.2.
|
|
9
|
+
"version": "2.2.2",
|
|
10
10
|
"packages": [
|
|
11
11
|
{
|
|
12
12
|
"registryType": "npm",
|
|
13
13
|
"identifier": "@privacyscrubber/mcp-server",
|
|
14
|
-
"version": "2.2.
|
|
14
|
+
"version": "2.2.2",
|
|
15
15
|
"transport": {
|
|
16
16
|
"type": "stdio"
|
|
17
17
|
},
|