Skip to content

A simple template built using FastAPI to help build custom tools for Vapi. Simply build your custom tools, add decorator and run. Handling Vapi's request response and registering functions on Vapi is done with a single command.

Notifications You must be signed in to change notification settings

codebuster22/vapi-tools-template

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

4 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Auto-Agent: Vapi Tool Code Generation & Registration System

A powerful FastAPI-based webhook server with automated tool code generation and registration for the Vapi (Voice API) platform. This system automatically discovers functions decorated with @vapi_function, generates Python modules with CreateFunctionToolDto objects, and registers them with Vapi for AI agent integration.

πŸš€ Quick Start

Prerequisites

  • Python 3.13+
  • Vapi API key (get from Vapi Dashboard)
  • Optional: Ngrok auth token for staging deployments

Installation

# Clone and install dependencies
git clone <repository-url>
cd auto-agent
pip install -e .

# Or using uv (recommended)
uv sync

Basic Usage

# 1. Generate tool registration code
uv run codegen

# 2. Start your webhook server (choose one):
uv run python src/main.py --port 8000           # Local development
uv run python src/main.py --ngrok --port 8001   # With ngrok tunnel

# 3. Register tools with Vapi platform
uv run migrate --server-url http://localhost:8000 --api-key your_vapi_key
# Or with ngrok URL:
uv run migrate --server-url https://abc123.ngrok.io --api-key your_vapi_key

πŸ“‹ Table of Contents

🎯 Core Concepts

What This System Does

  1. Function Discovery: Automatically scans your codebase for @vapi_function decorated functions
  2. Code Generation: Creates Python modules with CreateFunctionToolDto objects ready for Vapi registration
  3. Tool Registration: Registers your functions as callable tools with the Vapi platform
  4. Webhook Server: Provides a FastAPI server to handle Vapi tool calls and execute your functions

Architecture Overview

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚   Your Code     β”‚    β”‚   Code Generator β”‚    β”‚   Vapi Platform β”‚
β”‚                 β”‚    β”‚                  β”‚    β”‚                 β”‚
β”‚ @vapi_function  │───▢│  Discovery       │───▢│  Tool Registry  β”‚
β”‚ def my_tool()   β”‚    β”‚  Generation      β”‚    β”‚                 β”‚
β”‚                 β”‚    β”‚  Registration    β”‚    β”‚                 β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                                β”‚                        β”‚
                                β–Ό                        β–Ό
                       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                       β”‚ Generated Module β”‚    β”‚  Webhook Server β”‚
                       β”‚                  β”‚    β”‚                 β”‚
                       β”‚ - TOOL_METADATA  β”‚    β”‚  FastAPI App    β”‚
                       β”‚ - generate_tools β”‚    β”‚  /webhook/vapi  β”‚
                       β”‚ - register_tools β”‚    β”‚                 β”‚
                       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

πŸ”§ Creating Vapi Functions

Basic Function Definition

Create functions in your codebase and decorate them with @vapi_function:

# src/services/my_tools.py
from typing import Dict, Any, Optional
from src.services.vapi_schema import vapi_function

@vapi_function(
    name="get_weather",
    description="Get current weather information for a location"
)
def get_weather(location: str, units: str = "celsius") -> Dict[str, Any]:
    """Get weather information for a specific location.

    Args:
        location: City and country (e.g., "San Francisco, CA")
        units: Temperature units - celsius or fahrenheit

    Returns:
        Weather information including temperature and conditions
    """
    # Your implementation here
    return {
        "location": location,
        "temperature": 22,
        "units": units,
        "condition": "sunny"
    }

Advanced Function Examples

Function with Complex Types

from typing import List, Dict, Any, Optional
from datetime import datetime

