Broad drift audit against origin/main (b52b63396). Reference pages (most user-visible drift): - slash-commands: add /busy, /curator, /footer, /indicator, /redraw, /steer that were missing; drop non-existent /terminal-setup; fix /q footnote (resolves to /queue, not /quit); extend CLI-only list with all 24 CLI-only commands in the registry - cli-commands: add dedicated sections for hermes curator / fallback / hooks (new subcommands not previously documented); remove stale hermes honcho standalone section (the plugin registers dynamically via hermes memory); list curator/fallback/hooks in top-level table; fix completion to include fish - toolsets-reference: document the real 52-toolset count; split browser vs browser-cdp; add discord / discord_admin / spotify / yuanbao; correct hermes-cli tool count from 36 to 38; fix misleading claim that hermes-homeassistant adds tools (it's identical to hermes-cli) - tools-reference: bump tool count 55 -> 68; add 7 Spotify, 5 Yuanbao, 2 Discord toolsets; move browser_cdp/browser_dialog to their own browser-cdp toolset section - environment-variables: add 40+ user-facing HERMES_* vars that were undocumented (--yolo, --accept-hooks, --ignore-*, inference model override, agent/stream/checkpoint timeouts, OAuth trace, per-platform batch tuning for Telegram/Discord/Matrix/Feishu/WeCom, cron knobs, gateway restart/connect timeouts); dedupe the Cron Scheduler section; replace stale QQ_SANDBOX with QQ_PORTAL_HOST User-guide (top level): - cli.md: compression preserves last 20 turns, not 4 (protect_last_n: 20) - configuration.md: display.platforms is the canonical per-platform override key; tool_progress_overrides is deprecated and auto-migrated - profiles.md: model.default is the config key, not model.model - sessions.md: CLI/TUI session IDs use 6-char hex, gateway uses 8 - checkpoints-and-rollback.md: destructive-command list now matches _DESTRUCTIVE_PATTERNS (adds rmdir, cp, install, dd) - docker.md: the container runs as non-root hermes (UID 10000) via gosu; fix install command (uv pip); add missing --insecure on the dashboard compose example (required for non-loopback bind) - security.md: systemctl danger pattern also matches 'restart' - index.md: built-in tool count 47 -> 68 - integrations/index.md: 6 STT providers, 8 memory providers - integrations/providers.md: drop fictional dashscope/qwen aliases Features: - overview.md: 9 image models (not 8), 9 TTS providers (not 5), 8 memory providers (Supermemory was missing) - tool-gateway.md: 9 image models - tools.md: extend common-toolsets list with search / messaging / spotify / discord / debugging / safe - fallback-providers.md: add 6 real providers from PROVIDER_REGISTRY (lmstudio, kimi-coding-cn, stepfun, alibaba-coding-plan, tencent-tokenhub, azure-foundry) - plugins.md: Available Hooks table now includes on_session_finalize, on_session_reset, subagent_stop - built-in-plugins.md: add the 7 bundled plugins the page didn't mention (spotify, google_meet, three image_gen providers, two dashboard examples) - web-dashboard.md: add --insecure and --tui flags - cron.md: hermes cron create takes positional schedule/prompt, not flags Messaging: - telegram.md: TELEGRAM_WEBHOOK_SECRET is now REQUIRED when TELEGRAM_WEBHOOK_URL is set (gateway refuses to start without it per GHSA-3vpc-7q5r-276h). Biggest user-visible drift in the batch. - discord.md: HERMES_DISCORD_TEXT_BATCH_SPLIT_DELAY_SECONDS default is 2.0, not 0.1 - dingtalk.md: document DINGTALK_REQUIRE_MENTION / FREE_RESPONSE_CHATS / MENTION_PATTERNS / HOME_CHANNEL / ALLOW_ALL_USERS that the adapter supports - bluebubbles.md: drop fictional BLUEBUBBLES_SEND_READ_RECEIPTS env var; the setting lives in platforms.bluebubbles.extra only - qqbot.md: drop dead QQ_SANDBOX; add real QQ_PORTAL_HOST and QQ_GROUP_ALLOWED_USERS - wecom-callback.md: replace 'hermes gateway start' (service-only) with 'hermes gateway' for first-time setup Developer-guide: - architecture.md: refresh tool/toolset counts (61/52), terminal backend count (7), line counts for run_agent.py (~13.7k), cli.py (~11.5k), main.py (~10.4k), setup.py (~3.5k), gateway/run.py (~12.2k), mcp_tool.py (~3.1k); add yuanbao adapter, bump platform adapter count 18 -> 20 - agent-loop.md: run_agent.py line count 10.7k -> 13.7k - tools-runtime.md: add vercel_sandbox backend - adding-tools.md: remove stale 'Discovery import added to model_tools.py' checklist item (registry auto-discovery) - adding-platform-adapters.md: mark send_typing / get_chat_info as concrete base methods; only connect/disconnect/send are abstract - acp-internals.md: ACP sessions now persist to SessionDB (~/.hermes/state.db); acp.run_agent call uses use_unstable_protocol=True - cron-internals.md: gateway runs scheduler in a dedicated background thread via _start_cron_ticker, not on a maintenance cycle; locking is cross-process via fcntl.flock (Unix) / msvcrt.locking (Windows) - gateway-internals.md: gateway/run.py ~12k lines - provider-runtime.md: cron DOES support fallback (run_job reads fallback_providers from config) - session-storage.md: SCHEMA_VERSION = 11 (not 9); add migrations 10 and 11 (trigram FTS, inline-mode FTS5 re-index); add api_call_count column to Sessions DDL; document messages_fts_trigram and state_meta in the architecture tree - context-compression-and-caching.md: remove the obsolete 'context pressure warnings' section (warnings were removed for causing models to give up early) - context-engine-plugin.md: compress() signature now includes focus_topic param - extending-the-cli.md: _build_tui_layout_children signature now includes model_picker_widget; add to default layout Also fixed three pre-existing broken links/anchors the build warned about (docker.md -> api-server.md, yuanbao.md -> cron-jobs.md and tips#background-tasks, nix-setup.md -> #container-aware-cli). Regenerated per-skill pages via website/scripts/generate-skill-docs.py so catalog tables and sidebar are consistent with current SKILL.md frontmatter. docusaurus build: clean, no broken links or anchors.
5.1 KiB
BlueBubbles (iMessage)
Connect Hermes to Apple iMessage via BlueBubbles — a free, open-source macOS server that bridges iMessage to any device.
Prerequisites
- A Mac (always on) running BlueBubbles Server
- Apple ID signed into Messages.app on that Mac
- BlueBubbles Server v1.0.0+ (webhooks require this version)
- Network connectivity between Hermes and the BlueBubbles server
Setup
1. Install BlueBubbles Server
Download and install from bluebubbles.app. Complete the setup wizard — sign in with your Apple ID and configure a connection method (local network, Ngrok, Cloudflare, or Dynamic DNS).
2. Get your Server URL and Password
In BlueBubbles Server → Settings → API, note:
- Server URL (e.g.,
http://192.168.1.10:1234) - Server Password
3. Configure Hermes
Run the setup wizard:
hermes gateway setup
Select BlueBubbles (iMessage) and enter your server URL and password.
Or set environment variables directly in ~/.hermes/.env:
BLUEBUBBLES_SERVER_URL=http://192.168.1.10:1234
BLUEBUBBLES_PASSWORD=your-server-password
4. Authorize Users
Choose one approach:
DM Pairing (recommended): When someone messages your iMessage, Hermes automatically sends them a pairing code. Approve it with:
hermes pairing approve bluebubbles <CODE>
Use hermes pairing list to see pending codes and approved users.
Pre-authorize specific users (in ~/.hermes/.env):
BLUEBUBBLES_ALLOWED_USERS=user@icloud.com,+15551234567
Open access (in ~/.hermes/.env):
BLUEBUBBLES_ALLOW_ALL_USERS=true
5. Start the Gateway
hermes gateway run
Hermes will connect to your BlueBubbles server, register a webhook, and start listening for iMessage messages.
How It Works
iMessage → Messages.app → BlueBubbles Server → Webhook → Hermes
Hermes → BlueBubbles REST API → Messages.app → iMessage
- Inbound: BlueBubbles sends webhook events to a local listener when new messages arrive. No polling — instant delivery.
- Outbound: Hermes sends messages via the BlueBubbles REST API.
- Media: Images, voice messages, videos, and documents are supported in both directions. Inbound attachments are downloaded and cached locally for the agent to process.
Environment Variables
| Variable | Required | Default | Description |
|---|---|---|---|
BLUEBUBBLES_SERVER_URL |
Yes | — | BlueBubbles server URL |
BLUEBUBBLES_PASSWORD |
Yes | — | Server password |
BLUEBUBBLES_WEBHOOK_HOST |
No | 127.0.0.1 |
Webhook listener bind address |
BLUEBUBBLES_WEBHOOK_PORT |
No | 8645 |
Webhook listener port |
BLUEBUBBLES_WEBHOOK_PATH |
No | /bluebubbles-webhook |
Webhook URL path |
BLUEBUBBLES_HOME_CHANNEL |
No | — | Phone/email for cron delivery |
BLUEBUBBLES_ALLOWED_USERS |
No | — | Comma-separated authorized users |
BLUEBUBBLES_ALLOW_ALL_USERS |
No | false |
Allow all users |
Auto-marking messages as read is controlled by the send_read_receipts key under platforms.bluebubbles.extra in ~/.hermes/config.yaml (default: true). There is no corresponding environment variable.
Features
Text Messaging
Send and receive iMessages. Markdown is automatically stripped for clean plain-text delivery.
Rich Media
- Images: Photos appear natively in the iMessage conversation
- Voice messages: Audio files sent as iMessage voice messages
- Videos: Video attachments
- Documents: Files sent as iMessage attachments
Tapback Reactions
Love, like, dislike, laugh, emphasize, and question reactions. Requires the BlueBubbles Private API helper.
Typing Indicators
Shows "typing..." in the iMessage conversation while the agent is processing. Requires Private API.
Read Receipts
Automatically marks messages as read after processing. Requires Private API.
Chat Addressing
You can address chats by email or phone number — Hermes resolves them to BlueBubbles chat GUIDs automatically. No need to use raw GUID format.
Private API
Some features require the BlueBubbles Private API helper:
- Tapback reactions
- Typing indicators
- Read receipts
- Creating new chats by address
Without the Private API, basic text messaging and media still work.
Troubleshooting
"Cannot reach server"
- Verify the server URL is correct and the Mac is on
- Check that BlueBubbles Server is running
- Ensure network connectivity (firewall, port forwarding)
Messages not arriving
- Check that the webhook is registered in BlueBubbles Server → Settings → API → Webhooks
- Verify the webhook URL is reachable from the Mac
- Check
hermes logs gatewayfor webhook errors (orhermes logs -fto follow in real-time)
"Private API helper not connected"
- Install the Private API helper: docs.bluebubbles.app
- Basic messaging works without it — only reactions, typing, and read receipts require it