Privacy-preserving facial protection -- detect faces locally, protect them from recognition systems using neural adversarial perturbations.
- Local face detection using InsightFace (buffalo_sc model, never leaves your machine)
- Local CPU protection via ONNX perturbation generator (~30-60ms inference, no GPU required)
- GPU backend protection via goop-face-engine (diffusion-based, higher quality, multi-model evasion scoring)
- MCP server for AI agent integration (Claude Code, Claude Desktop, etc.)
- CLI for direct use from the terminal
- Batch processing for protecting multiple images in one call
- Sync and async Python clients for programmatic integration
pip install goop-faceFor MCP server support (adds the goop-face-mcp entry point):
pip install "goop-face[mcp]"For development:
pip install "goop-face[dev,mcp]"Note: On first run, InsightFace will download the buffalo_sc detection model (~300MB). This is a one-time download.
Detect faces in an image:
goop-face detect photo.jpgProtect using the local ONNX generator (CPU, no backend needed):
goop-face protect photo.jpg --localProtect with stealth mode (minimal visual change):
goop-face protect photo.jpg --local --mode stealthProtect using a GPU backend for higher quality:
goop-face protect photo.jpg --url http://gpu-server:8900Use INT8 quantized model for faster local inference:
goop-face protect photo.jpg --local --int8Specify output path:
goop-face protect photo.jpg --local -o protected_output.jpgAnalyze facial recognition vulnerability (requires GPU backend):
goop-face analyze photo.jpg --url http://gpu-server:8900Authenticate with the backend:
goop-face protect photo.jpg --url http://gpu-server:8900 --api-key your-keyfrom goop_face import LocalProtector
protector = LocalProtector()
result = protector.protect("photo.jpg", output_path="photo_protected.jpg", mode="balanced")
print(f"Faces protected: {result.faces_protected}")
print(f"SSIM per face: {result.ssim_per_face}")
print(f"Inference time: {result.inference_ms:.1f}ms")Using the backend client:
from goop_face import GoopFaceClient
with GoopFaceClient(base_url="http://gpu-server:8900", api_key="your-key") as client:
result = client.protect("photo.jpg", mode="maximum")
with open("photo_protected.jpg", "wb") as f:
f.write(result.image_bytes)
print(f"Evasion score: {result.evasion_score:.1f}%")
print(f"Models evaded: {result.models_evaded}/{result.models_total}")
print(f"SSIM: {result.ssim:.4f}")Async client:
from goop_face import AsyncGoopFaceClient
async with AsyncGoopFaceClient(base_url="http://gpu-server:8900") as client:
result = await client.protect("photo.jpg", mode="balanced")Face detection only:
from goop_face import FaceDetector
detector = FaceDetector()
faces = detector.detect("photo.jpg")
for face in faces:
print(f"Bounding box: {face.bbox}, confidence: {face.confidence:.3f}")goop-face exposes tools via MCP (Model Context Protocol) for AI agent integration. The goop-face-mcp entry point runs a FastMCP server over stdio transport.
Add to your project (creates .mcp.json in the project root):
{
"mcpServers": {
"goop-face": {
"type": "stdio",
"command": "goop-face-mcp"
}
}
}Or add globally to ~/.claude/settings.local.json with backend configuration:
{
"mcpServers": {
"goop-face": {
"type": "stdio",
"command": "goop-face-mcp",
"env": {
"GOOP_FACE_ENGINE_URL": "http://gpu-server:8900",
"GOOP_FACE_API_KEY": "your-key"
}
}
}
}Use the same configuration in Claude Desktop's MCP settings.
| Tool | Description | Requires Backend |
|---|---|---|
protect_face |
Protect a facial image from recognition systems. Accepts image_path, mode (stealth/balanced/maximum), tier (auto/local/server), and optional output_path. |
No (local tier) |
detect_faces |
Detect faces in an image. Returns bounding boxes and confidence scores. Runs entirely locally. | No |
analyze_face |
Analyze a face image's vulnerability to facial recognition systems. Returns a per-model vulnerability report. | Yes |
batch_protect |
Protect multiple images sequentially. Accepts image_paths (list), mode, and tier. Returns per-image results and aggregate summary. |
No (local tier) |
| Tier | Where | Latency | Requirements |
|---|---|---|---|
| Local (T1) | CPU via ONNX Runtime | ~30-60ms inference | Bundled ONNX model |
| Server (T2) | GPU backend (goop-face-engine) | ~9-28s | Running backend instance |
| Auto | Prefers server if configured, falls back to local | Varies | Either |
| Mode | Perturbation Scale | Typical SSIM | Use Case |
|---|---|---|---|
stealth |
0.5x | ~0.90 | Subtle changes, minimal visual difference |
balanced |
0.8x | ~0.86 | Default -- good privacy/quality tradeoff |
maximum |
1.0x | ~0.82 | Strongest protection, more visible artifacts |
- Face detection always runs locally -- original images never leave your machine.
- Local tier: Everything stays on-device. The ONNX generator runs via CPU, no network calls.
- Server tier: Only the detected 112x112 face crop is sent to the GPU backend, not the full image.
- Detect -- InsightFace (buffalo_sc) finds faces and produces bounding boxes
- Align -- Each face is cropped and resized to 112x112
- Perturb -- The ONNX generator (local) or diffusion model (server) produces adversarial perturbations
- Paste back -- Protected crops are resized and blended back into the original image with soft Gaussian-blurred edges
Environment variables (used by the MCP server via MCPConfig):
| Variable | Description | Default |
|---|---|---|
GOOP_FACE_ENGINE_URL |
GPU backend URL (enables server tier) | Not set (local only) |
GOOP_FACE_API_KEY |
API key for backend authentication (sent as Bearer token) |
Not set |
GOOP_FACE_DEFAULT_MODE |
Default protection mode | balanced |
GOOP_FACE_OUTPUT_DIR |
Default output directory for protected images | . |
git clone https://github.com/kobepaw/goop-face.git
cd goop-face
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,mcp]"
pytestRun with markers:
pytest -m "not gpu and not integration" # CPU tests only
pytest -m gpu # GPU tests (requires CUDA)
pytest -m integration # Integration tests (requires backend)Lint and type check:
ruff check src/ tests/
mypy src/Apache-2.0