@vapi_function(
    name="schedule_meeting",
    description="Schedule a meeting with participants"
)
def schedule_meeting(
    title: str,
    participants: List[str],
    start_time: datetime,
    duration_minutes: int = 30,
    location: Optional[str] = None
) -> Dict[str, Any]:
    """Schedule a meeting with multiple participants.

    Args:
        title: Meeting title
        participants: List of participant email addresses
        start_time: Meeting start time in ISO format
        duration_minutes: Meeting duration in minutes (default: 30)
        location: Optional meeting location or video link

    Returns:
        Meeting details with confirmation ID
    """
    return {
        "meeting_id": "mtg_123",
        "title": title,
        "participants": participants,
        "scheduled_for": start_time.isoformat(),
        "duration": duration_minutes,
        "location": location
    }

Async Function

@vapi_function(
    name="send_email",
    description="Send an email to recipients"
)
async def send_email(
    to: List[str],
    subject: str,
    body: str,
    cc: Optional[List[str]] = None
) -> Dict[str, Any]:
    """Send an email asynchronously.

    Args:
        to: List of recipient email addresses
        subject: Email subject line
        body: Email body content
        cc: Optional list of CC recipients

    Returns:
        Email delivery status and message ID
    """
    # Async email sending logic
    await send_email_async(to, subject, body, cc)
    return {
        "message_id": "msg_456",
        "status": "sent",
        "recipients": to
    }

Function Best Practices

1. Clear Descriptions

# βœ… Good - Clear and specific
@vapi_function(
    name="calculate_mortgage",
    description="Calculate monthly mortgage payment including principal, interest, taxes, and insurance"
)

# ❌ Bad - Too vague
@vapi_function(
    name="calculate",
    description="Does calculations"
)

2. Proper Type Hints

# βœ… Good - Explicit types
def book_flight(
    departure: str,
    destination: str,
    date: datetime,
    passengers: int = 1
) -> Dict[str, Any]:

# ❌ Bad - Missing or vague types
def book_flight(departure, destination, date, passengers=1):

3. Descriptive Docstrings

# βœ… Good - Detailed docstring
def transfer_money(amount: float, from_account: str, to_account: str) -> Dict[str, Any]:
    """Transfer money between bank accounts.

    Args:
        amount: Amount to transfer in USD (must be positive)
        from_account: Source account number (format: XXXX-XXXX-XXXX)
        to_account: Destination account number (format: XXXX-XXXX-XXXX)

    Returns:
        Transfer confirmation with transaction ID and timestamp

    Raises:
        ValueError: If amount is negative or accounts are invalid
    """

4. Handle Optional Parameters

# βœ… Good - Optional parameters with defaults
def search_products(
    query: str,
    category: Optional[str] = None,
    max_price: Optional[float] = None,
    sort_by: str = "relevance"
) -> List[Dict[str, Any]]:

πŸ—οΈ Code Generation

Basic Code Generation

Generate Python code with tool definitions:

# Generate with defaults
uv run codegen

# Custom output directory
uv run codegen --output-dir ./my_tools

# Custom module name
uv run codegen --module-name my_vapi_tools

# Specify server URL for webhooks
uv run codegen --server-url https://api.mycompany.com

# JSON output for automation
uv run codegen --json

Code Generation Options

Option Description Default
--output-dir Directory for generated code ./generated
--scan-path Directory to scan for functions ./src
--server-url Base URL for webhook endpoints None
--module-name Name of generated Python module generated_tools
--json Output results in JSON format False

Generated Module Structure

The codegen command creates a complete Python module:

# generated_tools.py
from typing import List, Dict, Any, Optional
from vapi import Vapi, CreateFunctionToolDto
from vapi.types.open_ai_function import OpenAiFunction
from vapi.types.server import Server

# Metadata extracted from your functions
TOOL_METADATA = [
    {
        "name": "get_weather",
        "description": "Get current weather information for a location",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {"type": "string", "description": "City and country"},
                "units": {"type": "string", "description": "Temperature units"}
            },
            "required": ["location"]
        },
        "endpoint_path": "/api/v1/webhook/get-weather"
    }
]

def generate_tools(server_base_url: str) -> List[CreateFunctionToolDto]:
    """Generate CreateFunctionToolDto objects for Vapi registration."""
    # Implementation...

async def register_tools(api_key: str, server_base_url: str, timeout: int = 30) -> List[Dict[str, Any]]:
    """Register all tools with Vapi platform."""
    # Implementation...

