---
schema_version: "1"
id: 00de81b19d0704a2b612ebc45328563cf68dcb8c563a0d1fbcb66d66d00102ef
title: MCP Personally Identifiable Information (PII) Detector Policy
collection: mulesoft
version: current
locale: en-us
portal_url: https://docs.salesforce.com/mulesoft/current/en-us/gateway/latest/policies-included-mcp-pii-detector.md
canonical_url: https://docs.mulesoft.com/gateway/latest/policies-included-mcp-pii-detector
source_site: docs.mulesoft.com
content_type: documentation
content_hash: fb8c6124b2837fe53fcea090c6370b7afda14089d3151a54963014c9e528bb6a
description: MuleSoft Documentation Site
release: "1.14"
latest: true
---
# MCP Personally Identifiable Information (PII) Detector Policy

<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 25%;">
<col style="width: 75%;">
</colgroup>
<tbody>
<tr>
<td class="tableblock halign-right valign-top"><p class="tableblock"><strong>Policy Name</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">MCP PII Detector Policy</p></td>
</tr>
<tr>
<td class="tableblock halign-right valign-top"><p class="tableblock"><strong>Summary</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Blocks elicitation responses containing personally identifiable information (PII) from reaching MCP servers</p></td>
</tr>
<tr>
<td class="tableblock halign-right valign-top"><p class="tableblock"><strong>Category</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">MCP</p></td>
</tr>
<tr>
<td class="tableblock halign-right valign-top"><p class="tableblock"><strong>First Omni Gateway version available</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">v1.9.3</p></td>
</tr>
<tr>
<td class="tableblock halign-right valign-top"><p class="tableblock"><strong>Release Notes</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><a href="https://docs.mulesoft.com/release-notes/gateway/policies/mcp-pii-detector-release-notes" class="xref page">MCP PII Detector</a></p></td>
</tr>
<tr>
<td class="tableblock halign-right valign-top"><p class="tableblock"><strong>Returned Status Codes</strong></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">No return codes exist for this policy. The policy reports a policy violation when PII is detected.</p></td>
</tr>
</tbody>
</table>

## [](#summary)Summary

The MCP PII Detector policy detects personally identifiable information (PII) in Model Context Protocol (MCP) JSON-RPC traffic on both the request and response sides.

When PII is detected, you can configure the policy to reject the request or response, log findings, or log masked findings. The policy reports a policy violation when PII is detected.

## [](#configuring-policy-parameters)Configuring Policy Parameters

### [](#omni-gateway-local-mode)Omni Gateway Local Mode

The MCP PII Detector policy isn’t supported in Local Mode.

### [](#connected-mode)Managed Omni Gateway and Omni Gateway Connected Mode

When you apply the policy from the UI, the following parameters are displayed:

<table class="tableblock frame-all grid-all fit-content spread">
<colgroup>
<col>
<col>
<col>
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Element</th>
<th class="tableblock halign-left valign-top">Required</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>PII Types</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Yes</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Array of built-in PII types to detect. Supported values are <strong>Email</strong>, <strong>US SSN</strong>, <strong>Credit Card</strong>, and <strong>Phone Number</strong>. For more information, see <a href="#pii-types">PII Types</a>.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Custom PII Patterns</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>No</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Array of custom regex patterns to detect additional sensitive values. Define a name and regex pattern for each array entry. For example, use <code>name: AWS Access Key</code> and <code>pattern: AKIA[0-9A-Z]{16}</code> to detect AWS access keys.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Action</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>No</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Action to take when PII is detected. Supported values are <strong>Reject</strong>, <strong>Log</strong>, and <strong>Log and mask</strong>. Default is <strong>Log</strong>.</p>
</div></div></td>
</tr>
</tbody>
</table>

## [](#how-this-policy-works)How This Policy Works

The MCP PII Detector policy is symmetric: it scans both request and response sides of MCP JSON-RPC traffic for PII. It recursively inspects all string values in both `params.` **(for requests) and `result.`** (for responses).

