Trace Agent Tools

Tool tracing takes your red team beyond black-box testing. During a scan, your agent reports each tool call and its result to Red, so evaluation is grounded in what the agent actually did — not only its final reply.

Tracing works for any agent you red team, however you run the scan — a target you connect in the AI Red Teaming platform, or a scan you drive with the SDK. The integration is the same: one outbound call at the tool boundary, in your agent’s own runtime, and it returns your tool’s result unchanged.

How it works

Intercept each tool result with a single call:

  1. Your tool runs and returns its result, exactly as today.
  2. The SDK sends the tool name, arguments, and result to the Red API over HTTPS.
  3. You get the same result back, in the same shape — string, number, boolean, null, array, or object.

Each call carries a conversation id you supply — your app’s own conversation, thread, or session id. Red uses it to tie the tool activity to the right scan and to line findings up with your own logs.

The call sits at the tool boundary, so it works wherever your tools run — in-process, behind an MCP client, or a custom runtime. No framework adapter.

Prerequisites

  • The lakera-red-sdk installed in your agent’s runtime (Node.js 22+ or Python 3.11+)
  • A Red Team API Key from the AI Red Teaming platform

Enable tracing

Tracing is gated by an environment variable, off by default: unless the environment opts in, every call is a no-op with zero network egress, so it is safe to wire into shared code. Gate the call in your own code as well for explicit control — the flag is the SDK-side backstop that no data leaves an environment that has not opted in.

$export LAKERA_RED_TOOL_INTERCEPT="true" # off by default
$export LAKERA_RED_API_KEY="your-red-team-api-key" # read from the environment
$export LAKERA_RED_URL="https://red-webhooks.lakera.ai" # Red API base URL

Inject the API key from your secrets manager at deploy time. Never hardcode it in source or commit it to version control. All traffic is sent over TLS.

Instrument a tool

Call interceptTool (TypeScript) / intercept_tool (Python) where your tool produces its result, and return what it gives back. Pass the tool name, the arguments as a JSON string, the result, and your conversation id. The function is module-level — there is nothing to instantiate.

1import { interceptTool } from "lakera-red-sdk"
2
3async function getTickets(status: string, conversationId: string) {
4 const result = await getTicketsApi(status) // your real tool
5 return await interceptTool({
6 toolName: "get_tickets",
7 toolArguments: JSON.stringify({ status }),
8 result,
9 conversationId, // your own conversation/thread id
10 })
11}

Instrument via a dispatch middleware

If your tools already flow through a single dispatch path or middleware wrapper, add the tracing call once there instead of editing each tool. Read the tool name and arguments from the call context, gate on the environment, and optionally scope to an allowlist.

1import { interceptTool } from "lakera-red-sdk"
2
3const LAKERA_RED_ENABLED = process.env.LAKERA_RED_TOOL_INTERCEPT === "true"
4const TRACED_TOOLS = new Set(["url_fetch"]) // optional: scope to specific tools
5
6// registered once in your existing tool-dispatch middleware
7const lakeraRedMiddleware = async (call, ctx, next) => {
8 const result = await next(call, ctx) // run the real tool
9
10 if (!LAKERA_RED_ENABLED || !TRACED_TOOLS.has(call.name)) {
11 return result
12 }
13
14 try {
15 return await interceptTool({
16 toolName: call.name,
17 toolArguments: JSON.stringify(call.args),
18 result,
19 conversationId: ctx.conversationId, // your stable per-conversation id
20 })
21 } catch {
22 return result // fail-open: never break the agent
23 }
24}

The middleware signature (call, ctx, next) is illustrative — map it to your runtime’s own wrapper. For MCP or other remote tools, place the call at the MCP-client boundary, where the tool result comes back.

Both placements are supported: intercept at the source for higher fidelity — the raw result, before any post-processing your tool does (redaction, sanitization, truncation) — or in the middleware, which captures what the model actually receives. Without post-processing the two are equivalent; the middleware is usually less invasive.

Connect tracing to your scan

Red associates reported tool calls with a scan using the conversation id. How that id is provided depends on how you run the scan:

  • Platform targets — a target you connect in the AI Red Teaming platform reports with its own session id, and Red associates it with the scan automatically. No extra step.
  • SDK-driven scans — bind the same conversation id to the scan session in your driver. See Enable Tool Tracing for SDK Scans.

Reference

JsonValue

The type of a traced tool result — any JSON value: string, number, boolean, null, an array of JsonValue, or an object with JsonValue fields. The call accepts any of these and returns the same shape.

interceptTool / intercept_tool

Reports one tool call and returns the result to use.

1function interceptTool(options: {
2 toolName: string
3 toolArguments: string
4 result: JsonValue
5 conversationId: string
6 apiKey?: string
7 baseUrl?: string
8}): Promise<JsonValue>
OptionTypeRequiredDescription
toolNamestringYesThe tool’s name, e.g. "get_tickets"
toolArgumentsstringYesThe tool’s arguments as a JSON string
resultJsonValueYesThe real tool result — see JsonValue
conversationIdstringYesYour conversation/thread id
apiKeystringNoOverrides the key read from LAKERA_RED_API_KEY
baseUrlstringNoOverrides the URL read from LAKERA_RED_URL

Returns the result to use — while tracing, the same value you passed in.

Environment variables

VariableRequiredDescription
LAKERA_RED_TOOL_INTERCEPTYesSet to "true" to enable. Off by default (no-op, no egress)
LAKERA_RED_API_KEYYesRed Team API Key, injected from your secrets manager
LAKERA_RED_URLYesRed API base URL, e.g. https://red-webhooks.lakera.ai

Data and security

  • What leaves your environment: the tool name, arguments, and result you pass to the call — over TLS to the Red API.
  • Opt-in: with LAKERA_RED_TOOL_INTERCEPT unset, the call is a no-op and makes no network request.
  • Tenancy: requests are attributed to your organization from the API key.
  • Conversation id: your own identifier. Red stores it to associate reported tool calls with the scan and to let you correlate findings with your logs.