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 tools | Client tools | |
|---|---|---|
| Defined by | Function nodes in the Agent Editor (e.g. Resend, CRM, API calls) | You, in your client or integration code |
| Where they run | On the server | On the client (your app) |
| How the agent sees them | As tools generated from the conversation graph; preview in the editor | As tools you register or that the agent is configured to call by name |
| When to use | Integrations, emails, server-side APIs, anything the server can do | Device actions, local data, user-specific APIs, or any logic only your client can execute |
How client tools work in the API
Client tools are used only over the real-time session connection. The flow is:- The agent decides to call a client tool and the server sends a tool call message to your client.
- Your client executes the tool (your code) and sends a tool call output message back with the result.
- The server uses that result and continues the conversation.
- Server → client:
tool_call-type: "tool_call",data:toolCallId,toolName,arguments(array of parameter objects withname,type,dataType,description,required,value). - Client → server:
tool_call_output-type: "tool_call_output",data:toolCallId,output(string). You must send this for eachtool_callso the agent can proceed.
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 handletool_call and send tool_call_output without building WebSocket messages by hand.
- JavaScript / TypeScript - Listen for the
tool_callevent, then callsession.sendToolCallOutput(toolCallId, output)with your result (oftenJSON.stringify(result)). - Python - In the async message stream, detect
ToolCall(ormsg.type == "tool_call"), run your handler, thenawait conn.send_tool_call_output(tool_call_id=msg.data.toolCallId, output=result_string). - Go - In the message loop, handle
vatel.TypeToolCall, parsevatel.ToolCallData, run your logic, thenconn.SendToolCallOutput(d.ToolCallID, output).

