Skip to main content

xchat

✓ Officialv0.1.0★ 300

X Chat gateway platform: run Hermes as a bot in X's end-to-end encrypted DMs. Messages are decrypted and encrypted locally with X's official Chat XDK, so X only routes ciphertext. Encrypted media, threaded replies, group mention gating and cron delivery.

Open in Hermes Desktop
hermes plugins install xchat

What it adds

Environment variables it needs 1

XCHAT_ACCESS_TOKEN

README

From the reviewed commit 82e9e4b ↗; it updates when the author re-pins.

X Chat (encrypted X DMs) for Hermes Agent

Part of the Hermes Official Plugins, Nous Research's official plugins for Hermes Agent.

X Chat is X's end-to-end encrypted direct-message system. The Hermes adapter connects your agent to a bot X account's DMs: message bodies are encrypted and decrypted locally with the official Chat XDK — X only ever routes ciphertext, and every message is signed so recipients can verify the sender.

Install

From the Hermes plugin catalog:

hermes plugins install xchat

Or straight from this repo (tracks main):

hermes plugins install NousResearch/hermes-official-plugins#xchat

The install asks once before preparing the plugin's Python dependencies: chatxdk (X's official Chat XDK, a native E2EE binding, pinned to 0.4.1) and httpx. Needs Hermes Agent 0.21.5 or newer.

Then run hermes xchat setup for a guided walk-through, or pick X Chat in hermes gateway setup.

Prerequisites

  • An X developer account with an app configured for OAuth 2.0 user context (Developer Console). X Chat endpoints require API access on your developer plan.
  • A user access token for the bot account with scopes: dm.read, dm.write, users.read, tweet.read (add offline.access to receive a refresh token so Hermes can auto-renew the ~2-hour access token, and media.write to send encrypted file/image attachments).

Setup

hermes xchat setup

The wizard:

  1. Stores the OAuth2 access token (and optional refresh token + client id) in ~/.hermes/.env.
  2. Derives the bot account's numeric user id via GET /2/users/me.
  3. Generates the E2EE identity + signing keypairs with the Chat XDK, saves the private-key blob to ~/.hermes/xchat/private_keys.b64 (mode 600), and registers the public keys with the X API.

Key registration is rate limited to a few writes per 24 hours per account. The setup is resume-safe: the key blob and registration payload are persisted before any network call, so an interrupted or rate-limited run resumes the same identity instead of minting a new one.

Check state anytime:

hermes xchat status

Environment variables

Variable Required Description
XCHAT_ACCESS_TOKEN Yes OAuth2 user access token (dm.read, dm.write, users.read, tweet.read)
XCHAT_REFRESH_TOKEN Recommended Refresh token — enables automatic access-token renewal (rotated on every refresh and re-persisted)
XCHAT_CLIENT_ID With refresh X app OAuth2 client id (required for token refresh)
XCHAT_CLIENT_SECRET Optional Only for confidential clients
XCHAT_USER_ID Auto Bot account's numeric user id (derived by setup)
XCHAT_SIGNING_KEY_VERSION Auto Registered public-key version (written by setup)
XCHAT_PRIVATE_KEYS_B64 Optional Key blob override — takes precedence over the blob file. ⚠️ This is the bot's entire E2EE identity: there is no forward secrecy in this protocol, so anyone holding the blob can decrypt all past and future messages. Keep it in ~/.hermes/.env (never commit it, never pass it on a command line)
XCHAT_ALLOWED_USERS Recommended Comma-separated numeric X user ids allowed to talk to the bot
XCHAT_ALLOW_ALL_USERS Optional true allows every sender (dev only)
XCHAT_CONVERSATION_IDS Optional Pin specific conversation ids to poll; omit to auto-discover
XCHAT_POLL_INTERVAL Optional Seconds between event polls (default 10, floor 2)
XCHAT_SEND_READ_RECEIPTS Optional true sends read receipts for processed messages (default false)
XCHAT_REQUIRE_MENTION Optional In group conversations, only respond when a wake word matches (default false)
XCHAT_MENTION_PATTERNS Optional Custom wake-word regexes (JSON list or comma-separated)
XCHAT_HOME_CHANNEL Optional Default conversation/user id for cron delivery
XCHAT_HOME_CHANNEL_NAME Optional Human label for the home channel

