ClaireDocs

Ask Claire

Search the project, not the web.

Answers are grounded in Claire’s published documentation and include the source pages used.

⌘/Ctrl + J opens Ask Claire anywhere in docs.

Matrix bridge reference

Reference for Claire’s Synapse and mautrix bridge integration.

Currentin progressReviewed 2026-08-17View source ↗

Claire bridges every messaging network through Matrix. This is the working reference for the mautrix APIs it depends on; the upstream documentation lives at docs.mau.fi.

Where the bridges sit — The Claire server talks to Synapse, which talks to one mautrix bridge per network, which talks to WhatsApp, Telegram, and Instagram.

Bridge bot commands#

Each bridge has a bot user that accepts commands in a control room — a direct message with the bot.

WhatsApp#

Bot: @whatsappbot:claire.local

CommandEffect
login qrStart the QR code login flow
login phoneStart the phone pairing-code flow
logoutDisconnect WhatsApp
pingCheck connection status
helpList available commands

After a successful login the bridge does three things, in order:

  1. Sends Successfully logged in as +<phone> as an m.notice.
  2. Creates portal rooms for each WhatsApp chat, which takes about a minute.
  3. Backfills the 50 most recent messages per room, configurably.

Telegram#

Bot: @telegrambot:claire.local. login prompts for a phone number and then a verification code; logout and ping behave as above.

Instagram#

Bot: @instagrambot:claire.local, with login-cookie to authenticate. The bridge is the Meta bridge, so it uses the meta_ prefix; set network.mode for Instagram DMs.

Ghost user patterns#

Ghost users represent remote platform contacts inside Matrix. Their IDs follow @<prefix><platform_id>:<server_name>.

PlatformPrefixExample
WhatsAppwhatsapp_@whatsapp_15551234567:claire.local
Telegram_telegram_@_telegram_123456789:claire.local
Instagrammeta_@meta_987654321:claire.local
iMessage_imessage_@_imessage_+15551234567:claire.local

The self ghost user#

Without double puppeting, a user’s own messages arrive from their ghost user rather than from the bot. If the linked WhatsApp number is +15551234567, outgoing messages come from @whatsapp_15551234567:claire.local. The server parses the number out of the login success message and tracks it as the session’s self ghost ID, so isFromMe is set correctly.

Double puppeting#

Enabled in Claire, gated behind ENABLE_DOUBLE_PUPPETING=true in the server environment. With it active, messages a user sends from their phone appear as their actual Matrix account instead of their ghost, the server tracks matrixUserId per session, and locally sent event IDs are tracked to prevent echo loops.

docker/matrix/bridges/<platform>/config.yaml
bridge:
  double_puppet:
    secrets:
      claire.local: "as_token:<bridge_as_token>"

Backfill behaviour#

Backfill is constrained by Matrix itself, and the constraints surprise people, so they are worth stating plainly:

  • Matrix does not support inserting messages into room history.
  • Backfilled messages land at the end of the timeline regardless of their original timestamp.
  • Historical backfill only works in new, empty rooms.
  • WhatsApp uses one-time history-sync blobs sent after device linking.
  • MSC2716, which would have allowed true history insertion, was abandoned.

Appservice registration#

Each bridge needs a registration file referenced from Synapse’s homeserver.yaml.

homeserver.yaml
app_service_config_files:
  - /data/whatsapp-registration.yaml
  - /data/telegram-registration.yaml
  - /data/instagram-registration.yaml
FieldPurpose
as_token / hs_tokenAuthentication between the bridge and Synapse.
username_templateControls the ghost user ID format. Must match GHOST_USER_PREFIXES.
bot_usernameThe bridge bot user ID.

Troubleshooting#

SymptomLikely cause
Bot not respondingAppservice connectivity — check docker logs claire-synapse.
No messages bridgedBridge is not logged in. Send ping in the control room.
Login loopWhatsApp disconnects linked devices after the phone is offline for more than two weeks.
“User not found”Ghost prefix mismatch between the bridge config and types.ts.
Terminal
docker logs claire-mautrix-whatsapp -f
docker logs claire-mautrix-telegram -f
docker logs claire-mautrix-instagram -f
docker logs claire-synapse -f