#11869: feat: Multi-account Matrix plugin with accountId routing
channel: matrix
stale
Cluster:
Multi-Account Matrix Support
## Multi-Account Matrix Support
Adds support for running multiple Matrix accounts from a single OpenClaw gateway, with per-account message routing.
### Changes
**Core multi-account support** (from earlier commits):
- `channels.matrix.accounts` config section for named accounts (each with own homeserver/accessToken/userId)
- `listMatrixAccountIds()` / `resolveMatrixAccount()` / `mergeMatrixAccountConfig()`
- Per-account credential storage, shared client state, and active client tracking
- Backward compatible: existing single-account configs work unchanged
**Routing fixes** (this commit):
1. **Handler passes accountId to `resolveAgentRoute`** — bindings with `accountId` now match correctly
2. **`accountId` added to Zod room schema** — was being silently stripped during validation
3. **Account-scoped room filtering** — default account handler skips rooms assigned to other accounts
4. **`listConfiguredAccountIds` includes default** — was only returning named accounts from `accounts` map
### Config Example
```json5
{
channels: {
matrix: {
homeserver: "http://...",
accessToken: "...",
userId: "@argos:...",
accounts: {
"poly": {
accessToken: "...",
userId: "@poly:..."
}
},
groups: {
"!roomId:server": {
accountId: "poly",
requireMention: false
}
}
}
},
bindings: [{
agentId: "polymarket",
match: { channel: "matrix", accountId: "poly", peer: { kind: "group", id: "!roomId:server" } }
}]
}
```
### Testing
- 44 existing matrix tests pass
- 19 new multi-account tests added
- Tested with local Synapse: two accounts (argos + poly) syncing simultaneously
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR successfully adds multi-account Matrix support with proper per-account routing. The implementation allows running multiple Matrix accounts from a single gateway, with each account maintaining independent credentials and room assignments.
**Key improvements:**
- Handler now passes `accountId` to `resolveAgentRoute` for correct binding matching
- `accountId` field added to Zod room schema (previously stripped during validation)
- Account-scoped room filtering prevents default account from processing rooms assigned to named accounts
- `listConfiguredAccountIds` now always includes default account for env-var-only configs
- Per-account credential storage in separate directories (`credentials/matrix/<accountId>/`)
- Shared client state properly partitioned by account key
- Active client tracking supports multiple concurrent accounts
**Testing:**
- 19 new multi-account tests added
- All 44 existing tests pass
- Tested with local Synapse running two accounts simultaneously
**Backward compatibility:**
Single-account configs continue to work unchanged - the default account still uses env vars and base-level config fields.
<h3>Confidence Score: 4/5</h3>
- Safe to merge with minor considerations
- The implementation is comprehensive and well-tested. Core routing logic correctly passes accountId through the handler chain, schemas are properly updated, and backward compatibility is maintained. Previous review comments from earlier commits have been addressed. The only considerations are the items already flagged in previous threads (runtime compatibility with toSorted, env-var account detection, and named account validation) which the team can address in follow-ups if needed.
- No files require special attention - the changes are consistent and properly integrated across the codebase
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#13013: feat(matrix): multi account support
by ti · 2026-02-10
90.2%
#21105: feat(matrix): multi-account support
by omnibot1985 · 2026-02-19
89.8%
#23333: fix(matrix): add accountId routing for multi-account message sending 🤖
by BadTurki · 2026-02-22
83.9%
#14852: feat(matrix): add multi-account support
by tfm-neo-ai · 2026-02-12
80.9%
#6517: fix(matrix): pass accountId through outbound chain to resolveMatrix...
by saxyguy81 · 2026-02-01
80.6%
#13057: feat(matrix): add sessionScope=room to route sessions by roomId
by spengrah · 2026-02-10
79.4%
#13451: feat(matrix): add forceRoomRouting to bypass DM detection for allow...
by yamoroc · 2026-02-10
73.7%
#13832: feat(matrix): add sessionScope and thread-scoped inbound sessions
by yamoroc · 2026-02-11
71.9%
#18718: matrix: add pending group history context for room messages
by pharasyte · 2026-02-17
70.7%
#19567: Fix: tighten Slack multi-account event filtering via api_app_id
by TARS-Nolan · 2026-02-17
70.3%