pseudonym-mcp 0.2.2 → 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 CHANGED
@@ -195,6 +195,41 @@ 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
235
  **Step 1** — Add to your MCP client (example for Claude Code — no install needed):
@@ -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"}
@@ -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;AAmBnE,wBAAgB,eAAe,IAAI,SAAS,CA4F3C;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
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"}
@@ -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() {
@@ -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;AAEpD,iFAAiF;AACjF,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAkB,CAAA;AAE1C,SAAS,iBAAiB,CAAC,SAAiB;IAC1C,IAAI,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAA;IACpC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,YAAY,CAAC,SAAS,CAAC,CAAC,CAAA;QAChD,QAAQ,CAAC,GAAG,CAAC,SAAS,EAAE,MAAM,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,eAAe;QACrB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAA;IAEF,MAAM,CAAC,IAAI,CACT,WAAW,EACX;;;;;;;6CAOyC,EACzC;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,0BAA0B,CAAC;QACrD,UAAU,EAAE,CAAC;aACV,MAAM,EAAE;aACR,QAAQ,EAAE;aACV,QAAQ,CACP,uFAAuF,CACxF;KACJ,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,UAAU,IAAI,MAAM,CAAC,UAAU,EAAE,CAAA;QAC7C,MAAM,MAAM,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAA;QAErC,IAAI,UAAkB,CAAA;QACtB,IAAI,CAAC;YACH,UAAU,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,yBAAyB,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBAClF,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;QAED,MAAM,GAAG,GAAG,aAAa,CAAC,WAAW,EAAE,CAAC,GAAG,EAAE,CAAA;QAE7C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAe;oBACrB,IAAI,EAAE,IAAI,CAAC,SAAS,CAClB;wBACE,UAAU,EAAE,GAAG;wBACf,WAAW,EAAE,UAAU;wBACvB,WAAW,EAAE,GAAG,CAAC,UAAU;qBAC5B,EACD,IAAI,EACJ,CAAC,CACF;iBACF;aACF;SACF,CAAA;IACH,CAAC,CACF,CAAA;IAED,MAAM,CAAC,IAAI,CACT,aAAa,EACb;;;yCAGqC,EACrC;QACE,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;QAC1E,UAAU,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sCAAsC,CAAC;KACxE,EACD,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE;QAC7B,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;QACvC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,OAAO,EAAE;oBACP;wBACE,IAAI,EAAE,MAAe;wBACrB,IAAI,EAAE,mBAAmB,UAAU,oDAAoD;qBACxF;iBACF;gBACD,OAAO,EAAE,IAAI;aACd,CAAA;QACH,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;QACpC,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;SACrD,CAAA;IACH,CAAC,CACF,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW;IAC/B,MAAM,MAAM,GAAG,eAAe,EAAE,CAAA;IAChC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;AACjC,CAAC"}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pseudonym-mcp",
3
- "version": "0.2.2",
3
+ "version": "0.2.3",
4
4
  "description": "MCP server for privacy-preserving pseudonymization of sensitive data before cloud LLM processing",
5
5
  "type": "module",
6
6
  "bin": {