# What is and isn’t detected

> Which text MCP Shield inspects, its prompt-injection detectors and DLP patterns, and what passes without inspection.

MCP Shield checks text with deterministic patterns. This page says exactly which text, with which detectors, and what passes without being looked at.

## Which text is inspected

| Direction | Setting | Text |
|---|---|---|
| Client to server | `inspect_requests` | `params.arguments` of `tools/call`, the `params` of `resources/read`, `params.arguments` of `prompts/get` |
| Server to client | `inspect_responses` | Every string in `result` and `error` of the server's responses to requests with an id (tool results, resource contents, prompts, and the tool descriptions of `tools/list`), and the `params` of requests the server sends to the client (`sampling/createMessage`, `elicitation/create`) |

JSON responses are read whole, up to 2 MiB. Server-sent event streams (`text/event-stream`, from a `POST` or from the `GET` stream) are checked one event at a time as they arrive; each event is forwarded as soon as it has been checked, so streaming and flushing keep working.

## Prompt injection and exfiltration

The same 27 detectors that protect AI endpoints, in English and Spanish. Each one only runs when one of its keywords appears in the text, so ordinary traffic skips almost all of them. Their ids start with:

- `pi.`: instruction overrides, system-prompt extraction, jailbreak personas and modes, fake system and compliance notices, orders to hide something from the user, chat-template tokens, forged tool calls, tool results and conversation turns, memory poisoning, orders to call a tool, approval bypass, and instructions inside HTML comments, base64 or percent or hex encoding.
- `agent.`: destructive commands such as `rm -rf /` or `DROP TABLE`.
- `exfil.`: remote scripts piped to a shell, secret harvesting, sending host data out, exfiltration through a rendered image or link.
- `hidden.`: text hidden from a human reader: zero-width characters, Unicode tag characters, CSS-hidden text.

## Credential leaks (DLP)

| Id | What it finds |
|---|---|
| `dlp.aws_access_key` | AWS access key ids (`AKIA…`) |
| `dlp.github_token` | GitHub personal and server tokens (`ghp_…`, `ghs_…`) |
| `dlp.stripe_secret_key`, `dlp.stripe_test_key` | Stripe secret keys (`sk_live_…`, `sk_test_…`) |
| `dlp.private_key` | PEM private key headers |
| `dlp.database_url` | PostgreSQL, MySQL and MongoDB connection URLs |
| `dlp.slack_token` | Slack tokens (`xox…`) |
| `dlp.sendgrid_key`, `dlp.mailgun_key` | SendGrid and Mailgun keys |
| `dlp.openai_key`, `dlp.anthropic_key` | OpenAI project, service-account and admin keys, Anthropic keys (`sk-ant-…`) |
| `dlp.openwaf_token`, `dlp.openwaf_egress_token` | OpenWAF API tokens (`owf_…`) and OpenWAF Egress placeholders (`OWE_TOKEN_…`) |
| `dlp.generic_api_secret` | A quoted value of 20 characters or more assigned to `api_secret` or `secret_key` |

A DLP match is stored redacted: only its first four characters followed by `…`. The secret itself never reaches events, the dashboard or the API.

## Policy checks

Besides inspection, every JSON-RPC message from the client is checked against the endpoint's policy. Their detection ids are `mcp.method_not_allowed`, `mcp.tool_denied`, `mcp.tool_not_allowed`, `mcp.rate_limited`, `mcp.parse_error`, `mcp.invalid_request` and `mcp.too_large`.

## What is not detected

- **Anything a pattern does not describe.** There is no semantic classifier and no language model. Paraphrased instructions, other languages and encodings the detectors do not cover pass. A clean result is not proof that a message is safe.
- **Notifications.** Their content is not inspected, in either direction. Client notifications still go through the allowed methods.
- **Requests from the server to the client** (`sampling/createMessage`, `elicitation/create`) are inspected but only logged, never replaced.
- **The client's answers** to those requests are not inspected.
- **Large or encoded responses.** A JSON response over 2 MiB, an SSE event over 2 MiB and a response that still arrives compressed (`Content-Encoding`) pass unchanged. They are counted as **uninspected** in the report.
- **Large requests in log mode.** A body over `max_request_kb` passes uninspected in log mode; in enforce mode it is refused.
- **Other methods' parameters.** `completion/complete`, `logging/setLevel`, list methods and the rest are checked against the allowed methods only.
- **Resources and prompts by name.** The tool lists apply to `tools/call` only; there is no allow or deny list for resource URIs or prompt names.
- **Headers and query strings.**
- **Authentication.** MCP Shield never validates the token; your server does.

## False positives

A tool that returns security material, such as logs of blocked attacks, a page about prompt injection or a sample `.env` file, will trigger detections on legitimate content. That is why inspection starts in `log`: read the detection ids and snippets in the events first, and keep `block` for the endpoints where a replaced result is acceptable.
