Skip to main content
Version: Latest (1.9.x dev)

Keep only the fields an MCP tool result needs

A tool called get_customer returns the whole customer record: name, address, date of birth, payment method, support history, internal risk flags. The agent needed the email address. Everything else now sits in the model's context. It is sent to the provider on the next turn, may be summarised into memory, and is one prompt injection away from leaking. Nothing was broken: the tool was allowed, the call was allowed, and the personal-data scan did its job. OWASP lists this as MCP10, Context Injection & Over-Sharing.

The scans ask whether a result holds something sensitive. This control asks whether the result needed those fields at all. DVARA, the AI governance platform, can remove the fields a tool's result did not need before they reach the model, even when the server is a vendor's and you cannot change what it returns.

Enterprise only

Not included in DVARA Open Source.

How it works​

You list, per tool, the fields to keep. Everything else in that tool's result is removed. A tool you have not listed is not changed, so you can adopt this one tool at a time.

Fields are written as paths: email, or customer.email for a field inside another. Lists are passed through: orders.total keeps total in every order. A path keeps the field and everything inside it.

Some tools key a result by data rather than by field name, for example a map from email address to customer. Write * for such a key: customers.*.email keeps the email under every customer. A named key wins over *.

The Gateway applies the list to:

  • the structured result (structuredContent);
  • a text part of the result that holds JSON (servers usually send the structured result there too, so it is trimmed the same way);
  • the JSON a REST tool returns.

A text part that is plain prose cannot be trimmed safely. It is left as it is, and the record counts it, so you can see that it still carries what it carried.

Fields are removed before the result is scanned for personal data and prompt injection. A removed field is never scanned, logged or sent on.

A valid result stays valid​

If the tool declares an output schema, a field the schema says is required is always kept, even when you did not list it. A client that checks results against the schema will not reject a trimmed one. The record says which fields were kept for this reason. If one of them is the sensitive field, the fix is in the tool or its schema, or in redaction by the personal-data scan.

A result that no longer matches its schema​

DVARA pins each tool's definition, its output schema included, when you approve it. When this control is on and a tool has an output schema, the record also lists the fields a result carries that the schema does not declare. A server returning more than it declared is over-sharing, or has changed shape since you approved it. This is recorded, not refused.

Turn it on​

Three modes, set per workspace:

ModeWhat happens
offNothing. The default.
discoverResults are not changed. Each tool call's audit record lists every field the result carried and, for a listed tool, what enforce would remove.
enforceFields not listed for a tool are removed from its results.

Start with discover, so you write the list from what the tool really returns:

  1. Set the mode to discover and call the tool.
  2. Read the tool call's record in the audit log: it lists the fields the result carried, and how many. Fields the tool's output schema declares are listed by name; any other key is shown as * (see What is recorded). For a tool with no output schema, take the names from its documentation.
  3. List the fields the agent needs, and check the record again: it shows what would be removed.
  4. Set the mode to enforce.

Set both in the workspace's metadata, for example with a GitOps import:

workspaces:
- name: support
metadata:
mcp.response-projection.mode: enforce
mcp.response-projection.tools:
crm/get_customer: [email, orders.total]

The tool is named as <server id>/<tool name>. The import refuses an unknown mode, a tool name without its server, and an entry with no fields. A change reaches the gateways with their next configuration update, with no restart.

What is recorded​

Each tool call's audit record names the fields that were removed and how many, the fields kept because the output schema requires them, and the fields outside the output schema. It never holds a field's value.

A field's path is built from the keys of the result, and a server can use data as a key: an email address, an account number. The audit record is signed and cannot be edited, so it must not hold them. A part of a path is written by name only when the tool's output schema or your list of fields names it. Any other part is written as *, as in customers.*.email, and a count says how many fields the paths stand for.

Limits​

  • No Flightdeck page yet. Set the keys by GitOps import.
  • Plain text is not trimmed. Only JSON can be cut down by field.
  • Tool calls only. Results read later through a task, and resources a client reads, are not trimmed.
  • Required fields stay. The Gateway will not make a result break its own schema.