SMS Skill
Send SMS/MMS, read inboxes, auto-reply as Claudius, and view conversation threads via Telnyx (2 numbers) and Twilio (6 numbers).
When to Use This Skill
- Sending a text message to any phone number
- Reading recent SMS messages (inbox)
- Listening for real-time inbound messages (two-way SMS)
- Auto-replying to inbound SMS as Claudius (soul-aware responses)
- Viewing a conversation thread with a specific number
- Listing available phone numbers across providers
- Sending MMS with image attachments
Prerequisites
Requires requests (uv pip install --system requests).
Credentials are loaded automatically:
- Telnyx:
TELNYX_API_KEYenv var, or falls back to~/.claude.json(already configured) - Twilio:
TWILIO_ACCOUNT_SID+TWILIO_AUTH_TOKENenv vars, or falls back to hardcoded defaults
Quick Start
# Send a text
python3 ~/.claude/skills/sms/scripts/sms_send.py "+19175551234" "Hello from Claude"
# Read recent messages
python3 ~/.claude/skills/sms/scripts/sms_read.py -n 10
# View conversation with someone
python3 ~/.claude/skills/sms/scripts/sms_conversation.py "+19175551234"
# List all available numbers
python3 ~/.claude/skills/sms/scripts/sms_numbers.py
# Start real-time listener (background)
python3 ~/.claude/skills/sms/scripts/sms_listen.py --bg
# Check inbound messages
python3 ~/.claude/skills/sms/scripts/sms_inbox.py
Available Scripts
1. sms_send.py — Send SMS/MMS
python3 ~/.claude/skills/sms/scripts/sms_send.py TO "MESSAGE" [OPTIONS]
| Flag | Description | |------|-------------| | --from NUMBER | Send from a specific number (auto-detects provider) | | --provider telnyx\|twilio | Force a specific provider | | --media URL | Attach media for MMS |
Examples:
# Send via Telnyx (default)
python3 ~/.claude/skills/sms/scripts/sms_send.py "+19175551234" "Meeting at 3pm"
# Send from a Twilio number
python3 ~/.claude/skills/sms/scripts/sms_send.py "+19175551234" "Hello" --from "+18508058037"
# Send MMS with image
python3 ~/.claude/skills/sms/scripts/sms_send.py "+19175551234" "Check this" --media "https://example.com/photo.jpg"
2. sms_read.py — Read Inbox
python3 ~/.claude/skills/sms/scripts/sms_read.py [OPTIONS]
| Flag | Description | |------|-------------| | --to NUMBER | Messages to a specific number | | --from-number NUMBER | Messages from a specific sender | | --direction inbound\|outbound | Filter by direction | | -n/--limit NUM | Number of messages (default: 10) | | --provider telnyx\|twilio | Query specific provider | | --all-providers | Query both providers |
Examples:
# Read last 10 messages (Twilio recommended for reads)
python3 ~/.claude/skills/sms/scripts/sms_read.py -n 10 --provider twilio
# Messages to a specific number
python3 ~/.claude/skills/sms/scripts/sms_read.py --to "+18508058037" --provider twilio
# Only inbound messages
python3 ~/.claude/skills/sms/scripts/sms_read.py --direction inbound --provider twilio
# Query both providers
python3 ~/.claude/skills/sms/scripts/sms_read.py --all-providers -n 20
3. sms_conversation.py — View Conversation Thread
python3 ~/.claude/skills/sms/scripts/sms_conversation.py NUMBER [OPTIONS]
| Flag | Description | |------|-------------| | -n/--limit NUM | Max messages per direction (default: 20) | | --our-number NUMBER | Filter to a specific one of our numbers | | --provider telnyx\|twilio | Query specific provider | | --all-providers | Query both providers |
Examples:
# View conversation with a number
python3 ~/.claude/skills/sms/scripts/sms_conversation.py "+19175551234" --provider twilio
# Limit to last 10 messages per direction
python3 ~/.claude/skills/sms/scripts/sms_conversation.py "+19175551234" -n 10 --provider twilio
# Filter to a specific one of our numbers
python3 ~/.claude/skills/sms/scripts/sms_conversation.py "+19175551234" --our-number "+18508058037"
4. sms_numbers.py — List Available Numbers
python3 ~/.claude/skills/sms/scripts/sms_numbers.py [OPTIONS]
| Flag | Description | |------|-------------| | --provider telnyx\|twilio | Filter by provider | | --live | Query APIs for live status (slower) |
Examples:
# List all 8 numbers
python3 ~/.claude/skills/sms/scripts/sms_numbers.py
# Twilio numbers only
python3 ~/.claude/skills/sms/scripts/sms_numbers.py --provider twilio
# Live API status check
python3 ~/.claude/skills/sms/scripts/sms_numbers.py --live
5. sms_listen.py — Real-Time Inbound Listener
Background daemon that polls Twilio for new inbound messages and runs a webhook server for Telnyx inbound. Messages are written to data/inbox.jsonl.
python3 ~/.claude/skills/sms/scripts/sms_listen.py [OPTIONS]
| Flag | Description | |------|-------------| | --bg | Run in background (daemonize) | | --stop | Stop running listener | | --status | Check if listener is running | | --interval N | Twilio poll interval in seconds (default: 10) | | --numbers +1... +1... | Twilio numbers to monitor (default: all 6) | | --webhook-port N | Telnyx webhook port (default: 9147) | | --no-telnyx | Disable Telnyx webhook server | | --no-twilio | Disable Twilio polling |
Examples:
# Start listener in background
python3 ~/.claude/skills/sms/scripts/sms_listen.py --bg
# Check status
python3 ~/.claude/skills/sms/scripts/sms_listen.py --status
# Stop listener
python3 ~/.claude/skills/sms/scripts/sms_listen.py --stop
# Monitor only the Aldea production number, poll every 5s
python3 ~/.claude/skills/sms/scripts/sms_listen.py --bg --numbers +18557066006 --interval 5
# Telnyx webhook only (no Twilio polling)
python3 ~/.claude/skills/sms/scripts/sms_listen.py --bg --no-twilio
Telnyx webhook setup: Point your Telnyx Messaging Profile webhook URL to http://localhost:9147/telnyx. For remote access, use ngrok or similar tunnel.
6. Auto-Reply — Two Modes
Mode A: /sms-respond Slash Command (Interactive)
Process unhandled SMS using the current Claude Code session as the LLM. No subprocess needed—follows the same pattern as /slack-respond.
/sms-respond # Process all unhandled messages
/sms-respond 2 # Process only message #2 from inbox
The slash command loads inbox, soul.md, and memory context dynamically, then walks through a 6-step cognitive pipeline (internal monologue → external dialogue → user model check → user model update → soul state check → soul state update). Replies are sent via sms_send.py and all memory layers are updated.
The command also starts a background watcher (sms_watch.py) after processing, which polls for new inbound messages every 5 seconds and notifies the session when one arrives—creating a continuous two-way SMS loop.
Use this when: You're in an active Claude Code session and want to reply to SMS.
Mode B: sms_respond.py Daemon (Standalone)
Standalone daemon for Mac Mini or headless deployment. Uses claude -p subprocess to generate responses. Does not work from within a running Claude Code session (subprocess nesting conflict).
python3 ~/.claude/skills/sms/scripts/sms_respond.py [OPTIONS]
| Flag | Description | |------|-------------| | --daemon | Loop continuously, polling inbox | | --bg | Run daemon in background (requires --daemon) | | --status | Check if responder daemon is running | | --stop | Stop running responder daemon | | --interval N | Poll interval in seconds (default: 5) | | --model MODEL | Override LLM model (default: claude-sonnet-4-5-20250514) | | --no-soul | Disable soul context (plain responses) | | --dry-run | Process messages without sending replies |
Examples:
# Start auto-reply daemon in background (Mac Mini)
python3 ~/.claude/skills/sms/scripts/sms_respond.py --daemon --bg
# Check daemon status
python3 ~/.claude/skills/sms/scripts/sms_respond.py --status
# Stop