use cases

Build what your client needs. We handle the phone.

Crixin Call Assistant is the phone primitive for developers shipping voice AI to clients. The MCP server gives your AI agent make_call, send_sms, transcribe_call. Every call lands in local SQLite — auditable, searchable, Wrapped-ready. You build the application; Crixin is the dial tone underneath.

npm i -g crixin && crixin voice install Install in 30 seconds Tool reference
STEP 01

Install

One npm install. Wires the MCP into Claude Code, Cursor, Codex CLI, Claude Desktop. Your AI agent can now place calls.

crixin voice install
STEP 02

Wire your logic

Your client's app calls make_call with a TwiML prompt or persona. CRM trigger, cron, webhook — your choice.

await makeCall(client, { to, prompt })
STEP 03

Read the receipts

Every call mirrored to local SQLite + (optional) Deepgram transcripts. Voice Wrapped + Caller Archetype + Ducked rebuilt for any time window.

crixin voice wrapped

01 — Restaurant AI receptionist

You're building for:   a restaurant client whose phone goes unanswered during dinner rush ·  Maria's Pizza, Joe's Diner, the local taqueria

The pain. 40% of inbound calls miss the host stand between 6–9pm. Each missed call is a probable reservation lost. Hiring a hostess just for the phone costs $14/hr + benefits. The fix. Twilio routes inbound to your endpoint. Crixin's MCP server speaks for you — Polly-Hala-Neural in Spanish or English, knows the menu (RAG over a Notion doc), books a reservation in the POS, hangs up. Average call: 38 seconds.

// app/api/twilio/inbound.ts — Vercel function on your client's project
import { speakOnly, wrap, say } from "crixin/voice";
import { getMenu, reserveTable } from "./pos";

export default async function handler(req, res) {
  const caller = req.body.From;
  const menu = await getMenu();

  // Inbound call lands here as a Twilio webhook. Return TwiML.
  const twiml = `<Response>
    <Gather input="speech" action="/api/twilio/handle" language="es-MX,en-US">
      <Say voice="Polly.Hala-Neural" language="es-MX">
        ${menu.greeting}
      </Say>
    </Gather>
  </Response>`;

  res.setHeader("Content-Type", "text/xml");
  res.send(twiml);
}

// Your AI agent picks up via the crixin-voice MCP server,
// classifies intent (reservation / hours / menu / human),
// and either books via reserveTable() or speaks back.
Maria's Pizza · this week
Calls answered
187
100% pickup, 0 misses
Reservations
94
avg party: 4.2
Avg call duration38s
Spanish (es-MX)61%
Menu Q&A42 calls
Transfers to human3
Twilio spend$1.84

02 — Dental clinic confirmations

You're building for:   a dental practice with a 28% no-show rate ·  clinics, physical therapy, salons, anyone with a calendar

The pain. 28% of scheduled appointments no-show, costing the clinic ~$8K/month in lost chair time. The front desk is supposed to confirm 24h prior — they don't, because they're already drowning in walk-ins and insurance calls. The fix. A cron job at 9am pulls tomorrow's appointments from the EHR, fires make_call for each. AI confirms, reschedules, or cancels. Writes back to the EHR. Done by 9:08am.

// scripts/morning-confirms.ts — runs daily at 9am via cron
import { TwilioClient, makeCall, loadEnv } from "crixin/voice";
import { tomorrowsAppointments, recordOutcome } from "./ehr";

const client = new TwilioClient(loadEnv());
const appts = await tomorrowsAppointments();

for (const a of appts) {
  const call = await makeCall(client, {
    to: a.phone,
    prompt: `Hi ${a.firstName}, this is Apex Dental confirming
    your ${a.procedure} appointment tomorrow at ${a.time}.
    Press 1 to confirm, 2 to reschedule, 3 to cancel.`,
    voice: "Polly.Joanna-Neural",
    record: true,
    maxRecordingSeconds: 20,
    consented: true, // existing patient relationship
  });
  recordOutcome(a.id, call.sid);
}
Apex Dental · last 30 days
Confirms made
412
100% next-day coverage
No-show rate
9.2%
was 28% before
Confirmed324
Rescheduled51
Cancelled (slot freed)37
Avg call duration26s
Recovered revenue$7,840

