> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mcpmanager.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Redact PII from tool responses with Presidio

> A hands-on MCP Manager lesson: add a Microsoft Presidio rule on the response leg of a gateway, fail it closed, trigger it with a tool result that contains an email address, and confirm the value was replaced with a typed tag in your logs.

This tutorial filters real PII out of a tool's result before it reaches the model. You'll add a [Microsoft Presidio](/features/gateway-rules/presidio) rule on the **response** leg of a gateway, set it to **fail closed**, then make a tool call whose result contains an email address and watch the gateway replace it with a typed tag — `<EMAIL_ADDRESS>` — on the way back to your client. That response-leg redaction is the core of keeping customer data out of the model.

It builds on [Add your first gateway rule](/tutorials/first-gateway-rule), which used a regex rule on the request leg. Here you use the managed Presidio engine on the response leg instead: model-driven detection, typed replacement tags, and a fail-closed posture.

<Info>
  This tutorial uses the **Microsoft Presidio** detection method, which is a managed **add-on**. If choosing Presidio in the rule editor shows a **Schedule consultation** option instead of configuration fields, your workspace doesn't have the add-on — follow [Add your first gateway rule](/tutorials/first-gateway-rule) with the built-in regex method instead, which is always available. Adding rules uses the **Basic gateway management** capability; see the [capabilities reference](/deployment/rbac-and-roles/capabilities).
</Info>

## What you'll need

* A gateway with a server whose tool returns text. The **Quickstart** gateway with the public docs MCP server from [Your first governed tool call](/tutorials/first-tool-call) works without any credentials.
* Your AI client connected to that gateway.
* The Presidio add-on enabled on your workspace.
* About 10 minutes.

## Why the response leg

A gateway rule fires on either the **request** leg (the client's `tools/call` heading to the server) or the **response** leg (the server's result heading back). PII filtering's main job is on the **response** leg: a tool returns data — a customer record, a search hit, a support ticket — and the gateway strips the PII out of that result before it ever reaches the model. That's the leg this rule runs on. (The request leg matters too, for stopping PII in tool *arguments* from leaving for an external server; see [PII Filtering](/features/pii-filtering).)

## Step 1: Add a Presidio rule on the response leg

<Steps>
  <Step title="Open the Rules tab">
    Open your gateway from [Gateways](https://app.mcpmanager.ai/settings/gateways) and go to its **Rules** tab. Click **Add new rule**.
  </Step>

  <Step title="Name it and choose Presidio">
    Give it a **Rule name** like `Redact emails in results`. Choose **Microsoft Presidio** as the **Detection method**. The configuration fields appear below; if you see a **Schedule consultation** option instead, your workspace doesn't have the add-on (see the note above).
  </Step>

  <Step title="Select the entity type">
    Under **Entity types**, select **`EMAIL_ADDRESS`**. Selecting one entity narrows detection to just emails, which keeps this first rule predictable. (Selecting none would detect every supported type.) Leave the **Confidence threshold** at its default of **0.2**.
  </Step>

  <Step title="Fire it on the response">
    Set the **Detection hook** to **Response**, so the rule scans the server's result on its way back to your client.
  </Step>

  <Step title="Fail closed and choose Replace">
    Set the **Failure mode** to **Block** — so if the Presidio service is ever unreachable the message is blocked rather than passed unscanned. This is the fail-closed posture you want for PII. Set the **Action** to **Replace**, which swaps each detected email for the typed tag `<EMAIL_ADDRESS>` and lets the rest of the result through.
  </Step>

  <Step title="Turn on alerts and enable it">
    Switch the **Alerts** toggle on, make sure the rule is **Enabled**, and save. The rule is now live on this gateway's response traffic.
  </Step>
</Steps>

<Tip>
  Presidio's **Replace** tags each value by its type — `<EMAIL_ADDRESS>`, `<CREDIT_CARD>`, `<US_SSN>` — which is more informative than the single `<SENSITIVE>` placeholder a regex Replace uses. The reader (and the model) can still see *what kind* of value was removed.
</Tip>

## Step 2: Trigger the rule

Make a tool call whose **result** contains an email address. With the public docs server connected, ask your client to fetch documentation that includes an example address:

```text theme={null}
Search the MCP Manager docs for an example email address and quote the matching text exactly.
```

The docs include example addresses such as `alice@example.com`, so the server's result carries one back through the gateway. On the response leg, the Presidio rule detects the `EMAIL_ADDRESS`, replaces it with `<EMAIL_ADDRESS>`, lets the (now-sanitized) result continue to your client, and raises an alert.

<Note>
  Any tool call whose result contains an email works — a CRM lookup, a Slack search, a support-ticket fetch. The docs server is just a credential-free way to produce one on demand. If your result happens to contain a person's name too, add `PERSON` to the entity types, but expect names in short or terse text to be caught less reliably than structured values like emails — see [Reliability with names](/features/gateway-rules/presidio#reliability-with-names-and-free-form-text).
</Note>

## Step 3: See that it fired

<Steps>
  <Step title="Open the logs">
    Go to [Logs](https://app.mcpmanager.ai/settings/logging/logs) and find the `tools/call` you just made. Filter on its `correlation_id` to see the four legs together.
  </Step>

  <Step title="Read the rule activity">
    Open the entry's **Log details**. Because the rule modified the result, it's recorded as a `policy_enforced_mutation`, and the `rule_engine_type` reads `modify`. The **Body** shows the email replaced with `<EMAIL_ADDRESS>` — the same sanitized text your client received. (Had you used **Block**, you'd see a `policy_enforced_abort` instead, and the result would never have reached the client.)
  </Step>
</Steps>

<Check>
  You added a managed PII detection rule on the response leg, failed it closed, triggered it with a real tool result, and confirmed in the audit trail that the email was replaced with a typed tag before it reached the model. That is the control that lets a regulated team connect a system full of customer data.
</Check>

## Where to take it next

* **Layer a regex rule for structured IDs.** Place a [regex](/features/gateway-rules/regex) rule that blocks credit cards or SSNs *above* this one; regex runs in-process with no failure mode and catches fixed-shape values dependably. See [rule order](/features/gateway-rules/overview#rule-order-and-the-enable-toggle).
* **Detect more entity types.** Switch the rule to detect all entity types, or add `PERSON`, `PHONE_NUMBER`, and `LOCATION`, then tune the confidence threshold against your own traffic.
* **Reach for a classifier on free text.** For names buried in unstructured text, add a [custom rule engine](/tutorials/custom-rule-engine), [Amazon Bedrock](/features/amazon-bedrock), or [Lakera Guard](/features/lakera-guard) above the Presidio rule.

## Further reading

<CardGroup cols={2}>
  <Card title="PII Filtering" icon="user-secret" href="/features/pii-filtering">
    Why this is the blocker for adopting MCP, and the full detection-and-action model.
  </Card>

  <Card title="Microsoft Presidio" icon="user-shield" href="/features/gateway-rules/presidio">
    Entity types, the confidence threshold, failure mode, and the limits of model-based detection.
  </Card>

  <Card title="Trace a call in your logs" icon="magnifying-glass" href="/tutorials/trace-in-logs">
    Read the redacted result and the rule activity in full detail.
  </Card>

  <Card title="Add your first gateway rule" icon="shield-halved" href="/tutorials/first-gateway-rule">
    The regex, request-leg, alert-only version of this lesson.
  </Card>
</CardGroup>
