Skip to main content

Voice Agent Tools

What a voice agent can call mid-conversation on a phone, WhatsApp or WebRTC call: built-in tools, your own REST tools, MCP servers, and the two tools that are always there.

Overview

A voice agent on a phone, WhatsApp or WebRTC call can call tools mid-sentence — look an order up, check a calendar, send the caller a link, hang up. This page covers that surface.

The Managed Voice Agent WebSocket gateway has its own tool protocol — you declare tools in Settings and answer FunctionCallRequest over the same socket, with a 30-second response window. That is a different mechanism from this page: there, your client runs the tool; here, we do.

Four sources, one tool list

Everything below is merged into a single list the model sees on the call.

SourceWhere it comes fromRuns where
Built-in toolsconfig.tools on the agent, by nameOur backend
Custom REST toolsThe agent tools APIYour endpoint, called by our backend
MCP serversconfig.mcp_servers on the agentYour MCP server
end_call, transfer_to_humanAlways attachedOur backend

A custom REST tool and a built-in tool cannot share a name — the custom tool wins and the built-in one is dropped, so the model never sees two tools with one name.

Built-in tools

Enable them by name in the agent's config.tools. GET /api/v1/bots/tool-catalog (Agents) lists every name you can put there.

web_search is always on — it is enabled for every agent whether or not it appears in config.tools.

CategoryExamples
Utilityweb_search, calculator, get_current_time
Knowledgesearch_knowledge_base, save_to_knowledge
Memoryremember, recall_memory
CRMupdate_contact, set_contact_optin
Schedulingcalcom_list_slots, calcom_book, google_calendar_find_free_slots, google_calendar_create_event
Spreadsheetsgoogle_sheets_find_rows, google_sheets_append_row, google_sheets_update_row, google_sheets_list_spreadsheets
Commerceshopify_order_status, shopify_product_lookup, woocommerce_order_status
WhatsApp messagingsend_text_message, send_template_message, send_quick_reply_buttons, send_list_menu, send_cta_url_button, send_location, request_contact_info
Callingrequest_call
Emailsend_email, gmail_send_email
HTTPhttp_request

A tool whose integration is not connected — a Shopify store, a Cal.com key, a Google account — does not break the call. It returns an error the model can speak its way out of ("I can't reach the calendar right now"), and the conversation continues.

The Google Sheets tools only reach the spreadsheets you choose with the Google file picker in the console (Tools → Connected apps → Google Sheets → Choose spreadsheets). Row 1 of each tab holds the column names, and the tools address columns by those names.

Order automation from Google Sheets

A spreadsheet chosen on the Google Sheets connection can also run on its own: when a new order row appears, CallMissed sends an approved WhatsApp template and/or has an agent call the customer to confirm, with separate settings for cash-on-delivery and other orders, and writes the result into the sheet's CallMissed Status and CallMissed Note columns (added if missing). Orders already in the sheet when you switch it on are left alone, calls stay inside the calling window you set and respect your do-not-call list, and unanswered calls are retried.

The calling agent receives the order as call variables — {{order_id}}, {{name}}, {{payment_type}}, {{order_details}} and one variable per column (e.g. {{total}}) — so its prompt should mention {{order_details}}. Set it up in the console (Tools → Connected apps → Google Sheets → Automate orders) or with POST /api/v1/sheet-automations; GET /api/v1/sheet-automations/{id}/orders lists what happened to each order.

An unknown name in config.tools is skipped and logged rather than taking the agent offline, so a stale entry left behind by a renamed tool is not an outage.

Messaging tools on calls

On WhatsApp calls and phone calls, the WhatsApp messaging tools above are enabled automatically — you do not have to list them. The most common request on a voice call is "send me that in the chat": a tracking link, an address, a price. If the call is not linked to a connected WhatsApp sender, the tool returns an error the model relays instead of sending anything.

Not available on voice

Two categories are excluded from voice calls:

CategoryWhy
conversationInbox-thread actions — notes, tags, status, escalation — belong to the chat channels
personal_whatsappNeeds a linked personal-WhatsApp session, which a call does not have

Every tool in those categories comes back from GET /api/v1/bots/tool-catalog with "unavailable_on": ["voice"], and listing one in a calling agent's config.tools returns an incompatible warning from POST /api/v1/bots/validate-config.

For escalation on a call, use transfer_to_human below.

Skills are not available on voice either

config.skills — the named bundles from GET /api/v1/bots/skill-catalog — is resolved on chat channels only. A calling agent never reads the key, so a skill set there adds neither its tools nor its instructions to the call. Put the tools a call needs directly in config.tools.

Custom REST tools

Your own read-only HTTP endpoint, described so the model can call it mid-conversation. Create and test it through the agent tools API — the same definitions the console's Tools screen writes — and it is attached to the call automatically.

On a voice call each invocation is one round trip to our backend, which owns the URL, your stored credentials, the outbound-request checks, the per-tool timeout and the response-size cap. Your credentials never reach the caller's client.

A failing custom tool returns a JSON error object to the model rather than raising, so a broken endpoint costs one turn, not the call. A definition we cannot attach is skipped and the rest stay — one bad tool does not drop the others.

MCP servers

Point an agent at remote MCP servers with config.mcp_servers. Each server's tools are listed at call setup and offered to the model alongside everything else.

{
  "mcp_servers": [
    {
      "id": "inventory",
      "url": "https://mcp.yourcompany.com/mcp",
      "header_value": "Bearer your_server_token",
      "allowed_tools": ["check_stock", "reserve_item"]
    }
  ]
}
FieldRequiredNotes
idYesYour label for the server, up to 64 characters
urlYesHTTPS only, and must resolve to a public address
header_valueNoSent as the Authorization header to your server. Never logged
allowed_toolsNoAllow-list of tool names. Omit it and every tool the server lists is offered
LimitValue
Servers per agent10
Tools taken per server40
Tools taken across all servers100

A server that is unreachable or slow to list is skipped for that call and logged — the agent still answers with its remaining tools. Tool listings are cached briefly per server, so a burst of calls does not re-list on every one.

Tool descriptions and tool results from an MCP server are untrusted text that reaches the model. A hostile or compromised server can attempt to steer the agent through either one. Set allowed_tools to the names you actually expect, and point agents only at servers you control or trust.

Always attached

Two tools are added to every call and cannot be removed.

end_call

Lets the agent hang up when the conversation is genuinely finished — the caller says goodbye, the request is resolved, or the caller has gone silent despite check-ins. It takes an optional reason for your logs and an unresponsive flag for the silence case.

A server-side check refuses end_call on a call that is only seconds old or where the caller has not spoken yet, so a model that reaches for it too early is told to keep going. That check is not something the system prompt can talk its way past.

transfer_to_human

transfer_to_human does not connect a person to the live call. It notifies your team, who call the caller back. The agent tells the caller someone will ring them back, then wraps up. Write your prompt around a callback, not a warm transfer.

It takes a short reason for the team and a 1–2 sentence summary written for the colleague picking it up: what the caller wants, what has been covered, key facts like an order number, and whether identity was checked. The result tells the model what to say next, including what to say when the team could not be reached.

Use it when the caller explicitly asks for a person, is upset and wants escalation, or has a request the agent genuinely cannot handle.

Errors

A tool failure is not a call failure. Whatever the tool raises is returned to the model as a readable message, and the model apologises, retries, or takes another route while the caller stays on the line. You see the failure in your usage and logs, not as a dropped call.