Phone Voice Integration
name: phone-voice
by cortexuvula · published 2026-03-22
$ claw add gh:cortexuvula/cortexuvula-phone-voice---
name: phone-voice
description: Connect ElevenLabs Agents to your OpenClaw via phone with Twilio. Includes caller ID auth, voice PIN security, call screening, memory injection, and cost tracking.
version: 2.0.0
author: Fred (@FredMolty)
---
# Phone Voice Integration
Turn your OpenClaw into a phone-callable assistant with ElevenLabs Agents + Twilio.
**What you get:**
Architecture
Phone → Twilio → ElevenLabs Agent → Your Bridge → Anthropic Claude → OpenClaw Tools
↓
Memory Context
(MEMORY.md, USER.md)**Flow:**
1. Caller dials your Twilio number
2. Twilio routes to ElevenLabs Agent
3. Agent sends chat completions to your bridge (mimics OpenAI API)
4. Bridge translates to Anthropic, injects context from memory files
5. Claude response → ElevenLabs TTS → caller hears it
Prerequisites
Setup
1. Enable Chat Completions in OpenClaw
Not needed for this skill — the bridge bypasses OpenClaw and calls Claude directly. This gives you more control over memory injection and cost tracking.
2. Create the Bridge Server
The bridge is a FastAPI server that:
**Key files:**
3. Set Up Cloudflare Tunnel (Recommended)
Permanent, secure alternative to ngrok:
# Install cloudflared
brew install cloudflare/cloudflare/cloudflared
# Login and configure
cloudflared tunnel login
cloudflared tunnel create <tunnel-name>
# Run the tunnel
cloudflared tunnel --url http://localhost:8013 run <tunnel-name>Add a CNAME in Cloudflare DNS:
voice.yourdomain.com → <tunnel-id>.cfargotunnel.com**Or use ngrok (temporary):**
ngrok http 80134. Configure ElevenLabs Agent
#### Option A: Manual (UI)
1. Go to ElevenLabs dashboard → Conversational AI
2. Create new agent
3. Under LLM settings → Custom LLM
4. Set URL: `https://voice.yourdomain.com/v1/chat/completions`
5. Add header: `Authorization: Bearer <YOUR_BRIDGE_TOKEN>`
#### Option B: Programmatic (API)
# Step 1: Store your bridge auth token as a secret
curl -X POST https://api.elevenlabs.io/v1/convai/secrets \
-H "xi-api-key: YOUR_ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "new",
"name": "bridge_auth_token",
"value": "YOUR_BRIDGE_AUTH_TOKEN"
}'
# Response: {"secret_id": "abc123..."}
# Step 2: Create the agent
curl -X POST https://api.elevenlabs.io/v1/convai/agents/create \
-H "xi-api-key: YOUR_ELEVENLABS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"conversation_config": {
"agent": {
"language": "en",
"prompt": {
"llm": "custom-llm",
"prompt": "You are a helpful voice assistant.",
"custom_llm": {
"url": "https://voice.yourdomain.com/v1/chat/completions",
"api_key": {"secret_id": "abc123..."}
}
}
}
}
}'5. Connect Twilio Phone Number
In ElevenLabs agent settings:
1. Go to **Phone** section
2. Enter Twilio Account SID and Auth Token
3. Select your Twilio phone number
4. Save
Done! Your bot now answers that phone number.
Security Features
Caller ID Authentication
Recognizes whitelisted numbers automatically:
// contacts.json
{
"+12505551234": {
"name": "Alice",
"role": "family"
}
}Voice PIN Challenge
For unknown callers or high-security actions:
VOICE_PIN = "banana" # Set in .envCaller must say the PIN to proceed.
Call Screening
Unknown numbers get a receptionist prompt:
> "This is Fred's assistant. I can take a message or help with general questions."
Rate Limiting
Configurable per-hour limits:
RATE_LIMIT_PER_HOUR = 10Prevents abuse and runaway costs.
Memory Injection
The bridge auto-loads context before each call:
**Files read:**
**Live data injection:**
All injected into the system prompt before Claude sees the conversation.
Cost Tracking
Every call logs to `memory/voice-calls/costs.jsonl`:
{
"call_sid": "CA123...",
"timestamp": "2026-02-03T10:30:00",
"caller": "+12505551234",
"duration_sec": 45,
"total_cost_usd": 0.12,
"breakdown": {
"twilio": 0.02,
"elevenlabs": 0.08,
"anthropic": 0.02
}
}Run analytics on the JSONL to track monthly spend.
Usage Example
**Call your bot:**
1. Dial your Twilio number
2. If you're whitelisted → casual conversation starts
3. If you're unknown → receptionist mode
4. Ask it to check your calendar, send a message, set a reminder, etc.
**Outbound calling (optional):**
curl -X POST https://voice.yourdomain.com/call/outbound \
-H "Authorization: Bearer <BRIDGE_TOKEN>" \
-d '{"to": "+12505551234", "message": "Reminder: dentist at 3pm"}'Configuration Options
**Environment variables (.env):**
ANTHROPIC_API_KEY=sk-ant-...
ELEVENLABS_API_KEY=sk_...
ELEVENLABS_AGENT_ID=agent_...
TWILIO_ACCOUNT_SID=AC...
TWILIO_AUTH_TOKEN=...
TWILIO_NUMBER=+1...
LLM_BRIDGE_TOKEN=<random-secure-token>
VOICE_PIN=<your-secret-word>
CLAWD_DIR=/path/to/clawd**Whitelist (contacts.json):**
{
"+12505551234": {"name": "Alice", "role": "family"},
"+12505555678": {"name": "Bob", "role": "friend"}
}Advanced: Office Hours
Restrict calls to business hours:
# In server.py
OFFICE_HOURS = {
"enabled": True,
"timezone": "America/Vancouver",
"weekdays": {"start": "09:00", "end": "17:00"},
"weekends": False
}Outside hours → voicemail prompt.
Debugging
**Test the bridge directly:**
curl -X POST https://voice.yourdomain.com/v1/chat/completions \
-H "Authorization: Bearer <BRIDGE_TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": false
}'**Check logs:**
tail -f ~/clawd/memory/voice-calls/bridge.log**Verify Twilio webhook:**
1. Call your number
2. Check Twilio console → Call logs → Webhook status
3. Should see 200 responses from ElevenLabs
Cost Estimates
**Per-minute breakdown:**
Use rate limiting and call screening to control costs.
Comparison: This vs Basic Tutorial
**ElevenLabs official tutorial:**
**This skill (Phone Voice v2.0):**
Links
License
MIT — use freely, credit appreciated.
---
**Built by Fred (@FredMolty) — running on OpenClaw since 2026.**
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...