mautrix-teams uses the standard mautrix bridgev2 config structure plus a small Teams-specific network section.
Use config.example.yaml for a readable starting point. If you need every framework-level default, generate a full config with ./mautrix-teams -e.
There are two layers:
- Framework config: homeserver, appservice, database, encryption, backfill, logging, provisioning, and common bridge behavior.
- Teams config: the
networkblock used by this connector.
That split matters because most knobs are inherited from mautrix, while most Teams behavior is hard-coded in the connector itself.
Teams-specific settings.
client_idRequired: optional Purpose: overrides the OAuth client ID used when extracting Teams MSAL localStorage and refreshing tokens. Default behavior: if empty, the bridge uses the built-in Teams web app client ID. Change this only when Teams login extraction breaks because Microsoft changed the web client ID.
Generic bridge runtime behavior.
Important fields:
-
command_prefixRequired: optional Used for management-room commands in environments that rely on commands. -
permissionsRequired: yes Controls which Matrix users can log in and administer the bridge. -
personal_filtering_spaces,private_chat_portal_meta,cleanup_on_logoutRequired: optional Affect room organization and cleanup behavior, not Teams protocol behavior.
Persistent storage for both bridgev2 state and Teams-specific tables.
-
typeRequired: yes Usesqlite3-fk-walfor local development orpostgresfor shared/long-lived deployments. -
uriRequired: yes SQLite example:file:mautrix-teams.db?_txlock=immediatePostgres example:postgres://user:password@host/mautrix_teams?sslmode=disable
Sensitive values:
- Postgres URIs usually contain credentials.
How the bridge reaches Matrix.
-
addressRequired: yes Base URL the bridge uses to talk to the homeserver. -
domainRequired: yes Matrix server name used for MXIDs and appservice registration. -
softwareRequired: yes Usuallystandard. Usehungryonly when you intentionally target Hungryserv/Beeper-style deployments. -
websocketRequired: optional Leavefalsefor normal homeservers. Enable only when the homeserver side really supports the mautrix websocket transport.
How the homeserver reaches the bridge.
-
addressRequired: yes URL the homeserver uses to reach the bridge listener. -
hostname,portRequired: yes Local bind address for the bridge process. -
idRequired: yes Stable appservice ID. Regenerate the registration if you change it. -
as_token,hs_tokenRequired: yes Shared secrets for homeserver ↔ appservice communication. -
bot.usernameRequired: yes Localpart for the bridge bot.
Sensitive values:
as_tokenhs_token
Matrix connector behavior.
Useful fields:
message_status_eventsdelivery_receiptsmessage_error_noticessync_direct_chat_listfederate_rooms
These tune Matrix-side UX. They do not change Teams protocol support.
Provisioning/API entrypoints for login and management.
-
shared_secretRequired: yes if you use provisioning Protect this carefully. Anyone with it may be able to drive bridge actions. -
debug_endpointsOptional Useful during maintenance, but higher exposure than a locked-down production deployment.
Sensitive values:
shared_secret
History import behavior.
This bridge is polling-based, so keep these values conservative until you understand the load profile on both Matrix and Teams.
End-to-bridge Matrix encryption settings.
This is a mautrix concern, not a Teams protocol concern, but it materially affects operability.
Sensitive values:
pickle_key
Bridge logs.
Default pattern:
- human-readable logs to stdout
- JSON logs to a file such as
./logs/bridge.log
Required for any useful deployment:
database.typedatabase.urihomeserver.addresshomeserver.domainhomeserver.softwareappservice.addressappservice.hostnameappservice.portappservice.idappservice.as_tokenappservice.hs_tokenappservice.bot.usernamebridge.permissions
Usually optional:
network.client_id- most
bridgeUX toggles - most
matrixtoggles backfillpublic_mediadirect_media
Required only in specific setups:
homeserver.websocketfor websocket-capable homeserversprovisioning.shared_secretif you expose provisioningencryption.*values for encrypted-room support
The bridge stores per-user Teams login state in the database, not in config.yaml.
Per-user login metadata includes:
- refresh token
- Skype token
- Graph access token
- token expiry timestamps
- Teams user ID
config.yaml only controls the bridge-wide auth environment:
- Matrix appservice auth via
appservice.as_tokenandappservice.hs_token - optional provisioning auth via
provisioning.shared_secret - optional Teams OAuth client-ID override via
network.client_id
Treat these as secrets:
appservice.as_tokenappservice.hs_tokenprovisioning.shared_secretdouble_puppet.secretsencryption.pickle_key- any database password embedded in
database.uri
Do not commit real values. The example config should stay placeholder-only.
Regenerate registration.yaml after changing:
appservice.idappservice.bot.username- appservice transport details that affect registration semantics
- encryption appservice mode settings
Usually no regeneration is needed after changing:
- logging
- database settings
- most bridge behavior flags
network.client_id