Featured

Deploy OpenClaw in 60 seconds — 20% off logoDeploy OpenClaw in 60 seconds — 20% off

Launch OpenClaw on Hostinger in about 60 seconds and keep your agent live 24/7. Our referral link gives you 20% off, no coupon code needed.

Launch on Hostinger
Run your Hermes agent on Hostinger, fully managed logoRun your Hermes agent on Hostinger, fully managed

Launch Hermes on Hostinger in one click, fully managed, no VPS knowledge needed. Use code ZACAARON10 for 10% off.

Launch on Hostinger
Crawl and scrape any site into clean data, 10% off logoCrawl and scrape any site into clean data, 10% off

Firecrawl crawls and scrapes any site into clean markdown for your agent. Get 1,000 free credits, and new users get 10% off their first purchase.

Try Firecrawl free
6,000+ web scrapers for your AI agent, start free logo6,000+ web scrapers for your AI agent, start free

Apify gives your agent live web data: 6,000+ prebuilt scrapers and actors, MCP-ready. Sign up free with $5 in usage credits.

Try Apify free
One API to scrape, enrich, and extract the internet. logoOne API to scrape, enrich, and extract the internet.

Context.dev gives your agents a single API to scrape, enrich, and extract live web data — no proxies, no parsers, no maintenance.

Start building free
SetupClaw: done-for-you OpenClaw for founders & exec teams logoSetupClaw: done-for-you OpenClaw for founders & exec teams

White-glove OpenClaw for founders and exec teams (4–50+ employees): we install, harden, integrate your tools, and maintain it — secured from day one.

Get it set up for you
SEO data APIs for your agent, $1 free credit logoSEO data APIs for your agent, $1 free credit

DataForSEO gives your agent live access to SERP results, keyword data, backlinks, and on-page SEO data through one API. New accounts get a $1 credit, good for up to 20,000 keyword or backlink lookups.

Try DataForSEO free
Reach 48,000+ AI builders

A flat monthly placement in front of developers actively installing AI tools. No lock-in, cancel anytime.

Advertise here
clawphone logo

clawphone

ranacseruet/clawphone

Otheropenclawby ranacseruet

Summary

OpenClaw plugin exposing 0 skills.

Install to Claude Code

openclaw plugin add ranacseruet/clawphone

Run in Claude Code. Add the marketplace first with /plugin marketplace add ranacseruet/clawphone if you haven't already.

README.md

clawphone

<p align="center"> <img src="docs/logo.png" alt="clawphone logo" width="200" /> </p>

