Open-source outbound call-control runtime for agent builders
Project description
call-use
Give your AI agent the ability to make phone calls. The browser-use for phones.
from call_use import CallAgent
outcome = await CallAgent(phone="+18001234567", instructions="Cancel my subscription").call()
print(outcome.disposition) # "completed"
What it does
- Dials outbound via Twilio SIP trunk through LiveKit
- Talks using Deepgram STT + GPT-4o + GPT-4o-mini TTS
- Reports structured
CallOutcomewith transcript, events, and disposition - Human takeover — pause the agent mid-call and take over the conversation
- Approval flow — agent asks for user approval before taking sensitive actions
- REST API — deploy as a service with
create_app()for multi-tenant usage
Why call-use?
| call-use | Build from scratch | Pine AI | |
|---|---|---|---|
| Make a phone call | 3 lines | months | sign up + $$$ |
| IVR navigation | built-in | weeks | built-in |
| Live transcript | built-in | weeks | built-in |
| Human takeover | built-in | weeks | — |
| Approval flow | built-in | days | — |
| Open source | yes | — | no |
| Self-hostable | yes | — | no |
| Any agent framework | yes | — | no |
Works with
Claude Code · LangChain · OpenAI Agents · CrewAI · Any agent that runs bash
Architecture
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Your code │────────▶│ LiveKit │────────▶│ Twilio SIP │
│ (CallAgent) │ room │ Cloud/OSS │ trunk │ → PSTN │
└──────────────┘ └──────────────┘ └──────────────┘
│
┌─────┴──────┐
│ call-use │
│ worker │
│ (Agent) │
└────────────┘
Two processes:
- Your code (or the REST API) creates a LiveKit room and dispatches an agent
- call-use worker joins the room, dials via SIP, runs the conversation, and publishes the outcome
Quick start
Prerequisites
- Python 3.11+
- LiveKit Cloud or self-hosted LiveKit server
- Twilio SIP trunk connected to LiveKit
- Deepgram API key (for STT)
- OpenAI API key (for LLM + TTS)
Install
pip install call-use
Configure
cp .env.example .env
# Fill in your keys
Required environment variables:
| Variable | Description |
|---|---|
LIVEKIT_URL |
LiveKit server URL (wss://...) |
LIVEKIT_API_KEY |
LiveKit API key |
LIVEKIT_API_SECRET |
LiveKit API secret |
SIP_TRUNK_ID |
Twilio SIP trunk ID in LiveKit |
DEEPGRAM_API_KEY |
Deepgram API key (STT) |
OPENAI_API_KEY |
OpenAI API key (LLM + TTS) |
Run the worker
call-use-worker start
Make a call
import asyncio
from call_use import CallAgent
async def main():
agent = CallAgent(
phone="+18001234567",
instructions="Ask about store hours",
approval_required=False,
)
outcome = await agent.call()
print(f"Done: {outcome.disposition.value}")
asyncio.run(main())
SDK usage
CallAgent
agent = CallAgent(
phone="+18001234567", # US/Canada number (required)
instructions="Your task...", # What the agent should do (required)
user_info={"name": "Alice"}, # Info the agent can reference
caller_id="+15551234567", # Outbound caller ID
voice_id="alloy", # TTS voice (alloy/echo/fable/onyx/nova/shimmer)
approval_required=True, # Agent asks before sensitive actions
timeout_seconds=600, # Max call duration
on_event=my_event_handler, # Real-time event callback
on_approval=my_approval_handler, # Approval decision callback
recording_disclaimer="This call may be recorded.",
)
Events
The on_event callback receives CallEvent objects:
| Event type | Description |
|---|---|
state_change |
Call state changed (connected, human_takeover, etc.) |
transcript |
New speech transcript (speaker + text) |
dtmf |
DTMF tone detected |
approval_request |
Agent needs user approval |
call_complete |
Call finished with outcome |
Human takeover
# Pause agent, get token to join as human
token = await agent.takeover()
# ... join LiveKit room with token, talk to callee ...
await agent.resume() # Hand back to agent
CallOutcome
outcome = await agent.call()
outcome.task_id # Unique call identifier
outcome.disposition # completed | failed | voicemail | no_answer | busy | timeout | cancelled
outcome.duration_seconds # Call duration
outcome.transcript # List of {speaker, text} dicts
outcome.events # List of CallEvent dicts
CLI
Any agent that can run bash can make phone calls:
pip install call-use
call-use dial "+18001234567" -i "Ask about store hours"
Events stream to stderr, structured JSON result goes to stdout:
call-use dial "+18001234567" -i "Cancel subscription" -u '{"account": "12345"}'
# stdout: {"task_id": "...", "disposition": "completed", "transcript": [...]}
MCP Server
Native tool integration for Claude Code, Codex, and other MCP-compatible agents:
{
"mcpServers": {
"call-use": {
"command": "call-use-mcp",
"env": {
"LIVEKIT_URL": "wss://...",
"LIVEKIT_API_KEY": "...",
"LIVEKIT_API_SECRET": "...",
"SIP_TRUNK_ID": "...",
"OPENAI_API_KEY": "..."
}
}
}
}
4 async tools: dial (non-blocking, returns task_id), status, cancel, result.
REST API
For multi-tenant or server deployments:
from call_use import create_app
app = create_app(api_key="your-secret-key")
# Run with: uvicorn your_module:app
Endpoints
| Method | Path | Description |
|---|---|---|
POST |
/calls |
Create a new outbound call |
GET |
/calls/{id} |
Get call status and room state |
POST |
/calls/{id}/inject |
Inject a message into the call |
POST |
/calls/{id}/takeover |
Human takeover |
POST |
/calls/{id}/resume |
Resume agent after takeover |
POST |
/calls/{id}/approve |
Approve pending action |
POST |
/calls/{id}/reject |
Reject pending action |
POST |
/calls/{id}/cancel |
Cancel the call |
All endpoints require X-API-Key header.
Examples
- LangChain tool — Use call-use as a LangChain tool
- OpenAI Agents SDK — Integrate with OpenAI Agents
- Claude Code MCP setup — Configure call-use as an MCP server
- Customer service refund agent — End-to-end refund automation
- Skill — Claude Code / agent skill for automatic phone call capability
Development
git clone https://github.com/agent-next/call-use.git
cd call-use
pip install -e ".[dev]"
pytest
Known Limitations
- In-memory state: The REST API server stores call state in memory. State is lost on restart. For production, consider using LiveKit room metadata for call recovery, or contribute a persistence backend.
- Caller ID: v0.1 validates caller ID format only. Ownership verification (via Twilio Lookup API) is planned for v0.2.
- Single worker: The agent worker is designed for single-instance deployment. Horizontal scaling requires a shared state backend.
- PSTN only: Currently supports outbound PSTN calls via Twilio SIP. WebRTC-to-WebRTC calls are not yet supported.
Legal Notice
call-use is a developer tool for legitimate business automation. Users are solely responsible for complying with all applicable telecommunications laws, including but not limited to:
- TCPA (Telephone Consumer Protection Act) — Obtain prior express consent before automated calls
- FCC regulations — AI-generated voices in calls are subject to full TCPA restrictions (FCC 24-17)
- Do Not Call Registry — Honor opt-out requests and scrub against the National DNC Registry
- Recording consent — Comply with federal and state recording laws (13 US states require two-party consent)
- Caller ID — Display accurate caller ID; spoofing for fraudulent purposes is illegal
- State and local laws — Additional restrictions may apply in your jurisdiction
call-use includes built-in safeguards (premium-rate number blocking, rate limiting, phone validation) but these do not guarantee legal compliance. Consult legal counsel before deploying automated calling systems.
This software is provided "AS IS" under the MIT License without warranty. See LICENSE for details.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file call_use-0.1.0.tar.gz.
File metadata
- Download URL: call_use-0.1.0.tar.gz
- Upload date:
- Size: 66.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b279d57cdc2114897d60a17fefdce44e740d8a79e0ccd285f4f11e50e110e068
|
|
| MD5 |
68bc150b523c6290d0cb43a021ead527
|
|
| BLAKE2b-256 |
52f4722d5b7b10334167c77e4f3dac7445698a058cc19a4491c8cc0d7cbf5377
|
File details
Details for the file call_use-0.1.0-py3-none-any.whl.
File metadata
- Download URL: call_use-0.1.0-py3-none-any.whl
- Upload date:
- Size: 30.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.0
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b835d496961af338d33ac46e0cc19c3a2167a66d91869c092cb59819c31014b
|
|
| MD5 |
1fb6d83d82bafd7486efbd0a15b592f9
|
|
| BLAKE2b-256 |
72772b53f53cd851efcef174cacc9f051890f7243342f4eb468f8ce4091dcbdc
|