hermes-agent/website/docs/user-guide/messaging/sms.md
Teknium 2d099fed1e
docs: deep audit — registry drift, stale claims, 2-week PR coverage, dashboard screenshot (#40952)
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).
2026-06-07 01:39:06 -07:00

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 accountSign 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
  • aiohttppip install 'hermes-agent[sms]'

Step 1: Get Your Twilio Credentials

  1. Go to the Twilio Console
  2. Copy your Account SID and Auth Token from the dashboard
  3. Go to Phone Numbers → Manage → Active Numbers — note your phone number in E.164 format (e.g., +15551234567)

Step 2: Configure Hermes

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:

  1. Go to Phone Numbers → Manage → Active Numbers
  2. Click your phone number
  3. Under Messaging → A MESSAGE COMES IN, set:
    • Webhook: https://your-server:8080/webhooks/twilio
    • HTTP Method: POST

:::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

  1. Check your Twilio webhook URL is correct and publicly accessible
  2. Verify TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN are correct
  3. Check the Twilio Console → Monitor → Logs → Messaging for delivery errors
  4. Ensure your phone number is in SMS_ALLOWED_USERS (or SMS_ALLOW_ALL_USERS=true)

Replies not sending

  1. Check TWILIO_PHONE_NUMBER is set correctly (E.164 format with +)
  2. Verify your Twilio account has SMS-capable numbers
  3. 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.