Skip to main content
Client tools are tools that the agent can call but that your application runs-on the device or backend that holds the WebSocket connection. They are only available when you integrate via the API (WebSocket); channels like telephony use server-side tools only.
Client tools are an advanced option and require an API connection (WebSocket + your code). Function node tools and server tools are configured directly in the Agent Editor-no API integration needed.

Function tools vs client tools

Function toolsClient tools
Defined byFunction nodes in the Agent Editor (e.g. Resend, CRM, API calls)You, in your client or integration code
Where they runOn the serverOn the client (your app)
How the agent sees themAs tools generated from the conversation graph; preview in the editorAs tools you register or that the agent is configured to call by name
When to useIntegrations, emails, server-side APIs, anything the server can doDevice actions, local data, user-specific APIs, or any logic only your client can execute
Function tools are built from nodes in the Agent Editor: each function node becomes a tool the agent can invoke, and the server executes that node when the agent calls it. Client tools are the opposite: the agent still decides to call a tool by name, but the server sends the request to your client; your code runs the tool and sends the result back. Use client tools when the capability lives in your app (e.g. opening a URL, reading local state, calling an API that only your client can access).

How client tools work in the API

Client tools are used only over the real-time session connection. The flow is:
  1. The agent decides to call a client tool and the server sends a tool call message to your client.
  2. Your client executes the tool (your code) and sends a tool call output message back with the result.
  3. The server uses that result and continues the conversation.
The protocol is defined on the Connection channel:
  • Server → client: tool_call - type: "tool_call", data: toolCallId, toolName, arguments (array of parameter objects with name, type, dataType, description, required, value).
  • Client → server: tool_call_output - type: "tool_call_output", data: toolCallId, output (string). You must send this for each tool_call so the agent can proceed.
The client is responsible for mapping toolName and arguments to your implementation and for returning a string result (e.g. JSON or plain text) in output.

Using client tools with the SDKs

All official SDKs expose this flow so you can handle tool_call and send tool_call_output without building WebSocket messages by hand.
  • JavaScript / TypeScript - Listen for the tool_call event, then call session.sendToolCallOutput(toolCallId, output) with your result (often JSON.stringify(result)).
  • Python - In the async message stream, detect ToolCall (or msg.type == "tool_call"), run your handler, then await conn.send_tool_call_output(tool_call_id=msg.data.toolCallId, output=result_string).
  • Go - In the message loop, handle vatel.TypeToolCall, parse vatel.ToolCallData, run your logic, then conn.SendToolCallOutput(d.ToolCallID, output).
For full request/response shapes and the rest of the session protocol, see the Connection reference.