- Python 100%
| bridge | ||
| config.json | ||
| LICENSE | ||
| README.md | ||
| requirements.txt | ||
IRC-Matrix_Bridge
A puppeting bridge that connects IRC channels to Matrix rooms. Each IRC user gets a dedicated Matrix puppet account, and each Matrix user gets a dedicated IRC connection — making conversations feel native on both sides.
Features
- Full puppeting — IRC users appear as real Matrix accounts; Matrix users appear with their display name on IRC
- Bidirectional media — images, video, audio, and files are proxied across both protocols
- Reply threading — Matrix reply context is rendered inline on IRC
- Duplicate suppression — fingerprint-based deduplication prevents message echo loops
- Persistent state — sync tokens, nick mappings, display names, and puppet sessions survive restarts (SQLite)
- Idle puppet cleanup — automatically deactivates Matrix accounts for IRC nicks that have been idle too long
- Rate-limit resilience — exponential backoff on Matrix login and sync rate limits
Requirements
- Python 3.11+
- A Matrix homeserver with Synapse admin API access (for puppet provisioning)
- An IRC server
Dependencies
matrix-nio
pydle
aiohttp
python-dotenv
Install with:
pip3 install -r requirements.txt
Configuration
Copy and edit config.json:
{
"matrix": {
"homeserver": "https://matrix.example.com",
"user_id": "@bridge_bot:example.com",
"access_token": "syt_...",
"device_id": null
},
"irc": {
"server": "irc.libera.chat",
"port": 6697,
"use_tls": true,
"server_password": null
},
"bridges": [
{
"matrix_room_id": "!roomid:example.com",
"irc_channel": "#example"
}
],
"puppet": {
"homeserver": "https://matrix.example.com",
"server_name": "example.com",
"admin_token": "syt_admin_...",
"puppet_prefix": "irc_",
"password_seed": "change-me-to-a-long-random-secret",
"device_id": null,
"idle_deactivate_hours": 720
},
"media": {
"server_port": 8087,
"server_url": "http://localhost:8087",
"dir": "media"
}
}
Key configuration fields
| Field | Description |
|---|---|
matrix.access_token |
Access token for the main bridge bot account |
matrix.user_id |
Full Matrix user ID of the bridge bot |
puppet.admin_token |
Synapse admin token used to provision puppet accounts |
puppet.puppet_prefix |
Prefix for puppet account localparts (e.g. irc_ → @irc_alice:example.com) |
puppet.password_seed |
Secret used to deterministically generate puppet passwords — change this |
puppet.idle_deactivate_hours |
Hours of inactivity before a puppet account is deactivated |
media.server_url |
Publicly accessible URL for the local media server (used in IRC links) |
bridges |
List of matrix_room_id ↔ irc_channel pairs to bridge |
Running
# From the project root
python3 -m bridge
Or directly:
python3 bridge/app.py
On first run, the bridge performs a full Matrix sync to catch up with room state. Subsequent runs resume from the saved sync token.
Puppeting
The bridge uses the Synapse admin API to create one Matrix account per IRC nick. These accounts are:
- Created/updated on first message from that nick
- Automatically invited to and joined in the bridged room
- Deactivated after
idle_deactivate_hoursof inactivity - Identified by the
puppet_prefixin their localpart
The main bridge bot account (matrix.user_id) must have permission to invite users to the bridged rooms.
Media Bridging
A lightweight HTTP server (aiohttp) serves downloaded Matrix media files at media.server_url/media/<filename>. This URL is sent to IRC when a Matrix user shares an image, video, audio file, or document.
In the other direction, IRC messages containing direct media links (.jpg, .mp4, .mp3, .pdf, etc.) are fetched and re-uploaded to the Matrix homeserver via the media upload API, then sent as proper Matrix media messages.
The maximum file size in both directions is 10 MiB.
Persistence
State is stored in bridge.db (SQLite, created automatically):
| Table | Contents |
|---|---|
seen_events |
Processed Matrix event IDs (deduplication) |
display_names |
Matrix user ID → IRC nick cache |
event_context |
Event ID → sender + message preview (for reply threading) |
nick_map |
Matrix display name → assigned IRC nick |
puppet_joined |
Tracks which puppets have joined which rooms |
sync_token |
Latest Matrix sync token for resumption |
Limitations
- Requires Synapse with admin API access — other homeserver implementations are not supported
- IRC nicks are truncated and sanitized to 30 characters
- No support for IRC private messages or Matrix direct messages
- Media files over 10 MiB are not bridged
- One IRC connection per Matrix user — high-traffic bridges may open many TCP connections
License
Distributed under the MIT License. See LICENSE for full terms.