fairquery-llm-data-guard
OfficialClick on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fairquery-llm-data-guardredact emails, phone numbers, and API keys from this text before sending to the LLM"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
LLM Data Guard: PII & Secret Redactor
Fairquery Apify Actor that finds and redacts personal data (PII) and secrets in text, HTML and PDF documents before they are sent to an LLM, a vector store or a third-party API. Each document gets a risk level, a list of findings (type, offsets, masked preview) and, in redact mode, a clean output_text you can pass straight to your model. Placeholders are reversible, so you can put the original values back into the model's answer.
No data retention. The Actor never logs document content and writes nothing except the result rows in the run's default dataset and a counts-only
RUN_SUMMARY. By default it also deletes the run'sINPUTrecord when it finishes (purgeInputAfterRun). Raw values are not stored in findings unless you turn onincludeFindingValues. You control the dataset; delete it (or the run) once you have read it.
When to use this Actor (LLM / tool selection)
Use it when an agent or pipeline needs to:
Strip emails, phone numbers, SSNs, card numbers, IBANs and IP addresses from prompts, chat logs, support tickets or CRM notes before LLM calls
Catch leaked credentials (AWS, GitHub, Slack, Stripe, OpenAI, Anthropic, Google, private keys, JWTs,
password=...) in logs, code snippets and config filesPseudonymise a dataset for RAG / fine-tuning with consistent placeholders (
[EMAIL_1],[PERSON_2])Restore real values in the LLM's answer (
mode: "restore")Audit a batch of documents for sensitive-data risk (
mode: "detect")
Covers OWASP LLM Top 10 risk LLM02 Sensitive Information Disclosure at the input side. It is a pattern-and-validation engine, not a guarantee: always keep defense in depth.
Related MCP server: classifinder-mcp
What it detects
Category | Types | Validation |
PII |
| Luhn + issuer prefix for cards, mod-97 + country length for IBANs, libphonenumber for phones, SSN area/group rules |
PII (opt-in) |
| Open-source NER (compromise, English) and street-address patterns |
Secrets |
| Gitleaks-style rules |
Secrets |
| Shannon-entropy threshold ( |
Secrets (opt-in) |
| Any 20+ char random-looking token |
Overlapping matches are resolved (secrets > cards/IBAN > SSN > email > IP > phone > address > names), so a card number is never also reported as a phone.
Redaction styles
| Example | Reversible |
|
| Yes, with |
|
| No |
|
| No; stable across runs if you set |
Input
Field | Type | Default | Description |
|
| example | One document per entry |
|
|
| Documents with your own IDs |
|
|
| Public txt/md/json/csv/HTML/PDF URLs (max 10 MB each) |
|
|
| |
|
|
| |
| bool |
| Adds |
| bool |
| Same value → same placeholder across documents |
| object |
| For |
| secret string | random per run | For |
| bool |
| |
| bool |
| Opt-in detectors |
| number |
| Bits/char for generic secrets |
| string |
| For numbers without |
|
| all | Only report these types |
|
|
| Values never flagged |
| bool |
| Put raw values into findings |
| int |
| Safety caps |
| bool |
| Delete the |
{
"texts": ["Hi, I'm Jane (jane.doe@acme.com, +1 415-555-0132). Card 4111 1111 1111 1111.", "AWS key AKIAIOSFODNN7EXAMPLE"],
"mode": "redact",
"redactionStyle": "placeholder",
"returnPlaceholderMap": true
}Output
One row per document (type: "document") plus machine-readable type: "error" rows.
{
"schema_version": "1.0.0", "type": "document", "id": "text-1", "source": "text", "chars": 78, "mode": "redact",
"finding_count": 3, "risk_level": "high",
"counts_by_type": { "EMAIL": 1, "PHONE": 1, "CREDIT_CARD": 1 },
"findings": [
{ "type": "EMAIL", "category": "pii", "rule": "email", "confidence": "high", "start": 14, "end": 31, "length": 17, "preview": "j***@a***.com", "replacement": "[EMAIL_1]" }
],
"output_text": "Hi, I'm Jane ([EMAIL_1], [PHONE_1]). Card [CREDIT_CARD_1].",
"placeholder_map": { "[EMAIL_1]": "jane.doe@acme.com", "[PHONE_1]": "+1 415-555-0132", "[CREDIT_CARD_1]": "4111 1111 1111 1111" }
}risk_level: high = any secret or card/SSN/IBAN/NI number; medium = other confident PII; low = only low-confidence (NER/entropy) hits; none.
Restore after the LLM answers:
{ "mode": "restore", "texts": ["Dear [EMAIL_1], your card ending [CREDIT_CARD_1]…"], "placeholderMap": { "[EMAIL_1]": "jane.doe@acme.com" } }Error codes: INPUT_EMPTY, MAX_DOCUMENTS_EXCEEDED, PLACEHOLDER_MAP_MISSING, DOCUMENT_FETCH_FAILED (error rows are never charged).
RUN_SUMMARY (key-value store) holds counts per type, charged events and settings only, never text.
Pricing
Pay per event:
Event | When |
| Each document scanned (or restored) |
| Each PII/secret finding reported |
Error rows are never charged. See the pricing tab for current prices.
Memory / runtime
Default 256 MB, no browser, no proxy. Regex detectors process roughly 1–5 MB of text per second; NER (detectNames) is slower, so give it 512 MB for big batches. PDFs are parsed with unpdf (text layer only, no OCR).
MCP / Apify tools
Call from agents via Apify MCP with Actor fairquery/llm-data-guard-pii-secrets:
{ "actor": "fairquery/llm-data-guard-pii-secrets", "input": { "texts": ["..."], "mode": "redact" } }Local stdio MCP server
The mcp/ folder is a stdio MCP server (TypeScript, @modelcontextprotocol/sdk) with two tools, both with annotations and output schemas:
Tool | What it does | Cost |
| Runs this Actor and returns the dataset rows | Needs |
| Lists detectable types, redaction styles and events | Free, local, no token |
cd mcp && npm install && npm run build
node scripts/smoke-test.mjs # initialize + tools/list + free tool, no token
APIFY_TOKEN=... node scripts/smoke-test.mjs --call # real call{ "mcpServers": { "fairquery-llm-data-guard": { "command": "node", "args": ["/path/to/llm-data-guard-pii-secrets/mcp/dist/index.js"], "env": { "APIFY_TOKEN": "<your Apify token>" } } } }Docker: the root Dockerfile builds the MCP server image (docker build -t fairquery-llm-data-guard-mcp .); it is also the Dockerfile for Glama. The Actor image is .actor/Dockerfile. glama.json lists fairquery as maintainer.
Local development
npm install
npx apify run # input from storage/key_value_stores/default/INPUT.json
npm testKits & templates
Optional guides from Fairquery for wiring this Actor into agents and automations (the Actor works fine without them):
AI Agent Data Toolkit Quick-Start (PDF): MCP setup for Claude Desktop and Cursor, API calls, recipes, cost estimates.
n8n + Zapier Workflow Template Pack: 10 importable n8n workflows for the four original Fairquery Actors (SEC EDGAR, website/tech, email, OSV); it does not include workflows for this Actor yet, but the patterns adapt easily.
Agent Prompt Pack for Research & Lead Ops: 69 prompts for company research, lead cleaning, SEO and security reviews.
Agent Starter Kit: 10 copy-paste MCP + n8n recipes ($5): 10 copy-paste MCP + n8n recipes, with ready-made Claude/Cursor configs and 3 starter workflows.
Disclaimer
Pattern-based detection finds most but not all sensitive data: unusual formats, non-English names, images and scanned PDFs (no OCR) can slip through, and some matches are false positives. Use it as one layer of a data-protection program, not as a compliance certification. Only process data you are allowed to process.
Links
License: MIT
Available Tools
2 toolsguard_textDetect / redact PII and secrets before LLM useARead-onlyIdempotent
WHAT: Scan text documents (or public document URLs: txt/md/json/csv/HTML/PDF) for PII (emails, phones, US SSNs, Luhn-valid cards, IBANs, UK NINOs, IPs, optional person names/addresses) and secrets (AWS/GitHub/Slack/Stripe/OpenAI/... keys, JWTs, private keys, URL credentials, high-entropy key=value). mode="redact" returns sanitized text; mode="restore" puts originals back into LLM output using a placeholder map. WHEN TO USE: before sending prompts, tickets, logs or files to an LLM or third party; to audit text for leaked credentials; to de-anonymize an LLM answer after a placeholder redaction. WHEN NOT TO USE: to see which entity types exist or pick entityTypes, call list_detectors (free, local). Not for binary files/images (PDF text layer only, no OCR) or for validating whether an email is deliverable. COST: paid. Runs Apify Actor fairquery/llm-data-guard-pii-secrets with your APIFY_TOKEN; pay-per-event billed per document processed and per finding (error rows free). Typical run a few seconds. RETURNS: {count, items}. One type="document" row per input with id, source, chars, truncated, mode, finding_count, counts_by_type, risk_level, findings[] (type, offsets, masked preview; raw values are not returned), output_text (redact/restore modes), placeholder_map (only if returnPlaceholderMap=true); or type="error" rows with code/message. EXAMPLE: {"texts":["Mail jane@acme.com, key AKIAIOSFODNN7EXAMPLE"],"mode":"redact","redactionStyle":"placeholder"} -> output_text with the email replaced by [EMAIL_1] and the key by a placeholder; findings lists EMAIL and AWS_ACCESS_KEY. Provide texts and/or documentUrls (at least one).
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | "detect" = report findings only; "redact" (default) = also return output_text with values replaced; "restore" = replace placeholders in texts with originals from placeholderMap. | |
| texts | No | Documents to scan, one string per document (prompt, chat message, ticket, log line, file content). Example: ["Hi, I am Jane (jane.doe@acme.com)"]. Optional if documentUrls is given. | |
| allowList | No | Exact values that are never flagged, e.g. ["support@yourcompany.com"]. Default []. | |
| detectNames | No | Default false. Detect person names with English NER (lower precision, slightly slower). | |
| entityTypes | No | Only report these entity types, e.g. ["EMAIL","CREDIT_CARD","AWS_ACCESS_KEY"]. Omit/empty = all enabled detectors. Valid names: see list_detectors. | |
| entropyScan | No | Default false. Also flag unlabeled random-looking tokens of 20+ chars (catches unknown key formats; may flag hashes/IDs). | |
| documentUrls | No | Public http(s) URLs of txt, md, json, csv, HTML or PDF files (max 10 MB each; PDFs text layer only). Example: ["https://example.com/report.pdf"]. Optional if texts is given. | |
| placeholderMap | No | Only for mode="restore": map of placeholder -> original value returned by a previous redact call, e.g. {"[EMAIL_1]":"jane@acme.com"}. Default {}. | |
| redactionStyle | No | Used in redact mode. "placeholder" (default) = [EMAIL_1], reversible via placeholder map; "mask" = j***@a***.com / **** 1111; "hash" = [EMAIL:3f2a9c0d1b7e] salted sha256 prefix. | |
| detectAddresses | No | Default false. Detect street addresses (English formats) and NER place names. | |
| defaultPhoneRegion | No | ISO 3166-1 alpha-2 country code used to parse phone numbers written without +country prefix, e.g. "US" (default), "DE", "GB". | |
| returnPlaceholderMap | No | Default false. If true, each row includes placeholder_map {"[EMAIL_1]":"jane@acme.com"} needed for restore mode. Contains the original sensitive values. |
Output Schema
| Name | Required | Description |
|---|---|---|
| count | Yes | Number of rows in items |
| items | Yes | Dataset rows: type=document (findings, risk_level, output_text) or type=error |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations: discloses the paid/pay-per-event cost model, the backing Actor and required APIFY_TOKEN, that raw sensitive values are not returned, that PDFs are text-layer only (no OCR), and the exact {count, items} shape including error rows. Annotations already cover safety, and the description adds rich operational context on top.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with labeled WHAT / WHEN TO USE / WHEN NOT TO USE / COST / RETURNS / EXAMPLE sections. Despite its length, every section earns its place given 12 parameters, a paid external Actor, and three operating modes.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers the at-least-one-of constraint (texts and/or documentUrls), unsupported inputs, cost, auth, and return shape even though an output schema exists. For a complex multi-mode tool with an external dependency, nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description earns extra by explaining mode semantics, illustrating redactionStyle output, and pointing entityTypes validation at list_detectors. It adds meaningful interpretation (e.g. returnPlaceholderMap contains original sensitive values) rather than restating the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States specific verbs (scan, redact, restore) and resources (text documents, public document URLs) and enumerates exactly what is detected (PII types, secrets). It distinguishes its three modes and names the sibling list_detectors, so an agent can separate it from alternatives without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN TO USE (before sending prompts/tickets/logs to an LLM, auditing for leaked credentials, de-anonymizing output) and WHEN NOT TO USE (entity discovery → list_detectors; no binary/image support; not email-deliverability validation). Both conditions and the alternative tool are named, leaving nothing to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_detectorsList detectors and redaction styles (free)ARead-onlyIdempotent
WHAT: Static catalog of the PII and secret entity types guard_text can detect, the available redaction styles, and the billable pricing events. WHEN TO USE: before guard_text, to choose entityTypes / redactionStyle or to explain coverage to a user. WHEN NOT TO USE: to actually scan or redact text - use guard_text. COST: free; local, no network, no APIFY_TOKEN, deterministic. RETURNS: {pii: string[], secret: string[], redaction_styles: {style: example}, pricing_events: {event: unit}}. Takes no arguments. EXAMPLE: {} -> {"pii":["EMAIL","PHONE",...],"secret":["AWS_ACCESS_KEY",...],...}
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| pii | Yes | PII entity types (opt-in ones marked) |
| secret | Yes | Secret/credential entity types |
| pricing_events | Yes | Billable Apify event -> unit |
| redaction_styles | Yes | Redaction style -> example output |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, destructiveHint=false and openWorldHint=false, but the description adds value beyond them: cost (free), no network, no APIFY_TOKEN required, and deterministic output. It stops short of 5 only because return shape is largely restated from the existing output schema.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Header-prefixed sections (WHAT/WHEN/COST/RETURNS/EXAMPLE) are scannable and front-loaded, with the routing rule stated in the first two blocks. Every sentence carries information; nothing is padded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a free, argument-less catalog tool the definition covers purpose, routing, cost/auth requirements, return shape and an example. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Zero parameters, so the baseline is 4 per the rubric. The description reinforces this by stating 'Takes no arguments' with an empty-object example, leaving no ambiguity for the caller.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource (catalog of PII/secret entity types, redaction styles, pricing events) and explicitly scopes it as the static catalog that guard_text relies on. An agent can distinguish it from guard_text without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit WHEN TO USE (before guard_text, to choose entityTypes/redactionStyle) and WHEN NOT TO USE (to actually scan or redact — use guard_text), naming the sibling as the alternative. Routing is unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
2 tool updates
v0.1.0- First observed
guard_text - First observed
list_detectors
TDQS
Scored across 2 tools
guard_text (scan/redact/restore text) and list_detectors (static catalog lookup) have clearly distinct purposes, and the descriptions explicitly cross-reference each other with WHEN NOT TO USE guidance. An agent can unambiguously pick the right tool, including the ordering hint to call list_detectors first.
Both names use the same snake_case verb_noun convention (guard_text, list_detectors) with an imperative verb leading. No casing or style mixing across the set.
Two tools is on the thin side, but the server wraps a single focused actor: one multi-mode tool covers scan/redact/restore and one free local helper exposes the entity catalog. Nothing feels redundant, though the surface is minimal.
Core lifecycle (discover entity types, scan, redact, restore) is fully covered, with inputs for raw text and document URLs. Gaps are minor and mostly out-of-scope by design (no OCR/images, no async job polling for long Apify runs, no custom entity patterns).
Maintenance
Related MCP Connectors
Detect and redact PII and secrets before text reaches an LLM, with reversible placeholders.
Detects and redacts PII (emails, phones, SSNs, names, addresses) from text. $0.02/call via x402.
Redact personal data from text before your agent sends it to a model or stores it: names, contact details, ID numbers, financial and health identifiers, card numbers, plus any exact terms you add. Nothing stored, no third-party AI. Tools - redact_text: returns the redacted text and a count of what was removed, by type. Never the removed values. Options: restrict to particular data types, add exact terms to remove, choose the replacement style (a type label such as <PERSON> by default) and set a confidence threshold. - list_entity_types: lists the detectable data types. Free. Data handling - Nothing you send is stored. Text is processed in memory and discarded when the call returns. - No third-party AI. Text is never sent to OpenAI, Anthropic, Google or any other outside model. - Tool arguments are never logged. Only counts are kept: credits used, a timestamp and how many of each type were found. PDFs, including scanned pages, are handled by the REST API with the same key and credits. They aren't offered as an MCP tool because a file doesn't fit in a tool call. Pricing: 1 credit per call plus 1 per 1,000 characters. 10 free credits on sign-up, no card. Credit packs from $5; purchased credits never expire. Failed calls and repeated identical calls are free. Setup and API key: https://eleyed.com/mcp?utm_source=glama&utm_medium=directory&utm_campaign=listing
Check a document for hidden text before your agent reads it. PDF, Office, RTF, HTML.
Related MCP Servers
- FlicenseAqualityCmaintenancePII sanitization layer for autonomous AI agent pipelines. Detects and redacts emails, phone numbers, national IDs, private keys, and financial data before text reaches LLMs. Supports EN, ES (LATAM), PT (BR/PT), DE, JA.12-

classifinder-mcpofficial
AlicenseAqualityBmaintenanceEnables AI agents to scan text for leaked secrets and prompt injection markers, and redact them before reaching an LLM.21MIT- AlicenseAqualityDmaintenanceScans prompts for PII and masks or redacts sensitive data locally before sending to an LLM, supporting multiple anonymization modes.1MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to redact PII from text, summarize redacted content, and manage custom redaction patterns across multiple languages.-