# AI Tools Hook

> Give the Broadcast AI assistant a new tool that runs your plugin code. Full example and common mistakes.

Source: https://sendbroadcast.net/docs/plugins-hook-ai-tools

> Coming in Broadcast 3.0. Until then, this page applies only to the Upcoming (edge) build.

Use this hook to give the Broadcast AI assistant a new tool. When a person asks a question that your tool can answer, the assistant can call it.

## How it works

Your manifest describes the tool. The assistant reads the description to decide when to use it, so write it for a reader who has never seen your plugin.

## Full example: find tags

`manifest.json`:

```json
{
  "id": "local.tag-helper",
  "name": "Tag helper",
  "version": "1.0.0",
  "requires": { "broadcast": ">=3.0.0 <4.0.0", "pluginApi": "1" },
  "permissions": {
    "tags": "read"
  },
  "hooks": {
    "aiTools": [
      {
        "name": "find_tags",
        "description": "Finds the tags in this channel that contain a word.",
        "readOnly": true,
        "input_schema": {
          "type": "object",
          "properties": {
            "word": { "type": "string", "description": "The word to look for" }
          },
          "required": ["word"]
        }
      }
    ]
  }
}
```

`dist/main.js`:

```javascript
export default definePlugin({
  aiTools: {
    async find_tags({ input }, ctx) {
      const word = String(input.word ?? "").toLowerCase();
      const tags = await ctx.broadcast.tags.list();
      return { tags: tags.filter((tag) => tag.toLowerCase().includes(word)) };
    },
  },
});
```

## The manifest fields

| Field | Meaning |
|---|---|
| `name` | Lower case letters, digits and `_` |
| `description` | Required. What the tool does |
| `input_schema` | Optional. A JSON schema of type `object` that describes the input |
| `readOnly` | Set it to `true` if the tool changes nothing. Without it, the tool counts as a write tool, and the person must confirm each call |

## What you get and return

You get this. The tool's arguments are in `input`:

```json
{ "name": "find_tags", "input": { "word": "new" } }
```

Return any JSON value. The assistant reads it and answers the person.

## Who can use the tool

The tool appears only in channels where the plugin is on. It appears only for people who hold every data permission that the plugin holds. For example, a person who may not read subscribers does not get the tools of a plugin that reads subscribers.

## Common mistakes

**You write a short description.** "Tags" tells the assistant nothing. Say what the tool does and when it is useful.

**You trust the input.** The input comes from an AI model. It can be missing or have an odd form. Check it.

**You return too much.** Return only what answers the question, and no more personal data than is needed.

**You mark a tool `readOnly` when it writes.** This removes the confirmation step, so people can lose the chance to say no.
