better-call-claude 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Shantanu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,661 @@
1
+ # Better Call Claude
2
+
3
+ <p align="center">
4
+ <img src="assets/marketing/hero-poster.png" alt="Better Call Claude - Agentic AI Communication Solution" width="400">
5
+ </p>
6
+
7
+ <p align="center">
8
+ <strong>Bi-directional communication for Claude Code via Voice Calls, SMS, and WhatsApp.</strong><br>
9
+ Call Claude from your phone to start tasks, and receive callbacks when Claude needs input or wants to share status.
10
+ </p>
11
+
12
+ > 📞 "Hey Claude, refactor the auth module and call me when you're done or need a decision."
13
+ >
14
+ > *[20 minutes later, phone rings]*
15
+ >
16
+ > 🤖 "I've finished the refactor but found a security issue. Should I fix it now or create a ticket?"
17
+
18
+ > 💬 *Or via SMS/WhatsApp:*
19
+ >
20
+ > You: "Claude, how's the deployment going?"
21
+ >
22
+ > Claude: "Deployment complete. 3 services updated, all health checks passing."
23
+
24
+ ## Features
25
+
26
+ - **📱 Inbound calls** - Call Claude Code from your phone to start tasks
27
+ - **📲 Outbound calls** - Claude calls you when done, stuck, or needs decisions
28
+ - **💬 SMS messaging** - Send and receive text messages with Claude
29
+ - **📱 WhatsApp** - Full WhatsApp Business integration
30
+ - **🔄 Cross-channel context** - Start on voice, continue on WhatsApp seamlessly
31
+ - **🔗 Persistent sessions** - Claude stays alive listening for WhatsApp messages
32
+ - **🔒 Secure transports** - Choose ngrok (easy) or Tailscale (enterprise-grade)
33
+ - **🗣️ Natural conversations** - Multi-turn interactions across all channels
34
+ - **🔧 Tool composable** - Claude can use other tools while communicating
35
+ - **⚡ Auto-webhook updates** - Twilio webhooks auto-update when ngrok URL changes
36
+ - **⌚ Works anywhere** - Phone, smartwatch, or any device
37
+
38
+ > ### ⚠️ Testing Status
39
+ >
40
+ > | Channel | Provider | Status |
41
+ > |---------|----------|--------|
42
+ > | Voice | Twilio | ✅ **Tested & Working** |
43
+ > | WhatsApp | Twilio Sandbox | ✅ **Tested & Working** |
44
+ > | SMS | Twilio | ⏳ Pending A2P 10DLC verification |
45
+ > | Voice | Telnyx | 🔬 Not yet tested |
46
+ > | SMS | Telnyx | 🔬 Not yet tested |
47
+ > | WhatsApp | Telnyx | 🔬 Not yet tested |
48
+ >
49
+ > *Contributions welcome for testing other provider/channel combinations!*
50
+
51
+ ---
52
+
53
+ ## Quick Start
54
+
55
+ ### 1. Get Required Accounts
56
+
57
+ | Service | Purpose | Cost |
58
+ |---------|---------|------|
59
+ | [Telnyx](https://telnyx.com) or [Twilio](https://twilio.com) | Phone calls | ~$1/mo + usage |
60
+ | [OpenAI](https://platform.openai.com) | Speech-to-text & text-to-speech | ~$0.03/min |
61
+ | [ngrok](https://ngrok.com) **OR** [Tailscale](https://tailscale.com) | Webhook tunneling | Free tier available |
62
+
63
+ ### 2. Set Up Phone Provider
64
+
65
+ <details>
66
+ <summary><b>Option A: Telnyx (Recommended - 50% cheaper)</b></summary>
67
+
68
+ 1. Create account at [portal.telnyx.com](https://portal.telnyx.com) and verify identity
69
+ 2. [Buy a phone number](https://portal.telnyx.com/#/numbers/buy-numbers) (~$1/month)
70
+ 3. [Create a Voice API application](https://portal.telnyx.com/#/call-control/applications):
71
+ - Set webhook URL to your tunnel URL + `/webhook/telnyx/inbound`
72
+ - Set API version to v2
73
+ 4. **Enable SMS** on your phone number:
74
+ - Go to [Messaging](https://portal.telnyx.com/#/messaging) and create a Messaging Profile
75
+ - Assign your phone number to the profile
76
+ - Set SMS webhook URL to your tunnel URL + `/webhook/telnyx/sms`
77
+ 5. **Enable WhatsApp** (optional):
78
+ - Go to [WhatsApp](https://portal.telnyx.com/#/whatsapp) in portal
79
+ - Complete WhatsApp Business verification
80
+ - Set webhook URL to your tunnel URL + `/webhook/telnyx/whatsapp`
81
+ 6. [Verify your phone number](https://portal.telnyx.com/#/numbers/verified-numbers) for outbound calls
82
+ 7. Get your **Connection ID** (or Messaging Profile ID) and **API Key**
83
+
84
+ </details>
85
+
86
+ <details>
87
+ <summary><b>Option B: Twilio</b></summary>
88
+
89
+ 1. Create account at [twilio.com/console](https://www.twilio.com/console)
90
+ 2. [Buy a phone number](https://www.twilio.com/console/phone-numbers/incoming)
91
+ 3. Configure webhooks for your number:
92
+ - Voice webhook: your tunnel URL + `/webhook/twilio/inbound`
93
+ - SMS webhook: your tunnel URL + `/webhook/twilio/sms`
94
+ 4. **Enable WhatsApp** (optional):
95
+ - Go to [WhatsApp Senders](https://www.twilio.com/console/sms/whatsapp/senders)
96
+ - Complete WhatsApp Business setup
97
+ - Set webhook URL to your tunnel URL + `/webhook/twilio/whatsapp`
98
+ 5. Get your **Account SID** and **Auth Token**
99
+
100
+ </details>
101
+
102
+ ### 3. Choose Your Transport
103
+
104
+ <details>
105
+ <summary><b>Option A: ngrok (Recommended for beginners)</b></summary>
106
+
107
+ **Pros:** Instant setup, works everywhere, no network configuration
108
+
109
+ 1. Sign up at [ngrok.com](https://ngrok.com)
110
+ 2. Copy your auth token from the dashboard
111
+ 3. Set `BETTERCALLCLAUDE_TRANSPORT=ngrok` in your config
112
+
113
+ </details>
114
+
115
+ <details>
116
+ <summary><b>Option B: Tailscale (Recommended for enterprise/security)</b></summary>
117
+
118
+ **Pros:** No public URLs, works behind firewalls, stable addresses, enterprise-grade security
119
+
120
+ **Requirements:** Tailscale installed on both your computer AND your phone provider must support private webhooks (or use Tailscale Funnel)
121
+
122
+ 1. Install [Tailscale](https://tailscale.com/download) on your machine
123
+ 2. Enable Tailscale Funnel for public webhook access:
124
+ ```bash
125
+ tailscale funnel 3333
126
+ ```
127
+ 3. Or use a relay server on your Tailscale network
128
+
129
+ </details>
130
+
131
+ ### 4. Install Better Call Claude
132
+
133
+ ```bash
134
+ # Quick start with bunx (recommended)
135
+ bunx better-call-claude
136
+
137
+ # Or install globally
138
+ bun install -g better-call-claude
139
+ better-call-claude
140
+ ```
141
+
142
+ ### 5. Add to Claude Code
143
+
144
+ Add to `~/.claude/settings.json`:
145
+
146
+ ```json
147
+ {
148
+ "mcpServers": {
149
+ "better-call-claude": {
150
+ "command": "bunx",
151
+ "args": ["better-call-claude"],
152
+ "env": {
153
+ "BETTERCALLCLAUDE_PHONE_PROVIDER": "telnyx",
154
+ "BETTERCALLCLAUDE_PHONE_ACCOUNT_SID": "your-connection-id",
155
+ "BETTERCALLCLAUDE_PHONE_AUTH_TOKEN": "your-api-key",
156
+ "BETTERCALLCLAUDE_PHONE_NUMBER": "+15551234567",
157
+ "BETTERCALLCLAUDE_USER_PHONE_NUMBER": "+15559876543",
158
+ "BETTERCALLCLAUDE_OPENAI_API_KEY": "sk-...",
159
+ "BETTERCALLCLAUDE_TRANSPORT": "ngrok",
160
+ "BETTERCALLCLAUDE_NGROK_AUTHTOKEN": "your-ngrok-token"
161
+ }
162
+ }
163
+ }
164
+ }
165
+ ```
166
+
167
+ Restart Claude Code. Done!
168
+
169
+ ---
170
+
171
+ ## Environment Variables
172
+
173
+ ### Required Variables
174
+
175
+ | Variable | Description |
176
+ |----------|-------------|
177
+ | `BETTERCALLCLAUDE_PHONE_PROVIDER` | `telnyx` or `twilio` |
178
+ | `BETTERCALLCLAUDE_PHONE_ACCOUNT_SID` | Provider account/connection ID |
179
+ | `BETTERCALLCLAUDE_PHONE_AUTH_TOKEN` | Provider API key/auth token |
180
+ | `BETTERCALLCLAUDE_PHONE_NUMBER` | Your Telnyx/Twilio phone number (E.164) |
181
+ | `BETTERCALLCLAUDE_WHATSAPP_NUMBER` | WhatsApp number if different (e.g., Twilio Sandbox) |
182
+ | `BETTERCALLCLAUDE_USER_PHONE_NUMBER` | Your personal phone number |
183
+ | `BETTERCALLCLAUDE_OPENAI_API_KEY` | OpenAI API key for TTS/STT |
184
+ | `BETTERCALLCLAUDE_TRANSPORT` | `ngrok` or `tailscale` |
185
+
186
+ ### Transport-Specific Variables
187
+
188
+ **For ngrok:**
189
+ | Variable | Default | Description |
190
+ |----------|---------|-------------|
191
+ | `BETTERCALLCLAUDE_NGROK_AUTHTOKEN` | - | ngrok auth token (required) |
192
+ | `BETTERCALLCLAUDE_NGROK_DOMAIN` | - | Custom domain (paid feature) |
193
+
194
+ **For Tailscale:**
195
+ | Variable | Default | Description |
196
+ |----------|---------|-------------|
197
+ | `BETTERCALLCLAUDE_TAILSCALE_HOSTNAME` | auto | Your Tailscale hostname |
198
+ | `BETTERCALLCLAUDE_TAILSCALE_USE_FUNNEL` | `false` | Use Tailscale Funnel for public access |
199
+ | `BETTERCALLCLAUDE_TAILSCALE_FUNNEL_PORT` | `443` | Funnel port |
200
+
201
+ ### Optional Variables
202
+
203
+ | Variable | Default | Description |
204
+ |----------|---------|-------------|
205
+ | `BETTERCALLCLAUDE_TTS_VOICE` | `onyx` | OpenAI voice (alloy, echo, fable, onyx, nova, shimmer) |
206
+ | `BETTERCALLCLAUDE_PORT` | `3333` | Local HTTP server port |
207
+ | `BETTERCALLCLAUDE_TRANSCRIPT_TIMEOUT_MS` | `180000` | Speech timeout (3 min) |
208
+ | `BETTERCALLCLAUDE_STT_SILENCE_DURATION_MS` | `800` | End-of-speech detection |
209
+
210
+ ---
211
+
212
+ ## Usage
213
+
214
+ ### Voice Calls
215
+
216
+ <p align="center">
217
+ <img src="assets/marketing/voice-call-comic.png" alt="Voice Call Example - Comic Style" width="500">
218
+ </p>
219
+
220
+ #### You → Claude (Inbound Calls)
221
+
222
+ Call your Telnyx/Twilio phone number from your personal phone:
223
+
224
+ > 📱 "Hey Claude, I need you to write unit tests for the payment module. Call me when you're done."
225
+
226
+ Claude will acknowledge and start working. When done, it calls you back.
227
+
228
+ #### Claude → You (Outbound Calls)
229
+
230
+ Claude can initiate calls when it needs your input:
231
+
232
+ > 🤖 "I found 3 different approaches for the caching layer. Want me to explain them so you can choose?"
233
+
234
+ #### Voice Commands During Calls
235
+
236
+ - **"Hang up"** or **"Goodbye"** - End the call
237
+ - **"Hold on"** - Claude waits for you to continue
238
+ - **"Go ahead"** - Claude continues with the task
239
+ - **"Cancel that"** - Abort current action
240
+
241
+ ---
242
+
243
+ ### SMS Messaging
244
+
245
+ #### You → Claude (Inbound SMS)
246
+
247
+ Text your Telnyx/Twilio number:
248
+
249
+ > 💬 "Hey Claude, what's the status of the deployment?"
250
+
251
+ Claude will respond via SMS:
252
+
253
+ > 🤖 "Deployment is 80% complete. Running integration tests now. ETA: 5 minutes."
254
+
255
+ #### Claude → You (Outbound SMS)
256
+
257
+ Claude can send you text updates:
258
+
259
+ > 🤖 "Build failed on line 42 of auth.ts. Reply with 'fix' to auto-fix or 'skip' to continue."
260
+
261
+ ---
262
+
263
+ ### WhatsApp
264
+
265
+ #### You → Claude (Inbound WhatsApp)
266
+
267
+ Send a WhatsApp message to your business number:
268
+
269
+ > 💬 "Show me the error logs from the last hour"
270
+
271
+ Claude responds in WhatsApp:
272
+
273
+ > 🤖 "Found 3 errors:\n1. Connection timeout at 14:32\n2. Auth failure at 14:45\n3. Rate limit at 15:01\n\nWant me to investigate any of these?"
274
+
275
+ #### Claude → You (Outbound WhatsApp)
276
+
277
+ Claude can send rich WhatsApp messages:
278
+
279
+ > 🤖 "Code review complete! Found 2 issues:\n• Line 23: Unused variable\n• Line 67: Missing error handling\n\nReply 'fix' to auto-fix or 'details' for more info."
280
+
281
+ ---
282
+
283
+ ### Cross-Channel Context
284
+
285
+ Start a task on voice and seamlessly continue on WhatsApp - Claude remembers everything.
286
+
287
+ <p align="center">
288
+ <img src="assets/marketing/whatsapp-continuation.png" alt="WhatsApp Continuation Example" width="350">
289
+ </p>
290
+
291
+ #### Example Flow
292
+
293
+ 1. **Call Claude:**
294
+ > 📞 "Hey Claude, run the todo app in dev mode and let's continue on WhatsApp"
295
+
296
+ 2. **Claude starts the app and enters WhatsApp listening mode:**
297
+ > 🤖 "Todo app running on port 5173. Send me WhatsApp messages for more instructions."
298
+
299
+ 3. **Send WhatsApp message:**
300
+ > 💬 "Expose it via localtunnel and add the URL to allowed hosts"
301
+
302
+ 4. **Claude responds via WhatsApp:**
303
+ > 🤖 "Done! Localtunnel URL: https://xyz.loca.lt - I've added it to vite.config.ts allowedHosts"
304
+
305
+ 5. **Continue the conversation:**
306
+ > 💬 "What's the public IP so I can access it remotely?"
307
+ >
308
+ > 🤖 "Your public IP is 203.0.113.42. Access the app at https://xyz.loca.lt"
309
+
310
+ **Key phrases to trigger WhatsApp listening:**
311
+ - "Continue on WhatsApp"
312
+ - "Let's talk on WhatsApp"
313
+ - "Listen for my WhatsApp messages"
314
+
315
+ ---
316
+
317
+ ### WhatsApp Sandbox (Twilio)
318
+
319
+ For testing, you can use Twilio's WhatsApp Sandbox instead of a full WhatsApp Business account.
320
+
321
+ 1. Go to [Twilio Console > Messaging > WhatsApp Sandbox](https://console.twilio.com/us1/develop/sms/try-it-out/whatsapp-learn)
322
+ 2. Send the join code to the sandbox number (+1 415 523 8886)
323
+ 3. Set the webhook URL to `{your-ngrok-url}/webhook/twilio/whatsapp`
324
+ 4. Add to your config:
325
+ ```json
326
+ "BETTERCALLCLAUDE_WHATSAPP_NUMBER": "+14155238886"
327
+ ```
328
+
329
+ > **Note:** Sandbox requires re-joining every 72 hours.
330
+
331
+ ---
332
+
333
+ ## How It Works
334
+
335
+ ```
336
+ ┌─────────────────┐ ┌──────────────────────────────────┐
337
+ │ Your Phone │────────>│ Phone Provider │
338
+ │ 📞 Voice │<────────│ (Telnyx/Twilio) │
339
+ │ 💬 SMS │ │ │
340
+ │ 📱 WhatsApp │ │ • Voice API │
341
+ └─────────────────┘ │ • Messaging API │
342
+ │ • WhatsApp Business API │
343
+ └──────────────┬───────────────────┘
344
+ │ webhooks
345
+
346
+ ┌──────────────────────────────────┐
347
+ │ Transport Layer │
348
+ │ (ngrok / Tailscale Funnel) │
349
+ └──────────────┬───────────────────┘
350
+
351
+
352
+ ┌─────────────────┐ ┌──────────────────────────────────┐
353
+ │ Claude Code │◄──────► │ Better Call Claude MCP Server │
354
+ │ (your IDE) │ stdio │ (local, port 3333) │
355
+ └─────────────────┘ │ │
356
+ │ • Voice handling │
357
+ │ • SMS handling │
358
+ │ • WhatsApp handling │
359
+ │ • Conversation management │
360
+ └──────────────┬───────────────────┘
361
+
362
+
363
+ ┌──────────────────────────────────┐
364
+ │ OpenAI API │
365
+ │ (Whisper STT + TTS) │
366
+ │ (Voice calls only) │
367
+ └──────────────────────────────────┘
368
+ ```
369
+
370
+ ### Communication Flows
371
+
372
+ **Voice:**
373
+ 1. **Inbound:** You call → Provider → Webhook → MCP Server → Claude Code
374
+ 2. **Outbound:** Claude Code → MCP Server → Provider → Your phone rings
375
+ 3. **Speech:** Your voice → Whisper STT → Text → Claude → TTS → Audio playback
376
+
377
+ **SMS:**
378
+ 1. **Inbound:** You text → Provider → Webhook → MCP Server → Claude Code
379
+ 2. **Outbound:** Claude Code → MCP Server → Provider API → SMS delivered
380
+
381
+ **WhatsApp:**
382
+ 1. **Inbound:** You message → Provider → Webhook → MCP Server → Claude Code
383
+ 2. **Outbound:** Claude Code → MCP Server → Provider API → WhatsApp delivered
384
+
385
+ ---
386
+
387
+ ## MCP Tools
388
+
389
+ ### Voice Tools
390
+
391
+ #### `receive_inbound_call`
392
+ Accept and process an incoming call from the user.
393
+
394
+ #### `initiate_call`
395
+ Start a phone call to the user.
396
+
397
+ ```typescript
398
+ const { callId, response } = await initiate_call({
399
+ message: "Hey! I finished the refactor. What should I work on next?"
400
+ });
401
+ ```
402
+
403
+ #### `continue_call`
404
+ Continue an active call with follow-up messages.
405
+
406
+ ```typescript
407
+ const response = await continue_call({
408
+ call_id: callId,
409
+ message: "Got it. Should I also add the caching layer?"
410
+ });
411
+ ```
412
+
413
+ #### `speak_to_user`
414
+ Speak without waiting for a response (for acknowledgments).
415
+
416
+ ```typescript
417
+ await speak_to_user({
418
+ call_id: callId,
419
+ message: "Let me search for that. One moment..."
420
+ });
421
+ ```
422
+
423
+ #### `end_call`
424
+ End an active call.
425
+
426
+ ```typescript
427
+ await end_call({
428
+ call_id: callId,
429
+ message: "Perfect, I'll get started. Talk soon!"
430
+ });
431
+ ```
432
+
433
+ #### `get_call_status`
434
+ Check status of current or recent calls.
435
+
436
+ ```typescript
437
+ const status = await get_call_status({ call_id: callId });
438
+ // { state: "active", duration: 45, transcript: [...] }
439
+ ```
440
+
441
+ ---
442
+
443
+ ### Messaging Tools
444
+
445
+ #### `receive_inbound_message`
446
+ Check for incoming SMS or WhatsApp messages.
447
+
448
+ ```typescript
449
+ const result = await receive_inbound_message({
450
+ channel: "any", // "sms", "whatsapp", or "any"
451
+ timeout_ms: 5000 // How long to wait
452
+ });
453
+ // { success: true, channel: "sms", conversation_id: "...", message: "Deploy now" }
454
+ ```
455
+
456
+ #### `send_sms`
457
+ Send an SMS message to the user.
458
+
459
+ ```typescript
460
+ const result = await send_sms({
461
+ message: "Build complete! 42 tests passed.",
462
+ wait_for_reply: true,
463
+ timeout_ms: 180000
464
+ });
465
+ // { success: true, conversation_id: "...", reply: "Great, deploy it" }
466
+ ```
467
+
468
+ #### `send_whatsapp`
469
+ Send a WhatsApp message to the user.
470
+
471
+ ```typescript
472
+ const result = await send_whatsapp({
473
+ message: "Found 3 issues in code review:\n• Issue 1\n• Issue 2\n• Issue 3",
474
+ wait_for_reply: true
475
+ });
476
+ // { success: true, conversation_id: "...", reply: "Fix issue 1 first" }
477
+ ```
478
+
479
+ #### `reply_to_conversation`
480
+ Reply to an existing conversation (works for voice, SMS, or WhatsApp).
481
+
482
+ ```typescript
483
+ const result = await reply_to_conversation({
484
+ conversation_id: "abc-123",
485
+ message: "Got it, fixing issue 1 now.",
486
+ wait_for_reply: false
487
+ });
488
+ ```
489
+
490
+ #### `get_conversation_history`
491
+ Get the full message history for any conversation.
492
+
493
+ ```typescript
494
+ const history = await get_conversation_history({
495
+ conversation_id: "abc-123"
496
+ });
497
+ // { success: true, channel: "whatsapp", messages: [...], state: "active" }
498
+ ```
499
+
500
+ ---
501
+
502
+ ## Costs
503
+
504
+ ### Voice Calls
505
+ | Service | Cost |
506
+ |---------|------|
507
+ | **Telnyx** outbound calls | ~$0.007/min |
508
+ | **Twilio** outbound calls | ~$0.014/min |
509
+ | **OpenAI** Whisper (STT) | ~$0.006/min |
510
+ | **OpenAI** TTS | ~$0.015/1K chars |
511
+
512
+ **Typical voice conversation:** ~$0.03-0.05/minute
513
+
514
+ ### SMS
515
+ | Service | Cost |
516
+ |---------|------|
517
+ | **Telnyx** SMS (US) | ~$0.004/message |
518
+ | **Twilio** SMS (US) | ~$0.0079/message |
519
+
520
+ **Typical SMS exchange:** ~$0.01-0.02/exchange
521
+
522
+ ### WhatsApp
523
+ | Service | Cost |
524
+ |---------|------|
525
+ | **Telnyx** WhatsApp | ~$0.005/message |
526
+ | **Twilio** WhatsApp | ~$0.005/message + conversation fees |
527
+
528
+ **Typical WhatsApp exchange:** ~$0.01-0.02/exchange
529
+
530
+ ### Infrastructure
531
+ | Service | Cost |
532
+ |---------|------|
533
+ | Phone number | ~$1/month |
534
+ | **ngrok** | Free tier available |
535
+ | **Tailscale** | Free for personal use |
536
+
537
+ ---
538
+
539
+ ## Security Considerations
540
+
541
+ ### With ngrok
542
+ - Public URLs can be discovered (use custom domains for production)
543
+ - Webhook signatures verified by default
544
+ - Consider IP allowlisting in ngrok dashboard
545
+
546
+ ### With Tailscale
547
+ - No public exposure by default
548
+ - Funnel creates public endpoint but traffic routes through Tailscale
549
+ - Integrates with SSO/SCIM for enterprise
550
+ - Audit logs available
551
+
552
+ ### General
553
+ - Phone numbers are never logged
554
+ - Call transcripts are ephemeral (cleared on restart)
555
+ - Use environment variables, never hardcode credentials
556
+
557
+ ---
558
+
559
+ ## Troubleshooting
560
+
561
+ ### Voice Issues
562
+
563
+ #### Claude doesn't answer calls
564
+ 1. Check the MCP server is running: `claude --debug`
565
+ 2. Verify webhook URL is configured in provider dashboard
566
+ 3. Ensure transport (ngrok/Tailscale) is active
567
+
568
+ #### Can't make outbound calls
569
+ 1. Verify `BETTERCALLCLAUDE_USER_PHONE_NUMBER` is correct
570
+ 2. Check phone number is verified with provider
571
+ 3. Ensure sufficient balance in provider account
572
+
573
+ #### Audio quality issues
574
+ 1. Check network connectivity
575
+ 2. Try different TTS voice: `BETTERCALLCLAUDE_TTS_VOICE=nova`
576
+ 3. Adjust silence detection: `BETTERCALLCLAUDE_STT_SILENCE_DURATION_MS=1000`
577
+
578
+ ### SMS Issues
579
+
580
+ #### SMS not being received
581
+ 1. Verify SMS is enabled on your phone number in provider dashboard
582
+ 2. Check SMS webhook URL is set: `/webhook/telnyx/sms` or `/webhook/twilio/sms`
583
+ 3. Verify Messaging Profile is assigned to phone number (Telnyx)
584
+
585
+ #### Can't send outbound SMS
586
+ 1. Check phone number has SMS capability
587
+ 2. Verify destination number format (E.164: +15551234567)
588
+ 3. Check provider account balance
589
+
590
+ ### WhatsApp Issues
591
+
592
+ #### WhatsApp messages not received
593
+ 1. Verify WhatsApp Business is set up in provider portal
594
+ 2. Check webhook URL: `/webhook/telnyx/whatsapp` or `/webhook/twilio/whatsapp`
595
+ 3. Ensure WhatsApp Business verification is complete
596
+
597
+ #### Can't send WhatsApp messages
598
+ 1. User must have messaged you first (WhatsApp 24-hour rule)
599
+ 2. Check WhatsApp Business approval status
600
+ 3. Verify message template compliance (for outbound-first messages)
601
+
602
+ ### Transport Issues
603
+
604
+ #### Tailscale Funnel not working
605
+ 1. Ensure Funnel is enabled: `tailscale funnel status`
606
+ 2. Check ACLs allow Funnel
607
+ 3. Verify HTTPS certificate is valid
608
+
609
+ #### ngrok tunnel disconnecting
610
+ 1. Upgrade to paid plan for stable URLs
611
+ 2. Use custom domain: `BETTERCALLCLAUDE_NGROK_DOMAIN`
612
+ 3. Check ngrok dashboard for connection limits
613
+
614
+ ---
615
+
616
+ ## Development
617
+
618
+ ```bash
619
+ # Clone the repo
620
+ git clone https://github.com/sns45/better-call-claude
621
+ cd better-call-claude
622
+
623
+ # Install dependencies
624
+ bun install
625
+
626
+ # Run in development mode
627
+ bun run dev
628
+ ```
629
+
630
+ ### Testing locally
631
+
632
+ ```bash
633
+ # Start the MCP server
634
+ bun run dev
635
+
636
+ # In another terminal, test with MCP inspector
637
+ npx @anthropics/mcp-inspector
638
+ ```
639
+
640
+ ---
641
+
642
+ ## Tech Stack
643
+
644
+ - **Runtime:** [Bun](https://bun.sh) - Fast JavaScript runtime
645
+ - **Web Framework:** [Hono](https://hono.dev) - Lightweight, fast web framework
646
+ - **Phone:** [Telnyx](https://telnyx.com) / [Twilio](https://twilio.com) - Telephony APIs
647
+ - **Speech:** [OpenAI Whisper](https://openai.com) - STT/TTS
648
+ - **Transport:** [ngrok](https://ngrok.com) / [Tailscale](https://tailscale.com) - Tunneling
649
+ - **Protocol:** [MCP](https://modelcontextprotocol.io) - Model Context Protocol
650
+
651
+ ---
652
+
653
+ ## Contributing
654
+
655
+ PRs welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines.
656
+
657
+ ---
658
+
659
+ ## License
660
+
661
+ MIT
Binary file