Channels
How to Connect OpenClaw to Matrix
Browse more in Channels.
All channels guides →This guide walks you through connecting OpenClaw to Matrix so your agents can chat in DMs and rooms on your homeserver. You’ll configure the bundled Matrix channel plugin, wire it up with either an access token or password, and tune auto-join and DM policies.
By the end, your OpenClaw bot will be able to send and receive messages on Matrix, with optional E2EE and streaming previews.
Prerequisites
- ✓An existing Matrix homeserver such as https://matrix.example.org that you can log into.
- ✓A Matrix account for your bot on that homeserver (for example @bot:example.org).
- ✓An OpenClaw gateway installation with access to its config (Matrix is a bundled channel plugin in current OpenClaw releases).
- ✓Either a Matrix access token (for example syt_xxx) or the bot account password so OpenClaw can authenticate.
Steps
- 1
Ensure the Matrix plugin is installed
Matrix ships as a bundled plugin in current OpenClaw releases, so you usually don’t need to install anything. If you’re on an older or custom build that excluded Matrix, install the plugin so the gateway can speak Matrix.
bashopenclaw plugins install @openclaw/matrix - 2
Optionally install Matrix from a local checkout
If you’re developing or vendoring the Matrix plugin locally, install it from your checkout instead of npm. This keeps your gateway using the exact plugin code in your repo.
bashopenclaw plugins install ./path/to/local/matrix-plugin - 3
Run the interactive Matrix channel setup
Use the OpenClaw channel wizard to add Matrix and capture the homeserver, auth method, and DM/room policies. The wizard also offers to keep auth in environment variables when it detects the relevant MATRIX_* vars, which is useful for production deployments.
bashopenclaw channels add openclaw configure --section channels - 4
Configure Matrix with a minimal token-based setup
If you already have a Matrix access token, wire it directly into your OpenClaw config. This minimal config enables the Matrix channel, points at your homeserver, and uses DM pairing so new users must be approved before full access.
json{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", accessToken: "syt_xxx", dm: { policy: "pairing" }, }, }, } - 5
Configure Matrix with password-based login instead of a token
If you prefer to log in with a Matrix user ID and password, use the password-based setup. OpenClaw caches the access token after login so it doesn’t need to re-authenticate on every start.
json{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", userId: "@bot:example.org", password: "replace-me", // pragma: allowlist secret deviceName: "OpenClaw Gateway", }, }, } - 6
Set Matrix auth via environment variables when needed
For production or containerized deployments, keep credentials out of the main config and use MATRIX_* environment variables instead. OpenClaw reads these when the corresponding config keys are unset, and the wizard can detect them and offer an env-based shortcut.
textMATRIX_HOMESERVER MATRIX_ACCESS_TOKEN MATRIX_USER_ID MATRIX_PASSWORD MATRIX_DEVICE_ID MATRIX_DEVICE_NAME - 7
Enable auto-join behavior for Matrix invites
By default the bot ignores new invites, which makes it look broken when you invite it to a room or DM. Decide whether you want it to join all invites or only specific rooms using an allowlist.
json{ channels: { matrix: { autoJoin: "allowlist", autoJoinAllowlist: ["!ops:example.org", "#support:example.org"], groups: { "!ops:example.org": { requireMention: true, }, }, }, }, } - 8
Join every Matrix invite when appropriate
If you’re running in a controlled environment and want the bot to accept all invites, switch autoJoin to always. This is convenient for testing but less safe on public homeservers.
json{ channels: { matrix: { autoJoin: "always", }, }, } - 9
Enable E2EE for Matrix rooms and DMs
Turn on encryption when you want OpenClaw to participate in end-to-end encrypted rooms. The Matrix plugin automatically detects E2EE state and handles encrypted thumbnails and attachments.
json{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", accessToken: "syt_xxx", encryption: true, dm: { policy: "pairing" }, }, }, } - 10
Use a practical baseline Matrix configuration
Once basic connectivity works, tighten DM and room policies and enable streaming previews. This baseline config pairs DMs, restricts groups via allowlists, and turns on partial streaming so users see live drafts.
json{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", accessToken: "syt_xxx", encryption: true, dm: { policy: "pairing", sessionScope: "per-room", threadReplies: "off", }, groupPolicy: "allowlist", groupAllowFrom: ["@admin:example.org"], groups: { "!roomid:example.org": { requireMention: true, }, }, autoJoin: "allowlist", autoJoinAllowlist: ["!roomid:example.org"], threadReplies: "inbound", replyToMode: "off", streaming: "partial", }, }, } - 11
Enable streaming previews for Matrix replies
If you want users to see the assistant typing, enable streaming previews. Partial streaming edits a single preview message in place while the model generates text, which matches how many Matrix clients surface notifications.
json{ channels: { matrix: { streaming: "partial", }, }, } - 12
Configure quiet streaming with self-hosted push rules (optional)
On self-hosted homeservers you can use quiet previews that only notify when the reply is finalized. This requires both `streaming: "quiet"` in OpenClaw and a per-user push rule that matches finalized preview edits from your bot.
json{ channels: { matrix: { streaming: "quiet", }, }, } - 13
Create a Matrix push rule for finalized preview notifications
Use the Matrix Client-Server API with the recipient’s access token to create an override push rule that fires when OpenClaw finalizes a preview. This makes quiet previews behave like normal notifications only when the reply is done.
bashcurl -sS -X PUT \ "https://matrix.example.org/_matrix/client/v3/pushrules/global/override/openclaw-finalized-preview-botname" \ -H "Authorization: Bearer $USER_ACCESS_TOKEN" \ -H "Content-Type: application/json" \ --data '{ "conditions": [ { "kind": "event_match", "key": "type", "pattern": "m.room.message" }, { "kind": "event_property_is", "key": "content.m\\.relates_to.rel_type", "value": "m.replace" }, { "kind": "event_property_is", "key": "content.com\\.openclaw\\.finalized_preview", "value": true }, { "kind": "event_match", "key": "sender", "pattern": "@bot:example.org" } ], "actions": [ "notify", { "set_tweak": "sound", "value": "default" }, { "set_tweak": "highlight", "value": false } ] }' - 14
Restart the OpenClaw gateway and invite the bot
After updating your config, restart the gateway so the Matrix plugin reconnects with the new settings. Then start a DM with the bot or invite it to a room that matches your autoJoin policy so you can verify end-to-end behavior.
Configuration
| Option | Description | Example |
|---|---|---|
| channels.matrix.enabled | Turns the Matrix channel on or off for your OpenClaw gateway. | |
| channels.matrix.homeserver | The Matrix homeserver base URL that the bot connects to. | https://matrix.example.org |
| channels.matrix.accessToken | Access token for token-based Matrix authentication. | syt_xxx |
| channels.matrix.userId | Full Matrix user ID for password-based login. | @bot:example.org |
| channels.matrix.password | Password used when logging in with userId instead of an access token. | replace-me |
| channels.matrix.deviceName | Human-readable device display name for the Matrix login session. | OpenClaw Gateway |
| channels.matrix.encryption | Enables end-to-end encryption support for Matrix rooms and DMs. | |
| channels.matrix.dm.policy | Controls how Matrix DMs are authorized, such as pairing or allowlist. | pairing |
| channels.matrix.dm.allowFrom | Allowlist of Matrix user IDs that can DM the bot when DM policy is allowlist. | |
| channels.matrix.groupPolicy | Room policy mode for Matrix groups: open, allowlist, or disabled. | allowlist |
| channels.matrix.groupAllowFrom | Allowlist of Matrix user IDs whose messages can trigger replies in rooms. | |
| channels.matrix.groups."!roomid:example.org".requireMention | When true, the bot only replies in that room when explicitly mentioned. | |
| channels.matrix.autoJoin | Controls whether the bot auto-joins Matrix invites: always, allowlist, or off. | allowlist |
| channels.matrix.autoJoinAllowlist | List of room IDs or aliases the bot is allowed to auto-join when autoJoin is allowlist. | |
| channels.matrix.streaming | Reply streaming mode for Matrix messages: off, partial, quiet, true, or false. | partial |
| channels.matrix.blockStreaming | When true, sends separate progress messages for completed assistant blocks while streaming is active. | |
| channels.matrix.historyLimit | Maximum number of recent room messages to include as inbound history context. | |
| channels.matrix.contextVisibility | Controls which senders’ supplemental context is visible to the agent. | allowlist |
| channels.matrix.allowBots | Controls whether messages from other configured Matrix bot accounts are accepted. | mentions |
| channels.matrix.execApprovals.enabled | Enables or disables Matrix as a native exec approval client. | auto |
| channels.matrix.execApprovals.approvers | Matrix user IDs allowed to approve exec requests. | |
| channels.matrix.execApprovals.target | Where to send Matrix approval prompts: dm, channel, or both. | dm |
| channels.matrix.defaultAccount | Preferred Matrix account ID when multiple accounts are configured. | assistant |
| channels.matrix.accounts.assistant.homeserver | Homeserver URL for the named assistant Matrix account. | https://matrix.example.org |
| channels.matrix.accounts.assistant.accessToken | Access token for the assistant Matrix account. | syt_assistant_xxx |
| channels.matrix.network.dangerouslyAllowPrivateNetwork | Allows this Matrix account to connect to private or LAN homeservers. | |
| channels.matrix.proxy | HTTP(S) proxy URL used for all Matrix traffic from this account. | http://127.0.0.1:7890 |
| MATRIX_HOMESERVER | Environment variable equivalent for channels.matrix.homeserver when the config key is unset. | https://matrix.example.org |
| MATRIX_ACCESS_TOKEN | Environment variable equivalent for channels.matrix.accessToken when the config key is unset. | syt_xxx |
| MATRIX_USER_ID | Environment variable equivalent for channels.matrix.userId when the config key is unset. | @bot:example.org |
| MATRIX_PASSWORD | Environment variable equivalent for channels.matrix.password when the config key is unset. | REDACTED |
| MATRIX_DEVICE_ID | Environment variable equivalent for channels.matrix.deviceId when the config key is unset. | DEVICEID123 |
| MATRIX_DEVICE_NAME | Environment variable equivalent for channels.matrix.deviceName when the config key is unset. | OpenClaw Gateway |
| MATRIX_OPS_HOMESERVER | Account-scoped homeserver env var for the ops Matrix account. | https://matrix.example.org |
| MATRIX_OPS_ACCESS_TOKEN | Account-scoped access token env var for the ops Matrix account. | syt_ops_xxx |
| MATRIX_OPS_X2D_BOT_HOMESERVER | Escaped account-scoped homeserver env var for the ops-bot Matrix account. | https://matrix.example.org |
| MATRIX_OPS_X2D_BOT_ACCESS_TOKEN | Escaped account-scoped access token env var for the ops-bot Matrix account. | syt_ops_bot_xxx |
Troubleshooting
The bot never joins new Matrix rooms or DMs when invited.
autoJoin` is `off`, so the bot ignores invites. Set `autoJoin: "allowlist"` with an `autoJoinAllowlist` of room IDs/aliases or `autoJoin: "always"` in your Matrix config so it can join new rooms.
{
channels: {
matrix: {
autoJoin: "always",
},
},
}
Invites are accepted but the bot never replies in a Matrix room.
When you use allowlists and mention gating, the bot only responds if the sender and room pass those checks and `requireMention` is satisfied. requireMention` are set so your test user is allowed and that you mention the bot when required.
{
channels: {
matrix: {
groupPolicy: "allowlist",
groupAllowFrom: ["@admin:example.org"],
groups: {
"!roomid:example.org": {
requireMention: true,
},
},
},
},
}
Encrypted Matrix rooms show up but messages fail to decrypt or send correctly.
The Matrix account may not be fully verified or encryption may be disabled. Enable `encryption: true` in your Matrix config and run the verification commands like `openclaw matrix verify status` and `openclaw matrix verify bootstrap` to bootstrap cross-signing and backup state.
openclaw matrix verify status
openclaw matrix verify bootstrap
openclaw matrix verify backup status
Quiet streaming previews never trigger push notifications for finalized replies.
Quiet mode requires both `streaming: "quiet"` in OpenClaw and a per-user override push rule that matches finalized preview edits. Use the recipient’s access token and create the `openclaw-finalized-preview-botname` rule via the Matrix pushrules API so the final in-place edit notifies.
curl -sS -X PUT \
"https://matrix.example.org/_matrix/client/v3/pushrules/global/override/openclaw-finalized-preview-botname" \
-H "Authorization: Bearer $USER_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
--data '{
"conditions": [
{ "kind": "event_match", "key": "type", "pattern": "m.room.message" },
{
"kind": "event_property_is",
"key": "content.m\\.relates_to.rel_type",
"value": "m.replace"
},
{
"kind": "event_property_is",
"key": "content.com\\.openclaw\\.finalized_preview",
"value": true
},
{ "kind": "event_match", "key": "sender", "pattern": "@bot:example.org" }
],
"actions": [
"notify",
{ "set_tweak": "sound", "value": "default" },
{ "set_tweak": "highlight", "value": false }
]
}'
DMs route to an old or wrong Matrix room for a user.
direct` mappings pointing at an old solo room. Inspect the current mapping with `openclaw matrix direct inspect --user-id` and repair it with `openclaw matrix direct repair --user-id` so new sends and verification notices target the correct DM.
openclaw matrix direct inspect --user-id @alice:example.org
openclaw matrix direct repair --user-id @alice:example.org
Frequently asked questions
Powered by Mem0
Add persistent memory to OpenClaw
Official Mem0 plugin for OpenClaw keeps context across chats and tools. Smaller prompts, lower cost, better continuity for your agents.