How it works

  • Inbound — each poll cycle lists the bot's conversations once (with each one's newest event id) and reads the events endpoint only for conversations that have something newer than the bot's persistent per-conversation cursor (~/.hermes/xchat/cursors.json), so idle conversations cost nothing. For a conversation that already existed when the gateway first started, it batch-decrypts the backlog (decrypt_events) to seed the SDK's verified conversation-key cache without replying to old messages; a conversation someone opens while the gateway is running is answered from its first message; after that every new event (including bursts larger than one page, and messages that arrived while the gateway was down) is processed exactly once. KeyChange events (conversation-key rotations) are verified and folded into the key cache automatically; message edits are treated as new messages.
  • Outbound — replies are encrypted and signed locally (encrypt_message with the session identity), then POSTed as ciphertext. Replies to a specific message use the native threaded-reply event when the target is in the adapter's recent-event cache; inbound threaded replies reach the agent with the quoted message.
  • Media — both directions are fully encrypted. Inbound attachments are downloaded, decrypted with the conversation key for the event's key version, and cached locally so vision/file tools can read them. Outbound MEDIA:<path> files (images, voice notes, videos, documents) are encrypted with the latest conversation key, uploaded through the 3-step chat-media flow, and attached by media_hash_key (requires the media.write scope).
  • Senders — each new sender's public keys are fetched once and pushed into the XDK's signing-key store so their message signatures verify.
  • New conversations — standalone sends (hermes send xchat:<user-id>, cron delivery) to a bare numeric user id perform the conversation-key handshake automatically: both parties' key bindings are verified, a fresh conversation key is wrapped for each participant, and the key change is POSTed before the first message.
  • Identity — user ids are numeric X user ids; conversation ids look like 123-456 (1:1) or g123… (group).

Authorization

By default all senders are denied. Either:

  1. Set XCHAT_ALLOWED_USERS to a comma-separated list of numeric X user ids, or
  2. Use DM pairing — an unknown sender gets a pairing code; approve with hermes pairing approve xchat <CODE>.

Group conversations

Group chats (g… conversation ids) work out of the box. To keep the bot quiet unless addressed:

XCHAT_REQUIRE_MENTION=true

The default wake words are hermes / hermes agent; override with XCHAT_MENTION_PATTERNS. DMs are never gated.

Using X Chat with cron jobs

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

Or target a conversation directly:

hermes send xchat:<conversation-id> "Done!"

Standalone delivery opens an ephemeral E2EE session, seeds the conversation key from the conversation's backlog, encrypts, and sends — no running gateway required.

Limitations

  • Polling latency. Inbound uses REST polling (default 10s). Webhook / activity-stream delivery may come later.
  • Group creation. The bot participates in existing group conversations but does not create new groups or manage membership.
  • Access tier. X Chat API availability depends on your X developer plan; media upload additionally requires the media.write scope.
accent-picker✓ Official★ 300

OKLCH accent colour picker for the Hermes Desktop status bar: drag it and the whole theme retints live, with palette commands to reset to the theme default or copy the current colour. A theme-authoring tool; the colour is scratch state and is never persisted. Desktop-only (desktop/plugin.js inside the plugin SDK surface); no agent tools, hooks, middleware or env vars.

Desktop
blender✓ Official★ 300

Official Blender Lab MCP server over stdio, pinned to upstream v1.0.3, with a Blender workflow skill. Requires Blender 5.1+, its separately installed MCP add-on, Git and uv. First startup downloads Python dependencies; prepare the uv environment before connecting. Disclosure — tools execute arbitrary Python in Blender with your privileges; first start downloads the pinned Blender Lab MCP server and its Python dependencies with uv; at install Hermes looks for Blender in the standard install locations (Windows uninstall registry and Program Files, /Applications and the Steam library on macOS, PATH, flatpak, snap and Steam on Linux) and refuses the install when it is missing. Server discovery does not prove scene readiness.

Tools
claude-subscription-directsdk✓ Official★ 300

Experimental model provider that runs Hermes turns on a Claude Pro/Max subscription through the official Claude Code CLI (the Agent SDK path), so no separate API key or per-token bill. Requires the claude CLI installed and logged in; the plugin checks for it at load, in hermes model, in the pickers and before every request, and refuses cleanly with the install hint when it is missing. Disclosure — every turn is billed against your Claude subscription's Agent SDK allowance, and the provider inherits whatever account claude is logged into.

Models
hermes-memory-wiki✓ Official★ 300

Memory Wiki dashboard tab: browsable subject pages and daily logs derived from local session history, plus a read-only Persistent Memory (MEMORY.md / USER.md) audit panel.

Desktop
hermes-telegram-business✓ Official★ 300

Observe-with-approval Telegram Business Mode (secretary bot): every drafted customer reply needs owner approval before it is sent.

Platforms
homeassistant✓ Official★ 300

Home Assistant gateway platform (state-change events in, persistent notifications and cron notify delivery out) plus the homeassistant toolset (ha_list_entities, ha_get_state, ha_list_services, ha_call_service). Formerly built into Hermes core; existing users are migrated automatically.

Platforms

← Back to the catalog · catalog built Oct 17, 2026