The policy scans:

- **JSON-RPC requests**: All string values under `params.*` from client to server
- **JSON-RPC responses**: All string values under `result.*` from server to client, including nested objects and arrays
- **Elicitation responses**: JSON-RPC responses sent from client back to server (MCP elicitation pattern)
- **SSE streams**: Each `data:` payload in Server-Sent Events (MCP Streamable HTTP transport)

<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 14.2857%;">
<col style="width: 28.5714%;">
<col style="width: 28.5714%;">
<col style="width: 28.5715%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Traffic Type</th>
<th class="tableblock halign-left valign-top">Reject</th>
<th class="tableblock halign-left valign-top">Log</th>
<th class="tableblock halign-left valign-top">Log and Mask</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Request processing</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Blocks the request with HTTP 403 error response. The upstream server never receives the request.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwards the request and logs findings with actual PII values.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwards the request and logs findings with masked values.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Response processing (application/json)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Blocks the response with HTTP 403 error response. The client doesn’t receive the original response containing PII.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwards the response and logs findings with actual PII values.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Rewrites every string under <code>result</code> with masked values and forwards the sanitized response.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Elicitation responses (client → server)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Rewrites the result to indicate the response was declined and forwards the sanitized body to the server.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwards the response and logs findings.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwards the response and logs masked findings.</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">SSE streams (text/event-stream)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Entire stream is replaced with a single JSON-RPC error envelope and Content-Type changes to application/json.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwards the stream unchanged and logs findings.</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Each event’s result strings are rewritten with masked variants while preserving SSE framing.</p></td>
</tr>
</tbody>
</table>

The policy detects overlapping PII patterns and keeps the longest (most specific) match. For example, a credit card number with delimiters that could also match an SSN pattern is detected as a credit card.

## [](#pii-types)PII Types

When you configure an MCP PII Detector policy, you can choose which types of PII to detect:

<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
<col style="width: 83.3334%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">PII Type</th>
<th class="tableblock halign-left valign-top">Description</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Email</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Standard email addresses such as <code>User.Name+tag@example.com</code>.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>US SSN</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>United States Social Security Numbers (SSNs), including formats with various delimiters such as <code>123-45-6789</code>, <code>123 45 6789</code>, <code>123.45.6789</code>, <code>123,45,6789</code>, <code>123/45/6789</code>, <code>123\45\6789</code>, or <code>123456789</code>.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Credit Card</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Credit card numbers for Visa, MasterCard, American Express, and Discover, with or without separators. Examples: <code>4111-1111-1111-1111</code>, <code>4111 1111 1111 1111</code>, <code>4111111111111111</code>, <code>4111.1111.1111.1111</code>, <code>5500-0000-0000-0004</code>, <code>3782-822463-10005</code>, <code>6011-0000-0000-0004</code>.</p>
</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Phone Number</p>
</div></div></td>
<td class="tableblock halign-left valign-top"><div class="content"><div class="paragraph">
<p>Phone numbers in common domestic and international formats based on ITU E.164 country codes. Examples include US numbers like <code>(555) 123-4567</code>, <code>555-123-4567</code>, <code>+1-555-123-4567</code>, and international numbers like <code>+91 98765 43210</code>, <code>+44 20 7946 0958</code>, <code>+49 30 12345678</code>.</p>
</div></div></td>
</tr>
</tbody>
</table>

## [](#example-request-and-logging)Example Request and Logging

