# Tools & actions

> The agent's Tools tab, the built-in tools an agent can call (tickets, WhatsApp messages, bookings, voice tools), how to turn your own API or MCP server into one, and the switches that decide what may fire.

Source: https://docs.amomic.in/build/tools

---

Knowledge lets an agent answer. Tools let it *act*. A tool is a named capability the agent can decide to invoke mid-conversation — opening a ticket, sending a message, looking up a live order, cancelling a booking — and the difference between a helpful agent and a merely articulate one is usually a tool.

This page covers the agent's **Tools** tab, the nine tools that ship built in, how to build your own on top of a knowledge base, and the settings that decide what any of them may do.

**Who can do this:** workspace **owners** and **admins**.

::: warning Tool switches are live the moment you flip them
Each switch on the **Tools** tab saves as soon as you change it, and the next message or call on every channel uses it. There is no separate save, and nothing waits for a publish. Turn on a tool that reaches customers (WhatsApp sending, booking, cancelling) only when you are ready for customers to get it, try it on the [Test](/build/testing) tab straight away, and publish afterwards to record it as a version.
:::

## The Tools tab

Open the agent and choose **Tools**. The tab has two cards.

![The Tools tab of Veloria Support: Built-in tools with Create support tickets enabled and its per-channel identity tiles, and Send WhatsApp messages enabled with its template list](https://docs.amomic.in/screens/agents/tools-built-in.light.webp)

*Built-in tools. Each switch saves as soon as you flip it.*

**Built-in tools** holds three switches:

| Switch | Default | What it turns on | Needs |
|---|---|---|---|
| **Create support tickets** | On (*Enabled by default*) | `create_support_ticket` | Nothing |
| **Send WhatsApp messages** | Off (*Off by default*) | `send_whatsapp_message` | A connected WhatsApp number |
| **Book appointments** | Off (*Off by default*) | The appointment tools | A booking calendar |

**Your own tools** holds one switch, **Let this agent take actions** (`Allowed` or `Blocked`), and an **Open Knowledge** link, because your own tools live on knowledge bases. See [Building your own tools](#building-your-own-tools) and [The tool policy](#the-tool-policy).

Below them, **What happens automatically** and **Safety policy** describe behaviour you cannot switch off.

The voice-only tools (`search_knowledge`, `end_call` and `schedule_callback`) have no switch. They are offered on every call where they apply.

## What a tool is

To the model, a tool is a name, a description of when to use it, and a set of typed parameters. On each turn it may either answer or call a tool; if it calls one, the result comes back and it continues from there. The loop runs at most three rounds before the agent is forced to answer with what it has, so a tool that misbehaves cannot trap a customer in silence.

Three properties are worth internalising before you build anything:

- **The description is the control surface.** The agent decides whether to call a tool almost entirely from its description. "Check stock" invites speculative calls; "Use when the customer asks whether a specific product is currently available, after they have named the product" does not.
- **A tool the agent cannot see cannot be called.** Disabling a tool does not add a rule telling the model to avoid it — the tool is never declared, so it does not exist as far as the model is concerned. That is a much stronger guarantee than an instruction.
- **Tool failures never surface as errors.** If a tool throws or times out, the failure is handed back to the model as text and it recovers in conversation. A customer sees "I could not reach our order system right now" rather than a stack trace or an abrupt silence.

## The built-in tools

The platform supplies the following tools when their channel and policy make them relevant. These are their exact registered names — what the model sees, and what you will see in a transcript.

| Tool | Available on | Enabled by default |
|---|---|---|
| `create_support_ticket` | Web chat, WhatsApp, voice | Yes |
| `send_whatsapp_message` | Web chat, WhatsApp, voice | No |
| `search_knowledge` | Voice calls only | Yes, when the agent has knowledge |
| `end_call` | Voice calls only | Yes |
| `schedule_callback` | Voice calls only | Yes |
| `check_appointment_availability` | Voice, WhatsApp, web chat | No |
| `book_appointment` | Voice, WhatsApp, web chat | No |
| `reschedule_appointment` | Voice, WhatsApp, web chat | Whenever booking is on |
| `cancel_appointment` | Voice, WhatsApp, web chat | No (**Let it move or cancel a booking**) |

### Create support tickets

The **Create support tickets** switch turns on `create_support_ticket`. It creates a support ticket and resolves or creates the customer's contact record in one guarded action. It returns a status and the ticket's public reference — `AM-4F91C2E0` — which the agent can read back to the customer.

**When the agent reaches for it:** when the customer asks for a human, asks for follow-up, asks to escalate, or has an unresolved problem that needs staff action. It is the mechanism behind every "let me get someone to look at this".

**How identity is resolved**, per channel — the agent never asks for information the channel already knows:

| Channel | What it uses |
|---|---|
| Web chat | Asks first name, then email; asks for a phone number only when creating a new contact |
| WhatsApp | The chat's own number. Asks for an email only if the contact record has none |
| Voice | The caller's number, automatically. The email and phone parameters are **structurally removed** from the tool on calls |

That voice behaviour is deliberate and worth understanding. Speech recognition is not reliable enough to transcribe an email address or a phone number correctly, so rather than accepting a plausible-looking wrong address, the fields are removed from the tool entirely. The caller ID is the identity.

**Ticketing is idempotent within a conversation.** A retry — the customer asking again, the model calling twice — returns the same ticket rather than opening a duplicate.

The agent is also instructed never to claim a ticket exists until the tool has actually returned success. If ticket creation fails, the customer is told it failed.

See [Tickets](/api/tickets) for what happens next, and [Escalate to a ticket](/recipes/support-escalation) for the end-to-end shape.

### Send WhatsApp messages

The **Send WhatsApp messages** switch turns on `send_whatsapp_message`. It puts a confirmation, a link, or a reference on the customer's phone — **from any channel**. A caller on the phone can be sent the booking reference by WhatsApp before they hang up. A web visitor can be sent the tracking link.

It is **off by default**, including for agents created before it existed.

![Send WhatsApp messages expanded with Templates this agent may send, two utility templates ticked, and Allow messaging a different number; Book appointments below with a calendar chosen](https://docs.amomic.in/screens/agents/tools-whatsapp-booking.light.webp)

*Only ticked templates can be sent outside the 24-hour window.*

On the **Tools** tab:

- The switch stays greyed out until the workspace has a WhatsApp number. The card says *Connect a WhatsApp number before this agent can send.* with a **Set up WhatsApp** link.
- With more than one number, **Send from** picks the sender. **Workspace default** uses the workspace's default number.
- **Templates this agent may send** lists your approved templates with their language and category. Tick the ones the agent may use. Templates still in review are counted underneath, for example *One more template is in review with Meta — they appear here once approved.*
- **Allow messaging a different number** is explained below.

**Who it can message.** By default, only the person the agent is already talking to. On WhatsApp itself, the customer's own WhatsApp ID is authoritative — if the model produces a different recipient, that recipient is ignored outright. There is one setting, **Allow messaging a different number**, that permits a model-chosen destination; it exists for cases like an order desk notifying a third party, and it is the one control that lets a customer's wording decide where a message goes. Leave it off unless you specifically need it.

**Which templates it may send.** You choose an explicit allowlist, up to 20 templates. That list becomes the set of values the `template_name` parameter will accept — the model literally cannot name a template you did not approve. If no template is approved yet, the agent can only reply inside an open WhatsApp conversation.

#### The closed-window result

WhatsApp permits free-form messages only within 24 hours of the customer's last inbound message. Outside that window, only pre-approved templates go out. See [The 24-hour window](/channels/whatsapp-window) for the rule itself.

What matters here is how the tool behaves when it hits that wall. It does not fail silently, and it does not quietly substitute different words. It returns a structured status the agent can reason about:

| Status | What happened |
|---|---|
| `sent` | The message went out. |
| `template_required` | The window is closed. Free text is not permitted; a template is needed. |
| `template_not_allowed` | A template was named, but it is not on this agent's allowlist. |
| `template_not_found` | The named template does not exist or is not approved. |
| `needs_information` | A required value is missing — a template variable, a recipient. |
| `opted_out` | The recipient has opted out of messages from you. |
| `needs_setup` | WhatsApp sending is enabled but no sender number is usable. |
| `not_configured` | WhatsApp is not connected for this workspace. |
| `failed` | The send was attempted and did not succeed. |

**The practical consequence:** on `template_required`, the agent knows *why* it could not send and can do something sensible — send an approved template instead, or tell the customer plainly that it cannot message them right now and offer another route. It does not tell the customer the message went out when nothing was sent. If you have approved no templates, this is the moment your agent starts apologising to customers at 2 a.m.; approving one utility template is usually the whole fix.

::: warning No template is sent automatically when a window closes
There is no hold-and-release queue and no automatic re-engagement. If the window closes with a message pending, the message does not go out later. Either the agent sends an approved template in the moment, or nothing is sent.
:::

### `search_knowledge`

**Voice calls only**, and only when the agent has knowledge attached.

On a call, the agent already holds a compressed fact sheet built from its knowledge base, so ordinary questions are answered without any lookup — which is what keeps a call feeling like a conversation rather than a query. `search_knowledge` is the long tail: when the caller asks for a specific detail the fact sheet does not carry, the agent searches the full knowledge base for it.

You do not configure this tool. It appears when the agent has content and disappears when it does not.

On chat channels there is no equivalent tool because retrieval is not a decision there — the relevant passages are put in front of the model before it answers. See [Knowledge bases](/build/knowledge).

### `end_call`

**Voice calls only.** Hangs up, after the agent's goodbye has finished playing.

This exists because a phone call needs an ending. Without it, an agent that has said goodbye sits on an open line waiting for a caller who has stopped talking, and the call ends on an idle timeout instead of a clean farewell. The tool waits for the spoken goodbye to complete before disconnecting, so the caller never hears themselves cut off mid-word.

### `schedule_callback`

**Voice calls only.** When a caller asks to be called later, this tool resolves the requested time in the workspace time zone, keeps it inside calling hours, and creates a visible scheduled call-back. The agent reads back the time that was actually booked rather than merely agreeing to the caller’s wording.

Scheduled calls appear on the [Calls page](/console/calls#customer-requested-call-backs), where staff can cancel them before they are placed.

### Appointment tools

The **Book appointments** switch lets the agent check what is free and book a time during the conversation. It is off by default.

On the **Tools** tab:

- The switch stays greyed out until the workspace has a booking calendar. The card says *No calendar set up yet.* with a **Set up a calendar** link. When you come back from creating one, booking is switched on with that calendar.
- **Calendar** chooses which calendar the agent books into, when you have more than one. Turning booking on picks your default calendar, so the agent is never on with no calendar.
- **Let it move or cancel a booking** lets the agent cancel a booking the customer already has.
- A summary line under the switch shows the calendar's booking rules, with **Change these** to edit them on the calendar.

The appointment tools are offered when **Book appointments** is on and a calendar is selected:

- `check_appointment_availability` reads live capacity and returns opaque slot ids. The agent must call it before offering a time.
- `book_appointment` accepts only a slot id returned by that check.
- `reschedule_appointment` reserves the new slot before releasing the old one. It is offered **whenever booking is on**, whatever the **Let it move or cancel a booking** switch says.
- `cancel_appointment` identifies the customer's existing booking and records the reason when supplied. It is offered only when **Let it move or cancel a booking** is on.

::: warning Booking on means rescheduling on
The console describes **Let it move or cancel a booking** as covering both moving and cancelling. In fact the switch only controls cancelling. An agent with booking on can always move a customer's existing appointment to another free slot, checked against the number or address the channel supplied. If an agent must never move bookings, keep **Book appointments** off for it.
:::

See [Appointments and calendars](/console/appointments#let-an-agent-book).

## Building your own tools

Your own tools are **knowledge sources**. There is no separate integrations screen, no plugin directory, and no third-party connector marketplace — a tool is an `endpoint` or `mcp` source on a knowledge base, and it reaches an agent through the same attachment that gives it knowledge.

That is a deliberate design: the thing that decides what an agent knows also decides what it can do, so there is exactly one place to audit.

### Read tools versus action tools

Every custom tool declares a capability.

| Capability | Meaning | Example |
|---|---|---|
| `read` | Looks something up. Nothing in your system changes. | Order status, stock level, appointment availability, invoice balance |
| `action` | Changes something in your system. | Accept a return, cancel a booking, reschedule a delivery, apply a credit |

In the console these read as **Look up data** and **Take an action**, and a source configured as an action carries an `Action` badge wherever it appears.

The distinction is enforced, not advisory:

- A `read` tool may only use `GET` or `POST`. Choose `PUT`, `PATCH`, or `DELETE` and you are told `{method} changes data — set capability to 'action' to use it.`
- An `action` must be a live tool. It cannot be a scheduled ingest, because ingesting a `DELETE` on a timer is not a thing anyone wants.
- A live tool must have a name the agent can call.

### A live read tool

Mode **Call it live**, capability **Look up data**. It is never ingested into the knowledge base; it is registered as a function the agent invokes mid-answer.

You provide:

- **The URL**, optionally with `{braces}` for values the agent fills in — `https://api.yourcompany.com/orders/{order_id}`. Each substituted value fills exactly one path segment; it cannot escape into the rest of the path.
- **A tool name** — a short verb, like `check_stock`. This is what appears in transcripts.
- **When should the agent use it?** — plain words. This is the field that stops the agent calling too eagerly, and it deserves more thought than the URL.
- **Headers**, if the endpoint needs auth. Values go into encrypted storage immediately and are never shown again.

The response is capped at 2 MB, and what reaches the model is truncated at 24,000 characters. Return the fields the agent needs, not your full object graph — a lean response is both faster and easier for the agent to use correctly.

::: tip Write the description as a rule, not a label
`check_stock` with the description "Checks stock" will be called for "do you have anything nice?". The same tool with "Use only after the customer has named a specific product, to report whether that product is currently in stock" will not. Every eager tool call in production traces back to a description that described the endpoint instead of the situation.
:::

### An action tool

Mode **Call it live**, capability **Take an action**. Same fields, plus a method that may be `POST`, `PUT`, `PATCH`, `DELETE`, or `GET`.

When any action tool is bound to an agent, extra rules are injected into its behaviour automatically:

- Confirm the customer actually asked for this before doing it.
- Gather missing details one at a time, not as a form.
- Never claim it is done before the tool returns success.
- Never call speculatively.

**Every action call is audited** — success or failure — with the workspace, agent, conversation, channel, deployment, source, tool name, capability, outcome, and latency. **Arguments and response bodies are deliberately not recorded**, because they carry customer data and, occasionally, credentials. You get a complete record of what happened without a second copy of the payload. Read-capability calls are not audited; nothing changed.

### MCP servers

An MCP server is added once and its tools become available to any agent the knowledge base is attached to. Up to 20 tools per server, and you can restrict which of them are allowed by name.

Because MCP does not declare which of a server's tools mutate state, **you classify the server, not the tool** — look-up or action — and every tool on it inherits that classification. If any tool on the server changes data, the whole server is an action server. That is a conservative default and it is the correct one.

Errors are reported in plain words: `The MCP server rejected our credentials (401).`, `The MCP server answered with HTTP {code}.`, `Couldn't reach the MCP server. Check the URL and try again.`, and `The MCP server lists no tools.`

### Safety at call time

Every custom tool call, read or action, runs through the same guards:

- The destination must resolve to a public address. Internal addresses, loopback, and cloud metadata endpoints are refused.
- Redirects are not followed, and the connection is pinned to the address that was checked — so a host cannot pass a check and then point somewhere else.
- Responses are capped at 2 MB, and what reaches the model at 24,000 characters.
- Credentials are read from encrypted storage at call time and are never present in any record you can read.

## The tool policy

The switches on the **Tools** tab make up the agent's tool policy. Each change is saved and live the moment you flip the switch. When you publish, the policy is recorded in the version, so what an agent was allowed to do on a given day can be looked up on the [Versions](/build/versions) tab, and a rollback restores it.

| Setting | Default | Effect |
|---|---|---|
| **Create support tickets** | **On** | Enables `create_support_ticket`. |
| **Send WhatsApp messages** | **Off** | Enables `send_whatsapp_message`, plus its sender, template allowlist, and recipient rule. |
| **Book appointments** | **Off** | Enables availability, booking and rescheduling against the selected calendar. |
| **Let it move or cancel a booking** | **Off** | Adds `cancel_appointment` once booking is on. Rescheduling does not depend on it. |
| **Let this agent take actions** | **On** (`Allowed`) | Master switch for action-capability tools on attached knowledge bases. |
| **Safety policy** | *Approved actions only* | Not configurable. The model cannot choose the workspace, the channel identity, or the contact id. |

**The actions master switch is absolute.** Turned off, action tools on an attached knowledge base are not declared to the model at all — it cannot try and be refused, because it never learns they exist. Read tools continue to work normally, so an agent with actions blocked can still look up an order but cannot cancel one. Turn it off when you want an agent that answers questions about a system it must not touch.

![The Your own tools card with Let this agent take actions set to Allowed, above the What happens automatically and Safety policy cards](https://docs.amomic.in/screens/agents/tools-your-own-tools.light.webp)

Tools are also only offered when their source is actually serving. A source that is still syncing or has failed contributes nothing, so a broken integration degrades the agent rather than breaking the conversation.

::: note What is deliberately not here
There is no per-deployment tool override: the agent's tool policy applies on every channel it is deployed to. There is no approval workflow for individual tool calls, and there is no per-agent-version allowlist beyond the WhatsApp template list. If two channels need different powers, build two agents.
:::

## What happens automatically

Three behaviours are not settings and cannot be turned off, because turning them off would only produce bad data:

- **Contact resolution.** Before creating anything, the agent resolves the customer against your directory by email, phone, and WhatsApp ID. A returning customer enriches the record that already exists. See [Conversations and contacts](/concepts/conversations).
- **Idempotent ticketing.** Retries within the same conversation return the same ticket rather than duplicates.
- **AI handoff context.** When a ticket is opened, the issue summary, the channel, the requester, and the conversation reference go with it, so the person who picks it up is not starting from nothing.

## Reading what a tool did

Every conversation in the [inbox](/concepts/conversations) shows an operational trail alongside the messages, and tool use appears there by kind: `Knowledge base`, `Live API`, `MCP tool`, and `Action`. That trail is staff-facing only — it is not part of the transcript a customer sees, and it is not returned by [`GET /conversations/{id}/messages`](/api/conversations).

When an agent gives a wrong answer, that trail is the first thing to read. It tells you immediately whether the agent looked anything up, called your API, or answered from memory — three very different bugs with three very different fixes.

## Troubleshooting

| What you see | Why | What to do |
|---|---|---|
| **Send WhatsApp messages** is greyed out | The workspace has no WhatsApp number. | Choose **Set up WhatsApp**. See [Set up WhatsApp](/channels/whatsapp). |
| **Book appointments** is greyed out | There is no booking calendar. | Choose **Set up a calendar**. |
| The template you want is not in the list | It is not approved yet, or it was rejected. | Check it on the WhatsApp templates page. See [Templates](/channels/whatsapp-templates). |
| The agent says it cannot message the customer right now | The 24-hour window is closed and no ticked template fits. | Tick an approved utility template. See [The closed-window result](#the-closed-window-result). |
| The agent moved a booking although the move-or-cancel switch is off | Rescheduling is on whenever booking is on. | See [Appointment tools](#appointment-tools). |
| The agent never calls your action tool | **Let this agent take actions** is `Blocked`, or the source is not serving. | Allow actions, and check the source on its knowledge base. |
| *Couldn’t update the tool.* | The switch did not save. | Try again. The switch shows the saved state. |

## Where to go next

::: cards

::: card Add the sources tools live on
[Knowledge bases](/build/knowledge) — endpoint and MCP sources, credentials, and refresh.
:::

::: card Get the WhatsApp side right
[The 24-hour window](/channels/whatsapp-window) and [Templates](/channels/whatsapp-templates) — what the send tool is allowed to do and when.
:::

::: card Watch the tools fire
[Testing and publishing](/build/testing) — the test tab shows what the agent looked up on every turn.
:::

::: card Handle the escalation end
[Escalate to a ticket](/recipes/support-escalation) — from the agent's tool call to your team's queue.
:::

:::
