Caricamento in corso...
Caricamento in corso...
Last synced: Today, 22:00
Technical reference for the OpenClaw framework. Real-time synchronization with the official documentation engine.
Use this file to discover all available pages before exploring further.
Matrix is a bundled channel plugin for OpenClaw. It uses the official
matrix-js-sdkCurrent packaged OpenClaw releases ship the Matrix plugin in the box. You do not need to install anything; configuring
channels.matrix.*For older builds or custom installs that exclude Matrix, install a current npm package when one is published:
bashopenclaw plugins install @openclaw/matrix
If npm reports the OpenClaw-owned package as deprecated, use a current packaged OpenClaw build or a local checkout until a newer npm package is published.
From a local checkout:
bashopenclaw plugins install ./path/to/local/matrix-plugin
plugins installopenclaw plugins enable matrixchannels.matrixhomeserveraccessTokenhomeserveruserIdpasswordautoJoinbashopenclaw channels add openclaw configure --section channels
The wizard asks for: homeserver URL, auth method (access token or password), user ID (password auth only), optional device name, whether to enable E2EE, and whether to configure room access and auto-join.
If matching
MATRIX_*openclaw channels resolve --channel matrix "Project Room"openclaw matrix encryption setupToken-based:
json5{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", accessToken: "syt_xxx", dm: { policy: "pairing" }, }, }, }
Password-based (the token is cached after first login):
json5{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", userId: "@bot:example.org", password: "replace-me", // pragma: allowlist secret deviceName: "OpenClaw Gateway", }, }, }
channels.matrix.autoJoinoffOpenClaw cannot tell at invite time whether an invited room is a DM or a group, so all invites — including DM-style invites — go through
autoJoindm.policyautoJoinAllowlist!roomId:server#alias:server*json5{ channels: { matrix: { autoJoin: "allowlist", autoJoinAllowlist: ["!ops:example.org", "#support:example.org"], groups: { "!ops:example.org": { requireMention: true }, }, }, }, }
To accept every invite, use
autoJoin: "always"DM and room allowlists are best populated with stable IDs:
dm.allowFromgroupAllowFromgroups.<room>.users@user:servergroupsautoJoinAllowlist!room:server#alias:serverThe wizard converts a friendly name into a normalized account ID. For example,
Ops Botops-bot-_X2D_ops-prodMATRIX_OPS_X2D_PROD_*Matrix stores cached credentials under
~/.openclaw/credentials/matrix/credentials.jsoncredentials-<account>.jsonWhen cached credentials exist there, OpenClaw treats Matrix as configured even if the access token is not in the config file — that covers setup,
openclaw doctorUsed when the equivalent config key is not set. The default account uses unprefixed names; named accounts use the account ID inserted before the suffix.
| Default account | Named account ( text <ID> |
|---|---|
text MATRIX_HOMESERVER | text MATRIX_<ID>_HOMESERVER |
text MATRIX_ACCESS_TOKEN | text MATRIX_<ID>_ACCESS_TOKEN |
text MATRIX_USER_ID | text MATRIX_<ID>_USER_ID |
text MATRIX_PASSWORD | text MATRIX_<ID>_PASSWORD |
text MATRIX_DEVICE_ID | text MATRIX_<ID>_DEVICE_ID |
text MATRIX_DEVICE_NAME | text MATRIX_<ID>_DEVICE_NAME |
text MATRIX_RECOVERY_KEY | text MATRIX_<ID>_RECOVERY_KEY |
For account
opsMATRIX_OPS_HOMESERVERMATRIX_OPS_ACCESS_TOKENverify backup restoreverify deviceverify bootstrap--recovery-key-stdinMATRIX_HOMESERVER.env.envA practical baseline with DM pairing, room allowlist, and E2EE:
json5{ 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", }, }, }
Matrix reply streaming is opt-in.
streamingblockStreamingjson5{ channels: { matrix: { streaming: "partial", }, }, }
To keep live answer previews but hide interim tool/progress lines, use object form:
json5{ channels: { matrix: { streaming: { mode: "partial", preview: { toolProgress: false, }, }, }, }, }
text streaming | Behavior |
|---|---|
text "off" | Wait for the full reply, send once. text truetext "partial"text falsetext "off" |
text "partial" | Edit one normal text message in place as the model writes the current block. Stock Matrix clients may notify on the first preview, not the final edit. |
text "quiet" | Same as text "partial" |
blockStreamingstreamingtext streaming | text blockStreaming: true | text blockStreaming: false |
|---|---|---|
text "partial"text "quiet" | Live draft for the current block, completed blocks kept as messages | Live draft for the current block, finalized in place |
text "off" | One notifying Matrix message per finished block | One notifying Matrix message for the full reply |
Notes:
streaming.preview.toolProgress: falsestreaming: "off"Matrix native approval prompts are normal
m.room.messagecom.openclaw.approvalWhen an approval prompt is too long for one Matrix event, OpenClaw chunks the visible text and attaches
com.openclaw.approvalstreaming: "quiet"By default, Matrix messages from other configured OpenClaw Matrix accounts are ignored.
Use
allowBotsjson5{ channels: { matrix: { allowBots: "mentions", // true | "mentions" groups: { "!roomid:example.org": { requireMention: true, }, }, }, }, }
allowBots: trueallowBots: "mentions"groups.<room>.allowBotsUse strict room allowlists and mention requirements when enabling bot-to-bot traffic in shared rooms.
In encrypted (E2EE) rooms, outbound image events use
thumbnail_filethumbnail_urlAll
openclaw matrix--verbose--json--account <id>bashopenclaw matrix encryption setup
Bootstraps secret storage and cross-signing, creates a room-key backup if needed, then prints status and next steps. Useful flags:
--recovery-key <key>--force-reset-cross-signingFor a new account, enable E2EE at creation time:
bashopenclaw matrix account add \ --homeserver https://matrix.example.org \ --access-token syt_xxx \ --enable-e2ee
--encryption--enable-e2eeManual config equivalent:
json5{ channels: { matrix: { enabled: true, homeserver: "https://matrix.example.org", accessToken: "syt_xxx", encryption: true, dm: { policy: "pairing" }, }, }, }
bashopenclaw matrix verify status openclaw matrix verify status --include-recovery-key --json
verify status--verboseLocally trustedCross-signing verifiedSigned by ownerVerified by owneryesCross-signing verifiedyes--allow-degraded-local-stateThe recovery key is sensitive — pipe it via stdin instead of passing it on the command line. Set
MATRIX_RECOVERY_KEYMATRIX_<ID>_RECOVERY_KEYbashprintf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify device --recovery-key-stdin
The command reports three states:
Recovery key acceptedBackup usableDevice verified by ownerIt exits non-zero when full identity trust is incomplete, even if the recovery key unlocked backup material. In that case, finish self-verification from another Matrix client:
bashopenclaw matrix verify self
verify selfCross-signing verified: yes--timeout-ms <ms>The literal-key form
openclaw matrix verify device "<recovery-key>"bashopenclaw matrix verify bootstrap
verify bootstrapIf the homeserver requires UIA to upload cross-signing keys, OpenClaw tries no-auth first, then
m.login.dummym.login.passwordchannels.matrix.passwordUseful flags:
--recovery-key-stdinprintf '%s\n' "$MATRIX_RECOVERY_KEY" | …--recovery-key <key>--force-reset-cross-signingbashopenclaw matrix verify backup status printf '%s\n' "$MATRIX_RECOVERY_KEY" | openclaw matrix verify backup restore --recovery-key-stdin
backup statusbackup restore--recovery-key-stdinTo replace a broken backup with a fresh baseline (accepts losing unrecoverable old history; can also recreate secret storage if the current backup secret is unloadable):
bashopenclaw matrix verify backup reset --yes
Add
--rotate-recovery-keybashopenclaw matrix verify list
Lists pending verification requests for the selected account.
bashopenclaw matrix verify request --own-user openclaw matrix verify request --user-id @ops:example.org --device-id ABCDEF
Sends a verification request from this OpenClaw account.
--own-user--user-id--device-id--room-id--own-userFor lower-level lifecycle handling — typically while shadowing inbound requests from another client — these commands act on a specific request
<id>verify listverify request| Command | Purpose |
|---|---|
text openclaw matrix verify accept <id> | Accept an inbound request |
text openclaw matrix verify start <id> | Start the SAS flow |
text openclaw matrix verify sas <id> | Print the SAS emoji or decimals |
text openclaw matrix verify confirm-sas <id> | Confirm that the SAS matches what the other client shows |
text openclaw matrix verify mismatch-sas <id> | Reject the SAS when the emoji or decimals do not match |
text openclaw matrix verify cancel <id> | Cancel; takes optional text --reason <text>text --code <matrix-code> |
acceptstartsasconfirm-sasmismatch-sascancel--user-id--room-idWithout
--account <id>channels.matrix.defaultAccountchannels.matrix.accounts.assistant.encryptionUpdate the Matrix self-profile for the selected account:
bashopenclaw matrix profile set --name "OpenClaw Assistant" openclaw matrix profile set --avatar-url https://cdn.example.org/avatar.png
You can pass both options in one call. Matrix accepts
mxc://http://https://mxc://channels.matrix.avatarUrlMatrix supports native Matrix threads for both automatic replies and message-tool sends. Two independent knobs control behavior:
sessionScopedm.sessionScope"per-user""per-room"Explicit conversation bindings always win over
sessionScopethreadRepliesthreadReplies"off""inbound""always"dm.threadRepliesthreadId/focus/unfocus/agents/session idle/session max-age/acp spawn/focusthreadBindings.spawnSubagentSessions: true/focus/acp spawn --thread hereWhen OpenClaw detects a Matrix DM room colliding with another DM room on the same shared session, it posts a one-time
m.notice/focusdm.sessionScopeMatrix rooms, DMs, and existing Matrix threads can be turned into durable ACP workspaces without changing the chat surface.
Fast operator flow:
/acp spawn codex --bind here--bind here/new/reset/acp closeNotes:
--bind herethreadBindings.spawnAcpSessions/acp spawn --thread auto|hereMatrix inherits global defaults from
session.threadBindingsthreadBindings.enabledthreadBindings.idleHoursthreadBindings.maxAgeHoursthreadBindings.spawnSubagentSessionsthreadBindings.spawnAcpSessionsMatrix thread-bound spawn flags are opt-in:
threadBindings.spawnSubagentSessions: true/focusthreadBindings.spawnAcpSessions: true/acp spawn --thread auto|hereMatrix supports outbound reactions, inbound reaction notifications, and ack reactions.
Outbound reaction tooling is gated by
channels.matrix.actions.reactionsreactreactionsemoji=""remove: trueResolution order (first defined value wins):
| Setting | Order |
|---|---|
text ackReaction | per-account → channel → text messages.ackReaction |
text ackReactionScope | per-account → channel → text messages.ackReactionScopetext "group-mentions" |
text reactionNotifications | per-account → channel → default text "own" |
reactionNotifications: "own"m.reaction"off"m.reactionchannels.matrix.historyLimitInboundHistorymessages.groupChat.historyLimit00InboundHistoryMatrix supports the shared
contextVisibilitycontextVisibility: "all"contextVisibility: "allowlist"contextVisibility: "allowlist_quote"allowlistThis setting affects supplemental context visibility, not whether the inbound message itself can trigger a reply. Trigger authorization still comes from
groupPolicygroupsgroupAllowFromjson5{ channels: { matrix: { dm: { policy: "allowlist", allowFrom: ["@admin:example.org"], threadReplies: "off", }, groupPolicy: "allowlist", groupAllowFrom: ["@admin:example.org"], groups: { "!roomid:example.org": { requireMention: true }, }, }, }, }
To silence DMs entirely while keeping rooms working, set
dm.enabled: falsejson5{ channels: { matrix: { dm: { enabled: false }, groupPolicy: "allowlist", groupAllowFrom: ["@admin:example.org"], }, }, }
See Groups for mention-gating and allowlist behavior.
Pairing example for Matrix DMs:
bashopenclaw pairing list matrix openclaw pairing approve matrix <CODE>
If an unapproved Matrix user keeps messaging you before approval, OpenClaw reuses the same pending pairing code and may send a reminder reply after a short cooldown instead of minting a new code.
See Pairing for the shared DM pairing flow and storage layout.
If direct-message state drifts out of sync, OpenClaw can end up with stale
m.directbashopenclaw matrix direct inspect --user-id @alice:example.org
Repair it:
bashopenclaw matrix direct repair --user-id @alice:example.org
Both commands accept
--account <id>m.directm.directIt does not delete old rooms automatically. It picks the healthy DM and updates the mapping so future Matrix sends, verification notices, and other direct-message flows target the right room.
Matrix can act as a native approval client. Configure under
channels.matrix.execApprovalschannels.matrix.accounts.<account>.execApprovalsenabled"auto"falseapprovers@owner:example.orgchannels.matrix.dm.allowFromtarget"dm""channel""both"agentFiltersessionFilterAuthorization differs slightly between approval kinds:
execApprovals.approversdm.allowFromdm.allowFromBoth kinds share Matrix reaction shortcuts and message updates. Approvers see reaction shortcuts on the primary approval message:
✅❌♾️Fallback slash commands:
/approve <id> allow-once/approve <id> allow-always/approve <id> denyOnly resolved approvers can approve or deny. Channel delivery for exec approvals includes the command text — only enable
channelbothRelated: Exec approvals.
Slash commands (
/new/reset/model/focus/unfocus/agents/session/acp/approve@bot:server /new@mention /commandAuthorization rules still apply: command senders must satisfy the same DM or room allowlist/owner policies as plain messages.
json5{ channels: { matrix: { enabled: true, defaultAccount: "assistant", dm: { policy: "pairing" }, accounts: { assistant: { homeserver: "https://matrix.example.org", accessToken: "syt_assistant_xxx", encryption: true, }, alerts: { homeserver: "https://matrix.example.org", accessToken: "syt_alerts_xxx", dm: { policy: "allowlist", allowFrom: ["@ops:example.org"], threadReplies: "off", }, }, }, }, }, }
Inheritance:
channels.matrixgroups.<room>.accountaccountaccount: "default"Default account selection:
defaultAccountdefaultdefaultAccountdefaultAccount--account <id>channels.matrix.*defaulthomeserveraccessTokenhomeserveruserIdpasswordhomeserveruserIdPromotion:
defaultAccountSee Configuration reference for the shared multi-account pattern.
By default, OpenClaw blocks private/internal Matrix homeservers for SSRF protection unless you explicitly opt in per account.
If your homeserver runs on localhost, a LAN/Tailscale IP, or an internal hostname, enable
network.dangerouslyAllowPrivateNetworkjson5{ channels: { matrix: { homeserver: "http://matrix-synapse:8008", network: { dangerouslyAllowPrivateNetwork: true, }, accessToken: "syt_internal_xxx", }, }, }
CLI setup example:
bashopenclaw matrix account add \ --account ops \ --homeserver http://matrix-synapse:8008 \ --allow-private-network \ --access-token syt_ops_xxx
This opt-in only allows trusted private/internal targets. Public cleartext homeservers such as
http://matrix.example.org:8008https://If your Matrix deployment needs an explicit outbound HTTP(S) proxy, set
channels.matrix.proxyjson5{ channels: { matrix: { homeserver: "https://matrix.example.org", accessToken: "syt_bot_xxx", proxy: "http://127.0.0.1:7890", }, }, }
Named accounts can override the top-level default with
channels.matrix.accounts.<id>.proxyMatrix accepts these target forms anywhere OpenClaw asks you for a room or user target:
@user:serveruser:@user:servermatrix:user:@user:server!room:serverroom:!room:servermatrix:room:!room:server#alias:serverchannel:#alias:servermatrix:channel:#alias:serverMatrix room IDs are case-sensitive. Use the exact room ID casing from Matrix when configuring explicit delivery targets, cron jobs, bindings, or allowlists. OpenClaw keeps internal session keys canonical for storage, so those lowercase keys are not a reliable source for Matrix delivery IDs.
Live directory lookup uses the logged-in Matrix account:
Allowlist-style fields (
groupAllowFromdm.allowFromgroups.<room>.usersenablednamedefaultAccountaccountschannels.matrixhomeserverhttps://matrix.example.orgnetwork.dangerouslyAllowPrivateNetworklocalhostproxyuserId@bot:example.orgaccessTokenpassworddeviceIddeviceNameavatarUrlprofile setinitialSyncLimitencryptionfalsestartupVerification"if-unverified""off"startupVerificationCooldownHours24groupPolicy"open""allowlist""disabled""allowlist"groupAllowFromdm.enabledfalsetruedm.policy"pairing""allowlist""open""disabled"dm.allowFromdm.sessionScope"per-user""per-room"dm.threadReplies"off""inbound""always"allowBotstrue"mentions"allowlistOnlytrue"disabled""open""allowlist""disabled"autoJoin"always""allowlist""off""off"autoJoinAllowlistautoJoin"allowlist"contextVisibility"all""allowlist""allowlist_quote"replyToMode"off""first""all""batched"threadReplies"off""inbound""always"threadBindingsstreaming"off""partial""quiet"{ mode, preview: { toolProgress } }true"partial"false"off"blockStreamingtruemarkdownresponsePrefixtextChunkLimitchunkMode: "length"4000chunkMode"length""newline"historyLimitInboundHistorymessages.groupChat.historyLimit0mediaMaxMbackReactionackReactionScope"group-mentions""group-all""direct""all""none""off"reactionNotifications"own""off"actionsmessagesreactionspinsprofilememberInfochannelInfoverificationgroupsroomsgroups.<room>.accountgroups.<room>.allowBotstrue"mentions"groups.<room>.usersgroups.<room>.toolsgroups.<room>.autoReplytruefalsegroups.<room>.skillsgroups.<room>.systemPromptexecApprovals.enabledexecApprovals.approversdm.allowFromexecApprovals.target"dm""channel""both"execApprovals.agentFilterexecApprovals.sessionFilter© 2024 TaskFlow Mirror
Powered by TaskFlow Sync Engine