From vapi-voice-ai
Create custom tools for Vapi voice assistants: function tools, API requests, call transfer, end call, and integrations with Google Calendar, Sheets, Slack. Use when adding capabilities to voice agents.
How this skill is triggered — by the user, by Claude, or both
Slash command
/vapi-voice-ai:create-toolThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Create tools that give voice assistants the ability to take actions during calls — look up data, book appointments, transfer calls, send messages, and more.
Create tools that give voice assistants the ability to take actions during calls — look up data, book appointments, transfer calls, send messages, and more.
Setup: Ensure
VAPI_API_KEYis set. See thesetup-api-keyskill if needed.
curl -X POST https://api.vapi.ai/tool \
-H "Authorization: Bearer $VAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g. San Francisco"
}
},
"required": ["location"]
}
},
"server": {
"url": "https://your-server.com/api/tools"
}
}'
import { VapiClient } from "@vapi-ai/server-sdk";
const vapi = new VapiClient({ token: process.env.VAPI_API_KEY! });
const tool = await vapi.tools.create({
type: "function",
function: {
name: "get_weather",
description: "Get current weather for a location",
parameters: {
type: "object",
properties: {
location: {
type: "string",
description: "City name, e.g. San Francisco",
},
},
required: ["location"],
},
},
server: {
url: "https://your-server.com/api/tools",
},
});
console.log("Tool created:", tool.id);
The most common tool type. Your server receives the function call and returns a result.
{
"type": "function",
"function": {
"name": "lookup_order",
"description": "Look up order status by order number",
"parameters": {
"type": "object",
"properties": {
"orderNumber": {
"type": "string",
"description": "The order number to look up"
}
},
"required": ["orderNumber"]
}
},
"server": {
"url": "https://your-server.com/api/tools"
},
"messages": [
{
"type": "request-start",
"content": "Let me look that up for you..."
},
{
"type": "request-complete",
"content": "I found your order information."
},
{
"type": "request-failed",
"content": "I'm having trouble looking that up. Let me try again."
}
]
}
Transfer the caller to another number or SIP endpoint.
{
"type": "transferCall",
"destinations": [
{
"type": "number",
"number": "+1234567890",
"message": "Transferring you to our billing department now.",
"description": "Transfer to billing department when customer has billing questions"
}
]
}
SIP transfer:
{
"type": "transferCall",
"destinations": [
{
"type": "sip",
"sipUri": "sip:[email protected]",
"description": "Transfer to billing via SIP"
}
]
}
Allows the assistant to end the call programmatically.
{
"type": "endCall"
}
Send DTMF tones (touch-tone signals) during a call for IVR navigation.
{
"type": "dtmf"
}
Detect and handle voicemail.
{
"type": "voicemail",
"beepDetectionEnabled": true
}
{
"type": "google.calendar.event.create",
"name": "create_calendar_event",
"description": "Schedule a meeting on Google Calendar"
}
{
"type": "google.sheets.row.append",
"name": "log_to_sheet",
"description": "Log call data to the configured Google Sheet"
}
{
"type": "slack.message.send",
"name": "notify_slack",
"description": "Send urgent notifications to the #customer-support Slack channel"
}
Connect Google or Slack under the dashboard's tool-provider integrations before using these built-in tools. Configure the spreadsheet, sheet range, calendar, or Slack channel in the dashboard as required; never put OAuth tokens in a tool payload.
Connect to Model Context Protocol servers.
{
"type": "mcp",
"server": {
"url": "https://your-mcp-server.com"
}
}
When the assistant calls a tool, Vapi sends a POST request to your server URL.
{
"message": {
"type": "tool-calls",
"toolCallList": [
{
"id": "call_abc123",
"name": "get_weather",
"parameters": {
"location": "San Francisco"
}
}
],
"call": {
"id": "call-uuid",
"orgId": "org-uuid",
"type": "webCall"
}
}
}
Your server must return:
{
"results": [
{
"toolCallId": "call_abc123",
"result": "San Francisco: 65°F, partly cloudy"
}
]
}
import express from "express";
const app = express();
app.use(express.json());
app.post("/api/tools", async (req, res) => {
const { message } = req.body;
const results = [];
for (const toolCall of message.toolCallList) {
let result: string;
switch (toolCall.name) {
case "get_weather":
const weather = await fetchWeather(toolCall.parameters.location);
result = `${toolCall.parameters.location}: ${weather.temp}°F, ${weather.condition}`;
break;
case "lookup_order":
const order = await lookupOrder(toolCall.parameters.orderNumber);
result = `Order ${order.number}: ${order.status}`;
break;
default:
result = "Unknown tool";
}
results.push({ toolCallId: toolCall.id, result });
}
res.json({ results });
});
app.listen(3000);
curl -X PATCH https://api.vapi.ai/assistant/{assistant-id} \
-H "Authorization: Bearer $VAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": {
"provider": "openai",
"model": "gpt-4.1",
"toolIds": ["tool-id-1", "tool-id-2"],
"messages": [{"role": "system", "content": "Your prompt here"}]
}
}'
Define tools directly in the assistant's model configuration — see the create-assistant skill.
# List all tools
curl https://api.vapi.ai/tool -H "Authorization: Bearer $VAPI_API_KEY"
# Get a tool
curl https://api.vapi.ai/tool/{id} -H "Authorization: Bearer $VAPI_API_KEY"
# Update a tool
curl -X PATCH https://api.vapi.ai/tool/{id} \
-H "Authorization: Bearer $VAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"function": {"description": "Updated description"}}'
# Delete a tool
curl -X DELETE https://api.vapi.ai/tool/{id} \
-H "Authorization: Bearer $VAPI_API_KEY"
For long-running operations, mark a tool as async. The assistant continues speaking while the tool executes:
{
"type": "function",
"async": true,
"function": {
"name": "send_email",
"description": "Send a confirmation email (runs in background)"
},
"server": {
"url": "https://your-server.com/api/tools"
}
}
Control what the assistant says during tool execution:
{
"messages": [
{
"type": "request-start",
"content": "One moment while I look that up..."
},
{
"type": "request-complete",
"content": "Got it!"
},
{
"type": "request-failed",
"content": "Sorry, I couldn't complete that action."
},
{
"type": "request-response-delayed",
"content": "This is taking a bit longer than usual, please hold.",
"timingMilliseconds": 5000
}
]
}
Vapi provides a documentation MCP server that gives compatible AI agents access to the Vapi knowledge base. Use its documentation search for advanced configuration, troubleshooting, SDK details, and anything beyond this skill.
To add the Vapi documentation MCP server manually in Claude Code, run:
claude mcp add vapi-docs -- npx -y mcp-remote https://docs.vapi.ai/_mcp/server
See the Vapi MCP integration guide for setup instructions across supported agents.
npx claudepluginhub vapiai/skills --plugin vapi-voice-aiConfigures Vapi server URLs and webhooks to receive real-time call events, transcripts, tool calls, and end-of-call reports. Use when setting up webhook endpoints or integrating Vapi events.
Builds and configures Retell AI voice agents with custom prompts, function calling, and call flow logic for appointment booking and telephony automation.
Builds ElevenLabs conversational AI voice agents: configure via CLI/dashboard, add tools/knowledge, integrate React/React Native/Swift/JS SDKs, test/deploy. For voice AI, phone systems, or ElevenLabs errors.