def get_tool_metadata() -> List[Dict[str, Any]]:
    """Get metadata about discovered functions."""
    # Implementation...

Using Generated Code

# Import the generated module
from generated.generated_tools import generate_tools, register_tools, get_tool_metadata

# Generate tool DTOs
tools = generate_tools("https://my-webhook-server.com")

# Register with Vapi (async)
import asyncio
results = asyncio.run(register_tools(
    api_key="your_vapi_api_key",
    server_base_url="https://my-webhook-server.com"
))

# Check metadata
metadata = get_tool_metadata()
for tool in metadata:
    print(f"Tool: {tool['name']} - {tool['description']}")

πŸ”„ Tool Registration

Workflow

The migrate command now follows a simple, explicit workflow:

Step 1: Start Your Server

# For local development
uv run python src/main.py --port 8000

# For public access with ngrok
uv run python src/main.py --ngrok --port 8001

# Or use your production server
# (already running at https://api.example.com)

Step 2: Register Tools

# Register with the server URL from Step 1
uv run migrate --server-url http://localhost:8000 --api-key your_vapi_key

# Or with ngrok URL
uv run migrate --server-url https://abc123.ngrok.io --api-key your_vapi_key

# Or with production URL
uv run migrate --server-url https://api.example.com --api-key your_vapi_key

Why This Approach?

  • βœ… Explicit Control: You manage server lifecycle separately
  • βœ… Flexibility: Use any server (local, ngrok, production)
  • βœ… Simplicity: No complex environment modes or auto-server management
  • βœ… Reliability: Clear separation between server and registration

Registration Options

Option Description Default Required
--server-url Server URL where webhook is accessible - βœ…
--api-key Vapi platform API key - βœ…
--output-dir Generated code directory ./generated
--timeout Registration timeout (seconds) 30
--scan-path Function scan directory ./src
--json JSON output format False

Environment Variables

Set these environment variables for easier usage:

# Required for tool registration
export VAPI_API_KEY="your_vapi_api_key_here"

# Optional: Default server URL for production
export SERVER_URL="https://your-webhook-server.com"

# Required for staging mode with ngrok
export NGROK_AUTHTOKEN="your_ngrok_auth_token"

Registration Results

The migrate command provides detailed feedback:

πŸš€ Tool migration completed
🌍 Environment: production
πŸ“Š Registered 3 tools successfully
πŸ”— Server URL: https://api.example.com
πŸ“‹ Tool IDs: tool_abc123, tool_def456, tool_ghi789

Registration Results (3):
Function              | Status    | Tool ID      | Error
----------------------+-----------+--------------+------
get_weather          | βœ… success | tool_abc123  |
schedule_meeting     | βœ… success | tool_def456  |
send_email           | βœ… success | tool_ghi789  |

Handling Registration Errors

If some tools fail to register:

⚠️ Tool migration partially completed
🌍 Environment: production
βœ… Successful: 2 tools
❌ Failed: 1 tools
πŸ“‹ Details:
  β€’ get_weather: success
  β€’ schedule_meeting: API rate limit exceeded
  β€’ send_email: success

Common registration errors:

  • API rate limiting: Wait and retry
  • Invalid webhook URL: Check server accessibility
  • Duplicate tool names: Ensure unique function names
  • API key issues: Verify your Vapi API key

πŸ–₯️ Server Deployment

Local Development Server

# Start FastAPI server for development
uvicorn src.main:app --reload --host 0.0.0.0 --port 8000

# Or using the built-in CLI
uv run python src.main.py --reload

# With custom port
uv run python src.main.py --port 8080

Production Server Deployment

Option 1: Direct uvicorn

# Production server (no auto-reload)
uvicorn src.main:app --host 0.0.0.0 --port 8000 --workers 4

Option 2: Docker Deployment

FROM python:3.13-slim

WORKDIR /app
COPY . .
RUN pip install -e .

EXPOSE 8000
CMD ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]

Option 3: Cloud Platforms

Heroku:

# Procfile
web: uvicorn src.main:app --host 0.0.0.0 --port $PORT

