> ## Documentation Index
> Fetch the complete documentation index at: https://docs.averta.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tool use

> Filter Anthropic tools and check model-requested `tool_use` blocks.

Anthropic tool protection has two separate stages:

* **Tool exposure**: remove blocked tools before Anthropic sees the request.
* **Tool-call check**: evaluate returned `tool_use` blocks before your app executes local code.

Keep those separate. Exposure controls what the model can plan with. Tool-call checks control what your app is allowed to execute.

## Supported Tools

The current wrapper supports user-defined client tools with a stable `name`. The tool `type` may be omitted, `custom`, or `function`.

```typescript theme={null}
const tools = [
  {
    name: "search_docs",
    description: "Search internal support documentation.",
    input_schema: {
      type: "object",
      properties: {
        query: { type: "string" },
      },
      required: ["query"],
      additionalProperties: false,
    },
  },
  {
    name: "send_email",
    description: "Send an email to a customer.",
    input_schema: {
      type: "object",
      properties: {
        to: { type: "string" },
        subject: { type: "string" },
        body: { type: "string" },
      },
      required: ["to", "subject", "body"],
      additionalProperties: false,
    },
  },
];
```

If policy blocks `send_email`, the wrapper forwards only the remaining tools.

## Tool Choice

When tools are filtered, the wrapper also sanitizes `tool_choice`.

If the request forces a specific tool with `tool_choice: { type: "tool", name: "send_email" }` and Averta blocks `send_email`, the wrapper removes that forced choice before forwarding the request. Otherwise the request would ask Anthropic to call a tool it can no longer see.

## Tool-call Checks

After Anthropic responds, the wrapper reads each returned `tool_use` block:

```typescript theme={null}
const toolUses = response.content.filter((block) => block.type === "tool_use");
```

For each block, Averta checks:

* the tool call id from `tool_use.id`
* the tool name from `tool_use.name`
* the tool arguments from `tool_use.input`
* bounded conversation context from the current Messages request
* the request `run_id` created by the request checkpoint

If a tool-call decision is `block`, the wrapper throws `AvertaSdkError` and does not return that response to your application. Your app should not execute the tool.

## Decision Callback

```typescript theme={null}
client = wrapAnthropic(client, {
  onDecision(event) {
    if (event.checkpointType === "request") {
      console.log("blocked tools:", event.decision.blockedTools ?? []);
      console.log("forwarded tools:", event.forwardedTools.length);
    }

    if (event.checkpointType === "tool_call") {
      console.log(event.tool.name, event.decision.decision);
    }
  },
});
```

## Unsupported Tool Shapes

Unsupported Anthropic tool shapes fail closed before provider execution. This is deliberate. A guardrail wrapper that silently forwards unsupported tools would create false confidence.

## Debugging

| Symptom                                                  | Check                                                                      |
| -------------------------------------------------------- | -------------------------------------------------------------------------- |
| A tool disappeared                                       | Inspect request decision `blockedTools`.                                   |
| Forced tool choice was ignored                           | The forced tool may have been blocked and `tool_choice` sanitized.         |
| `messages.create(...)` throws before Anthropic is called | Check for unsupported tool shapes or streaming input.                      |
| Tool execution never starts                              | The returned `tool_use` may have been blocked by the tool-call checkpoint. |
