Matrix gateway implementation - #1442
Closed
mrbende wants to merge 7 commits into
Closed
Conversation
Implements full Matrix platform support via matrix-nio AsyncClient, closing issue NousResearch#73. Includes adapter, tests, all gateway integration points, CLI setup wizard, env var registration, redaction, toolset, cron, send_message routing, prompt hints, and channel discovery.
|
See also #1225 The other pull request uses matrix-nio SDK for the Matrix Client-Server API, however this pull request has well argued reasons to avoid matrix-nio. |
Contributor
|
Closing — Matrix gateway adapter was merged independently via PR #1683 and is now on main, with a follow-up fix in #1711. This was an incredibly thorough PR — the E2EE design, setup wizard, Python 3.14 compatibility patches, and 93 tests were impressive work. Some of the design decisions (mautrix over matrix-nio, PgCryptoStore on SQLite, ghost device purging) are worth revisiting if we expand E2EE support in the current adapter. Thank you for the detailed contribution @mrbende. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(matrix-gateway): add Matrix protocol platform adapter
Summary
Full Matrix platform adapter for the Hermes gateway. Agents can be deployed as always-on Matrix bots with optional E2EE, cross-signing verification, full media support (inbound and outbound), typing indicators, and a zero-friction setup wizard that handles the entire configuration automatically in one pass.
I took on this PR as part of a self-hosted homelab project running hermes-agents on a private Matrix server. This PR should close issue #73
Files changed
23 files, ~4,650 lines
gateway/platforms/matrix.pyhermes_cli/gateway.pyverify-matrixcommand (+1,000 lines)tests/gateway/test_matrix.pywebsite/docs/user-guide/messaging/matrix.mdhermes_cli/config.pyOPTIONAL_ENV_VARSgateway/config.pyPlatform.MATRIXenum + env var loadinggateway/run.pyhermes_cli/main.pyhermes gateway verify-matrixsubcommand (+109 lines)toolsets.pyhermes-matrixtoolset + added tohermes-gatewaytools/send_message_tool.py_send_matrix()standalone send functiontools/cronjob_tools.py,cron/scheduler.pygateway/channel_directory.pyagent/prompt_builder.pyPLATFORM_HINTS["matrix"]agent/redact.py_MATRIX_ID_REpatternhermes_cli/status.py,hermes_cli/setup.pywebsite/docs/user-guide/messaging/index.mdwebsite/docs/user-guide/security.mdMATRIX_ALLOWED_USERSexampletools/terminal_tool.pyminisweagentimport (pre-existing bug caught during review)ADDING_A_PLATFORM.md checklist — all 16 items
check_matrix_requirements()gateway/config.py)gateway/run.py)platform_env_mapandplatform_allow_all_mapbuild_source()used (no new fields needed)agent/prompt_builder.py)hermes-matrix+ added tohermes-gatewaycompositecron/scheduler.py)_send_matrix()+ platform routingdeliverparam"matrix"in session-based discoveryhermes_cli/status.py)_setup_matrix()with auto-login, E2EE, trust verification_MATRIX_ID_REinagent/redact.pymatrix.md(new),index.md,security.md,README.mdtests/gateway/test_matrix.pyTechnical design
Library: mautrix-python (not matrix-nio)
matrix-nio was evaluated and found unsuitable for production E2EE hermes-agent and gave me too much hell, so mautrix was used:
mautrix-python is the library used by maubot and all production mautrix bridges. It has
PgCryptoStorefor proper persistence and active maintenance.E2EE design (mirrors maubot)
PgCryptoStoreon SQLite (~/.hermes/matrix/crypto.db) — all Olm/Megolm sessions, device keys, and cross-signing keys survive gateway restarts. This is the fundamental fix vs matrix-nio.resolve_trust()guard — cross-signing bootstrap runs once on first start only. All subsequent restarts skip it instantly via the local DB.~/.hermes/.envon first bootstrap so device self-signing works on every restart.content.file.url(notcontent.url) and requiredecrypt_attachmentbefore caching. Both handled.Python 3.14 compatibility
mautrix 0.21.0 has five incompatibilities with Python 3.14.
_patch_mautrix_py314()applies targeted monkey-patches at import time, no-op on Python < 3.14. Two patches fix real mautrix bugs on all Python versions and run unconditionally.Media support
Outbound — all methods use correct base-class parameter names and upload via
/_matrix/media/v3/upload. Supportssend_image,send_image_file,send_animation,send_voice,send_video,send_document. Accepts local paths or existingmxc://URIs.Inbound — mautrix msgtype strings (
"m.image","m.audio","m.video","m.file") compared as strings. Downloads, decrypts if E2EE, caches, and populatesevent.media_urls/event.media_typesfollowing the Telegram adapter pattern exactly. Agent sees files via the standard document context note.Typing indicators
send_typing()→PUT /rooms/{id}/typingwith 20s keepalive (Matrix typing expires at 30s). Clears insend_message(). Same pattern as nanobot's Matrix implementation.Setup wizard (zero manual steps)
hermes gateway setup:Re-configuration: wizard offers to wipe all E2EE state for a clean start.
Known limitations
_send_matrix()tool does not support E2EE — one-shot HTTP client, no sync loop. Messages to encrypted rooms will fail. Documented with warning log. The running gateway handles E2EE correctly; this only affects the standalone tool.SAS verification — implemented via
olm.Sasdirectly (mautrix 0.21.0 lacks built-in SAS). Tested with Element Desktop only.No explicit sync reconnection backoff — mautrix's
client.start()has internal retry but no configurable backoff wrapper.Testing
Tested against
k8s / self-hosted note
If media upload returns
500 Internal server error, themedia_storevolume may be owned by root. Fix:The standard Synapse k8s init container handles this on every pod start, but pre-existing volumes may need a one-time manual fix.
Needs community validation
How to test
Test results
Environment variables
MATRIX_HOMESERVER_URLhttps://matrix.example.orgMATRIX_ACCESS_TOKENsyt_...)MATRIX_USER_ID@bot:example.org)MATRIX_DEVICE_IDMATRIX_ALLOWED_USERSMATRIX_HOME_CHANNELMATRIX_HOME_CHANNEL_NAMEMATRIX_VERIFY_SSLfalsefor self-signed TLS (defaulttrue)MATRIX_E2EEtruefor E2EE (requires deps above)MATRIX_PASSWORDMATRIX_RECOVERY_KEYDependencies
All optional — only needed when
MATRIX_E2EE=true. Installed automatically by the setup wizard.mautrix[e2be]asyncpgPgCryptoStoreaiosqlitebase58libolmBranch:
feat/matrix-gateway| Python 3.14 | Synapse self-hosted | Element Desktop