Claude-skill-registry-data matrix-communication
Matrix chat communication. AUTOMATICALLY TRIGGER when user mentions Matrix rooms (#room:server), asks to send messages to chat, or wants to interact with Matrix. Use for sending messages to Matrix rooms on behalf of users via access token authentication.
git clone https://github.com/majiayu000/claude-skill-registry-data
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry-data "$T" && mkdir -p ~/.claude/skills && cp -r "$T/data/matrix-communication" ~/.claude/skills/majiayu000-claude-skill-registry-data-matrix-communication && rm -rf "$T"
data/matrix-communication/SKILL.mdMatrix Communication
Send messages to Matrix chat rooms on behalf of users.
Auto-Trigger
AUTOMATICALLY USE THIS SKILL when you encounter:
- Room references:
,#room:server!roomid:server - Chat requests: "send to matrix", "post in chat", "notify the team"
- Matrix URLs:
,https://matrix.*/https://element.*/ - Setup requests: "configure matrix", "set up matrix skill"
Setup Guide (for Agent)
When user asks to set up Matrix, guide them through these steps:
Step 1: Check if already configured
cat ~/.config/matrix/config.json 2>/dev/null && echo "Config exists" || echo "Not configured"
Step 2: If not configured, ask user for:
- User ID - e.g.,
or@username:matrix.org@username:company.com - Matrix password - for E2EE device creation (not stored, used once)
- Bot prefix (optional) - e.g.,
to mark automated messages🤖
Step 3: Discover homeserver URL
Extract the domain from the user ID and discover the homeserver via
.well-known:
# Extract domain from user ID (e.g., @user:example.com -> example.com) MATRIX_DOMAIN="DOMAIN_FROM_USER_ID" # Discover homeserver URL curl -s "https://${MATRIX_DOMAIN}/.well-known/matrix/client" | python3 -c "import sys,json; print(json.load(sys.stdin)['m.homeserver']['base_url'])"
Example: For
@sebastian.mendel:netresearch.de:
- Domain:
netresearch.de - Discovery URL:
https://netresearch.de/.well-known/matrix/client - Returns homeserver:
https://matrix.netresearch.de
Step 4: Create config file
mkdir -p ~/.config/matrix cat > ~/.config/matrix/config.json << 'EOF' { "homeserver": "DISCOVERED_HOMESERVER_URL", "user_id": "USER_PROVIDED_USER_ID", "bot_prefix": "🤖" } EOF chmod 600 ~/.config/matrix/config.json
Step 5: Set up E2EE device (recommended)
Three ways to provide the password:
Option A: Environment variable (recommended for agents)
MATRIX_PASSWORD="USER_PASSWORD" uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py
Option B: Interactive prompt (recommended for users)
uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py # Script will securely prompt for password
Option C: Command line argument (use with caution)
set +H && uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py "USER_PASSWORD"
This creates a dedicated "Matrix Skill E2EE" device. The password is used once and not stored.
Why environment variable? Avoids shell escaping issues with special characters (
!, $, etc.). The set +H workaround for command line is less reliable.
Step 6: Add access token to config
After E2EE setup, copy the access token to enable non-E2EE scripts:
# Extract access token from E2EE credentials and add to config ACCESS_TOKEN=$(python3 -c "import json; print(json.load(open('$HOME/.local/share/matrix-skill/store/credentials.json'))['access_token'])") # Update config with access token python3 -c " import json config_path = '$HOME/.config/matrix/config.json' with open(config_path) as f: config = json.load(f) config['access_token'] = '$ACCESS_TOKEN' with open(config_path, 'w') as f: json.dump(config, f, indent=2) print('Access token added to config') "
Step 7: Verify setup
uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py --status uv run skills/matrix-communication/scripts/matrix-rooms.py
Step 8: Verify device (IMPORTANT)
⚠️ STRONGLY RECOMMENDED: Verify the new "Matrix Skill E2EE" device to avoid security warnings.
Why verify?
- Other users see ⚠️ warnings when unverified devices send messages
- Some rooms may block messages from unverified devices
- Cross-signing establishes trust chain for your account
- Enables automatic room key sharing from other devices
Agent workflow for real-time emoji display:
The verification script writes emojis to
/tmp/matrix_verification_emojis.txt for agent polling. This enables showing emojis to the user BEFORE they need to confirm in Element.
Step 8a: Clear emoji file and start verification in background
rm -f /tmp/matrix_verification_emojis.txt uv run skills/matrix-communication/scripts/matrix-e2ee-verify.py --timeout 180 > /tmp/verify_log.txt 2>&1 &
Step 8b: Poll for emojis and show to user immediately
# Poll until emoji file appears (check every 1-2 seconds) for i in {1..30}; do if [ -f /tmp/matrix_verification_emojis.txt ]; then cat /tmp/matrix_verification_emojis.txt break fi sleep 1 done
The emojis display like this:
╔══════════════════════════════════════════════════════════╗ ║ 🔐 VERIFICATION EMOJIS - COMPARE NOW! 🔐 ║ ╠══════════════════════════════════════════════════════════╣ ║ 🐱 Cat ║ ║ 🔑 Key ║ ║ 🎸 Guitar ║ ║ ... (7 emojis total) ║ ╚══════════════════════════════════════════════════════════╝
Step 8c: Tell user to confirm in Element
Once emojis are displayed, instruct the user:
- "Compare these emojis with what Element shows"
- "Click 'They match' in Element to complete verification"
Step 8d: Wait for verification to complete
# Check verification result grep -q "VERIFICATION SUCCESSFUL" /tmp/verify_log.txt && echo "✅ Verified!"
Device selection: The script automatically prioritizes:
- Element Desktop/Mobile clients (interactive)
- Web clients (riot/chrome/firefox)
- Named devices
- Backup devices (lowest priority - can't respond interactively)
Use
--request DEVICE_ID to target a specific device.
Notes:
- User confirms emojis in Element, not in the terminal
- After verification, the script automatically fetches room keys
- The emoji file enables real-time display even with buffered command output
Troubleshooting
E2EE setup fails with "Invalid username or password":
If your password contains special characters (
!, $, \, etc.), bash may mangle them:
# WRONG - bash corrupts passwords with special characters uv run .../matrix-e2ee-setup.py "MyPass!word" # CORRECT - use environment variable (recommended) MATRIX_PASSWORD="MyPass!word" uv run .../matrix-e2ee-setup.py # CORRECT - use interactive prompt uv run .../matrix-e2ee-setup.py # Enter password when prompted # ALTERNATIVE - disable history expansion set +H && uv run .../matrix-e2ee-setup.py "MyPass!word"
E2EE setup fails with libolm error:
# Debian/Ubuntu sudo apt install libolm-dev # Fedora sudo dnf install libolm-devel # macOS brew install libolm
Non-E2EE scripts fail with "Config missing required fields: access_token":
After E2EE setup, the access token is stored separately. Copy it to the main config:
# Get token and add to config python3 -c " import json creds = json.load(open('$HOME/.local/share/matrix-skill/store/credentials.json')) config = json.load(open('$HOME/.config/matrix/config.json')) config['access_token'] = creds['access_token'] json.dump(config, open('$HOME/.config/matrix/config.json', 'w'), indent=2) print('Done') "
Config Reference
File:
~/.config/matrix/config.json
| Field | Required | Description |
|---|---|---|
| Yes | Matrix server URL |
| Yes | Full Matrix user ID |
| No | Prefix for messages (e.g., ) |
| No | Auto-created by E2EE setup |
Scripts
All scripts are in the
scripts/ directory. Run with uv run.
⚠️ ALWAYS USE E2EE SCRIPTS
Default to E2EE scripts (
) for all operations. Most Matrix rooms are encrypted. Only fall back to non-E2EE scripts if E2EE fails or user explicitly requests it.*-e2ee.py
| Operation | E2EE Script (preferred) | Non-E2EE Fallback |
|---|---|---|
| Send message | | |
| Read messages | | |
| Edit message | | |
| React | | (same) |
| Redact | | (same) |
| Script | Purpose |
|---|---|
| Send message (E2EE) - USE THIS |
| Read messages (E2EE) - USE THIS |
| Edit message (E2EE) - USE THIS |
| React to a message with emoji |
| Delete/redact a message |
| List joined rooms |
| Resolve room alias to room ID |
| One-time E2EE device setup |
| Device verification (experimental) |
| Request missing keys from other devices |
| Restore keys from server backup |
Room Identification
Scripts support multiple ways to identify rooms:
| Format | Example | Description |
|---|---|---|
| Room name | | Easiest - looked up from joined rooms |
| Room ID | | Direct - from output |
| Room alias | | Resolved via Matrix directory |
Best practice: Use room names for simplicity. The script will find the matching room from your joined rooms list.
# These all work - room name is easiest uv run skills/matrix-communication/scripts/matrix-send.py agent-work "Hello!" uv run skills/matrix-communication/scripts/matrix-send.py '!sZBoTOreI1z0BgHY' "Hello!" uv run skills/matrix-communication/scripts/matrix-send.py '#agent-work:server' "Hello!"
Quick Reference
# Send message by room name (easiest - PREFERRED) uv run skills/matrix-communication/scripts/matrix-send.py agent-work "Hello from Claude!" # Send message by room ID (from matrix-rooms.py output) uv run skills/matrix-communication/scripts/matrix-send.py '!sZBoTOreI1z0BgHY-s2ZC9MV63B1orGFigPXvYMQ22E' "Hello!" # Send message by room alias uv run skills/matrix-communication/scripts/matrix-send.py "#myroom:matrix.org" "Hello!" # Send formatted message (markdown) uv run skills/matrix-communication/scripts/matrix-send.py ops "**Deployment complete** for project X" # List joined rooms (shows name, alias, and ID) uv run skills/matrix-communication/scripts/matrix-rooms.py # Find room ID by name uv run skills/matrix-communication/scripts/matrix-rooms.py --lookup agent-work # Search rooms uv run skills/matrix-communication/scripts/matrix-rooms.py --search ops # Read recent messages (unencrypted only) uv run skills/matrix-communication/scripts/matrix-read.py myroom --limit 10 # Resolve room alias to ID uv run skills/matrix-communication/scripts/matrix-resolve.py "#myroom:matrix.org"
Message Types
Regular Messages (m.text)
Default - use for most communication.
Emote Messages (m.emote)
Like IRC
/me - displays as action. Use --emote flag.
# Appears as: "* username is deploying to production" uv run skills/matrix-communication/scripts/matrix-send.py "#ops:matrix.org" "is deploying to production" --emote
When to use: Status updates, actions, presence indicators.
Thread Replies
Reply in a thread to keep discussions organized. Use
--thread with root event ID.
# Start a thread or reply to existing thread uv run skills/matrix-communication/scripts/matrix-send.py "#dev:matrix.org" "Update: tests passing" --thread '$rootEventId'
When to use: Ongoing updates to a topic, multi-step processes, avoiding main room clutter.
Direct Replies
Reply to a specific message. Use
--reply with event ID.
uv run skills/matrix-communication/scripts/matrix-send.py "#team:matrix.org" "Agreed, let's proceed" --reply '$eventId'
Reactions
Add emoji reactions to messages to indicate status without new messages.
# React with checkmark (task done) uv run skills/matrix-communication/scripts/matrix-react.py "#ops:matrix.org" '$eventId' "✅" # Thumbs up (acknowledged) uv run skills/matrix-communication/scripts/matrix-react.py "#dev:matrix.org" '$eventId' "👍" # Eyes (looking into it) uv run skills/matrix-communication/scripts/matrix-react.py "#support:matrix.org" '$eventId' "👀"
Common Reaction Patterns
| Emoji | Meaning | Use Case |
|---|---|---|
| ✅ | Done/Complete | Mark task as finished |
| 👍 | Acknowledged | Confirm receipt |
| 👀 | Looking into it | Started investigating |
| 🚀 | Deployed/Shipped | Indicate release |
| ⏳ | In progress | Working on it |
| ❌ | Failed/Blocked | Indicate problem |
Workflow example: Send "Going to reboot server" → later add ✅ reaction when complete.
Visual Effects (Element Clients)
Include specific emoji to trigger visual effects in Element/SchildiChat:
| Emoji | Effect | Use Case |
|---|---|---|
| 🎉 🎊 | Confetti | Celebrations, milestones |
| 🎆 | Fireworks | Major achievements |
| ❄️ | Snowfall | Seasonal, cool features |
# Celebrate a release uv run skills/matrix-communication/scripts/matrix-send.py "#team:matrix.org" "🎉 Version 2.0 released!"
Note: Effects only show for Element/SchildiChat users. Other clients see the emoji normally.
Message Formatting
All formatting is automatic - just use markdown syntax.
Basic Formatting
| Syntax | Result | When to Use |
|---|---|---|
| bold | Emphasis, headings, status |
| italic | Secondary emphasis |
| | Commands, file names, variables |
| Corrections, outdated info | |
| linked text | Custom link labels |
Matrix-Specific Features
| Syntax | Result | When to Use |
|---|---|---|
| Clickable mention | Notify specific users |
| Clickable room link | Reference other rooms |
| Blockquote | Quote previous messages |
| Hidden text | Sensitive info, plot spoilers |
| Code block | Multi-line code with syntax highlighting |
Smart Link Shortening
URLs are automatically shortened to readable links:
| URL | Displayed As |
|---|---|
| PROJ-123 |
| owner/repo#42 |
| owner/repo#42 |
| group/proj#42 |
Lists
- Item one - Item two - Item three
When to Use Each Feature
Deployment notifications:
- Use bold for status:
,**Deployed****Failed** - Use lists for changes
- Link to Jira issue URL (auto-shortened)
Code sharing:
- Use
for multi-line code```lang ``` - Use
for single commands`inline`
Team communication:
- Use
to notify specific people@user:server - Use
to reference discussions in other rooms#room:server - Use
when replying to earlier messages> quote
Sensitive information:
- Use
for credentials, secrets in examples||spoiler||
E2EE Support
Which script to use?
| Scenario | Script | Notes |
|---|---|---|
| Unencrypted room | | Fast, no deps |
| E2EE room with "allow unverified" | | Works but not encrypted |
| E2EE room, proper encryption | | Requires libolm + setup |
E2EE Setup (Recommended)
Use a dedicated device - this avoids key sync conflicts with Element:
# One-time setup: create dedicated E2EE device # Option 1: Environment variable (recommended - handles special chars) MATRIX_PASSWORD="YOUR_PASSWORD" uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py # Option 2: Interactive prompt (secure - password not in history) uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py # Now send encrypted messages uv run skills/matrix-communication/scripts/matrix-send-e2ee.py '#room:server' 'Encrypted message' # Check setup status uv run skills/matrix-communication/scripts/matrix-e2ee-setup.py --status
Why dedicated device?
- Clean key state, no conflicts with Element
- Proper cross-signing setup
- Avoids "signature verification failed" errors
⚠️ Access token fallback (not recommended): Using
access_token from config reuses Element's device, which causes key sync issues and verification problems. Only use if password-based setup isn't possible.
E2EE Script Usage
# First run after setup is slow (~5-10s) - syncs keys uv run skills/matrix-communication/scripts/matrix-send-e2ee.py '#encrypted-room:server' 'Secret message' # Subsequent runs faster (uses cached keys) uv run skills/matrix-communication/scripts/matrix-send-e2ee.py '#encrypted-room:server' 'Another message'
Storage locations:
- Device credentials:
~/.local/share/matrix-skill/store/credentials.json - Encryption keys:
~/.local/share/matrix-skill/store/*.db
Device Verification (Recommended)
Device verification marks a device as trusted and enables automatic key sharing from other devices.
# Auto-find Element device and initiate verification uv run skills/matrix-communication/scripts/matrix-e2ee-verify.py --timeout 180 # Target specific device uv run skills/matrix-communication/scripts/matrix-e2ee-verify.py --request DEVICE_ID --timeout 180 # With debug output uv run skills/matrix-communication/scripts/matrix-e2ee-verify.py --debug --timeout 180
Smart device selection: The script automatically prioritizes Element clients (Desktop/Android/iOS) over backup devices that can't respond to verification.
Real-time emoji display: Emojis are written to
/tmp/matrix_verification_emojis.txt so agents can poll and display them immediately while the user confirms in Element.
Why verify?
- Removes ⚠️ "unverified device" warnings for other users
- Enables automatic room key sharing from other devices
- Required for some security-conscious rooms
Reading E2EE Messages
# Read recent encrypted messages uv run skills/matrix-communication/scripts/matrix-read-e2ee.py '#room:server' --limit 10 # JSON output uv run skills/matrix-communication/scripts/matrix-read-e2ee.py '#room:server' --json
Note: Messages sent before your device was created show as
[Unable to decrypt] - this is normal E2EE behavior (new devices can't read old messages without key sharing).
Fetching Missing Keys
New devices can't decrypt old messages by default. After verification, use these methods to get missing keys:
Method 1: Request from Other Devices (Recommended)
After device verification, other devices can forward keys automatically. This works without any passwords or recovery keys:
# Fetch keys for a specific room uv run skills/matrix-communication/scripts/matrix-fetch-keys.py ROOM --sync-time 60 # Example: Fetch keys for IT room with extended wait uv run skills/matrix-communication/scripts/matrix-fetch-keys.py IT --limit 200 --sync-time 120
This script:
- Reads room history to find undecryptable messages
- Requests keys from your other verified devices
- Receives forwarded keys automatically
Requirements:
- Device must be verified (run verification first)
- Other verified devices must be online
- Works best with Element running on another device
Method 2: Restore from Server Backup
If key forwarding doesn't work (no other devices online), restore from backup using your recovery key or passphrase:
# Check backup status uv run skills/matrix-communication/scripts/matrix-key-backup.py --status # Restore using recovery key (looks like: EsTj qRGp YB4C ...) uv run skills/matrix-communication/scripts/matrix-key-backup.py --recovery-key "EsTj qRGp YB4C ..." # Restore using passphrase uv run skills/matrix-communication/scripts/matrix-key-backup.py --passphrase "your recovery passphrase"
Find your recovery key in Element: Settings → Security & Privacy → Secure Backup → "Show Recovery Key"
| Script | Purpose |
|---|---|
| Request keys from other devices (no secrets needed) |
| Restore keys from server backup (needs recovery key) |
Limitations
- Old messages: Can't decrypt without key backup restoration
- First sync: Initial run is slow due to key exchange
- Device trust: Auto-trusts devices (TOFU model)
- Setup required: First use requires user's Matrix password (one-time only)
- Verification: Experimental - cross-signing/room-based verification not fully supported
- Key backup: Requires recovery key/passphrase (stored in Element settings)
Common Patterns
Deployment notification with Jira link
uv run skills/matrix-communication/scripts/matrix-send.py "#ops:matrix.org" \ "**Deployed** to production https://jira.example.com/browse/PROJ-123 - Version: 1.2.3 - Changes: Auth improvements"
Status update with mentions
uv run skills/matrix-communication/scripts/matrix-send.py "#dev:matrix.org" \ "**Done**: API refactoring complete @lead:matrix.org ready for review See #code-review:matrix.org for PR discussion"
Share code snippet
uv run skills/matrix-communication/scripts/matrix-send.py "#dev:matrix.org" \ "Fix for the auth bug: \`\`\`python def validate_token(token): return token.startswith('valid_') \`\`\`"
Quote and respond
uv run skills/matrix-communication/scripts/matrix-send.py "#team:matrix.org" \ "> Should we deploy today? **Yes** - all tests passing. Deploying now."
Check room before sending
# List rooms to find the right one uv run skills/matrix-communication/scripts/matrix-rooms.py | grep -i ops # Then send uv run skills/matrix-communication/scripts/matrix-send.py "#ops-team:matrix.org" "Message here"
Server maintenance with status updates
# 1. Announce (save event ID from output) uv run skills/matrix-communication/scripts/matrix-send.py "#ops:matrix.org" "⏳ Starting server maintenance..." # Output: Event ID: $abc123 # 2. Update status via reaction uv run skills/matrix-communication/scripts/matrix-react.py "#ops:matrix.org" '$abc123' "✅" # 3. Or add thread update uv run skills/matrix-communication/scripts/matrix-send.py "#ops:matrix.org" "Maintenance complete, all services restored" --thread '$abc123'
Celebrate milestone
uv run skills/matrix-communication/scripts/matrix-send.py "#team:matrix.org" "🎉 **Milestone reached!** We hit 1000 users today! Thanks to everyone who contributed."
Error Handling
| Error | Cause | Solution |
|---|---|---|
| Not in room or no permission | Join room first in Element |
| Invalid/expired token | Get new token from Element |
| Room doesn't exist | Check room alias spelling |
| Name lookup failed | Use to list available rooms |
| Ambiguous room name | Use more specific name or room ID from list |
| Alias doesn't exist | Try room name instead of alias |
Bash Quoting
Important: Bash history expansion treats
! specially, which can corrupt messages and passwords.
Best Solution: Disable History Expansion
# MOST RELIABLE - disable history expansion for the command set +H && uv run skills/matrix-communication/scripts/matrix-send.py "#room:server" "Done!"
Alternative: Quote Carefully
# Single quotes - works for simple messages uv run skills/matrix-communication/scripts/matrix-send.py "#room:server" 'Done!' # WRONG - double quotes allow history expansion uv run skills/matrix-communication/scripts/matrix-send.py "#room:server" "Done!" # Results in: Done\!
For Passwords with Special Characters
Use environment variable (most reliable) or interactive prompt:
# BEST - environment variable handles all special characters MATRIX_PASSWORD="MyP@ss!word" uv run .../matrix-e2ee-setup.py # GOOD - interactive prompt (password not in shell history) uv run .../matrix-e2ee-setup.py # Enter password when prompted # ALTERNATIVE - disable history expansion for command line set +H && uv run .../matrix-e2ee-setup.py "MyP@ss!word"
Related
- Matrix Client-Server API
- Matrix API endpointsreferences/api-reference.md