Open source Ai voice agent builder platform
12
stars
2,191
commits
Python
primary language
Sep 7, 2026
updated
License: MIT Python FastAPI React PostgreSQL
The open source alternative to Retell, Synthflow, and Vapi - Build reliable, observable, and easily testable AI voice agents with a focus on developer experience.
This project is an open source AI Voice agent Builder that empowers developers and businesses to create sophisticated voice agents without vendor lock-in. Built with reliability, observability, and real-time testing at its core.
We believe in democratizing AI voice technology through open source solutions. Our platform provides:
Frontend
Backend
Infrastructure
python --version) git clone https://github.com/tonehq/tone.git
cd tone
.env file # Create a .env file in the project root with:
# DATABASE_URL=postgresql://<user>:<password>@<host>/<dbname>
# JWT_SECRET_KEY=<your-secret-key>
# ENCRYPTION_KEY=<your-encryption-key>
#
# Infisical (used by bootstrap/dev-bootstrap.sh and to run the app):
# INFISICAL_PROJECT_ID=<your-project-id>
# INFISICAL_ENV=<staging|dev|production>
#
# Cloudsmith (private tone-pipecat package):
# PIP_EXTRA_INDEX_URL=https://<user>:<token>@dl.cloudsmith.io/<entitlement>/tonehq/tone/python/simple/
#
# Optional: provider API keys (OPENAI_API_KEY, DEEPGRAM_API_KEY, etc.)
# macOS
brew install infisical/get-cli/infisical
# Linux
curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | sudo -E bash
sudo apt install -y infisical
# Log in once (opens a browser)
infisical login
tone-pipecat package) # Get the real URL from Cloudsmith → tonehq/tone repo → Set Me Up → Python.
export PIP_EXTRA_INDEX_URL="https://<user>:<token>@dl.cloudsmith.io/<entitlement>/tonehq/tone/python/simple/"
Runs Python install, venv, dependencies, migrations, procrastinate schema, DB seed, Node.js install, and frontend npm install — all in one go.
Before running: open
bootstrap/dev-bootstrap.shand read the PREREQUISITES block at the top. It lists everything you must have in place first (Homebrew,PIP_EXTRA_INDEX_URL,infisical login,.envkeys, a reachable Postgres DB, optional provider API keys). The seed step is interactive — have your organization name, owner email, and password ready.
./bootstrap/dev-bootstrap.sh
Adding another organization on an already-initialized DB? See Adding a new organization below.
When it finishes, start the servers:
# Backend (secrets are injected by infisical run)
source venv/bin/activate
infisical run --projectId "$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" -- \
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# Frontend (in a separate terminal)
cd frontend && npm run dev
Local development: use
--env=local, not--env=staging. The auth token rides in an httpOnly cookie whoseDomain/Secureattributes come from Infisical. Deployed envs setCOOKIE_DOMAIN=.trytone.aiandCOOKIE_SECURE=true, which a browser cannot store forhttp://localhost— so login succeeds (200) but the cookie is dropped,middleware.tssees no session, and every route bounces back to/login?next=…. ThelocalInfisical environment overrides these for local dev (COOKIE_DOMAIN=localhost,COOKIE_SECURE=false,ENV=local,CORS_ALLOW_ORIGINS=http://localhost:3000):infisical run --projectId "$INFISICAL_PROJECT_ID" --env=local -- \ uvicorn main:app --reload --host 0.0.0.0 --port 8000If you previously logged in against staging secrets, clear existing
localhostcookies before retrying — a staleSecure/.trytone.aicookie can linger.
Prefer to run each step yourself? Follow the manual backend and frontend steps below.
# Create virtual environment (requires Python 3.10+)
python -m venv venv
# Activate the virtual environment
source venv/bin/activate # macOS / Linux
# venv\Scripts\activate # Windows (PowerShell/CMD)
# Configure Cloudsmith index for the private `tone-pipecat` package.
# Get the entitlement token from Cloudsmith (tonehq/tone repo).
export PIP_EXTRA_INDEX_URL="https://<user>:<token>@dl.cloudsmith.io/<entitlement>/tonehq/tone/python/simple/"
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
# Create a .env file in the project root with the required configuration:
# DATABASE_URL=postgresql://<user>:<password>@<host>/<dbname>
# JWT_SECRET_KEY=<your-secret-key>
# ENCRYPTION_KEY=<your-encryption-key>
# Run database migrations
alembic upgrade head
# Apply the Procrastinate ingestion-queue schema (one-time, per environment).
# Required before the document-ingestion worker can run.
PYTHONPATH=. python -m procrastinate --app=core.services.ingestion_queue.app schema --apply
# Seed service providers, models, and voices
python dev/seed.py
# Start the backend server with uvicorn (auto-reload for development)
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
# Enterprise edition
# uvicorn main_ee:app --host 0.0.0.0 --port 8000 --reload
Seed Data (dev/seed.py)
The seed script sets up your initial data — it creates an owner user, organization, and populates all supported service providers (LLM, STT, TTS), their models, and voices from dev/dev-data.json.
When you run python dev/seed.py, it will interactively prompt you for:
.env file before running the script. For example:
Any provider whose API key env var is not set will be seeded without a key — you can add keys later through the UI. cd frontend
# Install dependencies
npm install
# Start the frontend dev server (Next.js + Turbopack on :3000)
npm run dev
Use bootstrap/db-bootstrap.sh when your machine is already set up
(Python, venv, dependencies, Node all installed) and you just need to
initialize a fresh, empty database — for example, pointing at a
newly provisioned staging/production DB, or resetting your local DB.
It runs three steps:
alembic upgrade head — creates the full schemadev/seed.py — creates the first user + org and seeds the
global provider/model/voice catalogue# Local — reads DATABASE_URL from .env
./bootstrap/db-bootstrap.sh
# With Infisical (DATABASE_URL and provider API keys injected from Infisical)
infisical run --projectId "$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" -- \
./bootstrap/db-bootstrap.sh
Prerequisites (also listed at the top of bootstrap/db-bootstrap.sh):
DATABASE_URL in .env (or
injected by infisical run)OPENAI_API_KEY, etc.) if you
want them seeded automaticallyThe seed step is interactive — have organization name, owner email, and password ready.
Use bootstrap/org-bootstrap.sh when you need to add another organization to
an already-initialized database (migrations + provider catalogue already
seeded via bootstrap/db-bootstrap.sh). Creates the user + org + member,
seeds app_integrations and built-in tools for only the new org, and
optionally attaches provider API keys pulled from environment variables.
# Prompts for org name, owner email, password. Skips API keys.
./bootstrap/org-bootstrap.sh
# Same, but also seeds provider API keys from env vars
# (OPENAI_API_KEY, DEEPGRAM_API_KEY, ELEVENLABS_API_KEY, etc.)
./bootstrap/org-bootstrap.sh --api-keys-from-env
# Run with Infisical-injected secrets (recommended — matches how the app runs)
infisical run --projectId "$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" -- \
./bootstrap/org-bootstrap.sh --api-keys-from-env
Pre-flight checks it runs before touching the DB:
run ./bootstrap/db-bootstrap.sh first)Which DB does it target? The same one the app uses — resolved via
shared/config.py from DATABASE_URL in your .env (or Infisical if you
wrap with infisical run). Double-check by running:
python -c "from shared.config import settings; print(settings.DATABASE_URL)"
# Build the backend image
docker build -f core/Dockerfile -t tone .
# Run it (expects DATABASE_URL and other env vars to be provided)
docker run --rm -p 8000:8000 --env-file .env tone
Our codebase follows a clean architecture pattern:
core/
├── api/v1/ # FastAPI route handlers
│ ├── agents.py
│ ├── auth.py
│ ├── channels.py
│ ├── models.py
│ ├── organizations.py
│ ├── service_providers.py
│ └── voices.py
├── services/ # Business logic layer
│ ├── agent_service.py
│ ├── agent_factory_service.py
│ ├── voice_service.py
│ ├── channel_service.py
│ └── model_service.py
├── models/ # SQLAlchemy ORM models
│ ├── agent.py
│ ├── organization.py
│ ├── service_provider.py
│ ├── voice.py
│ └── user.py
├── middleware/ # Auth & request middleware
│ └── auth.py
├── utils/ # Utility functions
│ └── encryption.py # AES encryption for API keys
├── bot.py # Voice pipeline entry point
└── database/ # DB session & connection
dev/
├── seed.py # Data seeding script
└── dev-data.json # Provider/model/voice definitions
⭐ Star this repository if you find it useful!
Made with ❤️ by the open source community
1,107 commits
397 commits
349 commits
218 commits
Python
67.7%
TypeScript
31.8%
Open source Ai voice agent builder platform
12
stars
2,191
commits
Python
primary language
Sep 7, 2026
updated
License: MIT Python FastAPI React PostgreSQL
The open source alternative to Retell, Synthflow, and Vapi - Build reliable, observable, and easily testable AI voice agents with a focus on developer experience.
This project is an open source AI Voice agent Builder that empowers developers and businesses to create sophisticated voice agents without vendor lock-in. Built with reliability, observability, and real-time testing at its core.
We believe in democratizing AI voice technology through open source solutions. Our platform provides:
Frontend
Backend
Infrastructure
python --version) git clone https://github.com/tonehq/tone.git
cd tone
.env file # Create a .env file in the project root with:
# DATABASE_URL=postgresql://<user>:<password>@<host>/<dbname>
# JWT_SECRET_KEY=<your-secret-key>
# ENCRYPTION_KEY=<your-encryption-key>
#
# Infisical (used by bootstrap/dev-bootstrap.sh and to run the app):
# INFISICAL_PROJECT_ID=<your-project-id>
# INFISICAL_ENV=<staging|dev|production>
#
# Cloudsmith (private tone-pipecat package):
# PIP_EXTRA_INDEX_URL=https://<user>:<token>@dl.cloudsmith.io/<entitlement>/tonehq/tone/python/simple/
#
# Optional: provider API keys (OPENAI_API_KEY, DEEPGRAM_API_KEY, etc.)
# macOS
brew install infisical/get-cli/infisical
# Linux
curl -1sLf 'https://artifacts-cli.infisical.com/setup.deb.sh' | sudo -E bash
sudo apt install -y infisical
# Log in once (opens a browser)
infisical login
tone-pipecat package) # Get the real URL from Cloudsmith → tonehq/tone repo → Set Me Up → Python.
export PIP_EXTRA_INDEX_URL="https://<user>:<token>@dl.cloudsmith.io/<entitlement>/tonehq/tone/python/simple/"
Runs Python install, venv, dependencies, migrations, procrastinate schema, DB seed, Node.js install, and frontend npm install — all in one go.
Before running: open
bootstrap/dev-bootstrap.shand read the PREREQUISITES block at the top. It lists everything you must have in place first (Homebrew,PIP_EXTRA_INDEX_URL,infisical login,.envkeys, a reachable Postgres DB, optional provider API keys). The seed step is interactive — have your organization name, owner email, and password ready.
./bootstrap/dev-bootstrap.sh
Adding another organization on an already-initialized DB? See Adding a new organization below.
When it finishes, start the servers:
# Backend (secrets are injected by infisical run)
source venv/bin/activate
infisical run --projectId "$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" -- \
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# Frontend (in a separate terminal)
cd frontend && npm run dev
Local development: use
--env=local, not--env=staging. The auth token rides in an httpOnly cookie whoseDomain/Secureattributes come from Infisical. Deployed envs setCOOKIE_DOMAIN=.trytone.aiandCOOKIE_SECURE=true, which a browser cannot store forhttp://localhost— so login succeeds (200) but the cookie is dropped,middleware.tssees no session, and every route bounces back to/login?next=…. ThelocalInfisical environment overrides these for local dev (COOKIE_DOMAIN=localhost,COOKIE_SECURE=false,ENV=local,CORS_ALLOW_ORIGINS=http://localhost:3000):infisical run --projectId "$INFISICAL_PROJECT_ID" --env=local -- \ uvicorn main:app --reload --host 0.0.0.0 --port 8000If you previously logged in against staging secrets, clear existing
localhostcookies before retrying — a staleSecure/.trytone.aicookie can linger.
Prefer to run each step yourself? Follow the manual backend and frontend steps below.
# Create virtual environment (requires Python 3.10+)
python -m venv venv
# Activate the virtual environment
source venv/bin/activate # macOS / Linux
# venv\Scripts\activate # Windows (PowerShell/CMD)
# Configure Cloudsmith index for the private `tone-pipecat` package.
# Get the entitlement token from Cloudsmith (tonehq/tone repo).
export PIP_EXTRA_INDEX_URL="https://<user>:<token>@dl.cloudsmith.io/<entitlement>/tonehq/tone/python/simple/"
# Install dependencies
pip install -r requirements.txt
# Set up environment variables
# Create a .env file in the project root with the required configuration:
# DATABASE_URL=postgresql://<user>:<password>@<host>/<dbname>
# JWT_SECRET_KEY=<your-secret-key>
# ENCRYPTION_KEY=<your-encryption-key>
# Run database migrations
alembic upgrade head
# Apply the Procrastinate ingestion-queue schema (one-time, per environment).
# Required before the document-ingestion worker can run.
PYTHONPATH=. python -m procrastinate --app=core.services.ingestion_queue.app schema --apply
# Seed service providers, models, and voices
python dev/seed.py
# Start the backend server with uvicorn (auto-reload for development)
uvicorn main:app --host 0.0.0.0 --port 8000 --reload
# Enterprise edition
# uvicorn main_ee:app --host 0.0.0.0 --port 8000 --reload
Seed Data (dev/seed.py)
The seed script sets up your initial data — it creates an owner user, organization, and populates all supported service providers (LLM, STT, TTS), their models, and voices from dev/dev-data.json.
When you run python dev/seed.py, it will interactively prompt you for:
.env file before running the script. For example:
Any provider whose API key env var is not set will be seeded without a key — you can add keys later through the UI. cd frontend
# Install dependencies
npm install
# Start the frontend dev server (Next.js + Turbopack on :3000)
npm run dev
Use bootstrap/db-bootstrap.sh when your machine is already set up
(Python, venv, dependencies, Node all installed) and you just need to
initialize a fresh, empty database — for example, pointing at a
newly provisioned staging/production DB, or resetting your local DB.
It runs three steps:
alembic upgrade head — creates the full schemadev/seed.py — creates the first user + org and seeds the
global provider/model/voice catalogue# Local — reads DATABASE_URL from .env
./bootstrap/db-bootstrap.sh
# With Infisical (DATABASE_URL and provider API keys injected from Infisical)
infisical run --projectId "$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" -- \
./bootstrap/db-bootstrap.sh
Prerequisites (also listed at the top of bootstrap/db-bootstrap.sh):
DATABASE_URL in .env (or
injected by infisical run)OPENAI_API_KEY, etc.) if you
want them seeded automaticallyThe seed step is interactive — have organization name, owner email, and password ready.
Use bootstrap/org-bootstrap.sh when you need to add another organization to
an already-initialized database (migrations + provider catalogue already
seeded via bootstrap/db-bootstrap.sh). Creates the user + org + member,
seeds app_integrations and built-in tools for only the new org, and
optionally attaches provider API keys pulled from environment variables.
# Prompts for org name, owner email, password. Skips API keys.
./bootstrap/org-bootstrap.sh
# Same, but also seeds provider API keys from env vars
# (OPENAI_API_KEY, DEEPGRAM_API_KEY, ELEVENLABS_API_KEY, etc.)
./bootstrap/org-bootstrap.sh --api-keys-from-env
# Run with Infisical-injected secrets (recommended — matches how the app runs)
infisical run --projectId "$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" -- \
./bootstrap/org-bootstrap.sh --api-keys-from-env
Pre-flight checks it runs before touching the DB:
run ./bootstrap/db-bootstrap.sh first)Which DB does it target? The same one the app uses — resolved via
shared/config.py from DATABASE_URL in your .env (or Infisical if you
wrap with infisical run). Double-check by running:
python -c "from shared.config import settings; print(settings.DATABASE_URL)"
# Build the backend image
docker build -f core/Dockerfile -t tone .
# Run it (expects DATABASE_URL and other env vars to be provided)
docker run --rm -p 8000:8000 --env-file .env tone
Our codebase follows a clean architecture pattern:
core/
├── api/v1/ # FastAPI route handlers
│ ├── agents.py
│ ├── auth.py
│ ├── channels.py
│ ├── models.py
│ ├── organizations.py
│ ├── service_providers.py
│ └── voices.py
├── services/ # Business logic layer
│ ├── agent_service.py
│ ├── agent_factory_service.py
│ ├── voice_service.py
│ ├── channel_service.py
│ └── model_service.py
├── models/ # SQLAlchemy ORM models
│ ├── agent.py
│ ├── organization.py
│ ├── service_provider.py
│ ├── voice.py
│ └── user.py
├── middleware/ # Auth & request middleware
│ └── auth.py
├── utils/ # Utility functions
│ └── encryption.py # AES encryption for API keys
├── bot.py # Voice pipeline entry point
└── database/ # DB session & connection
dev/
├── seed.py # Data seeding script
└── dev-data.json # Provider/model/voice definitions
⭐ Star this repository if you find it useful!
Made with ❤️ by the open source community
1,107 commits
397 commits
349 commits
218 commits
Python
67.7%
TypeScript
31.8%