Files
kshitijk4poor 1ec84a2dae fix(simplex): document contactId-only allowlist and warn on name entries
After #44729 SIMPLEX_ALLOWED_USERS matches only the numeric contactId, but
the docs still told operators display names work, and existing name
entries would silently stop matching. Update the docs and log a one-time
warning at first connect listing non-numeric entries that are now ignored.
2026-09-27 20:47:41 +05:30

6.1 KiB

SimpleX Chat

SimpleX Chat is a private, decentralised messaging platform where users own their contacts and groups. Unlike other platforms, SimpleX assigns no persistent user IDs — every contact is identified by an opaque internal ID generated at connection time, which makes it one of the most private messengers available.

Run hermes gateway setup and pick SimpleX for a guided walk-through.

Prerequisites

  • The simplex-chat CLI installed and running as a daemon
  • Python package websockets (hermes pm repair)

Install simplex-chat

Download the latest release from the simplex-chat GitHub releases page:

# Linux / macOS binary
curl -L https://github.com/simplex-chat/simplex-chat/releases/latest/download/simplex-chat-ubuntu-22_04-x86_64 -o simplex-chat
chmod +x simplex-chat

The SimpleX Chat project does not publish a prebuilt Docker image for the chat client; to run it under Docker, build from source from the simplex-chat repository.

Start the daemon

simplex-chat -p 5225

The daemon listens on WebSocket at ws://127.0.0.1:5225 by default.

Configure Hermes

Via setup wizard

hermes gateway setup

Select SimpleX Chat and follow the prompts.

Via environment variables

Add these to ~/.hermes/.env:

SIMPLEX_WS_URL=ws://127.0.0.1:5225
SIMPLEX_ALLOWED_USERS=<contact-id-1>,<contact-id-2>
SIMPLEX_HOME_CHANNEL=<contact-id>
Variable Required Description
SIMPLEX_WS_URL Yes WebSocket URL of the simplex-chat daemon
SIMPLEX_ALLOWED_USERS Recommended Comma-separated allowlist of numeric contactIds. Display names are not accepted — any contact can change theirs.
SIMPLEX_ALLOW_ALL_USERS Optional Set true to allow every contact (use carefully)
SIMPLEX_AUTO_ACCEPT Optional Auto-accept incoming contact requests (default: true)
SIMPLEX_GROUP_ALLOWED Optional Comma-separated group IDs the bot participates in, or * for any group. Omit to ignore group messages entirely
SIMPLEX_HOME_CHANNEL Optional Default contact/group ID for cron job delivery
SIMPLEX_HOME_CHANNEL_NAME Optional Human label for the home channel
HERMES_SIMPLEX_TEXT_BATCH_DELAY Optional Quiet-period seconds (default: 0.8) used to concatenate rapid-fire inbound text messages into one event

Find your contact ID

After starting the daemon, open a conversation with your agent contact. The numeric contactId appears in session logs (or run /contacts in the daemon). SIMPLEX_ALLOWED_USERS matches only this ID: display names are chosen by the contact and can collide, so they are ignored.

Authorization

By default all contacts are denied. You must either:

  1. Set SIMPLEX_ALLOWED_USERS to a comma-separated list of numeric contactIds (e.g. SIMPLEX_ALLOWED_USERS=4,9), or
  2. Use DM pairing — send any message to the bot and it will reply with a pairing code. Enter that code via hermes pairing approve simplex <CODE>.

Group chats

By default the adapter ignores group messages — a bot in a group otherwise processes every member's traffic. Opt-in explicitly:

SIMPLEX_GROUP_ALLOWED=12,34          # specific group IDs
# or
SIMPLEX_GROUP_ALLOWED=*              # any group the bot is in

Address groups by prefixing the chat ID with group:, e.g. simplex:group:12 as a cron deliver= target or in a hermes send call.

Sending with hermes send

SimpleX works as a standalone send target — the daemon must be running, but a live gateway is not required for plain text:

hermes send --to simplex:alice "hello"          # DM by contact display name
hermes send --to simplex:group:12 "hello"       # group by numeric ID
hermes send --to simplex "hello"                # SIMPLEX_HOME_CHANNEL

While the gateway is running, the adapter enumerates your contacts and allowed groups into the channel directory (refreshed every 5 minutes), so hermes send --list shows them by name. Before the first gateway run the platform still appears in --list with a "no channels discovered yet" hint — direct targets like the ones above work regardless.

Attachments

The adapter supports native SimpleX attachments in both directions:

  • Inbound — incoming images, voice notes, and files are accepted via the daemon's XFTP flow (rcvFileDescrReady → /freceive → wait for rcvFileComplete) and surfaced as MessageEvent.media_urls with the appropriate MessageType (PHOTO, VOICE, TEXT + document).
  • Outbound — send_image_file, send_voice, send_document, and send_video all use the structured /_send form with filePath, so the receiving SimpleX client renders images inline and plays voice notes inline rather than offering them as downloads.

Agent replies can also embed MEDIA:/path/to/file tags in plain text — the adapter strips the tag from the body and sends the file as either a voice note (audio extensions) or a document.

Using SimpleX with cron jobs

cronjob(
    action="create",
    schedule="every 1h",
    deliver="simplex",          # uses SIMPLEX_HOME_CHANNEL
    prompt="Check for alerts and summarise."
)

Or target a specific contact via the cron job's deliver: field, or from a shell script with the hermes send CLI:

hermes send simplex:<contact-id> "Done!"

Privacy notes

  • SimpleX never reveals phone numbers or email addresses — contacts use opaque IDs
  • The connection between Hermes and the daemon is local WebSocket (ws://127.0.0.1:5225) — no data leaves your machine
  • Messages are end-to-end encrypted by the SimpleX protocol before reaching the daemon

Troubleshooting

"Cannot reach daemon" — Ensure simplex-chat -p 5225 is running and the port matches SIMPLEX_WS_URL.

"websockets not installed" — Run hermes pm repair.

Messages not received — Check that the contact's ID is in SIMPLEX_ALLOWED_USERS or approve them via DM pairing.