Skip to main content
Glama

query-sanitizer-mcp

プロンプトと外部LLMの間に配置される軽量なMCPミドルウェアです。データがマシンから送信される前に、機密データを自動的に編集します。

[Your Prompt] → sanitize_query() → [Safe Prompt] → External LLM → [Response] → restore_response() → [You]

v0.3.0 — 4段階のDLPパイプライン:正規表現 → GLiNER NER → LLMによる精査 → ポストスキャンチェック。 100%オープンソース、100%ローカルで動作します。M4 MacBookおよびGoogle Colab T4でテスト済みです。


なぜ必要なのか

Claude、ChatGPT、その他のクラウドLLMに内部コンテキストを貼り付けるたびに、以下の情報が漏洩するリスクがあります:

  • 従業員名、メールアドレス、電話番号

  • 内部プロジェクトのコードネーム

  • インフラストラクチャの詳細(IPアドレス、ホスト名、DB名)

  • APIキーおよび認証情報

  • 会社名、取引規模、法的参照情報

このMCPサーバーはテキストをインターセプトし、機密トークンを型付きプレースホルダー([ORG_NAME_1][PII_NAME_1]など)に置き換えます。レスポンス時にはこれらを元に戻すため、ユーザーは自然なテキストを確認でき、クラウドLLM側は実際の値を一切目にすることはありません。


Related MCP server: zentric-protocol-mcp

ツール

ツール

説明

sanitize_query(text)

3段階の編集処理。安全なテキストと san_id を返します。

restore_response(text, san_id)

プレースホルダーを元の値に戻します。

scan_response(text)

LLMのレスポンスをスキャンし、生成または漏洩した可能性のあるデータを確認します。

view_ledger(last_n)

最近のサニタイズ履歴を表示します。


検出パイプライン

フェーズ 1 — 正規表現による事前パス(常に実行、モデル不要)

構造化トークンのための決定論的パターン。ローカルモデルがオフラインの場合でも実行されます。

パターン

カテゴリ

ブロック対象か?

AWSアクセスキー (AKIA…)

CREDENTIAL

はい — ブロック

GitHubトークン (ghp_…, gho_…)

CREDENTIAL

はい

JWT (eyJ…)

CREDENTIAL

はい

Slackトークン (xox[baprs]-…)

CREDENTIAL

はい

api_key = "…" 形式の代入

CREDENTIAL

はい