03 — SaaS activation calls

You're building for:   a B2B SaaS where 60% of trials never reach "aha" ·  PLG product, devtool, vertical SaaS

The pain. Trial users sign up, send 3 messages, then ghost. The activation team is one person, and they're busy. Email nudges convert at 4%. The fix. 3 days into the trial, if the user hasn't hit the activation event, your app fires make_call. AI walks them through the missing step, answers questions, books a Calendly with a human if they want one. Tracked back to Mixpanel.

// services/activation-checker.ts — runs hourly
import { TwilioClient, makeCall, loadEnv } from "crixin/voice";
import { stalledTrials, trackEvent } from "./analytics";

const client = new TwilioClient(loadEnv());

for (const user of await stalledTrials({ daysSinceSignup: 3, activatedEvent: false })) {
  await makeCall(client, {
    to: user.phone,
    prompt: `Hi ${user.firstName}, I'm calling from Acme. I saw you
    signed up Tuesday but haven't connected your first data source yet.
    It's a 90-second step. Can I walk you through it, or would you rather
    book 15 minutes with someone on our team?`,
    voice: "Polly.Joanna-Neural",
    consented: true, // signup ToS captures consent
  });
  trackEvent(user.id, "activation_call_placed");
}
Acme PLG · Q2 trial cohort
Calls placed
512
to stalled trials
Activation lift
+34%
vs. email-only control
Activated within 24h189
Booked a Calendly47
Asked to be removed12 → opt-out honored
Caller archetypePatient Listener
Cost / activation$0.41

04 — B2B sales discovery

You're building for:   a small B2B sales team that can't afford 4 SDRs ·  outbound to business numbers, B2B-only

The pain. Founder/AE needs to qualify 100 leads/week. Hiring SDRs costs $4–6K/mo loaded. Outreach platforms send email — but the lead in question already gets 200 emails/week. The fix. AI agent calls businesses on the lead list (B2B = looser TCPA), asks 4–5 discovery questions, books the qualified ones into the founder's Calendly. Disqualifies the rest. Founder gets meetings, not a list.

// scripts/b2b-discovery.ts — fed leads from Clay / Apollo / Google Places
import { TwilioClient, makeCall, loadEnv } from "crixin/voice";
import { qualifyLead, bookMeeting } from "./crm";

const client = new TwilioClient(loadEnv());

for (const lead of leads) {
  // Geo-gate auto-enforces: this is a US business landline.
  // crixin voice doctor confirmed our setup.
  const call = await makeCall(client, {
    to: lead.businessPhone,
    prompt: `Hi, this is James from Apex. I'm calling because
    I noticed ${lead.companyName} just expanded to a second location —
    nice. Quick question — who handles your POS integration these days?
    Looking to chat about a 15% margin lift if you're open to it.`,
    voice: "Polly.Joanna-Neural",
    record: true,
    maxRecordingSeconds: 120,
    machineDetection: "DetectMessageEnd",
    // B2B landline + no DNC: no --consented needed under TCPA carve-out
  });

  const outcome = await qualifyLead(call.sid); // transcribe + classify
  if (outcome === "qualified") await bookMeeting(lead);
}
Apex Sales · last month
Dials made
832
B2B landlines only
Meetings booked
41
conversion: 4.9%
Qualified callbacks213
Voicemails left311
Avg call duration1m 12s
Caller archetypeDiscovery Caller
Duck rate8% (target <10%)
Cost / booked meeting$1.78

05 — Field-service after-hours triage

You're building for:   HVAC / plumbing / locksmith / roadside SaaS ·  ServiceTitan-adjacent, Housecall Pro

The pain. The on-call tech can't take every after-hours call — most are not emergencies (it's a thermostat reset, or "what time do you open"). But the few that ARE emergencies (no heat in February, water actively flooding) need a human in 5 minutes. The fix. Inbound → AI agent triages. Reads the answer back, classifies urgency, pages the on-call tech via SMS only if the situation is real. Logs everything to the CRM ticketing system.

// app/api/triage.ts — inbound webhook from Twilio
import { promptAndRecord } from "crixin/voice";
import { TwilioClient, sendSms, transcribeRecording } from "crixin/voice";
import { classifyUrgency, pageOnCall, createTicket } from "./crm";

