内容
# PII 匿名化工具 — MCP 服务器
MCP 服务器,允许 AI 助手(Claude、ChatGPT、Cursor 等)自动检测和隐藏 PII 信息,然后再处理敏感文本。
**所有处理都在本地进行。无需网络调用。数据不会离开机器。**
---
## 快速开始(2 分钟)
```bash
# 1. 克隆并安装
git clone https://github.com/kofi-sketch/pii-anonymizer-mcp.git
cd pii-anonymizer-mcp
npm install
# 2. 验证是否正常工作
npm test
```
你应该看到:
```
✓ 检测到 6 个 PII 项目
✓ anonymize_text 功能正常
✓ deanonymize_text 功能正常
✓ 所有测试均通过
```
**就这样。服务器已经准备就绪。**
---
## 连接到您的 AI 客户端
服务器通过 **stdio**(标准 MCP 传输协议)运行。将其添加到您使用的任意客户端:
### Claude 桌面版
编辑 `~/Library/Application Support/Claude/claude_desktop_config.json`(macOS)或 `%APPDATA%\Claude\claude_desktop_config.json`(Windows):
```json
{
"mcpServers": {
"pii-anonymizer": {
"command": "node",
"args": ["/absolute/path/to/pii-anonymizer-mcp/server.js"]
}
}
}
```
### Cursor
编辑 `.cursor/mcp.json` 在您的项目根目录(或全局设置):
```json
{
"mcpServers": {
"pii-anonymizer": {
"command": "node",
"args": ["/absolute/path/to/pii-anonymizer-mcp/server.js"]
}
}
}
```
### VS Code(GitHub Copilot)
添加到您的 VS Code `settings.json`:
```json
{
"mcp": {
"servers": {
"pii-anonymizer": {
"command": "node",
"args": ["/absolute/path/to/pii-anonymizer-mcp/server.js"]
}
}
}
}
```
### 任意其他 MCP 客户端
stdio 传输协议 — 在 stdin/stdout 上使用 JSON-RPC 2.0:
```bash
node server.js
```
> **注意:** 将 `/absolute/path/to/` 替换为您实际克隆仓库的路径。 在仓库目录中运行 `pwd` 获取路径。
---
## 您将获得:6 种工具
### `anonymize_text`
传递任意文本。返回净化文本 + 实体映射。
```
输入: "Hi, I'm John Smith. SSN: 123-45-6789. Email: john@example.com"
输出: "Hi, I'm [PERSON_NAME_1] [PERSON_NAME_2]. SSN: [SSN]. Email: [EMAIL]"
```
实体映射允许您稍后恢复:
```json
{
"[PERSON_NAME_1]": "John",
"[PERSON_NAME_2]": "Smith",
"[SSN]": "123-45-6789",
"[EMAIL]": "john@example.com"
}
```
**参数:**
- `text`(必填)— 要匿名化的文本
- `detectors`(可选)— 要使用的检测器 ID 数组(默认:全部)。从 `list_detectors` 获取 ID。
### `deanonymize_text`
在 AI 处理净化文本后,恢复原始文本:
```
输入: "[PERSON_NAME_1]'s account has been updated" + 实体映射
输出: "John's account has been updated"
```
**参数:**
- `anonymizedText`(必填)— 带有占位符的文本
- `entityMap`(必填)— 来自 `anonymize_text` 的映射
### `list_detectors`
返回所有 30+ 个检测器模式,包含 ID、类别和描述。 使用此功能有选择地启用/禁用检测器。
### `add_custom_names`
添加您自己的姓名、用户名、代号或应标记为 PII 的术语:
```json
{ "names": ["Satoshi", "Nakamoto", "kraken_admin_42", "ProjectPhoenix"] }
```
这些信息在会话期间持续存在,并被检测为 `[PERSON_NAME]`。
### `add_custom_patterns`
添加自定义正则表达式模式,用于组织特定的 PII — 员工 ID、内部代码、票据编号:
```json
{
"patterns": [
{ "regex": "EMP-\\d{6}", "label": "Employee ID", "placeholder": "EMPLOYEE_ID" },
{ "regex": "PROJ-[A-Z]{3}-\\d{4}", "label": "Project Code", "placeholder": "PROJECT_ID" },
{ "regex": "TICKET-\\d+", "label": "Support Ticket", "placeholder": "TICKET_ID" }
]
}
```
### `clear_custom_dictionaries`
重置所有自定义名称和模式。 内置检测器不受影响。
---
## 它检测什么
| 类别 | 示例 |
|----------|---------|
| **姓名** | 40+ 种文化中的 6,000+ 个姓名。 根据上下文智能识别 — 不会将 "will" 在 "will do" 中标记为姓名,但会捕获 "Dear Will," |
| **财务** | 信用卡(Luhn 验证)、IBAN、路由号码、账号、英国排序代码 |
| **身份** | 美国 SSN、英国 NI 编号、护照号码、驾驶执照、出生日期 |
| **联系方式** | 电子邮件地址、国际电话号码、街道地址、英国邮政编码、美国 ZIP 代码 |
| **加密货币/密钥** | 以太坊/比特币地址、BIP-39 种子短语、JWT 令牌、API 密钥(Stripe、GitHub、GitLab、Slack) |
| **系统** | UUID、会话令牌、设备 ID、用户 ID |
此外还有**上下文智能分类** — 在关键词(如 "account"、"routing"、"SSN")附近捕获独立数字,即使没有固定格式。
---
## 典型工作流程
```
1. 用户在 AI 聊天中粘贴敏感文本
2. AI 调用 anonymize_text → 获取干净的文本 + 实体映射
3. AI 处理净化文本(总结、分类、提取、翻译等)
4. AI 调用 deanonymize_text → 在输出中恢复原始文本
5. 用户获取结果,真实数据完整
```
用户无需手动清理。 AI 自动处理。
---
## CLI 工具
包含两个独立的命令行工具 — 无需 MCP 客户端。
### `pii-anonymize` — 净化和恢复
```bash
# 通过管道传输文本
echo "John Smith, SSN 123-45-6789" | node cli.js
# → [PERSON_NAME_1] [PERSON_NAME_2], SSN [SSN]
# 净化文件,保存实体映射以备后用
node cli.js --file ticket.txt -o clean.txt --map map.json
# 在 AI 处理后恢复原始文本
node cli.js --restore --file ai-response.txt --map map.json
# 完整 JSON 输出(匿名文本 + 实体映射 + 统计信息)
node cli.js --file data.txt --json
# 使用自定义组织词典
node cli.js --config kraken-pii.json --file logs.txt
# 仅运行特定检测器
node cli.js --detectors email,credit_card,ssn --file data.csv
# 仅统计信息
node cli.js --stats --file data.txt
```
### `pii-scan` — 只读扫描器
报告 PII 发现结果,不会修改任何内容。 适用于审计和 CI/CD 门控。
```bash
# 扫描文件
node scan.js --file ticket.txt
# ⚠ ticket.txt: 发现 6 个 PII 项目
# PERSON_NAME(2)
# → J***
# → S****
# SSN(1)
# → ***6789
# CREDIT_CARD(1)
# → ***0366
# 严重程度:HIGH
# 显示每个发现结果周围的上下文
node scan.js --file ticket.txt --verbose
# JSON 报告
node scan.js --file data.csv --json
# CI/CD 门控 — 退出代码 0=干净,1=PII 被发现
node scan.js --file output.txt -q || echo "BLOCKED: PII detected"
# 批量扫描目录
find ./logs -name "*.txt" -exec node scan.js --file {} -q \;
```
---
## 自定义词典
通过配置文件添加您组织的自定义姓名和模式。
在 `server.js` 旁边创建 `pii-config.json`(启动时自动加载):
```json
{
"names": ["Jesse Powell", "internal_admin_42"],
"nameFiles": ["employees.txt", "contractors.csv"],
"patterns": [
{ "regex": "EMP-\\d{6}", "label": "Employee ID", "placeholder": "EMPLOYEE_ID" },
{ "regex": "TICKET-\\d+", "label": "Support Ticket", "placeholder": "TICKET_ID" }
]
}
```
- `names` — 内联姓名/术语列表
- `nameFiles` — 文本文件路径(每行一个姓名)或 CSV 文件
- `patterns` — 自定义正则表达式,包含标签和占位符类型
对于 CLI,传递 `--config /path/to/config.json`。 对于 MCP 服务器,传递 `--config=` 作为参数或将 `pii-config.json` 放在 `server.js` 旁边。
参见 `pii-config.example.json` 获取完整示例。
---
## 与所有工具兼容
该工具使用 MCP(Model Context Protocol)— 一个开放标准。 它与您的团队已经使用的任何其他 MCP 服务器或数据工具配合使用。
```
┌─────────────────────────────────────────────────────┐
│ AI 客户端(Claude、Cursor 等) │
│ │
│ "获取 Superset 中的支持票据, │
│ 总结它们,但首先净化 PII" │
└──────┬──────────────────────────┬────────────────────┘
│ │
▼ ▼
┌──────────────┐ ┌──────────────────┐
│ Superset │ │ PII 匿名化工具 │
│ MCP 服务器 │ │ MCP 服务器 │
│ (您的数据) │ │ (净化 PII) │
└──────────────┘ └──────────────────┘
```
**示例流程:**
1. AI 从 Superset(或 DataHub、Postgres、Slack、任意 MCP 服务器)拉取查询结果
2. AI 将结果传递给 `anonymize_text` → PII 被替换
3. AI 处理干净的数据(总结、分类、提取)
4. AI 调用 `deanonymize_text` → 在最终输出中恢复原始文本
CLI 工具以相同的方式与任何管道配合使用:
```bash
# Superset 导出 → 净化 → 提供给 AI
superset export --query 42 | pii-anonymize -o clean.csv --map map.json
# 扫描任意数据源中的 PII 而不更改它
cat database_dump.csv | pii-scan
# CI/CD:阻止泄露 PII 的部署
pii-scan --file api-response.json -q || exit 1
```
**它不需要了解您的其他工具。** 它只是处理通过它的文本 — 查询、日志、票据、聊天记录、API 响应、数据库导出。 如果是文本,它就可以被净化。
---
## 架构
```
┌─────────────┐ stdio(JSON-RPC) ┌──────────────────┐
│ MCP 客户端 │ ◄──────────────────────► │ pii-anonymizer │
│ (Claude、 │ │ server.js │
│ Cursor、 │ anonymize_text() │ engine.js │
│ VS Code) │ deanonymize_text() │ (全部本地) │
└─────────────┘ list_detectors() └──────────────────┘
│
无网络调用
无外部 API
无数据存储
```
- **2 个文件**:`server.js`(MCP 包装器)和 `engine.js`(检测逻辑)
- **1 个依赖项**:`@modelcontextprotocol/sdk`(MCP 协议库)
- **在进程中运行** — 无 Docker,无云,无账户
---
## Docker
运行容器化 — 打印到 STDOUT,无需网络。
```bash
# 构建
docker build -t pii-anonymizer .
# 通过容器传输文本
echo "John Smith, SSN 123-45-6789" | docker run -i pii-anonymizer
# 净化文件(挂载文件)
docker run -i pii-anonymizer < ticket.txt > clean.txt
# JSON 输出
echo "John Smith, SSN 123-45-6789" | docker run -i pii-anonymizer cli.js --json
# 只读扫描
echo "John Smith, SSN 123-45-6789" | docker run -i pii-anonymizer scan.js
# MCP 服务器模式(用于 AI 客户端集成)
docker run -i pii-anonymizer server.js
# 使用自定义配置(挂载您的配置文件)
docker run -i -v /path/to/pii-config.json:/app/pii-config.json pii-anonymizer
# CI/CD 门控 — 如果发现 PII,则退出代码 1
echo "some text" | docker run -i pii-anonymizer scan.js -q || echo "BLOCKED"
```
**镜像:** `node:18-alpine`(~50MB)。运行时无网络调用。 除非使用自定义词典,否则无需卷。
---
## 要求
- Node.js 18+(或 Docker)
- 就是这样。 无 API 密钥,无账户,无网络。
## 许可证
MIT
---
由 @kofi.owusu 在 Slack 上构建