pseudonym-mcp 0.2.1 → 0.2.3
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 +43 -12
- package/dist/mcp/prompts.d.ts +13 -0
- package/dist/mcp/prompts.d.ts.map +1 -0
- package/dist/mcp/prompts.js +17 -0
- package/dist/mcp/prompts.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +40 -0
- package/dist/mcp/server.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -195,12 +195,47 @@ Use unmask_text with session_id abc123 on the response
|
|
|
195
195
|
|
|
196
196
|
The `session_id` keeps the token map alive for the entire session — the same `[PERSON:1]` always refers to the same person, no matter how many times they appear across different notes.
|
|
197
197
|
|
|
198
|
+
## MCP Prompt Templates
|
|
199
|
+
|
|
200
|
+
pseudonym-mcp ships two built-in prompt templates that chain masking, an LLM task, and unmasking into a single workflow — no glue code needed.
|
|
201
|
+
|
|
202
|
+
### `pseudonymize_task` — inline text
|
|
203
|
+
|
|
204
|
+
```
|
|
205
|
+
/pseudonymize_task text="Meeting with Jan Kowalski (PESEL: 90010112318). Contract: 45 000 zł." task="Extract action items"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
What happens:
|
|
209
|
+
|
|
210
|
+
1. pseudonym-mcp masks PII locally → `[PERSON:1]`, `[PESEL:1]`
|
|
211
|
+
2. Claude processes the anonymized text
|
|
212
|
+
3. pseudonym-mcp restores originals in the response
|
|
213
|
+
|
|
214
|
+
Optional `lang` argument: `en` (default) or `pl`.
|
|
215
|
+
|
|
216
|
+
### `privacy_scan_file` — file / PDF (macOS only)
|
|
217
|
+
|
|
218
|
+
> **Requires [macos-vision-mcp](https://github.com/woladi/macos-vision-mcp)** — a separate MCP server that uses Apple's Vision framework to extract text from PDFs and images. macOS only.
|
|
219
|
+
|
|
220
|
+
```
|
|
221
|
+
/privacy_scan_file filePath="/Users/me/contracts/nda.pdf" task="Summarize obligations and deadlines"
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
What happens:
|
|
225
|
+
|
|
226
|
+
1. macos-vision-mcp extracts text from the file
|
|
227
|
+
2. pseudonym-mcp masks all PII locally
|
|
228
|
+
3. Claude processes the anonymized content
|
|
229
|
+
4. pseudonym-mcp restores originals before the response is shown
|
|
230
|
+
|
|
231
|
+
Optional arguments: `task` (default: _summarize the key points_), `lang` (`en` or `pl`).
|
|
232
|
+
|
|
198
233
|
## Quick Start
|
|
199
234
|
|
|
200
|
-
**Step 1** —
|
|
235
|
+
**Step 1** — Add to your MCP client (example for Claude Code — no install needed):
|
|
201
236
|
|
|
202
237
|
```sh
|
|
203
|
-
|
|
238
|
+
claude mcp add pseudonym-mcp -- npx -y pseudonym-mcp --engines hybrid
|
|
204
239
|
```
|
|
205
240
|
|
|
206
241
|
**Step 2** — (Optional) Pull an Ollama model for full hybrid NER:
|
|
@@ -211,11 +246,7 @@ ollama pull llama3
|
|
|
211
246
|
|
|
212
247
|
Skip this step if you only need regex-based masking (`--engines regex`).
|
|
213
248
|
|
|
214
|
-
**
|
|
215
|
-
|
|
216
|
-
```sh
|
|
217
|
-
claude mcp add pseudonym-mcp -- pseudonym-mcp --engines hybrid
|
|
218
|
-
```
|
|
249
|
+
> **Global install** — if you prefer `npm install -g pseudonym-mcp`, replace `npx -y pseudonym-mcp` with `pseudonym-mcp` in all snippets below.
|
|
219
250
|
|
|
220
251
|
Restart your client. The `mask_text` and `unmask_text` tools appear automatically.
|
|
221
252
|
|
|
@@ -298,7 +329,7 @@ pseudonym-mcp --lang en --engines regex --ollama-model llama3 --auto-unmask
|
|
|
298
329
|
### Claude Code
|
|
299
330
|
|
|
300
331
|
```sh
|
|
301
|
-
claude mcp add pseudonym-mcp -- pseudonym-mcp --engines hybrid
|
|
332
|
+
claude mcp add pseudonym-mcp -- npx -y pseudonym-mcp --engines hybrid
|
|
302
333
|
```
|
|
303
334
|
|
|
304
335
|
### Claude Desktop
|
|
@@ -309,8 +340,8 @@ Edit `~/Library/Application Support/Claude/claude_desktop_config.json`:
|
|
|
309
340
|
{
|
|
310
341
|
"mcpServers": {
|
|
311
342
|
"pseudonym-mcp": {
|
|
312
|
-
"command": "
|
|
313
|
-
"args": ["--engines", "hybrid"]
|
|
343
|
+
"command": "npx",
|
|
344
|
+
"args": ["-y", "pseudonym-mcp", "--engines", "hybrid"]
|
|
314
345
|
}
|
|
315
346
|
}
|
|
316
347
|
}
|
|
@@ -324,8 +355,8 @@ Add to `~/.cursor/mcp.json`:
|
|
|
324
355
|
{
|
|
325
356
|
"mcpServers": {
|
|
326
357
|
"pseudonym-mcp": {
|
|
327
|
-
"command": "
|
|
328
|
-
"args": ["--engines", "regex"]
|
|
358
|
+
"command": "npx",
|
|
359
|
+
"args": ["-y", "pseudonym-mcp", "--engines", "regex"]
|
|
329
360
|
}
|
|
330
361
|
}
|
|
331
362
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export interface PseudonymizeTaskArgs {
|
|
2
|
+
text: string;
|
|
3
|
+
task: string;
|
|
4
|
+
lang?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface PrivacyScanFileArgs {
|
|
7
|
+
filePath: string;
|
|
8
|
+
task?: string;
|
|
9
|
+
lang?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function pseudonymizeTaskMessage(args: PseudonymizeTaskArgs): string;
|
|
12
|
+
export declare function privacyScanFileMessage(args: PrivacyScanFileArgs): string;
|
|
13
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAQ1E;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CASxE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ConfigManager } from '../config/manager.js';
|
|
2
|
+
export function pseudonymizeTaskMessage(args) {
|
|
3
|
+
const lang = args.lang ?? ConfigManager.getInstance().get().lang;
|
|
4
|
+
return (`Use pseudonym-mcp mask_text on the following text (lang: ${lang}) and save the session_id:\n\n` +
|
|
5
|
+
`<text>\n${args.text}\n</text>\n\n` +
|
|
6
|
+
`Then: ${args.task}\n\n` +
|
|
7
|
+
`Finally, call pseudonym-mcp unmask_text with the saved session_id to restore original values before showing the response.`);
|
|
8
|
+
}
|
|
9
|
+
export function privacyScanFileMessage(args) {
|
|
10
|
+
const lang = args.lang ?? ConfigManager.getInstance().get().lang;
|
|
11
|
+
const task = args.task ?? 'summarize the key points';
|
|
12
|
+
return (`Use macos-vision-mcp to extract text from ${args.filePath}.\n` +
|
|
13
|
+
`Then use pseudonym-mcp mask_text on the result (lang: ${lang}), save session_id.\n` +
|
|
14
|
+
`Then: ${task}.\n` +
|
|
15
|
+
`Finally call pseudonym-mcp unmask_text with the session_id to restore original values in the response.`);
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/mcp/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AAcpD,MAAM,UAAU,uBAAuB,CAAC,IAA0B;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,aAAa,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAA;IAChE,OAAO,CACL,4DAA4D,IAAI,gCAAgC;QAChG,WAAW,IAAI,CAAC,IAAI,eAAe;QACnC,SAAS,IAAI,CAAC,IAAI,MAAM;QACxB,2HAA2H,CAC5H,CAAA;AACH,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAyB;IAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,aAAa,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,CAAC,IAAI,CAAA;IAChE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAA;IACpD,OAAO,CACL,6CAA6C,IAAI,CAAC,QAAQ,KAAK;QAC/D,yDAAyD,IAAI,uBAAuB;QACpF,SAAS,IAAI,KAAK;QAClB,wGAAwG,CACzG,CAAA;AACH,CAAC"}
|
package/dist/mcp/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAoBnE,wBAAgB,eAAe,IAAI,SAAS,CA8I3C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
|
package/dist/mcp/server.js
CHANGED
|
@@ -4,6 +4,7 @@ import { z } from 'zod';
|
|
|
4
4
|
import { Engine } from '../core/engine.js';
|
|
5
5
|
import { MappingStore } from '../core/mapping-store.js';
|
|
6
6
|
import { ConfigManager } from '../config/manager.js';
|
|
7
|
+
import { pseudonymizeTaskMessage, privacyScanFileMessage } from './prompts.js';
|
|
7
8
|
// Session registry: session_id → Engine (each Engine holds its own MappingStore)
|
|
8
9
|
const sessions = new Map();
|
|
9
10
|
function getOrCreateEngine(sessionId) {
|
|
@@ -83,6 +84,45 @@ in the session identified by session_id.`, {
|
|
|
83
84
|
content: [{ type: 'text', text: restored }],
|
|
84
85
|
};
|
|
85
86
|
});
|
|
87
|
+
server.registerPrompt('pseudonymize_task', {
|
|
88
|
+
description: 'Mask PII in text, run a task, then restore originals — all locally',
|
|
89
|
+
argsSchema: {
|
|
90
|
+
text: z.string().describe('Text containing sensitive data'),
|
|
91
|
+
task: z.string().describe('What to do with the anonymized text'),
|
|
92
|
+
lang: z
|
|
93
|
+
.enum(['en', 'pl'])
|
|
94
|
+
.optional()
|
|
95
|
+
.describe('Language for PII detection (default: config lang)'),
|
|
96
|
+
},
|
|
97
|
+
}, ({ text, task, lang }) => ({
|
|
98
|
+
messages: [
|
|
99
|
+
{
|
|
100
|
+
role: 'user',
|
|
101
|
+
content: { type: 'text', text: pseudonymizeTaskMessage({ text, task, lang }) },
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
}));
|
|
105
|
+
server.registerPrompt('privacy_scan_file', {
|
|
106
|
+
description: 'Extract text from a file via macos-vision-mcp (macOS only), anonymize PII, process with the LLM, then restore originals',
|
|
107
|
+
argsSchema: {
|
|
108
|
+
filePath: z.string().describe('Path to the file to scan (PDF, image, etc.)'),
|
|
109
|
+
task: z
|
|
110
|
+
.string()
|
|
111
|
+
.optional()
|
|
112
|
+
.describe('What to do with the content (default: summarize the key points)'),
|
|
113
|
+
lang: z
|
|
114
|
+
.enum(['en', 'pl'])
|
|
115
|
+
.optional()
|
|
116
|
+
.describe('Language for PII detection (default: config lang)'),
|
|
117
|
+
},
|
|
118
|
+
}, ({ filePath, task, lang }) => ({
|
|
119
|
+
messages: [
|
|
120
|
+
{
|
|
121
|
+
role: 'user',
|
|
122
|
+
content: { type: 'text', text: privacyScanFileMessage({ filePath, task, lang }) },
|
|
123
|
+
},
|
|
124
|
+
],
|
|
125
|
+
}));
|
|
86
126
|
return server;
|
|
87
127
|
}
|
|
88
128
|
export async function startServer() {
|
package/dist/mcp/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAA;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAA;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
|