The reload-tools webhook was referencing agent._n8n_mcp which was
removed in commit
|
||
|---|---|---|
| .github | ||
| docs | ||
| frontend | ||
| mobile | ||
| models | ||
| n8n-workflows | ||
| prompt | ||
| src/caal | ||
| .dockerignore | ||
| .env.example | ||
| .gitattributes | ||
| .gitignore | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| docker-compose.apple.yaml | ||
| docker-compose.dev.yml | ||
| docker-compose.distributed.yml | ||
| docker-compose.yaml | ||
| Dockerfile | ||
| entrypoint.sh | ||
| LICENSE | ||
| livekit-tailscale.yaml | ||
| livekit-tailscale.yaml.template | ||
| livekit.yaml | ||
| mcp_servers.default.json | ||
| mcp_servers.json.example | ||
| nginx-distributed.conf | ||
| nginx.conf | ||
| pyproject.toml | ||
| README.md | ||
| SECURITY.md | ||
| settings.default.json | ||
| start-apple.sh | ||
| uv.lock | ||
| voice_agent.py | ||
CAAL
Local voice assistant that learns new abilities via auto-discovered n8n workflows exposed as tools via MCP
Built on LiveKit Agents with fully local STT/TTS/LLM using Speaches, Kokoro, and Ollama.
Features
- Local Voice Pipeline - Speaches (Faster-Whisper STT) + Kokoro (TTS) + Ollama LLM
- Wake Word Detection - "Hey Cal" activation via Picovoice Porcupine
- n8n Integrations - Home Assistant, APIs, databases - anything n8n can connect to
- 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
Quick Start
Choose your deployment mode:
| Mode | Hardware | Command | Documentation |
|---|---|---|---|
| NVIDIA GPU | Linux + NVIDIA GPU | docker compose up -d |
Below |
| Apple Silicon | M1/M2/M3/M4 Mac | ./start-apple.sh |
docs/APPLE-SILICON.md |
| Distributed | GPU Server + macOS | See docs | docs/DISTRIBUTED-DEPLOYMENT.md |
NVIDIA GPU (Linux)
Requirements
- Docker with NVIDIA Container Toolkit
- Ollama running on your network
- n8n with MCP enabled (Settings > MCP Access)
- 12GB+ VRAM recommended
Installation
# Clone and configure
git clone https://github.com/CoreWorxLab/caal.git
cd caal
cp .env.example .env
nano .env # Set CAAL_HOST_IP, OLLAMA_HOST, N8N_MCP_URL, N8N_MCP_TOKEN
# Deploy
docker compose up -d
Open http://YOUR_SERVER_IP:3000 from any device on your network.
Apple Silicon (macOS)
CAAL runs on Apple Silicon Macs using mlx-audio for Metal-accelerated STT/TTS.
./start-apple.sh
See docs/APPLE-SILICON.md for full setup instructions.
Distributed Deployment
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.
Network Modes
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 |
docker compose --profile https up -d |
| Tailscale | Anywhere | https://your-machine.tailnet.ts.net |
docker compose --profile https up -d |
Why? Browsers block microphone access on HTTP except from localhost. HTTPS is required for voice from other devices.
LAN HTTP (Default)
CAAL_HOST_IP=192.168.1.100 # Set in .env
docker compose up -d
LAN HTTPS (mkcert)
# Generate certificates
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
chmod 644 certs/server.key
# Configure .env
CAAL_HOST_IP=192.168.1.100
HTTPS_DOMAIN=192.168.1.100
# Build and start
docker compose --profile https build frontend
docker compose --profile https up -d
Tailscale (Remote Access)
# 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
# Build and start
docker compose --profile https build frontend
docker compose --profile https up -d
Configuration
Essential Environment Variables
| Variable | Description | Required |
|---|---|---|
CAAL_HOST_IP |
Your server's LAN/Tailscale IP | Yes |
OLLAMA_HOST |
Ollama server URL | Yes |
N8N_MCP_URL |
n8n MCP endpoint | Yes |
N8N_MCP_TOKEN |
n8n access token | Yes |
OLLAMA_MODEL |
LLM model (default: ministral-3:8b) |
No |
TTS_VOICE |
Kokoro voice (default: am_puck) |
No |
PORCUPINE_ACCESS_KEY |
Picovoice key for wake word | No |
See .env.example for full configuration options.
Integrations
n8n Workflows
CAAL discovers tools from n8n workflows via MCP. Each workflow with a webhook trigger becomes a voice command.
cd n8n-workflows
cp config.env.example config.env
nano config.env # Set your n8n IP and API key
python setup.py # Creates all workflows
Setup n8n:
- Enable MCP: Settings > MCP Access > Enable MCP
- Set connection method to Access Token and copy the token
- Set
N8N_MCP_URLin.env
See n8n-workflows/README.md for included workflows.
Wake Word Detection
- Get a free access key from Picovoice Console
- Train "Hey Cal" wake word, download Web (WASM) model
- Place
hey_cal.ppninfrontend/public/ - Set
PORCUPINE_ACCESS_KEYin.env - Rebuild:
docker compose build frontend && docker compose up -d
Webhook API
| 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 |
curl -X POST http://localhost:8889/announce \
-H "Content-Type: application/json" \
-d '{"message": "Package delivered"}'
Mobile App
Flutter client for Android and iOS in mobile/.
cd mobile
flutter pub get
flutter run
See mobile/README.md for full documentation.
Development
# 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 dev
Commands:
uv run ruff check src/ # Lint
uv run mypy src/ # Type check
uv run pytest # Test
Architecture
┌───────────────────────────────────────────────────────────────────────┐
│ Docker Compose Stack │
│ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Frontend │ │ LiveKit │ │ Speaches │ │ Kokoro │ │
│ │ (Next.js) │ │ Server │ │ (STT, GPU) │ │ (TTS, GPU) │ │
│ │ :3000 │ │ :7880 │ │ :8000 │ │ :8880 │ │
│ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ └─────┬──────┘ │
│ │ │ │ │ │
│ │ └───────────────┼───────────────┘ │
│ └───────────────────────┐ │ │
│ │ │ │
│ ┌─────┴───────┴─────┐ │
│ │ Agent │ │
│ │ (Voice Pipeline) │ │
│ │ :8889 (webhooks) │ │
│ └─────────┬─────────┘ │
│ │ │
└────────────────────────────────────┼──────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
┌─────┴─────┐ ┌─────┴─────┐ ┌─────┴─────┐
│ Ollama │ │ n8n │ │ Your │
│ (LLM) │ │ Workflows │ │ APIs │
└───────────┘ └───────────┘ └───────────┘
External Services (on your network)
Troubleshooting
WebRTC Not Connecting
- Check
CAAL_HOST_IPmatches your network mode - Verify firewall ports: 3000, 7880, 7881, 50000-50100 (UDP)
- Check logs:
docker compose logs livekit | grep -i "ice\|error"
Ollama Connection Failed
# 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:11434
First Start Is Slow
Normal - models download on first run (~2-5 minutes):
docker compose logs -f speaches kokoro
Related Projects
- LiveKit Agents - Voice agent framework
- Speaches - Faster-Whisper STT server
- Kokoro-FastAPI - Kokoro TTS server
- mlx-audio - STT/TTS for Apple Silicon
- Ollama - Local LLM server
- n8n - Workflow automation
Contributing
We welcome contributions! See CONTRIBUTING.md for guidelines.
License
MIT License - see LICENSE for details.