Railway/Render:

uvicorn src.main:app --host 0.0.0.0 --port $PORT

Ngrok for Public Access

For development/staging with public webhooks:

# Install ngrok and get auth token from https://ngrok.com
export NGROK_AUTHTOKEN="your_token"

# Start server with ngrok tunnel
uv run python src.main.py --ngrok

# Custom port with ngrok
uv run python src.main.py --ngrok --port 8080

Server Endpoints

Once running, your server provides:

  • Webhook Endpoint: POST /webhook/vapi - Handles Vapi tool calls
  • Health Check: GET /health - Server health status
  • API Documentation: GET /docs - Interactive API docs
  • OpenAPI Spec: GET /openapi.json - API specification

Testing Server

# Test health endpoint
curl http://localhost:8000/health

# Test webhook endpoint
curl -X POST http://localhost:8000/webhook/vapi \
  -H "Content-Type: application/json" \
  -d '{
    "message": {
      "toolCallList": [{
        "id": "test_call",
        "name": "get_weather",
        "arguments": {"location": "San Francisco, CA"}
      }]
    }
  }'

🌍 Deployment Options

Local Development

# Start server
uv run python src/main.py --port 8000

# Register tools
uv run migrate --server-url http://localhost:8000 --api-key your_key

Use cases:

  • Local development and testing
  • Function debugging
  • Integration testing with localhost

Public Development (with Ngrok)

# Start server with ngrok tunnel
export NGROK_AUTHTOKEN="your_ngrok_token"
uv run python src/main.py --ngrok --port 8001

# Copy the ngrok URL from output, then register
uv run migrate --server-url https://abc123.ngrok.io --api-key your_key

Use cases:

  • Testing with real Vapi voice agents
  • Sharing development environment
  • Integration testing with public webhooks

Production Deployment

# Your server is already running at https://api.example.com

# Just register the tools
uv run migrate --server-url https://api.example.com --api-key your_key

Use cases:

  • Deploying to production
  • Updating tool registrations
  • CI/CD pipeline integration

πŸ”§ Advanced Usage

Custom Function Discovery

By default, the system scans ./src for functions. Customize the scan path:

# Scan specific directory
uv run codegen --scan-path ./my_functions

# Scan multiple directories (run multiple times)
uv run codegen --scan-path ./services
uv run codegen --scan-path ./utils --output-dir ./generated/utils

Batch Operations

The migrate command handles both generation and registration:

# Automatically generates code and registers tools
uv run migrate --server-url https://api.example.com --api-key your_key

# Just generate code without registration
uv run codegen

JSON Output for Automation

# Get JSON output for scripting
uv run codegen --json > codegen_results.json
uv run migrate --server-url https://api.example.com --json > registration_results.json

Example JSON output:

{
  "success": true,
  "operation": "migrate",
  "environment": "production",
  "server_url": "https://api.example.com",
  "total_tools": 3,
  "successful_registrations": 3,
  "failed_registrations": 0,
  "tool_ids": ["tool_abc123", "tool_def456", "tool_ghi789"],
  "registration_details": [...]
}

Environment-Specific Configuration

Create environment-specific configurations:

# .env.development
VAPI_API_KEY=dev_api_key
SERVER_URL=http://localhost:8000

# .env.staging
VAPI_API_KEY=staging_api_key
NGROK_AUTHTOKEN=staging_ngrok_token

# .env.production
VAPI_API_KEY=prod_api_key
SERVER_URL=https://api.mycompany.com

Integration with CI/CD

# GitHub Actions example
name: Deploy Vapi Tools
on:
  push:
    branches: [main]

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: '3.13'

      - name: Install dependencies
        run: pip install -e .

      - name: Register tools
        env:
          VAPI_API_KEY: ${{ secrets.VAPI_API_KEY }}
        run: |
          uv run migrate --server-url ${{ secrets.WEBHOOK_SERVER_URL }} --json

πŸ“š API Reference

CLI Commands

codegen

Generate Python code with CreateFunctionToolDto objects.

uv run codegen [OPTIONS]