This example shows a request containing PII and the corresponding log output for different action configurations:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "id": 1,
  "params": {
    "name": "send_email",
    "arguments": {
      "to": "john.doe@example.com",
      "message": "Contact info: phone is (555) 123-4567, SSN is 123-45-6789"
    }
  }
}
```

- Log
- Log and Mask
- Reject

When the action is set to **Log**, the policy logs detect PII with the actual values:

```text
[accessLog] PII detected in request (log only): [{"pii_type": "Email", "value": "john.doe@example.com", "start": 0, "end": 20}, {"pii_type": "Phone", "value": "(555) 123-4567", "start": 0, "end": 14}, {"pii_type": "SSN", "value": "123-45-6789", "start": 0, "end": 11}]
```

When the action is set to **Log and mask**, the policy logs detect PII with masked values:

```text
[accessLog] PII detected in request (log only): [{"pii_type": "Email", "masked_value": "****@example.com", "start": 0, "end": 20}, {"pii_type": "Phone", "masked_value": "+1******567", "start": 0, "end": 14}, {"pii_type": "SSN", "masked_value": "***-**-*789", "start": 0, "end": 11}]
```

When the action is set to **Reject**, the policy blocks the request, logs masked findings, and returns an HTTP 403 error response:

Log output:

```text
[accessLog] PII detected in request and declined: [{"pii_type": "Email", "masked_value": "****@example.com", "start": 0, "end": 20}, {"pii_type": "Phone", "masked_value": "+1******567", "start": 0, "end": 14}, {"pii_type": "SSN", "masked_value": "***-**-*789", "start": 0, "end": 11}]
```

Error response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32602,
    "message": "Request payload validation error",
    "data": {
      "reason": "policy_pii_detected",
      "phase": "request",
      "policy": "mcp-pii-detector",
      "findings": [
        { "pii_type": "Email", "masked_value": "****@example.com" },
        { "pii_type": "Phone", "masked_value": "+1******567" },
        { "pii_type": "SSN", "masked_value": "***-**-*789" }
      ]
    }
  }
}
```

The upstream server never receives the original request containing PII.

<table><tbody><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">Request-side rejections use error code <code>-32602</code> (Invalid params) to indicate a client error, while response-side rejections use error code <code>-32603</code> (Internal error) to indicate the server response could not be safely returned.</td></tr></tbody></table>

## [](#example-response-and-logging)Example Response and Logging

This example shows a server response containing PII and the corresponding behavior for different action configurations:

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "User contact: john.doe@example.com, SSN: 123-45-6789"
      }
    ]
  }
}
```

- Log
- Log and Mask
- Reject

When the action is set to **Log**, the policy forwards the response and logs detected PII with actual values:

```text
[accessLog] PII detected in server response (log only): [{"pii_type": "Email", "value": "john.doe@example.com", "start": 14, "end": 34}, {"pii_type": "SSN", "value": "123-45-6789", "start": 41, "end": 52}]
```

When the action is set to **Log and mask**, the policy rewrites the response with masked values and logs masked findings:

Response sent to client:

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "User contact: ****@example.com, SSN: ***-**-*789"
      }
    ]
  }
}
```

Log output:

```text
[accessLog] PII detected in server response (masked in body): [{"pii_type": "Email", "masked_value": "****@example.com", "start": 14, "end": 34}, {"pii_type": "SSN", "masked_value": "***-**-*789", "start": 41, "end": 52}]
```

When the action is set to **Reject**, the policy blocks the response, logs masked findings, and returns an HTTP 403 error:

Log output:

```text
[accessLog] PII detected in server response and declined: [{"pii_type": "Email", "masked_value": "****@example.com", "start": 14, "end": 34}, {"pii_type": "SSN", "masked_value": "***-**-*789", "start": 41, "end": 52}]
```

Error response:

```json
{
  "jsonrpc": "2.0",
  "id": 7,
  "error": {
    "code": -32603,
    "message": "Internal error",
    "data": {
      "reason": "policy_pii_detected",
      "phase": "response",
      "policy": "mcp-pii-detector",
      "findings": [
        { "pii_type": "Email", "masked_value": "****@example.com" },
        { "pii_type": "SSN", "masked_value": "***-**-*789" }
      ]
    }
  }
}
```

The client does not receive the original response containing PII.

### [](#elicitation-response-example)Elicitation Response Example