URL内のパスワード (://user:pass@)

CREDENTIAL

はい

メールアドレス

PII_NAME

いいえ — 復元

電話番号

PII_NAME

いいえ

SSN (NNN-NN-NNNN)

PII_ID

いいえ

従業員/バッジID (EMP-…)

PII_ID

いいえ

RFC 1918 プライベートIP

INFRA

いいえ

ドル金額

FINANCIAL

いいえ

設定定義済みのエンティティ(組織名、従業員、コードネーム、ドメイン)

varies

いいえ

フェーズ 2 — LLMによる精査(コンテキスト依存、ベストエフォート)

文脈的な理解が必要なエンティティ(コンテキスト内で使用される組織名、プロジェクトのコードネーム、GEO_INTERNAL参照、LEGAL用語、INTERNAL_URLパターンなど)を捕捉します。ローカルモデルが利用できない場合は、明確な警告とともにフェーズ1の出力が返されます。

フェーズ 3 — ポストスキャンによる信頼性チェック

編集後のテキストに対して高信頼度の正規表現パターンを実行し、LLMが見逃した可能性のあるデータ(例:モデルが捕捉できなかったJWT)をフラグ立てします。レポート内で警告として表示されます。


セットアップ

オプション A — M4 MacBook(推奨)

スタック: Ollama 0.19+ (MLXバックエンド、M4で約50 tok/s) + GLiNER NER (MPS、約80ms/回)

# 1. Install Ollama and pull the recommended model
brew install ollama
ollama pull qwen2.5:3b   # 2GB, fast + strong instruction following
ollama serve             # Ollama 0.19+ uses MLX automatically on Apple Silicon

# 2. Clone and install with NER layer
git clone https://github.com/vidoluco/query-sanitizer-mcp
cd query-sanitizer-mcp
python3 -m venv .venv
.venv/bin/pip install -e ".[nlp]"   # fastmcp + gliner (GLiNER NER layer)

Claude Codeに追加 (~/.claude/settings.json):

{
  "mcpServers": {
    "query-sanitizer": {
      "command": "/path/to/query-sanitizer-mcp/.venv/bin/python",
      "args": ["/path/to/query-sanitizer-mcp/server.py"],
      "env": {
        "SANITIZER_MODEL_NAME": "qwen2.5:3b",
        "SANITIZER_GLINER_MODEL": "urchade/gliner_medium-v2.1"
      }
    }
  }
}

M4用代替LLMモデル(すべてOllama経由):

モデル

サイズ

M4での速度

用途

qwen2.5:3b

2 GB

約50 tok/s

デフォルト — 高速かつ正確

phi4-mini

3 GB

約40 tok/s

強力な推論

llama3.2:3b

2 GB

約45 tok/s

幅広い汎用用途

qwen2.5:7b

5 GB

約30 tok/s

高精度、より多くのRAMが必要


オプション B — Google Colab T4

スタック: HuggingFace transformers (Ollama不要) + GLiNER (CUDA)

# Cell 1 — install
!pip install "query-sanitizer-mcp[colab]" -q
# fastmcp + gliner + transformers + torch + accelerate

# Cell 2 — configure
import os
os.environ["SANITIZER_BACKEND"]    = "hf"
os.environ["SANITIZER_HF_MODEL"]   = "Qwen/Qwen2.5-3B-Instruct"  # ~6GB, fits T4 16GB
os.environ["SANITIZER_GLINER_MODEL"] = "urchade/gliner_medium-v2.1"
os.environ["SANITIZER_LEDGER_DIR"] = "/content/sanitizer-ledger"

# Cell 3 — use directly (no MCP client needed in Colab)
import sys; sys.path.insert(0, ".")
from server import sanitize_query, restore_response, scan_response

result = sanitize_query("Send report to jane.doe@acme.com re: Project Phoenix")
print(result)

初回実行時に Qwen2.5-3B-Instruct (約6 GB) と gliner_medium-v2.1 (約500 MB) がColabキャッシュにダウンロードされます。2回目以降は即座に実行可能です。


最小構成(正規表現のみ、モデル不要)

依存関係ゼロで運用したい場合(純粋な正規表現、Ollamaなし、GLiNERなし):

pip install fastmcp
SANITIZER_MODEL_RETRIES=0 python server.py

認証情報、メールアドレス、SSN、プライベートIP、金額は正規表現のみで捕捉されます。人名、組織名、プロジェクトのコードネームにはGLiNERまたはLLMレイヤーが必要です。


設定

.sanitizer-ledger/config.json を作成します(または python scripts/ledger.py init-config を実行):

{
  "org_names": ["Acme Corp", "Acme"],
  "org_domains": ["acme-internal.net"],
  "project_codenames": ["Phoenix", "Titan"],
  "known_employees": ["Jane Smith", "Marcus Webb"],
  "internal_ip_ranges": ["10.0.0.0/8"],
  "custom_patterns": [
    {"pattern": "JIRA-\\d{4,}", "category": "PROJECT_NAME", "description": "Jira tickets"}
  ],
  "always_allow": ["Google Cloud", "Kubernetes", "BigQuery", "Terraform", "Docker"]
}

設定で定義されたエンティティ(org_namesknown_employeesなど)は、正規表現による事前パス(決定論的マッチング用)とLLMシステムプロンプト(コンテキストバリアント用)の両方に組み込まれます。変更は次回の sanitize_query 呼び出し時に反映され、サーバーの再起動は不要です。


環境変数

変数

デフォルト

説明

SANITIZER_MODEL_URL

http://localhost:11434/v1/chat/completions

ローカルモデルのエンドポイント

SANITIZER_MODEL_NAME

llama3.2

モデル名

SANITIZER_MODEL_RETRIES

2

モデル失敗時のリトライ回数 (2s, 4s バックオフ)

SANITIZER_LEDGER_DIR

.sanitizer-ledger/

レジャーディレクトリのパス

SANITIZER_LEDGER_STORE_ORIGINALS

true

false に設定すると、元の値をディスクに保存しません(GDPRモード — 復元は同一セッション内でのみ機能します)


レジャーCLI

python scripts/ledger.py list [N]                # recent N entries
python scripts/ledger.py lookup <san_id>         # full mapping for one entry
python scripts/ledger.py restore <san_id> <text> # restore from CLI
python scripts/ledger.py stats                   # aggregate stats by category and source
python scripts/ledger.py purge --older-than 30d  # enforce retention policy
python scripts/ledger.py init-config             # create starter config.json

編集カテゴリ

カテゴリ

重要度

CREDENTIAL

APIキー、トークン、パスワード

CRITICAL — ブロック、復元不可

INTERNAL_URL

イントラネットURL、ステージングエンドポイント

CRITICAL

PII_NAME

名前、メールアドレス、電話番号

HIGH

PII_ID

SSN、従業員ID、バッジ番号

HIGH

ORG_NAME

会社名 / 子会社名

HIGH

LEGAL

契約条件、事件番号

HIGH

PROJECT_NAME

内部コードネーム

MEDIUM

INFRA

IPアドレス、ホスト名、DB名

MEDIUM

FINANCIAL

収益、取引規模、予算

MEDIUM

GEO_INTERNAL

オフィス所在地、建物名

LOW


セキュリティモデル

  • 認証情報は保存されません — 元の値の代わりに [BLOCKED] がレジャーに書き込まれます

  • フェイルセーフ設計 — モデルが利用できない場合は正規表現によるフォールバックがトリガーされ、プレーンテキストがそのまま通過することはありません

  • ローカル推論のみ — サニタイズ処理のために外部APIへデータが送信されることはありません

  • プライバシーモード (SANITIZER_LEDGER_STORE_ORIGINALS=false) — 元の値はディスクに一切書き込まれません。復元はメモリ内キャッシュを介して同一サーバーセッション内でのみ機能します


セッションの完全なトレースについては examples/ を参照してください:

  1. 01_api_key_leak.md — 正規表現の事前パスによってブロックされたAWS認証情報

  2. 02_employee_pii.md — 名前、メール、従業員IDを含む人事プロンプト + 復元

  3. 03_internal_infra.md — Ollamaオフライン時のインフラデバッグ(正規表現フォールバック)


コントリビューション

Issueを作成するか、PRを送信してください。

今後のアイデア:

  • [ ] 検出されたパターンからの設定エントリの自動提案

  • [ ] Claude Codeフック統合(プロンプト前の自動サニタイズ)

  • [ ] 信頼度しきい値の設定

  • [ ] バッチ / 一括サニタイズモード

  • [ ] コードブロックのスキャン(インラインシークレット、インポートパス)

  • [ ] レジャーの暗号化保存

  • [ ] レジャー確認用のWeb UI


ライセンス

MIT

Related MCP Connectors

Related MCP Servers