Skip to main content
Use @averta-security/sdk-anthropic when your app already uses the Anthropic JavaScript SDK and you want Averta decisions around the native Messages API lifecycle. The wrapper keeps the Anthropic client shape intact:
const message = await client.messages.create({
  model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-5",
  max_tokens: 512,
  system: "You are a careful support agent.",
  messages: [
    {
      role: "user",
      content: "Summarize password reset link expiration guidance.",
    },
  ],
});

Guarded Surface

The current wrapper guards:
Anthropic callStatusNotes
client.messages.create(...)SupportedNon-streaming Messages calls.
client.messages.create({ stream: true, ... })Not supportedFails closed before Anthropic is called.
client.messages.stream(...)Not supportedFails closed before Anthropic is called.
wrapAnthropic(...) mutates and returns the client you pass in. Do not wrap the same client more than once. Create a fresh Anthropic client for each distinct Averta configuration.

Request Lifecycle

For each supported messages.create(...) call, the wrapper runs these stages:
  1. Validate that the request uses a supported non-streaming Messages shape.
  2. Normalize the latest user message into an Averta request checkpoint payload.
  3. Evaluate request policy and filter tools when Averta returns restrict_tools.
  4. Check pending tool_result blocks when this call is a pure tool-result continuation.
  5. Call Anthropic with the filtered request.
  6. Check returned tool_use blocks before your app receives them.
  7. Check final text output when the response does not contain more tool calls.
If a checkpoint returns block, the wrapper throws AvertaSdkError.

Tool Loop Example

Anthropic tool use stays provider-native. Your app still owns tool execution and message history.
const messages: Anthropic.Messages.MessageParam[] = [
  {
    role: "user",
    content: "Search the docs for password reset guidance.",
  },
];

let response = await client.messages.create({
  model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-5",
  max_tokens: 1024,
  system: "You are a careful support agent. Use tools when they help.",
  messages,
  tools,
});

const toolUses = response.content.filter((block) => block.type === "tool_use");

if (toolUses.length > 0) {
  messages.push({
    role: "assistant",
    content: response.content,
  });

  messages.push({
    role: "user",
    content: toolUses.map((toolUse) => ({
      type: "tool_result",
      tool_use_id: toolUse.id,
      content: JSON.stringify({
        matches: ["Password reset links expire after 24 hours."],
      }),
    })),
  });

  response = await client.messages.create({
    model: process.env.ANTHROPIC_MODEL ?? "claude-sonnet-4-5",
    max_tokens: 1024,
    system: "You are a careful support agent. Use tools when they help.",
    messages,
    tools,
  });
}
The second messages.create(...) call is where Averta evaluates the returned tool content before Anthropic sees it.

What Gets Normalized

InputAverta behavior
Latest user textSent as the request checkpoint payload.
Latest user base64 image blocksSent as media on the request checkpoint.
Tool definitionsSent for request-time exposure policy.
Final user message containing only tool_result blocksSent through tool-result checkpoints before provider execution.
Assistant tool_use blocks returned by AnthropicSent through tool-call checkpoints before your app receives them.
Final assistant textSent through output checkpoints when no tool calls remain.

Rich Media

Request preflight supports Anthropic image content blocks only when source.type is base64. Supported MIME types:
  • image/jpeg
  • image/png
  • image/webp
URL image sources, GIF images, document blocks, and other non-text media fail closed before provider execution.

Decision Events

Use onDecision when you need visibility into runtime behavior:
client = wrapAnthropic(client, {
  onDecision(event) {
    console.log(event.checkpointType, event.decision.decision);
  },
});
Expected checkpoint names are request, tool_call, tool_result, and output. The exact sequence depends on whether the model requests tools.