When a client sends a JSON-RPC response back to the server (MCP elicitation pattern) containing PII, and the action is set to **Reject**, the policy rewrites the result:

Original elicitation response:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [
      {
        "type": "text",
        "text": "User SSN is 123-45-6789"
      }
    ]
  }
}
```

Sanitized response forwarded to server:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "action": "decline",
    "reason": "Elicitation response declined due to detected PII"
  }
}
```

### [](#custom-pattern-example)Custom Pattern Example

This example shows detection of a custom AWS Access Key pattern in a request:

```json
{
  "jsonrpc": "2.0",
  "method": "tools/call",
  "id": 1,
  "params": {
    "name": "deploy",
    "arguments": {
      "key": "AKIAIOSFODNN7EXAMPLE"
    }
  }
}
```

With a custom pattern configured (`name: AWS Access Key`, `pattern: AKIA[0-9A-Z]{16}`), the policy logs:

```text
[accessLog] PII detected in request (log only): [{"pii_type": "AWS Access Key", "value": "AKIAIOSFODNN7EXAMPLE", "start": 0, "end": 20}]
```

## [](#server-sent-events-sse-considerations)Server-Sent Events (SSE) Considerations

When the MCP server uses Server-Sent Events (text/event-stream) for streaming responses, the policy buffers and processes the entire stream:

- **Log**: The stream is forwarded unchanged with raw PII values logged.
- **Log and mask**: Each event’s result strings are rewritten with masked values while preserving SSE framing (event names, IDs, comments).
- **Reject**: The entire stream is replaced with a single JSON-RPC error envelope, and the Content-Type changes to application/json with HTTP 403 status.

<table><tbody><tr><td class="icon"><i class="fa icon-important" title="Important"></i></td><td class="content">SSE buffering is suitable for short-lived tool-call responses but might not be appropriate for long-lived server-pushed streams. For notification streams or progress updates, use the <strong>Log</strong> action to avoid buffering.</td></tr></tbody></table>

<table><tbody><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">When <strong>Reject</strong> is applied to an SSE stream, the response Content-Type changes from text/event-stream to application/json. Clients that strictly require SSE formatting might need to handle this change.</td></tr></tbody></table>

## [](#compliance-and-data-flow)Compliance and Data Flow

This table shows where raw PII values appear based on the configured action:

<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 20%;">
<col style="width: 40%;">
<col style="width: 40%;">
</colgroup>
<thead>
<tr>
<th class="tableblock halign-left valign-top">Action</th>
<th class="tableblock halign-left valign-top">Request/Response Body on Wire</th>
<th class="tableblock halign-left valign-top">Access Log</th>
</tr>
</thead>
<tbody>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Reject</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Masked (findings in error.data.findings[].masked_value)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Masked</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Log and mask</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Masked (rewrites response body) or unchanged (forwards request unchanged)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Masked</p></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"><p class="tableblock">Log</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Forwarded unchanged (raw PII flows through)</p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock">Raw</p></td>
</tr>
</tbody>
</table>

<table><tbody><tr><td class="icon"><i class="fa icon-important" title="Important"></i></td><td class="content"><strong>Reject</strong> is the strict mode that never writes raw PII values anywhere (wire or log). If you need raw values in logs for diagnostics, use the <strong>Log</strong> action instead.</td></tr></tbody></table>

<table><tbody><tr><td class="icon"><i class="fa icon-note" title="Note"></i></td><td class="content">For the A2A PII Detector policy, the <strong>Log and mask</strong> action only masks the access log, not the request body. The MCP PII Detector’s <strong>Log and mask</strong> action rewrites response bodies but forwards request bodies unchanged.</td></tr></tbody></table>

## [](#see-also)See Also

- [A2A PII Detector Policy](https://docs.mulesoft.com/gateway/latest/policies-included-a2a-pii-detector)
- [LLM PII Detection Policy](https://docs.mulesoft.com/gateway/latest/policies-included-llm-pii-detection)