Skip to main content
Glama

Codex Call

An independent, MIT-licensed phone calling service for Codex and other MCP clients, using your own LiveKit, Telnyx, Anthropic, Deepgram and ElevenLabs accounts. This is not an official OpenAI product. The first release serves one operator.

flowchart LR
    Client[Codex / MCP client] --> MCP[MCP tools]
    MCP --> API[Authenticated API]
    API --> DB[(SQLite)]
    API --> Dispatch[LiveKit dispatch]
    Dispatch --> Worker[Voice worker]
    Worker <--> Room[LiveKit room]
    Room <--> SIP[Telnyx SIP trunk]
    SIP <--> Phone[Recipient]
    Worker <--> Models[Speech recognition / LLM / speech synthesis]
    Worker --> Task[Correlated external task]
    Task --> Events[Signed Events webhook]
    Events --> Host[Authorized host]
    Host --> MCP

The service persists calls and transcripts, enforces duration limits, and retries room cleanup. Its prompt-based worker supports spoken menus, keypad tones, hold periods and hangup. A task bridge lets an authorized host return results while a call waits; it does not share other apps' credentials.

Capability

Implemented and offline tested

Live verification

Authenticated API, SQLite lifecycle, idempotency, cancellation and restart recovery

Yes

Local HTTP tested

Seven MCP tools and stdio negotiation

Yes

Local SDK tested; actual Codex session unverified

LiveKit dispatch, SIP dialing, provider interfaces, transcript capture and worker tools

Yes, with remote boundaries substituted

Phone audio, providers, real IVR/hold unverified

Signed Events callbacks and correlated results

Yes, local HTTP/TLS and persistence tests

External callbacks and ChatGPT host unverified

Docker/Compose deployment

Packaged and statically reviewed

Image build/run unverified

Start in simulation

Install uv and Python 3.11–3.13; Python 3.12 is the tested version. From a fresh checkout:

uv sync --locked --python 3.12
cp .env.example .env
uv run python - <<'PY'
import secrets
from pathlib import Path
path = Path('.env')
text = path.read_text()
text = text.replace('replace-owner-token', secrets.token_urlsafe(32))
text = text.replace('replace-worker-token', secrets.token_urlsafe(32))
path.write_text(text)
path.chmod(0o600)
PY
mkdir -p data
chmod 700 data
umask 077
uv run codex-call-api --host 127.0.0.1 --port 8000

These commands generate different tokens without printing them. Configuration loads .env from the project working directory. Leave CODEX_CALL_MODE=simulate: this creates local records and a simulated answered state, never a phone call. Simulation has no audio or generated transcript; end the simulated call with codex_call_hangup_call.

In another terminal, register the stdio MCP server using the setup guide. The API remains a separate process. Live calling requires explicit CODEX_CALL_MODE=live, a configured SIP trunk, provider credentials and a separate worker.

Related MCP server: DialMCP

MCP tools

Every tool takes a single params object; client-specific wrappers may display it differently.

Tool

Parameters / behavior

codex_call_place_call

to_number (E.164), task, required idempotency_key; optional personality, max_duration_s (30–1800, default 600)

codex_call_get_call

call_id; includes persisted mode, lifecycle status and safe error code

codex_call_list_calls

limit (default 20, max 100), offset; summaries without briefings

codex_call_get_transcript

call_id; full single-call transcript with speaker roles

codex_call_hangup_call

call_id; cancels an active call and requests room cleanup

codex_call_list_tasks

call_id; pending/completed/expired/cancelled host tasks

codex_call_submit_task_result

call_id, request_id, result; identical retries accepted, changed/late results conflict

Example tools/call parameters, safe to use only in simulation unless the call is authorized:

{
  "name": "codex_call_place_call",
  "arguments": {
    "params": {
      "to_number": "+14155550123",
      "task": "Ask when the shop opens; make no purchases or commitments.",
      "idempotency_key": "shop-hours-001"
    }
  }
}

Reuse the same key and identical payload when retrying one request. Queued or answered status is not evidence that a task succeeded. Inspect final status and transcript. The independently written calling skill captures this workflow; it is packaged here and not installed automatically.

Operation and development

See setup for Telnyx/LiveKit configuration, separate API and worker processes, Docker, storage permissions and retention. See Events for the opt-in host bridge and HTTP MCP protocol requirements.

Run one API process per database. Startup marks interrupted calls failed and requests room cleanup; it does not redial them. This release has no multi-instance HA, inbound answering, human transfers, billing, dashboard or recordings. Transcripts and event secrets persist locally until the operator removes the database and its backups.

uv run pytest -q
uv run ruff check .
uv run ruff format --check .
uv build
uv run codex-call-api --help
uv run codex-call-worker --help
uv run codex-call-worker start --help
uv run codex-call-mcp --help

Tests exercise local authentication, SQLite, subprocess CLI/stdio, SDK contracts and simulated network boundaries. They do not exercise phone audio, live provider access or ChatGPT integration. CI uses locked dependencies and Python 3.12. The MIT license covers this original source. Dependencies are installed separately, not vendored; their licenses and provider account terms still apply (see dependency licensing).

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    A hosted MCP server that enables AI agents to place real phone calls from a verified caller ID, with async call management and built-in safety controls.
    36 npm
    1
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    A single MCP server that provides a provider-neutral 14-tool contract for telephony operations (calls, SMS, recordings, transcripts, and number lifecycle), supporting hosted, fully local, or bring-your-own-key backends.
    1
    MIT