Options:

  • --output-dir PATH: Output directory (default: ./generated)
  • --scan-path PATH: Directory to scan (default: ./src)
  • --server-url URL: Base webhook server URL
  • --module-name NAME: Generated module name (default: generated_tools)
  • --json: Output JSON format
  • --help: Show help message

migrate

Generate code and register tools with Vapi platform.

uv run migrate --server-url URL --api-key KEY [OPTIONS]

Required Arguments:

  • --server-url URL: Server URL where webhook is accessible
  • --api-key KEY: Vapi API key for registration

Options:

  • --output-dir PATH: Generated code directory (default: ./generated)
  • --timeout SECONDS: Registration timeout (default: 30)
  • --scan-path PATH: Function scan directory (default: ./src)
  • --json: Output JSON format
  • --help: Show help message

Server API

Webhook Endpoint

POST /webhook/vapi
Content-Type: application/json

{
  "message": {
    "toolCallList": [
      {
        "id": "call_123",
        "name": "function_name",
        "arguments": { "param": "value" }
      }
    ]
  }
}

Response:

{
  "results": [
    {
      "toolCallId": "call_123",
      "result": { "status": "success", "data": "..." }
    }
  ]
}

Health Check

GET /health

Response:

{
  "status": "healthy",
  "timestamp": "2024-01-01T12:00:00Z",
  "functions_registered": 3
}

Function Decorator

@vapi_function

from src.services.vapi_schema import vapi_function

@vapi_function(
    name: Optional[str] = None,           # Function name (defaults to Python function name)
    description: Optional[str] = None,    # Description (defaults to docstring)
    max_tokens: Optional[int] = None,     # Max tokens for execution
    strict: bool = True,                  # Strict parameter validation
    async_execution: bool = False,        # Async execution flag
    parameter_descriptions: Optional[Dict[str, str]] = None  # Parameter description overrides
)
def your_function(...):
    pass

πŸ” Troubleshooting

Common Issues

1. "No functions found"

# Problem: codegen finds 0 functions
uv run codegen
# βœ… Code generation completed
# πŸ”§ Generated 0 tool definitions

Solutions:

  • Check that functions use @vapi_function decorator
  • Verify import path: from src.services.vapi_schema import vapi_function
  • Ensure scan path contains your function files
  • Check for Python syntax errors in scanned files

2. "Import errors during discovery"

# Problem: Functions found but import fails
ModuleNotFoundError: No module named 'src.services.vapi_schema'

Solutions:

  • Fix import paths in your function files
  • Ensure all dependencies are installed
  • Check Python path and working directory

3. "Parameters marked as required when they should be optional"

# ❌ Problem: This creates required parameters
def my_function(param: str) -> str:

# βœ… Solution: Add default values for optional parameters
def my_function(param: str = None) -> str:

4. "API authentication failed"

# Problem: Registration fails with auth error
❌ Tool migration failed: API authentication failed

Solutions:

  • Verify VAPI_API_KEY environment variable
  • Check API key format and validity
  • Ensure API key has tool registration permissions

5. "Port already in use"

# Problem: Development server won't start
❌ Tool migration failed: Port 8000 is already in use

Solutions:

  • Use different port: --port 8001
  • Kill existing process on port 8000
  • Check for other running servers

6. "Webhook URL not accessible"

# Problem: Vapi can't reach webhook URLs
❌ Tool registration failed: Webhook URL accessibility

Solutions:

  • Ensure server is publicly accessible
  • Check firewall and security group settings
  • Use ngrok for local development: --staging
  • Verify SSL certificate for HTTPS URLs

Debug Mode

Enable debug output for troubleshooting:

# Add --debug flag (if implemented) or check logs
uv run migrate --dev --debug

# Or check server logs
uvicorn src.main:app --log-level debug

Logging

The system provides detailed logging:

import logging
logging.basicConfig(level=logging.DEBUG)

# Function discovery logs
logger = logging.getLogger('src.services.discovery')

# Registration logs
logger = logging.getLogger('src.cli.migrate')

Testing Individual Functions

Test functions before registration:

# Import your function directly
from src.services.my_tools import get_weather

