callbay
OfficialIntegrates with OpenAI for live voice conversations using GPT-Live audio and a back-office Responses model that can invoke call-control tools such as ending the call, asking the user, and pressing digits.
Integrates with Stripe for prepaid credits, Checkout payments, monthly subscription reloads, and webhooks for invoices, subscriptions, and refunds.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@callbayCall Acme Plumbing and ask if they can fix the leak today."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
callbay
Your coding agent (Claude Code, Codex, Claude Desktop, ChatGPT) gets one new tool: make a phone call. Prepaid credits from $10 via Stripe Checkout, reloading monthly by default; one MCP URL with the key in it.
How a call works
agent ──MCP──▶ worker ──POST /v2/calls──▶ Telnyx ──PSTN──▶ business
▲ │ media stream (PCMU, bidirectional RTP)
│ webhooks ▼
└──────────────── CallSession (Durable Object) ◀──WS──▶ GPT-Live (gpt-live-1, audio/pcmu 8k)
└─ back office (Responses model):
end_call · ask_user · press_digitssrc/server/voice/prompt.ts: what the caller is told. The product lives here: no opening disclosure, no recording notice, no end-of-call read-back; honest if sincerely asked whether it's an AI.src/server/voice/session.ts: the audio relay and back-office functions.src/server/services/dialer.ts: placing calls, per-account numbers, answering callbacks.src/server/mcp/server.ts: the MCP tools.
The app does not request recording when dialing or answering. Existing recordings stored by Telnyx
can be retrieved after a call ends using callbay_get_recordings({ call_id }) over MCP, or
GET /api/calls/{call_id}/recordings with a callbay API key or OAuth token in the Bearer header.
Both check account ownership before contacting Telnyx and return fresh download links without
storing them. Empty results can mean processing is pending or no recording was saved. Links may
expire and should only be shared with the account owner.
Trunk recordings use call leg IDs. A separate provider ID table receives these from verified webhooks; existing calls resolve them from an exact control ID match in Telnyx webhook history. The app never guesses a match from phone numbers or timestamps. If provider history has expired and no mapping was saved, only recordings directly associated with the control ID can be found.
The recording lookup never contacts the voice session or changes prompts, live tools, audio, or Telnyx recording settings. Existing call status and transcript responses are unchanged.
The recording API's OpenAPI document is served at /api/openapi.json. Run
npm run openapi:generate to regenerate openapi.json from the shared MCP and HTTP schemas.
CI checks the generated artifact for drift. Run npm test, npm run check, npm run lint,
and npx wrangler deploy --dry-run before deploying through git.
Related MCP server: Twilio Call Service MCP Server
Setup
Telnyx: a Call Control application (its id is
TELNYX_CONNECTION_ID) with webhook URLhttps://<host>/webhooks/telnyx, an API key, and the account's webhook public key. Each account's number is bought on its first call and attached to that application.OpenAI: an API key with GPT-Live access.
Stripe: webhook endpoint
https://<host>/webhooks/stripeforcheckout.session.completed,checkout.session.async_payment_succeeded,invoice.paid,customer.subscription.updated,customer.subscription.deleted,charge.refunded. The blog's supporter subscriptions arrive on the same endpoint, taggedapp=callbay, kind=supporter(seesrc/server/services/supporters.ts).
Credits
Everything is prepaid. Loads start at $10 and, by default, the same amount reloads monthly (a Stripe
subscription; invoice.paid adds the credits). A call holds its maximum cost before it dials, in one
conditional insert so parallel calls can't overspend, and settles to the real talk time when it ends.
4. Secrets (wrangler secret put): see src/server/env.d.ts.
Blog
/blog is markdown files in src/content/blog (one per post, listed in index.ts, headline image at
public/static/blog/<slug>.svg), with an Atom feed, likes, comments, an email newsletter (sent from
/admin/blog, for the ADMIN_EMAILS accounts), and paid posts for monthly supporters.
Self-hosting
Fork it, create your own D1 database (wrangler d1 create callbay) and put its id and your own hostname in wrangler.jsonc.
Local: npm run db:migrate:local && npm run dev with a .dev.vars holding the same secrets.
AI monitoring
Raindrop monitors the live conversation (callbay_voice_call), back office model runs
(callbay_back_office), and the recap after hangup (callbay_call_recap). Each event uses
the account ID as its user ID and the call ID as its conversation ID. Model names, timing,
status, and back office tool spans are included. No phone audio or recording URLs are uploaded.
Add RAINDROP_WRITE_KEY to .dev.vars locally and configure the same key as a Cloudflare
Worker secret with npx wrangler secret put RAINDROP_WRITE_KEY. Optional
RAINDROP_PROJECT_ID selects a project slug; unset uses the write key's default project.
Without a write key, monitoring is disabled. .dev.vars.example lists these optional settings.
AI inputs and outputs use Raindrop's PII redaction, with Callbay's existing masking for per call secrets applied first. Tool arguments and results appear in redacted back office AI output. Tool spans contain names, timing, and generic failure status, keeping sensitive payloads out of unredacted trace attributes. Account names and emails are not sent as user traits. SDK PII redaction is pattern based and does not guarantee removal of every sensitive detail.
Monitoring runs separately from live audio and tools. Terminal events and queued tool spans are flushed within the Worker or Durable Object lifetime. An unfinished back office run at hangup is marked interrupted; later tool results do not reopen the closed monitoring client.
After a call, check the three event names in Raindrop, with actual inputs and outputs, the matching account and call IDs, and tool names and durations. A call that never invokes a back office model has no back office event. Feedback signals, audio attachments, and agent self diagnostics are not instrumented because the current call flow has no corresponding feedback controls or diagnostics tools.
For investigation, connect the Raindrop MCP server and install
the investigation skill with npx skills add raindrop-ai/skills --skill raindrop-investigate.
Connect Slack in Raindrop for alerts. Create a Raindrop account if needed.
License
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
Give AI agents real phone numbers, messages, and voice calls via MCP.
Give AI agents a phone number. Voice calls, SMS, and phone number management for MCP clients.
Phone, SMS & email for AI agents — one remote MCP endpoint, OAuth login, zero install.
Give AI agents a phone layer for consent-based calls, transcripts, summaries, and outcomes.
Related MCP Servers
- AlicenseAqualityCmaintenanceGives AI agents phone numbers, email, SMS, and voice calls as MCP tools, enabling them to provision numbers, capture 2FA codes, send messages, and make calls.15MIT
- FlicenseNot gradedqualityDmaintenanceEnables AI-driven interaction with Twilio call services, including initiating outbound calls and retrieving call history via FastMCP tools.-
- AlicenseBqualityBmaintenanceEnables MCP-compatible agents to make safe, consented phone calls using Twilio and Deepgram.4Apache 2.0

ClawCall MCP Serverofficial
AlicenseNot gradedqualityBmaintenanceEnables AI agents to make real outbound phone calls to US/Canada numbers, handle conversations, and return transcripts and recordings via the Model Context Protocol.7MIT