Matrix is an open, decentralized messaging protocol. CoderClaw connects as a Matrix user on any homeserver, so you need a Matrix account for the bot. Once it is logged in, you can DM the bot directly or invite it to rooms (Matrix βgroupsβ). Beeper is a valid client option too, but it requires E2EE to be enabled.
Status: supported via plugin (@vector-im/matrix-bot-sdk). Direct messages, rooms, threads, media, reactions, polls (send + poll-start as text), location, and E2EE (with crypto support).
Matrix ships as a plugin and is not bundled with the core install.
Install via CLI (npm registry):
coderclaw plugins install @coderclaw/matrix
Local checkout (when running from a git repo):
coderclaw plugins install ./extensions/matrix
If you choose Matrix during configure/onboarding and a git checkout is detected, CoderClaw will offer the local install path automatically.
Details: Plugins
coderclaw plugins install @coderclaw/matrixcoderclaw plugins install ./extensions/matrixcurl at your home server:curl --request POST \
--url https://matrix.example.org/_matrix/client/v3/login \
--header 'Content-Type: application/json' \
--data '{
"type": "m.login.password",
"identifier": {
"type": "m.id.user",
"user": "your-user-name"
},
"password": "your-password"
}'
matrix.example.org with your homeserver URL.channels.matrix.userId + channels.matrix.password: CoderClaw calls the same
login endpoint, stores the access token in ~/.coderclaw/credentials/matrix/credentials.json,
and reuses it on next start.MATRIX_HOMESERVER, MATRIX_ACCESS_TOKEN (or MATRIX_USER_ID + MATRIX_PASSWORD)channels.matrix.*/whoami.channels.matrix.userId should be the full Matrix ID (example: @bot:example.org).channels.matrix.encryption: true and verify the device.Minimal config (access token, user ID auto-fetched):
{
channels: {
matrix: {
enabled: true,
homeserver: "https://matrix.example.org",
accessToken: "syt_***",
dm: { policy: "pairing" },
},
},
}
E2EE config (end to end encryption enabled):
{
channels: {
matrix: {
enabled: true,
homeserver: "https://matrix.example.org",
accessToken: "syt_***",
encryption: true,
dm: { policy: "pairing" },
},
},
}
End-to-end encryption is supported via the Rust crypto SDK.
Enable with channels.matrix.encryption: true:
@matrix-org/matrix-sdk-crypto-nodejs-*),
allow build scripts for @matrix-org/matrix-sdk-crypto-nodejs and run
pnpm rebuild @matrix-org/matrix-sdk-crypto-nodejs or fetch the binary with
node node_modules/@matrix-org/matrix-sdk-crypto-nodejs/download-lib.js.Crypto state is stored per account + access token in
~/.coderclaw/matrix/accounts/<account>/<homeserver>__<user>/<token-hash>/crypto/
(SQLite database). Sync state lives alongside it in bot-storage.json.
If the access token (device) changes, a new store is created and the bot must be
re-verified for encrypted rooms.
Device verification: When E2EE is enabled, the bot will request verification from your other sessions on startup. Open Element (or another client) and approve the verification request to establish trust. Once verified, the bot can decrypt messages in encrypted rooms.
Multi-account support: use channels.matrix.accounts with per-account credentials and optional name. See gateway/configuration for the shared pattern.
Each account runs as a separate Matrix user on any homeserver. Per-account config
inherits from the top-level channels.matrix settings and can override any option
(DM policy, groups, encryption, etc.).
{
channels: {
matrix: {
enabled: true,
dm: { policy: "pairing" },
accounts: {
assistant: {
name: "Main assistant",
homeserver: "https://matrix.example.org",
accessToken: "syt_assistant_***",
encryption: true,
},
alerts: {
name: "Alerts bot",
homeserver: "https://matrix.example.org",
accessToken: "syt_alerts_***",
dm: { policy: "allowlist", allowFrom: ["@admin:example.org"] },
},
},
},
},
}
Notes:
MATRIX_HOMESERVER, MATRIX_ACCESS_TOKEN, etc.) only apply to the default account.bindings[].match.accountId to route each account to a different agent.channels.matrix.dm.policy = "pairing". Unknown senders get a pairing code.coderclaw pairing list matrixcoderclaw pairing approve matrix <CODE>channels.matrix.dm.policy="open" plus channels.matrix.dm.allowFrom=["*"].channels.matrix.dm.allowFrom accepts full Matrix user IDs (example: @user:server). The wizard resolves display names to user IDs when directory search finds a single exact match."Alice" or "alice"). They are ambiguous and are ignored for allowlist matching. Use full @user:server IDs.channels.matrix.groupPolicy = "allowlist" (mention-gated). Use channels.defaults.groupPolicy to override the default when unset.channels.matrix.groups (room IDs or aliases; names are resolved to IDs when directory search finds a single exact match):{
channels: {
matrix: {
groupPolicy: "allowlist",
groups: {
"!roomId:example.org": { allow: true },
"#alias:example.org": { allow: true },
},
groupAllowFrom: ["@owner:example.org"],
},
},
}
requireMention: false enables auto-reply in that room.groups."*" can set defaults for mention gating across rooms.groupAllowFrom restricts which senders can trigger the bot in rooms (full Matrix user IDs).users allowlists can further restrict senders inside a specific room (use full Matrix user IDs).channels.matrix.autoJoin and channels.matrix.autoJoinAllowlist.channels.matrix.groupPolicy: "disabled" (or keep an empty allowlist).channels.matrix.rooms (same shape as groups).channels.matrix.threadReplies controls whether replies stay in threads:
off, inbound (default), alwayschannels.matrix.replyToMode controls reply-to metadata when not replying in a thread:
off (default), first, all| Feature | Status |
|---|---|
| Direct messages | β Supported |
| Rooms | β Supported |
| Threads | β Supported |
| Media | β Supported |
| E2EE | β Supported (crypto module required) |
| Reactions | β Supported (send/read via tools) |
| Polls | β Send supported; inbound poll starts are converted to text (responses/ends ignored) |
| Location | β Supported (geo URI; altitude ignored) |
| Native commands | β Supported |
Run this ladder first:
coderclaw status
coderclaw gateway status
coderclaw logs --follow
coderclaw doctor
coderclaw channels status --probe
Then confirm DM pairing state if needed:
coderclaw pairing list matrix
Common failures:
groupPolicy or room allowlist.channels.matrix.dm.policy="pairing".For triage flow: /channels/troubleshooting.
Full configuration: Configuration
Provider options:
channels.matrix.enabled: enable/disable channel startup.channels.matrix.homeserver: homeserver URL.channels.matrix.userId: Matrix user ID (optional with access token).channels.matrix.accessToken: access token.channels.matrix.password: password for login (token stored).channels.matrix.deviceName: device display name.channels.matrix.encryption: enable E2EE (default: false).channels.matrix.initialSyncLimit: initial sync limit.channels.matrix.threadReplies: off | inbound | always (default: inbound).channels.matrix.textChunkLimit: outbound text chunk size (chars).channels.matrix.chunkMode: length (default) or newline to split on blank lines (paragraph boundaries) before length chunking.channels.matrix.dm.policy: pairing | allowlist | open | disabled (default: pairing).channels.matrix.dm.allowFrom: DM allowlist (full Matrix user IDs). open requires "*". The wizard resolves names to IDs when possible.channels.matrix.groupPolicy: allowlist | open | disabled (default: allowlist).channels.matrix.groupAllowFrom: allowlisted senders for group messages (full Matrix user IDs).channels.matrix.allowlistOnly: force allowlist rules for DMs + rooms.channels.matrix.groups: group allowlist + per-room settings map.channels.matrix.rooms: legacy group allowlist/config.channels.matrix.replyToMode: reply-to mode for threads/tags.channels.matrix.mediaMaxMb: inbound/outbound media cap (MB).channels.matrix.autoJoin: invite handling (always | allowlist | off, default: always).channels.matrix.autoJoinAllowlist: allowed room IDs/aliases for auto-join.channels.matrix.accounts: multi-account configuration keyed by account ID (each account inherits top-level settings).channels.matrix.actions: per-action tool gating (reactions/messages/pins/memberInfo/channelInfo).