# Test manually
result = get_weather("San Francisco, CA", "celsius")
print(result)

# Test with webhook server
curl -X POST http://localhost:8000/webhook/vapi \
  -H "Content-Type: application/json" \
  -d '{"message":{"toolCallList":[{"id":"test","name":"get_weather","arguments":{"location":"San Francisco, CA"}}]}}'

Performance Optimization

For large numbers of functions:

# Use timeout adjustment for many tools
uv run migrate --timeout 60 --server-url https://api.example.com

# Register in batches if needed (split scan paths)
uv run migrate --scan-path ./services/batch1
uv run migrate --scan-path ./services/batch2

Getting Help

# Command help
uv run codegen --help
uv run migrate --help

# Check server status
curl http://localhost:8000/health

# View API documentation
# Visit: http://localhost:8000/docs

πŸ“Š Examples & Tutorials

Complete Example: Weather Service

  1. Create the function:
# src/services/weather.py
from typing import Dict, Any, Optional
from src.services.vapi_schema import vapi_function

@vapi_function(
    name="get_weather_forecast",
    description="Get detailed weather forecast for a location with multiple days"
)
def get_weather_forecast(
    location: str,
    days: int = 3,
    units: str = "celsius",
    include_hourly: bool = False
) -> Dict[str, Any]:
    """Get weather forecast for a location.

    Args:
        location: City and country (e.g., "Paris, France")
        days: Number of forecast days (1-7)
        units: Temperature units (celsius/fahrenheit)
        include_hourly: Include hourly breakdown

    Returns:
        Detailed weather forecast data
    """
    return {
        "location": location,
        "forecast_days": days,
        "units": units,
        "daily_forecasts": [
            {
                "date": f"2024-01-{i+1:02d}",
                "high": 20 + i,
                "low": 10 + i,
                "condition": "sunny"
            }
            for i in range(days)
        ],
        "hourly_included": include_hourly
    }
  1. Generate and test locally:
# Start server
uv run python src/main.py --port 8000

# Register tools
uv run migrate --server-url http://localhost:8000 --api-key your_key

# Test the function
curl -X POST http://localhost:8000/webhook/vapi \
  -H "Content-Type: application/json" \
  -d '{
    "message": {
      "toolCallList": [{
        "id": "weather_test",
        "name": "get_weather_forecast",
        "arguments": {
          "location": "Tokyo, Japan",
          "days": 5,
          "include_hourly": true
        }
      }]
    }
  }'
  1. Deploy to production:
# Register with production server
uv run migrate --server-url https://your-production-webhook.com --api-key your_production_key

Integration with Vapi Voice Agent

After registering your tools, use them in Vapi:

// Vapi dashboard configuration
{
  "model": {
    "provider": "openai",
    "model": "gpt-4",
    "functions": [
      {
        "name": "get_weather_forecast",
        "description": "Get detailed weather forecast for a location",
        // Tool automatically registered by migrate command
      }
    ]
  },
  "voice": {
    "provider": "11labs",
    "voiceId": "..."
  }
}

The voice agent can now call your function during conversations:

User: "What's the weather going to be like in Tokyo for the next 5 days?"

Agent: [Calls get_weather_forecast with location="Tokyo, Japan", days=5]

Agent: "Based on the forecast, Tokyo will have sunny weather for the next 5 days with temperatures ranging from 10Β°C to 25Β°C..."


πŸš€ Getting Started Checklist

  • Install Python 3.13+ and dependencies
  • Get Vapi API key from dashboard
  • Create your first @vapi_function decorated function
  • Run uv run codegen to generate tool code
  • Start server with uv run python src/main.py --port 8000
  • Test with uv run migrate --server-url http://localhost:8000 --api-key your_key
  • Deploy webhook server to production
  • Register tools with uv run migrate --server-url <production-url> --api-key your_key
  • Configure Vapi voice agent to use your tools
  • Test end-to-end voice conversation

About

A simple template built using FastAPI to help build custom tools for Vapi. Simply build your custom tools, add decorator and run. Handling Vapi's request response and registering functions on Vapi is done with a single command.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published