Open-source outbound call-control runtime for agent builders
Project description
call-use
Give your AI agent the ability to make phone calls.
from call_use import CallAgent
outcome = await CallAgent(
phone="+18001234567",
instructions="Cancel my internet subscription",
).call()
print(outcome.disposition) # "completed"
print(outcome.transcript) # [{speaker: "agent", text: "..."}, ...]
Open-source. Self-hostable. Works with any agent framework.
Features
4 interfaces — use whichever fits your stack:
# Python SDK
outcome = await CallAgent(phone="+18001234567", instructions="...").call()
# CLI — any agent that runs bash can make calls
call-use dial "+18001234567" -i "Ask about store hours"
# MCP Server — native Claude Code / Codex integration
call-use-mcp # stdio transport, 4 async tools
# REST API — multi-tenant deployments
curl -X POST localhost:8000/calls -H "X-API-Key: ..." -d '{"phone_number": "+18001234567"}'
Built-in capabilities:
| IVR navigation | Navigate phone menus, press buttons, handle hold music |
| Human takeover | Pause the agent mid-call, join as a human, hand back |
| Approval flow | Agent asks for permission before sensitive actions |
| Structured outcomes | Transcript, events, disposition, duration — all typed |
| Phone validation | Premium-rate blocking, Caribbean NPA blocking, E.164 |
| Rate limiting | Per-key sliding window for REST API |
Quick start
pip install call-use
Configure environment (full guide):
export LIVEKIT_URL="wss://..." # LiveKit Cloud or self-hosted
export LIVEKIT_API_KEY="..."
export LIVEKIT_API_SECRET="..."
export SIP_TRUNK_ID="..." # Twilio SIP trunk in LiveKit
export DEEPGRAM_API_KEY="..." # STT
export OPENAI_API_KEY="..." # LLM + TTS
Start the worker, then make a call:
call-use-worker start
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"{outcome.disposition.value}: {outcome.duration_seconds:.0f}s")
for t in outcome.transcript:
print(f" [{t['speaker']}] {t['text']}")
asyncio.run(main())
Human takeover
Pause the AI, join the call yourself, then hand back:
token = await agent.takeover() # returns LiveKit JWT
# ... join room with token, talk to callee ...
await agent.resume() # agent takes over again
Approval flow
Agent pauses and asks before sensitive actions:
agent = CallAgent(
phone="+18001234567",
instructions="Cancel my subscription. If they offer a discount, ask me first.",
approval_required=True,
on_approval=lambda data: input(f"Approve '{data['details']}'? [y/n]: "),
)
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 (returns immediately), status, cancel, result.
REST API
from call_use import create_app
app = create_app(api_key="your-secret-key")
# uvicorn your_module:app
| Method | Path | Description |
|---|---|---|
| POST | /calls |
Create outbound call |
| GET | /calls/{id} |
Get status |
| POST | /calls/{id}/inject |
Inject message into call |
| POST | /calls/{id}/takeover |
Human takeover |
| POST | /calls/{id}/resume |
Resume agent |
| POST | /calls/{id}/approve |
Approve pending action |
| POST | /calls/{id}/reject |
Reject pending action |
| POST | /calls/{id}/cancel |
Cancel call |
All endpoints require X-API-Key header.
Architecture
Your code ──▶ LiveKit Cloud ──▶ Twilio SIP ──▶ PSTN
│
call-use worker
(Deepgram STT + GPT-4o + OpenAI TTS)
Two processes: your code dispatches an agent into a LiveKit room; the worker joins, dials via SIP, runs the conversation, publishes the outcome.
Examples
| Example | Description |
|---|---|
| Customer service refund | End-to-end refund automation |
| Appointment scheduler | Navigate IVR, book appointment |
| Insurance claim | File claim, capture claim number |
| Subscription cancellation | Handle retention offers via approval |
| Multi-call workflow | Chain sequential calls |
| Webhook integration | FastAPI + WebSocket events |
| LangChain tool | Use as a LangChain tool |
| OpenAI Agents | OpenAI Agents SDK integration |
| CrewAI | PhoneCallTool for CrewAI |
| Claude Code MCP | MCP server setup guide |
Documentation
Full docs at docs.call-use.com — getting started, guides, API reference, architecture.
Contributing
git clone https://github.com/agent-next/call-use.git
cd call-use
pip install -e ".[dev]"
make check # lint + typecheck + test (100% coverage) + build
See CONTRIBUTING.md for guidelines.
Known Limitations
- In-memory state — REST API call state lost on restart
- Caller ID — Format validation only; ownership verification planned for v0.2
- Single worker — Horizontal scaling requires shared state backend
- US/Canada only — Outbound PSTN via Twilio SIP; international and inbound planned
Legal Notice
call-use is a developer tool for legitimate business automation. Users are solely responsible for complying with all applicable telecommunications laws including TCPA, FCC regulations on AI-generated voices (FCC 24-17), Do Not Call registry, and state recording consent laws. See SECURITY.md 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.1.tar.gz.
File metadata
- Download URL: call_use-0.1.1.tar.gz
- Upload date:
- Size: 64.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4493ed9921c8aae90da0e94713ff81374956f6e519decdd85a1f987757f7bd2c
|
|
| MD5 |
0e4f73912b5cc4529e2e37de9f914380
|
|
| BLAKE2b-256 |
b6210f1619d3a886a87aa993b17aa10af93507d7577ddce40ae1ead67b625b78
|
Provenance
The following attestation bundles were made for call_use-0.1.1.tar.gz:
Publisher:
publish.yml on agent-next/call-use
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
call_use-0.1.1.tar.gz -
Subject digest:
4493ed9921c8aae90da0e94713ff81374956f6e519decdd85a1f987757f7bd2c - Sigstore transparency entry: 1107820803
- Sigstore integration time:
-
Permalink:
agent-next/call-use@2536bce5ca299f1f66e768f7a24a3ddd785864d0 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/agent-next
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2536bce5ca299f1f66e768f7a24a3ddd785864d0 -
Trigger Event:
push
-
Statement type:
File details
Details for the file call_use-0.1.1-py3-none-any.whl.
File metadata
- Download URL: call_use-0.1.1-py3-none-any.whl
- Upload date:
- Size: 29.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
64919557e4a96764fa802e02a16680a81dc4d6edcf942cd62cb46e004dc39a20
|
|
| MD5 |
c62d2159d73e223d10ae85623dcf162d
|
|
| BLAKE2b-256 |
d25b186042af01e14a87d84fa1b99b0713043ee6ca633921306b0ee078bdf1f8
|
Provenance
The following attestation bundles were made for call_use-0.1.1-py3-none-any.whl:
Publisher:
publish.yml on agent-next/call-use
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
call_use-0.1.1-py3-none-any.whl -
Subject digest:
64919557e4a96764fa802e02a16680a81dc4d6edcf942cd62cb46e004dc39a20 - Sigstore transparency entry: 1107820806
- Sigstore integration time:
-
Permalink:
agent-next/call-use@2536bce5ca299f1f66e768f7a24a3ddd785864d0 -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/agent-next
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@2536bce5ca299f1f66e768f7a24a3ddd785864d0 -
Trigger Event:
push
-
Statement type: