Repository navigation
feat(guardrails): support during_call and MCP tool call modes in the Airia guardrail - #49709
Draft
airia-open-source wants to merge 6 commits into
Draft
airia-open-source wants to merge 6 commits into
airia-open-source wants to merge 6 commits into
Conversation
… a tool call Cover the cases the marker must not appear in: during_call and post_call evaluations, and client request data shaped like an MCP call (a top-level mcp_tool_name, mcp_tool_call_metadata, or metadata.mcp_tool_name). Also pin the fallback name used when an MCP evaluation carries none, and that a hook that does not run leaves no marker for the next evaluation.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The Airia guardrail now runs on two more points: while the model call is in flight (
during_call), and around MCP tool calls the proxy makes (pre_mcp_callchecks a tool's arguments before it runs,post_mcp_callchecks its result). MCP evaluations tell the Airia gateway which tool they are for, so Airia applies the tenant's tool-call and tool-response filters to them instead of its prompt and response filters.Details
TLDR
Problem this solves:
pre_callandpost_callHow it solves it:
during_call,pre_mcp_callandpost_mcp_callto the supported modesduring_callblocks on a block or a redact, since the call is already runningmcp_tool_nameso Airia picks the tool filtersUser Flow
Before: a proxy admin who wants Airia to check MCP tool traffic cannot turn it on
mode: [pre_call, post_call, pre_mcp_call, post_mcp_call]to theairiaguardrail and start the proxypre_mcp_callis not a supported mode forairia/mcp-rest/tools/callreaches the tool with the user's email address in its argumentsAfter: the same config checks MCP tool arguments and results
/mcp-rest/tools/callforsend_emailwith an email inbody: the tool receives[EmailAddress1]400and the tool never runsPre-Submission checklist
pytest tests/unit/proxy/guardrails/guardrail_hooks/test_airia.py→ 61 passedScreenshots / Proof of Fix
Run against a live local Airia stack, no mocks: LiteLLM proxy → Airia AI Gateway (AiriaLLC/airia-ai-gateway#1317 at
6e1f225c) → Airia Platform and Policy Engine (origin/main, 2026-11-02) → the real PII and secrets detectors. The model is an echo server and the MCP server is a small tool server; both record what they actually received, so each case is checked on the far side of the proxy, not from the guardrail's own answer.Shared setup:
A51-317 LiteLLM demoon the tenant, targeted at LiteLLM: Standard PII (email address, phone number) → Redact & Replace; Secrets Detection → Block with the messageSecret blocked by A51-317 demo policy.Inspection points stored on both filters: Input, Output, Tool call, Tool response.guardrail: airia,mode: [pre_call, post_call, pre_mcp_call, post_mcp_call],default_on: true; theduring_callcases usemode: [during_call, post_call].POST /mcp-rest/tools/callwith{"server_id":"harness_tools","name":...,"arguments":{...}};GET /_seenon the tool server lists what each tool received.Airia Platform, the guardrail on the LiteLLM surface:
LiteLLM Dashboard, Test Guardrail panel (After; the
airiaguardrail lists all four modes):Before (f8f12a2)
Start the proxy with the new modes
mode: [during_call, post_call], then withmode: [pre_call, post_call, pre_mcp_call, post_mcp_call]Skipping guardrail 'airia': invalid configuration, proxy is starting WITHOUT this guardrail: Event hook GuardrailEventHooks.during_call is not in the supported event hooks [pre_call, post_call], and the same withpre_mcp_callfor the second configChat: allowed, redacted, blocked
mode: [pre_call, post_call], the only modes supported herewhat is the capital of France?→ 200, the model received it unchangedEmail me at ada@example.com→ 200, the model receivedEmail me at [EmailAddress1]my aws key is AKIAIOSFODNN7EXAMPLE→ 400Secret blocked by A51-317 demo policy., the model was called 0 timesduring_call: a secret in the prompt
[during_call, post_call], POST/v1/chat/completionswithmy aws key is AKIAIOSFODNN7EXAMPLEecho: my aws key is AKIAIOSFODNN7EXAMPLE: the guardrail was dropped at startup, nothing was checkedduring_call: an email, which the gateway would redact
/v1/chat/completionswithEmail me at ada@example.comecho: Email me at ada@example.compre_mcp_call: an email in the arguments
[pre_call, post_call, pre_mcp_call, post_mcp_call], callsend_emailwith{"to":"ada@example.com","body":"hello"}/_seen:{"tool":"send_email","to":"ada@example.com","body":"hello"}, 1 execution, nothing redactedpre_mcp_call: an AWS key in the arguments
run_sqlwith{"query":"select 1 -- AKIAIOSFODNN7EXAMPLE"}/_seenshows the query reached the tool, 1 executionpost_mcp_call: contact details in the result
lookup_contactwith{"name":"Ada"}Ada: reach ada@example.com or call 415-555-0199, nothing redactedNo Tool call or Tool response filters configured
send_email,run_sqlandlookup_contactcalls aboveAfter (0e1cb53)
Start the proxy with the new modes
mode: [during_call, post_call], then withmode: [pre_call, post_call, pre_mcp_call, post_mcp_call]GET /guardrails/listand the dashboard showairiawithpre_call, post_call, pre_mcp_call, post_mcp_callChat: allowed, redacted, blocked
what is the capital of France?→ 200, the model received it unchangedEmail me at ada@example.com→ 200, the model receivedEmail me at [EmailAddress1]my aws key is AKIAIOSFODNN7EXAMPLE→ 400Guardrail raised an exception, Guardrail: airia, Message: Secret blocked by A51-317 demo policy., the model was called 0 timesduring_call: a secret in the prompt
[during_call, post_call], POST/v1/chat/completionswithmy aws key is AKIAIOSFODNN7EXAMPLEGuardrail raised an exception, Guardrail: airia, Message: Secret blocked by A51-317 demo policy.; the model was called once, in parallel with the check, and its reply was discardedduring_call: an email, which the gateway would redact
/v1/chat/completionswithEmail me at ada@example.comGuardrail raised an exception, Guardrail: airia, Message: Blocked by your organization's content policy.: the call is already running, so a redaction cannot be applied and comes back as a blockpre_mcp_call: an email in the arguments
send_emailwith{"to":"ada@example.com","body":"hello"}/_seen:{"tool":"send_email","to":"[EmailAddress1]","body":"hello"}, 1 executionpre_mcp_call: an AWS key in the arguments
run_sqlwith{"query":"select 1 -- AKIAIOSFODNN7EXAMPLE"}guardrail_violation ... Secret blocked by A51-317 demo policy.;/_seenis empty, the tool never ranpost_mcp_call: contact details in the result
lookup_contactwith{"name":"Ada"}Ada: reach [EmailAddress1] or call 415-555-0199; the email is redacted. The phone number is not: the detector does not flag the fictional555number, which is a detector matter, not this changeNo Tool call or Tool response filters configured
ada@example.com, the AWS key query runs, the result is not redacted. MCP traffic is checked only under Tool call and Tool response filters, never under the prompt and response filtersType
🆕 New Feature
Caveats (if any)
Medium
mcp_tool_nameand checks MCP traffic with prompt/response filterspre_mcp_callalso runs when the proxy scans a server's tool catalog, which is how LiteLLM treats every guardrail in that mode (MCP_GUARDRAIL_CALL_TYPESincludeslist_mcp_tools;tool_catalog_guardruns on eachtools/list)texts, ahead of any argumentstools/listand blocks calls to it whatever the argumentsLow
during_mcp_callis intentionally not supported