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

# Tool Policy Hooks

> Enforce tool policies on agent tool calls before execution

## Overview

The Tool Policy Hooks endpoint lets you enforce your organization's tool policies on agent tool calls. Before your agent executes a tool — whether it's a terminal command, an MCP tool, or any other action — send a request to this endpoint to check whether the call should be allowed, denied, or requires user approval.

Any agent framework or custom application can integrate with it.

Policies are configured at [gateway.getunbound.ai/policies/tool-policies](https://gateway.getunbound.ai/policies/tool-policies).

## Endpoint

```http theme={null}
POST /v1/hooks/pretool
```

## Authentication

Include your API key in the Authorization header:

```
Authorization: Bearer YOUR_API_KEY
```

## Request Body

| Parameter           | Type   | Required | Description                                                                                |
| ------------------- | ------ | -------- | ------------------------------------------------------------------------------------------ |
| `conversation_id`   | string | Yes      | Unique identifier for the conversation or session                                          |
| `model`             | string | Yes      | The model being used                                                                       |
| `event_name`        | string | Yes      | `pre_tool_use` for tool policy checks, `user_prompt` for prompt guardrails                 |
| `unbound_app_label` | string | Yes      | Your application identifier (e.g., `openclaw`, `claude-code`, `cursor`, or a custom label) |
| `pre_tool_use_data` | object | Yes      | Details about the tool being invoked (see below)                                           |
| `messages`          | array  | No       | Conversation messages for context                                                          |

### pre\_tool\_use\_data Object

| Parameter   | Type   | Required    | Description                                                                                                                                 |
| ----------- | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `tool_name` | string | Yes         | Name of the tool. Use `Bash`, `Shell`, or `exec` for terminal commands. For MCP tools, use the full name (e.g., `mcp__slack__send_message`) |
| `command`   | string | Conditional | The shell command string. Required when `tool_name` is `Bash`, `Shell`, or `exec`                                                           |
| `metadata`  | object | No          | Additional metadata. For MCP tools, include `mcp_server` and `mcp_tool`                                                                     |

## Response

| Field      | Type   | Description                                                            |
| ---------- | ------ | ---------------------------------------------------------------------- |
| `decision` | string | `allow`, `deny`, or `ask`                                              |
| `reason`   | string | Present when `decision` is `deny` or `ask`. Human-readable explanation |

### Decision Values

| Decision | Meaning                              | Recommended Action                                                                                                                   |
| -------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ |
| `allow`  | Tool call is permitted               | Proceed with execution                                                                                                               |
| `deny`   | Tool call is blocked by policy       | Do not execute. Show the `reason` to the user                                                                                        |
| `ask`    | Tool call requires user confirmation | Prompt the user for approval before executing. If your agent has no confirmation UI, treat as `allow` based on your security posture |

## How It Works

The endpoint handles two types of tools differently:

**Terminal commands** (`Bash`, `Shell`, `exec`): The command is automatically classified and matched against your configured terminal command policies.

**MCP tools**: The `mcp_server` and `mcp_tool` from metadata are matched against your MCP tool policies.

**Other tools**: Tools that don't match a terminal command or MCP tool pattern return `allow`.

## Examples

### Terminal Command (Blocked)

```bash theme={null}
curl -X POST 'https://api.getunbound.ai/v1/hooks/pretool' \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "session-123",
    "model": "claude-sonnet-4-20250514",
    "event_name": "pre_tool_use",
    "unbound_app_label": "my-agent",
    "pre_tool_use_data": {
      "tool_name": "Bash",
      "command": "rm -rf /tmp/data",
      "metadata": {}
    },
    "messages": [
      {"role": "user", "content": "clean up temp files"}
    ]
  }'
```

**Response:**

```json theme={null}
{
  "decision": "deny",
  "reason": "This command is blocked by your organization's policy."
}
```

### Terminal Command (Allowed)

```bash theme={null}
curl -X POST 'https://api.getunbound.ai/v1/hooks/pretool' \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "session-123",
    "model": "claude-sonnet-4-20250514",
    "event_name": "pre_tool_use",
    "unbound_app_label": "my-agent",
    "pre_tool_use_data": {
      "tool_name": "Bash",
      "command": "ls -la /tmp",
      "metadata": {}
    },
    "messages": []
  }'
```

**Response:**

```json theme={null}
{
  "decision": "allow"
}
```

### MCP Tool

```bash theme={null}
curl -X POST 'https://api.getunbound.ai/v1/hooks/pretool' \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "session-123",
    "model": "claude-sonnet-4-20250514",
    "event_name": "pre_tool_use",
    "unbound_app_label": "my-agent",
    "pre_tool_use_data": {
      "tool_name": "mcp__slack__send_message",
      "command": "",
      "metadata": {
        "mcp_server": "slack",
        "mcp_tool": "send_message"
      }
    },
    "messages": []
  }'
```

**Response** (depends on your configured policies):

```json theme={null}
{
  "decision": "deny",
  "reason": "This MCP tool call is blocked by your organization's policy."
}
```

## Integration Guide

To integrate tool policies into your agent framework:

1. **Before each tool execution**, send a `POST` request to `/v1/hooks/pretool` with the tool details
2. **Check the `decision`** in the response:
   * `allow` — execute the tool normally
   * `deny` — block execution and surface the `reason` to the user
   * `ask` — prompt the user for confirmation, or treat as `allow` if your agent has no interactive UI
3. **Handle errors gracefully** — if the endpoint is unreachable, decide whether to fail open (allow) or fail closed (deny) based on your security requirements
4. **Configure policies** at [gateway.getunbound.ai/policies/tool-policies](https://gateway.getunbound.ai/policies/tool-policies)
