Local voice assistant with n8n workflow integrations and Home Assistant control
Built on LiveKit Agents. Runs fully local with Ollama + Speaches + Kokoro, cloud with Groq or OpenRouter, or any OpenAI-compatible API.
- First-Start Wizard - Configure everything from the browser, only one edit in
.envrequired - Flexible Providers - Ollama (local), Groq, OpenRouter, or any OpenAI-compatible API for LLM. Speaches or Groq for STT. Kokoro or Piper for TTS
- Home Assistant - Native MCP integration with simplified
hass_controlandhass_get_statetools - n8n Workflows - Expandable LLM tool capability - any n8n workflow can become a tool for CAAL
- Wake Word Detection - "Hey Cal" activation via OpenWakeWord (server-side)
- Web Search - DuckDuckGo integration for real-time information
- Webhook API - External triggers for announcements and tool reload
- Mobile App - Flutter client for Android and iOS
git clone https://github.com/CoreWorxLab/caal.git
cd caal
cp .env.example .env
nano .env # Set CAAL_HOST_IP to your server's LAN IP
# GPU mode (Ollama + Kokoro)
docker compose up -d
# CPU-only mode (Groq + Piper) - no GPU required
docker compose -f docker-compose.cpu.yaml up -dOpen http://YOUR_SERVER_IP:3000 and complete the setup wizard.
| Mode | Hardware | Command |
|---|---|---|
| GPU | Linux + NVIDIA GPU | docker compose up -d |
| CPU-only | Any Docker host | docker compose -f docker-compose.cpu.yaml up -d |
| Apple Silicon | M1/M2/M3/M4 Mac | docs/APPLE-SILICON.md |
| Distributed | GPU Server + Mac | docs/DISTRIBUTED-DEPLOYMENT.md |
Full local stack with GPU-accelerated STT (Speaches), LLM (Ollama) and TTS (Kokoro).
- Docker with NVIDIA Container Toolkit
- 12GB+ VRAM recommended
git clone https://github.com/CoreWorxLab/caal.git
cd caal
cp .env.example .env
nano .env # Set CAAL_HOST_IP
docker compose up -dThe setup wizard will guide you through LLM (Ollama), TTS, and integration configuration.
Run CAAL without a GPU using Groq for LLM/STT and Piper (CPU) for TTS.
docker compose -f docker-compose.cpu.yaml up -dFor HTTPS:
docker compose -f docker-compose.cpu.yaml --profile https up -dIn the setup wizard:
- Choose your STT provider (Speaches or Groq Whisper)
- Select your LLM provider — Groq (free API key), OpenRouter (free/paid models), or any OpenAI-compatible API
- Select Piper as TTS provider (models download automatically)
Note: Cloud providers send data to external APIs. For fully local operation, use GPU mode with Ollama.
CAAL runs on Apple Silicon Macs using mlx-audio for Metal-accelerated STT/TTS.
./start-apple.shSee docs/APPLE-SILICON.md for full setup instructions.
Run the GPU-intensive backend on a Linux server while using the frontend on a Mac or another device.
See docs/DISTRIBUTED-DEPLOYMENT.md for full setup instructions.
CAAL supports three network configurations:
| Mode | Voice From | Access URL | Command |
|---|---|---|---|
| LAN HTTP | Host machine only | http://localhost:3000 |
docker compose up -d |
| LAN HTTPS | Any LAN device | https://192.168.1.100:3443 |
docker compose --profile https up -d |
| Tailscale | Anywhere | https://your-machine.tailnet.ts.net:3443 |
docker compose --profile https up -d |
Why? Browsers block microphone access on HTTP except from localhost. HTTPS is required for voice from other devices.
Note: For utilization with mobile app as the client, only LAN HTTP is required, not HTTPS
CAAL_HOST_IP=192.168.1.100 # Set in .env
docker compose up -dSelf-signed certificates are auto-generated if none exist in ./certs/.
# Configure .env
CAAL_HOST_IP=192.168.1.100
HTTPS_DOMAIN=192.168.1.100
# Start with HTTPS profile (certs auto-generated)
docker compose --profile https up -dAccess: https://192.168.1.100:3443
Trusted certs: For browser-trusted certs without warnings, use mkcert:
mkcert -install && mkcert 192.168.1.100 mkdir -p certs && mv 192.168.1.100.pem certs/server.crt && mv 192.168.1.100-key.pem certs/server.key
# Generate Tailscale certs
tailscale cert your-machine.tailnet.ts.net
mkdir -p certs && mv your-machine.tailnet.ts.net.crt certs/server.crt && mv your-machine.tailnet.ts.net.key certs/server.key
# Configure .env
CAAL_HOST_IP=100.x.x.x # tailscale ip -4
HTTPS_DOMAIN=your-machine.tailnet.ts.net
# Start
docker compose --profile https up -dAccess: https://your-machine.tailnet.ts.net:3443
Only CAAL_HOST_IP is required. Everything else is configured via the web UI.
| Variable | Description | Required |
|---|---|---|
CAAL_HOST_IP |
Your server's LAN/Tailscale IP | Yes |
HTTPS_DOMAIN |
Domain for HTTPS mode | No |
See .env.example for additional options (ports, default models).
After setup, click the gear icon to access the settings panel:
- Agent - Agent name, wake greetings, wake word settings
- Prompt - Default or custom system prompt
- Voice Pipeline - STT provider (Speaches/Groq Whisper), TTS engine (Kokoro/Piper), voice selection
- AI Provider - LLM provider (Ollama/Groq/OpenRouter/OpenAI-compatible), model selection, temperature, context size
- Integrations - Home Assistant and n8n connection configuration
Control your smart home with voice commands. CAAL exposes two simplified tools:
hass_control(action, target, value)- Control devices- Actions:
turn_on,turn_off,set_volume,volume_up,volume_down,mute,unmute,pause,play,next,previous - Value: 0-100 for
set_volume
- Actions:
hass_get_state(target)- Query device states
Setup:
- Create a Long-Lived Access Token in Home Assistant
- In CAAL settings, enable Home Assistant and enter your host URL and token
- Restart the agent - CAAL auto-discovers your devices
See docs/HOME-ASSISTANT.md for action mappings and examples.
Extend CAAL with any API, database, or service via n8n workflows exposed through MCP.
Setup n8n:
- Enable MCP: Settings > MCP Access > Enable MCP
- Set connection method to Access Token and copy the token
- In CAAL settings, enable n8n and enter your MCP URL and token
Browse and install community tools from the CAAL Tool Registry - install directly from the Tools panel in the web UI.
See docs/N8N-WORKFLOWS.md for how to create your own workflows.
Enable "Hey Cal" wake word in the settings panel. Two options:
- OpenWakeWord (Server-side) - Runs on the server, works with any client
- Picovoice (Client-side) - Requires access key and trained model per device
The agent exposes a REST API on port 8889 for external integrations.
Core Endpoints:
| Endpoint | Method | Description |
|---|---|---|
/announce |
POST | Make CAAL speak a message |
/wake |
POST | Trigger wake word greeting |
/reload-tools |
POST | Refresh MCP tool cache |
/health |
GET | Health check |
Settings & Configuration:
| Endpoint | Method | Description |
|---|---|---|
/settings |
GET/POST | Read/update settings |
/prompt |
GET/POST | Read/update system prompt |
/voices |
GET | List available TTS voices |
/models |
GET | List available Ollama models |
Wake Word:
| Endpoint | Method | Description |
|---|---|---|
/wake-word/status |
GET | Get wake word status |
/wake-word/enable |
POST | Enable wake word detection |
/wake-word/disable |
POST | Disable wake word detection |
/wake-word/models |
GET | List available wake word models |
curl -X POST http://localhost:8889/announce \
-H "Content-Type: application/json" \
-d '{"message": "Package delivered"}'Android app available from GitHub Releases. Download the APK and install on your device.
Building from source:
cd mobile
flutter pub get
flutter build apkSee mobile/README.md for full documentation.
# Install dependencies
uv sync
# Start infrastructure
docker compose up -d livekit speaches kokoro
# Run agent locally
uv run voice_agent.py dev
# Run frontend locally
cd frontend && pnpm install && pnpm devCommands:
uv run ruff check src/ # Lint
uv run mypy src/ # Type check
uv run pytest # Test┌───────────────────────────────────────────────────────────────────────┐
│ Docker Compose Stack │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Frontend │ │ LiveKit │ │ Speaches │ │Kokoro/Piper│ │
│ │ (Next.js) │ │ Server │ │(STT, GPU) │ │ (TTS) │ │
│ │ :3000 │ │ :7880 │ │ :8000 │ │ :8880 │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ │ └───────────────┼───────────────┘ │
│ └───────────────────────┐ │ │
│ │ │ │
│ ┌─────┴───────┴─────┐ │
│ │ Agent │ │
│ │ (Voice Pipeline) │ │
│ │ :8889 (webhooks) │ │
│ └─────────┬─────────┘ │
│ │ │
└────────────────────────────────────┼──────────────────────────────────┘
│
┌────────────────────────┼────────────────────────┐
│ │ │
┌─────┴─────┐ ┌──────┴──────┐ ┌──────┴──────┐
│Ollama/Groq│ │ n8n │ │ Home │
│/OpenRouter│ │ Workflows │ │ Assistant │
└───────────┘ └─────────────┘ └─────────────┘
External Services (via MCP)
- Check
CAAL_HOST_IPmatches your network mode - Verify firewall ports: 3000, 7880, 7881, 51000-51100 (UDP)
- Check logs:
docker compose logs livekit | grep -i "ice\|error"
# Ensure Ollama binds to network
OLLAMA_HOST=0.0.0.0 ollama serve
# From Docker, use host.docker.internal
OLLAMA_HOST=http://host.docker.internal:11434Normal - models download on first run (~2-5 minutes):
docker compose logs -f speaches kokoroIf Home Assistant or n8n fail to connect, you'll see a toast notification with the error. Check:
- Host URL is reachable from the Docker container
- Access token is valid and has correct permissions
- For n8n: MCP Access is enabled in Settings
- LiveKit Agents - Voice agent framework
- Speaches - Faster-Whisper STT server (also includes Piper TTS)
- Kokoro-FastAPI - Kokoro TTS server
- Piper - Fast local TTS (CPU-friendly)
- mlx-audio - STT/TTS for Apple Silicon
- Ollama - Local LLM server
- Groq - Fast cloud LLM inference (free tier available)
- OpenRouter - Unified API for 200+ LLM models
- n8n - Workflow automation
- Home Assistant - Smart home platform
We welcome contributions! See CONTRIBUTING.md for guidelines.
MIT License - see LICENSE for details.
