Full-corpus correctness audit of the hand-written docs against the codebase, plus a 2-week merged-PR coverage sweep and one live dashboard screenshot. Correctness (verified against COMMAND_REGISTRY / PROVIDER_REGISTRY / TOOLSETS / tools.registry / DEFAULT_CONFIG / source): - reference: add /version slash command, context_engine toolset, openai-api + novita-ai to --provider; fix tool count 64->71; model_catalog ttl 24->1; add profile describe to summary table; add real provider env vars (LM_API_KEY/LM_BASE_URL, KIMI_CODING_API_KEY, ALIBABA_CODING_PLAN_*, ANTHROPIC_BASE_URL, COPILOT_API_BASE_URL); fix faq "Windows: not natively". - user-guide: fix broken `hermes -w -q` (->-z) and `hermes logs --tail` (->-f); language list 8->16; aux slots 8->11; docker separate-dashboard claim; _SECURITY_ARGS -> _BASE_SECURITY_ARGS. - features: curator prune_builtins truth + missing CLI verbs; codex-runtime aux keys (context_compression->compression, vision_detect->vision); kanban terminate endpoint + promote/reassign/schedule/diagnostics/edit + per-profile cap; mcp mTLS (client_cert/client_key); built-in-plugins nemo_relay + teams_pipeline; api-server run approval endpoint; computer-use frontmatter. - features N-Z + integrations: StepFun step-3-mini->step-3.5-flash; web-search backends 4->8; tool-gateway image-model IDs; voice-mode STT/TTS enums; remove phantom `rl` toolset; nous-portal status subcommand. - messaging: WeCom typing/streaming cols; telegram transport default edit->auto; sms host default; simplex/ntfy `gateway setup` + pairing approve; line smart-chunking; matrix MATRIX_DM_AUTO_THREAD. - developer-guide: build-a-plugin code examples (register_command signature, ContextEngine/ImageGenProvider/MemoryProvider ABCs); model-provider-plugin entry-point group hermes.plugins->hermes_agent.plugins; PLUGIN.yaml->plugin.yaml; agent-loop stale LOC; web-search-provider phantom crawl(). PR coverage (2-week window, 149 feat PRs): - desktop.md refreshed for ~15 shipped features (zh-Hans switcher, rebindable shortcuts + zoom + Cmd+K, status-bar model picker + YOLO toggle, session-by-id + archive, multi-profile concurrent + cross-profile @session, composer history, Providers pane, per-profile remote hosts, Grok OAuth, aux-pin warning). - configuration.md gateway-streaming default corrected to per-platform. - tool-gateway.md free tool pool entitlement note. Media: - New /img/dashboard/admin-config.png — live dashboard Config admin page (captured from a clean profile, no secrets/personalization).
6.4 KiB
| sidebar_position | sidebar_label | title | description |
|---|---|---|---|
| 8 | SMS (Twilio) | SMS (Twilio) | Set up Hermes Agent as an SMS chatbot via Twilio |
SMS Setup (Twilio)
Hermes connects to SMS through the Twilio API. People text your Twilio phone number and get AI responses back — same conversational experience as Telegram or Discord, but over standard text messages.
:::info Shared Credentials
The SMS gateway shares credentials with the optional telephony skill. If you've already set up Twilio for voice calls or one-off SMS, the gateway works with the same TWILIO_ACCOUNT_SID, TWILIO_AUTH_TOKEN, and TWILIO_PHONE_NUMBER.
:::
Prerequisites
- Twilio account — Sign up at twilio.com (free trial available)
- A Twilio phone number with SMS capability
- A publicly accessible server — Twilio sends webhooks to your server when SMS arrives
- aiohttp —
pip install 'hermes-agent[sms]'
Step 1: Get Your Twilio Credentials
- Go to the Twilio Console
- Copy your Account SID and Auth Token from the dashboard
- Go to Phone Numbers → Manage → Active Numbers — note your phone number in E.164 format (e.g.,
+15551234567)
Step 2: Configure Hermes
Interactive setup (recommended)
hermes gateway setup
Select SMS (Twilio) from the platform list. The wizard will prompt for your credentials.
Manual setup
Add to ~/.hermes/.env:
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=your_auth_token_here
TWILIO_PHONE_NUMBER=+15551234567
# Security: restrict to specific phone numbers (recommended)
SMS_ALLOWED_USERS=+15559876543,+15551112222
# Optional: set a home channel for cron job delivery
SMS_HOME_CHANNEL=+15559876543
Step 3: Configure Twilio Webhook
Twilio needs to know where to send incoming messages. In the Twilio Console:
- Go to Phone Numbers → Manage → Active Numbers
- Click your phone number
- Under Messaging → A MESSAGE COMES IN, set:
- Webhook:
https://your-server:8080/webhooks/twilio - HTTP Method:
POST
- Webhook:
:::tip Exposing Your Webhook If you're running Hermes locally, use a tunnel to expose the webhook:
# Using cloudflared
cloudflared tunnel --url http://localhost:8080
# Using ngrok
ngrok http 8080
Set the resulting public URL as your Twilio webhook. :::
Set SMS_WEBHOOK_URL to the same URL you configured in Twilio. This is required for Twilio signature validation — the adapter will refuse to start without it:
# Must match the webhook URL in your Twilio Console
SMS_WEBHOOK_URL=https://your-server:8080/webhooks/twilio
The webhook port defaults to 8080. Override with:
SMS_WEBHOOK_PORT=3000
Step 4: Start the Gateway
hermes gateway
You should see:
[sms] Twilio webhook server listening on 127.0.0.1:8080, from: +1555***4567
If you see Refusing to start: SMS_WEBHOOK_URL is required, set SMS_WEBHOOK_URL to the public URL configured in your Twilio Console (see Step 3).
Text your Twilio number — Hermes will respond via SMS.
Environment Variables
| Variable | Required | Description |
|---|---|---|
TWILIO_ACCOUNT_SID |
Yes | Twilio Account SID (starts with AC) |
TWILIO_AUTH_TOKEN |
Yes | Twilio Auth Token (also used for webhook signature validation) |
TWILIO_PHONE_NUMBER |
Yes | Your Twilio phone number (E.164 format) |
SMS_WEBHOOK_URL |
Yes | Public URL for Twilio signature validation — must match the webhook URL in your Twilio Console |
SMS_WEBHOOK_PORT |
No | Webhook listener port (default: 8080) |
SMS_WEBHOOK_HOST |
No | Webhook bind address (default: 127.0.0.1) |
SMS_INSECURE_NO_SIGNATURE |
No | Set to true to disable signature validation (local dev only — not for production) |
SMS_ALLOWED_USERS |
No | Comma-separated E.164 phone numbers allowed to chat |
SMS_ALLOW_ALL_USERS |
No | Set to true to allow anyone (not recommended) |
SMS_HOME_CHANNEL |
No | Phone number for cron job / notification delivery |
SMS_HOME_CHANNEL_NAME |
No | Display name for the home channel (default: Home) |
SMS-Specific Behavior
- Plain text only — Markdown is automatically stripped since SMS renders it as literal characters
- 1600 character limit — Longer responses are split across multiple messages at natural boundaries (newlines, then spaces)
- Echo prevention — Messages from your own Twilio number are ignored to prevent loops
- Phone number redaction — Phone numbers are redacted in logs for privacy
Security
Webhook signature validation
Hermes validates that inbound webhooks genuinely originate from Twilio by verifying the X-Twilio-Signature header (HMAC-SHA1). This prevents attackers from injecting forged messages.
SMS_WEBHOOK_URL is required. Set it to the public URL configured in your Twilio Console. The adapter will refuse to start without it.
For local development without a public URL, you can disable validation:
# Local dev only — NOT for production
SMS_INSECURE_NO_SIGNATURE=true
User allowlists
The gateway denies all users by default. Configure an allowlist:
# Recommended: restrict to specific phone numbers
SMS_ALLOWED_USERS=+15559876543,+15551112222
# Or allow all (NOT recommended for bots with terminal access)
SMS_ALLOW_ALL_USERS=true
:::warning SMS has no built-in encryption. Don't use SMS for sensitive operations unless you understand the security implications. For sensitive use cases, prefer Signal or Telegram. :::
Troubleshooting
Messages not arriving
- Check your Twilio webhook URL is correct and publicly accessible
- Verify
TWILIO_ACCOUNT_SIDandTWILIO_AUTH_TOKENare correct - Check the Twilio Console → Monitor → Logs → Messaging for delivery errors
- Ensure your phone number is in
SMS_ALLOWED_USERS(orSMS_ALLOW_ALL_USERS=true)
Replies not sending
- Check
TWILIO_PHONE_NUMBERis set correctly (E.164 format with+) - Verify your Twilio account has SMS-capable numbers
- Check Hermes gateway logs for Twilio API errors
Webhook port conflicts
If port 8080 is already in use, change it:
SMS_WEBHOOK_PORT=3001
Update the webhook URL in Twilio Console to match.