// 1. Inbound TwiML: ask what the issue is, record 30s.
export const twimlPrompt = promptAndRecord({
  prompt: "You've reached Houston HVAC after hours. Tell me what's going on — be specific.",
  voice: "Polly.Joanna-Neural",
  recordOptions: { maxLength: 30 },
});

// 2. Recording webhook: transcribe → classify → route.
export async function onRecording(req, res) {
  const t = await transcribeRecording(client, {
    recordingSid: req.body.RecordingSid,
  });
  const urgency = await classifyUrgency(t.transcript);

  await createTicket({ phone: req.body.From, transcript: t.transcript, urgency });
  if (urgency === "emergency") await pageOnCall(t.transcript);
}
Houston HVAC · last 14 nights
Calls triaged
142
11pm – 7am
Real emergencies
17
paged in <90s
"What time do you open"38 calls
Thermostat / reset help29 calls
Scheduled callback (AM)58 calls
Paged on-call tech17 — all confirmed real
Tech sleep restored88% of nights
Twilio + Deepgram$11.20

06 — E-commerce NPS & review calls

You're building for:   a Shopify brand that ships premium goods ·  DTC, mid-market e-comm, agencies serving them

The pain. Post-purchase email surveys hit 2% response rate. The product-page review widget gets 4%. The brand wants real NPS data + a Google review at-scale. The fix. 7 days post-delivery, AI agent calls the customer (with their checkout-time consent), asks two questions — *"Did the espresso machine arrive in good shape?"* and *"On a scale of 1–10, how likely are you to recommend us?"* — and offers to send a Google-review link via SMS if they say 9+. Calls take ~45 seconds.

// queues/post-delivery-nps.ts — fires 7 days after fulfillment
import { TwilioClient, makeCall, sendSms, loadEnv } from "crixin/voice";
import { orderById, saveNPS } from "./shopify";

const client = new TwilioClient(loadEnv());

export async function processNPS(orderId: string) {
  const order = await orderById(orderId);

  const call = await makeCall(client, {
    to: order.customer.phone,
    prompt: `Hi ${order.customer.firstName}, this is Anna from
    ${order.brand}. Quick 30 seconds — did your ${order.itemName} arrive
    in good shape, and on a scale of 1 to 10, how likely are you to
    recommend us to a friend?`,
    voice: "Polly.Joanna-Neural",
    record: true,
    maxRecordingSeconds: 30,
    consented: true, // captured at checkout
  });

  const { score, sentiment } = await saveNPS(call.sid);
  if (score >= 9) {
    await sendSms(client, {
      to: order.customer.phone,
      body: `Thanks! If you have 60s, would love a Google review: ${order.reviewUrl}`,
    });
  }
}
Lumen Coffee · Q1 launch
NPS calls placed
1,247
100% post-purchase
Response rate
71%
vs. 4% email survey
NPS score62 (great)
9–10 promoters621 callers
Google reviews triggered441 SMS sent
Net Google reviews +30d+187
Avg call duration42s
Cost / NPS data point$0.24

After 30 days, you'll see this.

crixin voice ingest mirrors your Twilio history into local SQLite. crixin voice wrapped writes this as a single self-contained HTML file. Drop it into a client report; screenshot it for a deck; share it with your team.

Voice Wrapped · Q2 2026

Acme PLG · client snapshot
Total calls
3,418
across 6 use cases
Total minutes
2,089
avg 36s / call
Twilio + Deepgram
$58.24
$0.017 / call avg
Unique destinations
1,612
US / CA / MX
Caller archetype
Quick Pitcher
avg call < 60s
Duck rate
7.4%
below industry avg

Top use cases by call volume

NPS & review calls36%
Restaurant receptionist22%
B2B discovery17%
Field service triage11%
SaaS activation9%
Appointment confirms5%

Outcome distribution

Booked / confirmed / completed1,891
Voicemail / no-answer704
Callback scheduled438
Transferred to human197
Opted out (DNC honored)52
Errored136

Language mix

en-US71%
es-MX / es-US22%
ar-EG7%

What your AI ducked when asked

"let me get back to you"47×
"that's a great question"38×
"I'll have my team follow up"21×
Generated locally · PII auto-stripped · shareable as a screenshot