![CI](https://github.com/ranacseruet/clawphone/actions/workflows/ci.yml) ![npm](https://www.npmjs.com/package/@ranacseruet/clawphone) ![License: MIT](LICENSE) ![Node.js](package.json)

A Node.js HTTP gateway that bridges Twilio voice calls and SMS to the OpenClaw agent. No framework — raw node:http, ES Modules only.

Runs as a standalone server (Node / PM2) or as an OpenClaw plugin.

Why clawphone?

OpenClaw ships an official @openclaw/voice-call plugin, but it is built on a fundamentally different architecture — and has different operational requirements. clawphone is designed to be the lightest possible path from a Twilio phone number to an AI agent.

Architecture: TwiML polling vs. Media Streams

@openclaw/voice-call uses Twilio Media Streams: a persistent WebSocket carries raw mu-law audio both ways, with external STT and TTS services (OpenAI, ElevenLabs) processing the stream. This delivers lower latency and higher voice quality, but requires additional API accounts and more infrastructure.

clawphone uses TwiML webhook polling with Twilio's built-in speech services — no external TTS or STT accounts needed:

/voice      →  <Gather input="speech">     Twilio records + transcribes the caller
/speech     →  fire agent async            returns <Redirect /speech-wait?key=…>
/speech-wait → poll until reply ready  →  <Say> agent reply (Twilio synthesises speech)

Everything runs over plain HTTP — no WebSocket server, no audio encoding, no streaming pipeline to manage.

Feature comparison

| | @openclaw/voice-call | clawphone | |---|:---:|:---:| | Deployment | | | | Standalone server (PM2 / systemd) | — | ✓ | | OpenClaw plugin mode | — | ✓ | | Gateway-required | ✓ | — | | Voice pipeline | | | | External TTS required (OpenAI / ElevenLabs) | ✓ | — | | External STT required | ✓ | — | | WebSocket / Media Streams infrastructure | ✓ | — | | Twilio built-in <Say> + <Gather> | — | ✓ | | SMS | | | | SMS support (fast + async paths) | — | ✓ | | Security & reliability | | | | Twilio webhook signature validation | — | ✓ | | Per-number rate limiting | — | ✓ | | Graceful shutdown with voice drain | — | ✓ | | Observability | | | | Structured JSON logging | — | ✓ | | Providers | | | | Multi-provider (Telnyx, Plivo) | ✓ | — |

The honest trade-off

clawphone trades voice quality and latency for operational simplicity. Twilio's built-in neural voices sound good; the polling loop adds a second or two of response time compared to a streaming pipeline. For a personal assistant or low-traffic deployment this is the right balance — one Twilio account, one Node process, no external APIs.

Media Streams support (WebSocket pipeline, pluggable TTS/STT) is a potential future direction if there is demand for it. If that — or anything else — is something you need, open a feature request. Knowing what people actually need drives what gets built next.

Prerequisites

| Dependency | Purpose | |---|---| | openclaw CLI | Agent backend; must be on $PATH | | cloudflared | Exposes the local server to Twilio via a public HTTPS tunnel | | Node.js ≥ 22 | Runtime |

Quick start (standalone)

# 1. Install dependencies
npm install

# 2. Configure
cp .env.example .env
# Edit .env — see Configuration below

# 3. Start
node server.mjs

# 4. Expose via tunnel (separate terminal)
cloudflared tunnel --url http://localhost:8787

Cloudflared prints a public URL like https://xxxx.trycloudflare.com. In the Twilio Console, set your phone number's webhooks:

| Event | Method | URL | |---|---|---| | A call comes in | POST | https://xxxx.trycloudflare.com/voice | | A message comes in | POST | https://xxxx.trycloudflare.com/sms |

Production (PM2)

pm2 start ecosystem.config.cjs
pm2 logs clawphone
pm2 restart clawphone

pm2 stop / pm2 restart send SIGTERM. The server stops accepting new connections, waits up to 30 s for any in-flight voice agent calls to complete, then exits — so active calls are not abruptly cut off.

OpenClaw plugin mode

See docs/plugin-install.md for full instructions — install, configure, update, and compare plugin vs. standalone deployment.

Configuration

All configuration is via environment variables (loaded from .env by dotenv). Variables already in the environment take precedence over .env.

| Variable | Default | Description | |---|---|---| | PORT | 8787 | HTTP listen port | | ALLOW_FROM | (none) | Comma-separated E.164 allowlist; blank = allow all | | TWILIO_ACCOUNT_SID | — | Twilio account SID (required for async SMS) | | TWILIO_AUTH_TOKEN | — | Twilio auth token (required for async SMS and webhook validation) | | PUBLIC_BASE_URL | (none) | Public server URL; when set with TWILIO_AUTH_TOKEN, enables webhook signature validation | | TWILIO_SMS_FROM | (inbound To) | Override sender number for outbound async SMS | | OPENCLAW_PHONE_SESSION_ID | phone | OpenClaw session ID for voice/SMS calls | | OPENCLAW_AGENT_ID | phone | OpenClaw agent ID | | OPENCLAW_MAX_CONCURRENT | 10 | Max simultaneous agent invocations | | DISCORD_LOG_CHANNEL_ID | (disabled) | Discord channel for call/SMS logging; unset to disable | | SMS_MAX_CHARS | 280 | Max characters in an SMS reply | | SMS_FAST_TIMEOUT_MS | 15000 | Fast-path timeout (ms) before falling back to async SMS | | RATE_LIMIT_MAX | 20 | Max requests per phone number per window (0 = disabled) | | RATE_LIMIT_WINDOW_MS | 60000 | Rate limit window in ms (default: 1 minute) | | SPEECH_WAIT_PAUSE_SECONDS | 1 | Seconds to pause between /speech-wait polls while waiting for the agent (Twilio minimum: 1) | | TWILIO_STT_MODEL | phone_call | Twilio STT (speech recognition) model (phone_call, googlev2_telephony, googlev2_telephony_short, default) | | CALLER_NAME | (none) | Optional name shown in Discord logs and agent prompt (e.g. Alice) | | AGENT_NAME | (none) | Optional agent display name shown in Discord logs (e.g. Bot) | | GREETING_TEXT | You are connected. Say something after the beep. | Voice greeting spoken when a call connects |

See .env.example for a fully-annotated reference.

Tips for best results

See docs/best-practices.md for guidance on model selection, disabling extended thinking, writing a voice-optimised system prompt, and tuning key config values.

Testing

npm test                        # run all tests
node --test test/sms.test.mjs   # run a single file

Tests use Node's built-in node:test runner with no external framework. No real Twilio API calls or Discord messages are made during testing.

Documentation

Contributing

See CONTRIBUTING.md for development setup, testing instructions, and the pull request process.

License

MIT

Related plugins

Browse all →