Skip to content

Tool Call Inspection

The DLP pipeline inspects tool call arguments and tool results, not just user messages and model responses. The ToolPayloadParser normalizes three provider message formats into a common ToolContent representation, which is then scanned through the same DLP pipeline tiers as any other text.

Malformed tool messages are logged and skipped (fail-open). This ensures that parser errors do not produce false positives or block legitimate requests.

The parser handles tool calls and results from three provider message formats:

Provider Tool Call (Input) Tool Result (Output)
OpenAI function_call object on assistant message; tool_calls array on assistant message role: "tool" message with content string
Anthropic tool_use content block (with name and input fields) tool_result content block (with content text or text blocks)
MCP JSON-RPC message with method: "tools/call" and params.name + params.arguments JSON-RPC message with result containing content array of text blocks

Each parsed tool message is normalized into a ToolContent object with the following fields:

Field Type Description
tool_name string Name of the tool being called (empty for result messages)
arguments dict Tool call arguments as key-value pairs (empty for results)
result string Tool result text (empty for input-direction messages)
direction "input" or "output" Whether this is a tool call (input) or tool result (output)
provider_format string Source format: "openai", "anthropic", or "mcp"
raw dict Original message for audit trail

Tool content passes through the same DLP pipeline as prompt and response text:

  • Input direction (tool call arguments): the tool name and arguments are serialized to JSON and scanned through the regex and NER tiers
  • Output direction (tool results): the result text is scanned through the DLP pipeline and optionally through the Tier 0 prompt injection classifier

DLP findings from tool content appear in the same audit event as other scan results, with standard tier and entity_type fields.

Messages arrive
ToolPayloadParser.parse(messages)
├─ OpenAI format? → parse function_call / tool_calls / tool role
├─ Anthropic format? → parse tool_use / tool_result content blocks
└─ MCP format? → parse JSON-RPC method / result
List[ToolContent]
extract_scannable_text(tool_content)
├─ Input: JSON.dumps({tool_name, arguments})
└─ Output: result string
DLP Pipeline (same tiers as prompt/response scanning)

When the parser encounters a malformed tool message, it:

  1. Logs a warning with event tool_parser_skip and the exception details
  2. Skips the malformed message
  3. Continues processing remaining messages

The request is not blocked due to parser errors. This design prevents false positives from unexpected message structures and ensures that legitimate traffic is not disrupted by format edge cases.

OpenAI uses three message structures for tool interactions:

Legacy function_call — assistant message with a function_call object:

{
"role": "assistant",
"function_call": {
"name": "get_weather",
"arguments": "{\"location\": \"New York\"}"
}
}

tool_calls array — assistant message with multiple tool calls:

{
"role": "assistant",
"tool_calls": [
{
"id": "call_abc123",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\": \"New York\"}"
}
}
]
}

Tool result — message with role: "tool":

{
"role": "tool",
"tool_call_id": "call_abc123",
"content": "Temperature in New York is 72°F"
}

Arguments are JSON strings that the parser deserializes. Invalid JSON triggers tool_parser_skip and the tool call is excluded from scanning.

Anthropic uses content blocks within messages:

tool_use block (input):

{
"role": "assistant",
"content": [
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "get_weather",
"input": {"location": "New York"}
}
]
}

tool_result block (output):

{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Temperature in New York is 72°F"
}
]
}

Result content can be a plain string or a list of text blocks. Both forms are supported.

MCP uses JSON-RPC messages:

Tool invocation (input):

{
"jsonrpc": "2.0",
"method": "tools/call",
"params": {
"name": "get_weather",
"arguments": {"location": "New York"}
},
"id": 1
}

Tool result (output):

{
"jsonrpc": "2.0",
"result": {
"content": [
{"type": "text", "text": "Temperature in New York is 72°F"}
]
},
"id": 1
}

For MCP servers registered in the platform, tool call inspection applies to both the request (tools/call) and response (result) phases.

Three runtime switches control tool inspection behavior. All default to disabled (false). Toggle them in Admin → Tool Inspection or programmatically via the system config API.

Config key: tool_content_scanning_enabled

When enabled, tool call arguments and tool results are scanned through the DLP pipeline. This is the master switch for the ToolPayloadParser flow described above — when disabled, tool messages pass through without DLP inspection.

Enable this when your organization uses tool-calling models and you need DLP coverage on tool I/O (e.g., tools that return database records, PII, or sensitive documents). Disable it to reduce scan overhead if your deployment does not use tool calls.

Config key: tool_manifest_validation_enabled

When enabled, the platform validates tool manifest schemas and checks for undeclared tool calls — tool invocations that reference tools not present in the registered manifest. Undeclared tool calls are flagged in the audit log.

Enable this to enforce tool governance: only declared, schema-valid tools are permitted. Disable it during development or when integrating third-party MCP servers whose manifests are not yet registered.

Config key: mcp_inline_proxy_enabled

When enabled, activates the POST /api/v1/mcp/proxy transparent interception endpoint. All MCP tool calls routed through this endpoint are subject to DLP scanning, manifest validation (if enabled), and audit logging.

Important: When proxy mode is active, your MCP clients must be configured to send tool calls through /api/v1/mcp/proxy instead of connecting directly to MCP servers. Direct connections bypass the inspection pipeline entirely.

Enable this for full tool-call interception in MCP deployments. Disable it if MCP traffic is already routed through the gateway’s standard intake path or if you do not use MCP.

Read current values:

Terminal window
curl https://platform.arbitex.ai/api/v1/admin/config \
-H "Authorization: Bearer $ADMIN_TOKEN"

Update a toggle:

Terminal window
curl -X PUT https://platform.arbitex.ai/api/v1/admin/config/tool_content_scanning_enabled \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{"value": true}'

Replace the key in the URL path for any of the three config keys above.