Skip to content

netresearch/matrix-communication

v3.1.8(MIT AND CC-BY-SA-4.0)

Agentic Skills for Matrix: client-side chat (matrix-communication), Synapse homeserver administration (matrix-administration), and structured announcement composition (matrix-announcement). Works with any Matrix/Synapse homeserver.

Matrix Skill

Agentic Skills for Matrix, distributed as a Claude Code plugin. Three skills ship in this repo:

SkillPurposeAPI surface
matrix-communicationSend / read / edit / react in chat rooms on behalf of a regular user, with full E2EE support, and follow a room live through a daemonMatrix Client-Server API
matrix-administrationOperate a Synapse homeserver — snapshot rooms, rate room health, render a Graphviz map, force-join, promote, harden, deactivate, search historySynapse Admin API
matrix-announcementCompose scannable, structured Matrix announcements — release notes, digests, heads-ups, postmortems. HTML subset, type-tag system, glyph rules, and HTML-card-to-PNG templates.Content guidance only — pairs with matrix-communication

The three skills are independent — you can install the plugin and use any combination. matrix-communication and matrix-administration share ~/.config/matrix/config.json. matrix-announcement has no runtime; it's reference material the agent reads while composing messages.

What is an Agentic Skill? Platform-agnostic instructions and tools that AI coding agents can use. This skill is packaged as a Claude Code plugin but follows the open Agentic Skills specification.

matrix-communication — Features

Follow a room while you work. matrix-watchd.py holds the E2EE store, syncs, decrypts, and appends every event of a watched room to a per-room JSONL log. matrix-watch.py follows that log without opening the store, so any number of readers run at once — an agent can stay current with a room, post its status and answer, without a second process ever touching the encryption state.

  • Send messages to any joined Matrix room
  • Rich formatting — bold, italic, code, strikethrough, spoilers, lists, blockquotes
  • Real mentions — --mention '@user:server' sets m.mentions, which is what notifies a client, and renders that name in your text as a pill; a plain @name without --mention does neither
  • Smart link shortening — Jira, GitHub, GitLab URLs become readable links
  • Room links — #room:server becomes a clickable room link
  • Code blocks — syntax-highlighted multi-line code
  • Emotes — /me style action messages (--emote)
  • Thread replies — keep discussions organized (--thread)
  • Reactions — add emoji reactions to messages
  • Edit and redact — modify or delete messages you sent
  • Visual effects — confetti, fireworks, snowfall (Element clients)
  • List rooms to find the right destination
  • Read messages — both unencrypted and E2EE decryption
  • Bot prefix — optional 🤖 prefix for automated messages
  • Device verification — SAS emoji verification for E2EE
  • One writer per store — every path that opens the E2EE store takes an exclusive lock, so two processes cannot corrupt it

Installation

Marketplace (Recommended)

Add the Netresearch marketplace once, then browse and install skills:

# Claude Code
/plugin marketplace add netresearch/claude-code-marketplace
/plugin install matrix-communication@netresearch-claude-code-marketplace

Without a marketplace

Since Claude Code 2.1.157 a plugin directory under your personal skills directory loads on its own, including the commands this repo ships:

mkdir -p ~/.claude/skills
git clone https://github.com/netresearch/matrix-skill.git \
  ~/.claude/skills/matrix-communication

It loads as matrix-communication@skills-dir on the next session. Update with git -C ~/.claude/skills/matrix-communication pull and start a new session; remove it by deleting the directory. This route has no claude plugin update.

npx (skills.sh)

Install with any Agent Skills-compatible agent:

npx skills add https://github.com/netresearch/matrix-skill --skill matrix-communication

Limitation: npx skills installs SKILL.md-based skills only. This repo also ships commands, which it does not install — use the marketplace or the skills directory for those.

Download Release

Download the latest release and extract to your agent's skills directory.

Git Clone

git clone https://github.com/netresearch/matrix-skill.git

Composer (PHP Projects)

composer require netresearch/matrix-skill

Requires netresearch/composer-agent-skill-plugin.

npm (Node Projects)

npm install --save-dev \
  @netresearch/agent-skill-coordinator \
  github:netresearch/matrix-skill

Requires @netresearch/agent-skill-coordinator, which discovers the skill in node_modules and registers it in AGENTS.md via a postinstall hook. For pnpm, also allowlist the coordinator's postinstall:

{
  "pnpm": {
    "onlyBuiltDependencies": ["@netresearch/agent-skill-coordinator"]
  }
}

Prerequisites

For E2EE support (most Matrix rooms), install libolm:

sudo apt install libolm-dev    # Debian/Ubuntu
sudo dnf install libolm-devel  # Fedora
brew install libolm            # macOS

Usage

Paths are shortened to $C below:

C=skills/matrix-communication/scripts

The *-e2ee.py scripts are the ones to use. Most Matrix rooms are encrypted, and the non-E2EE variants cannot read or write in them. Prepend set +H to any command whose arguments contain !, or bash history expansion eats it.

Send a Message

set +H && uv run $C/matrix-send-e2ee.py "#myroom:matrix.org" "Deployment complete"
set +H && uv run $C/matrix-send-e2ee.py "!abc123:matrix.org" "**Build passed** for abc123"

# Notify someone. --mention is what actually reaches them.
set +H && uv run $C/matrix-send-e2ee.py "#dev:matrix.org" \
  "alex, schaust du drauf?" --mention '@alex:matrix.org'

Follow a Room

# Add rooms to watch_rooms in ~/.config/matrix/config.json, then:
uv run $C/matrix-watchd.py --start
uv run $C/matrix-watchd.py --status

# One line per event on stdout, for a human or an agent's monitor
uv run $C/matrix-watch.py "#myroom:matrix.org"

# What arrived since this reader last looked, then exit
uv run $C/matrix-watch.py "#myroom:matrix.org" --once

While the daemon runs it owns the store; send, react, redact and edit route through it automatically. With no daemon they open the store themselves. Nothing changes at the call site either way.

List Joined Rooms

uv run $C/matrix-rooms.py
uv run $C/matrix-rooms.py --search ops

Read Messages

uv run $C/matrix-read-e2ee.py "#myroom:matrix.org" --limit 10
uv run $C/matrix-read-e2ee.py "#myroom:matrix.org" --limit 50 --json

Resolve Room Alias

uv run $C/matrix-resolve.py "#myroom:matrix.org"

Check the Setup

python3 $C/matrix-doctor.py          # verifies every credential against the homeserver

E2EE Support

matrix-e2ee-setup.py creates a dedicated "Matrix Skill E2EE" device that runs alongside your Element client. It logs in once with your password, which is used and not stored.

ScriptPurpose
matrix-send-e2ee.pySend encrypted messages
matrix-read-e2ee.pyRead and decrypt messages
matrix-edit-e2ee.pyEdit a message you sent
matrix-download-e2ee.pyDownload and decrypt attachments
matrix-e2ee-setup.pyCreate or remove the agent's device
matrix-e2ee-verify.pySAS emoji verification
matrix-fetch-keys.pyRequest missing room keys from your other devices
matrix-key-backup.pyRestore room keys from the server-side backup
matrix-watchd.pyThe daemon that owns the store and follows rooms

First run takes ~2–5 s for the initial key sync; later runs are faster.

Never reuse a running client's access token

Not from Element, Element X, FluffyChat or a browser session. A token carries a device_id, and E2EE state is per device: two clients on one device cannot read each other's messages, and the one that breaks is the client you use — it starts showing [Unable to decrypt] for its own messages. Nothing fails at the moment you paste it.

Earlier versions of this documentation offered that as a fallback "if password-based setup isn't possible". That advice was wrong and is retracted. No password means no E2EE, and that is the answer.

Verification

C=skills/matrix-communication/scripts

# You start it, aimed at one of your own devices
uv run $C/matrix-e2ee-verify.py --list                      # find the device id
uv run $C/matrix-e2ee-verify.py --request DEVICE --timeout 300

# Or Element starts it and this side waits — needs --listen
uv run $C/matrix-e2ee-verify.py --listen --timeout 300

Without --request and without --listen the script picks a device itself, which is rarely the one you are sitting in front of.

Use Element Desktop or Element Android. Element X has an incompatible verification flow.

The matrix-nio pin

The scripts pin matrix-nio[e2e]<0.26. 0.26 sends the SAS commitment in a format Element rejects, so no verification completes (matrix-nio#570), and the two releases write incompatible store formats — opening one with the other fails as BAD_ACCOUNT_KEY, which names a key that is not the problem.

Moving the pin is a migration, not a version bump. The store cannot be converted:

uv run $C/matrix-e2ee-setup.py --logout && uv run $C/matrix-e2ee-setup.py
uv run $C/matrix-key-backup.py --import-keys
uv run $C/matrix-e2ee-verify.py --request DEVICE

matrix-administration — Features

Synapse homeserver administration via the Synapse Admin API. Stdlib-only Python (no E2EE deps required). Works against any Synapse 1.x server.

  • Paginated room snapshot (synapse-fetch-rooms.py → rooms.json)
  • Health rating with EN+DE phrasing — public, unencrypted, orphaned-from-spaces
  • Colour-coded Graphviz SVG of the entire room/space tree
  • Force-join, promote-admin, link-room-to-space
  • One-shot hardening pipeline: add to space + restrict joins + enable encryption + restore power levels
  • Destructive user deactivation with optional GDPR --erase
  • Inspection: list user's admin/membership rooms, replay join/leave timelines, search unencrypted history, find biggest rooms by DB size

Quick start:

# Snapshot all rooms (the admin token comes from ~/.config/matrix/config.json)
python3 skills/matrix-administration/scripts/synapse-fetch-rooms.py

# Rate them in German, treating !home:example.com as our home space
python3 skills/matrix-administration/scripts/synapse-rate-rooms.py \
    --language de --space '!home:example.com'

# Render a Graphviz SVG (requires the `dot` binary)
python3 skills/matrix-administration/scripts/synapse-graph.py --space '!home:example.com'

Full reference and safety guide live in skills/matrix-administration/.

matrix-announcement — Features

Content-design guidance for any agent-authored Matrix room post longer than a single line — release notes, version bumps, weekly digests, breaking-change heads-ups, postmortems, RFCs, multi-skill pipeline summaries.

  • Five rules — one headline, formatted_body always, lists beat paragraphs, code in <pre><code>, layout-heavy → render to PNG
  • Type-tag system — Release / Patch / Heads-up / Digest / Postmortem / RFC / New skill. Pick one; never stack.
  • Glyph rules — one prefix glyph max, no rockets (🚀), no party emoji (🎉), no multi-emoji ladders
  • m.text vs m.notice — m.notice for unattended automation (bots can't auto-reply, prevents loops)
  • Three rendered HTML card templates — release-card.html (1200×630), weekly-digest.html (1200×1500), comparison.html (1200×900) — render headlessly with Chromium and post as m.image
  • Seven formatted_body skeletons — drop-in templates for each type tag
  • Visual gallery at skills/matrix-announcement/references/gallery.html — preview every rule, all five worked examples, and the three card templates side-by-side
# Open the live preview gallery
xdg-open skills/matrix-announcement/references/gallery.html

# Render a release card to PNG
chromium --headless=new --hide-scrollbars --window-size=1200,630 \
  --screenshot=card.png \
  "file://$(pwd)/skills/matrix-announcement/references/templates/release-card.html"

Full reference lives in skills/matrix-announcement/.

Structure

matrix-skill/
├── .claude-plugin/
│   └── plugin.json              # Plugin manifest (lists all three skills)
├── skills/
│   ├── matrix-communication/    # Client-Server API, E2EE chat
│   │   ├── SKILL.md
│   │   ├── scripts/
│   │   │   ├── _lib/                    # stdlib-only shared helpers
│   │   │   ├── matrix-create-room.py    # Create a room
│   │   │   ├── matrix-doctor.py         # Health check (python3, not uv run)
│   │   │   ├── matrix-download-e2ee.py  # Download attachments (E2EE)
│   │   │   ├── matrix-e2ee-setup.py     # Create or remove the agent device
│   │   │   ├── matrix-e2ee-verify.py    # SAS emoji verification
│   │   │   ├── matrix-edit-e2ee.py      # Edit (E2EE) — USE THIS
│   │   │   ├── matrix-edit.py           # Edit (non-E2EE fallback)
│   │   │   ├── matrix-fetch-keys.py     # Request missing room keys
│   │   │   ├── matrix-invite.py         # Invite a user
│   │   │   ├── matrix-key-backup.py     # Restore keys from server backup
│   │   │   ├── matrix-power-level.py    # Read or set power levels
│   │   │   ├── matrix-react.py          # React to messages
│   │   │   ├── matrix-read-e2ee.py      # Read (E2EE) — USE THIS
│   │   │   ├── matrix-read.py           # Read (non-E2EE fallback)
│   │   │   ├── matrix-redact.py         # Delete messages
│   │   │   ├── matrix-resolve.py        # Resolve aliases
│   │   │   ├── matrix-rooms.py          # List rooms
│   │   │   ├── matrix-send-e2ee.py      # Send (E2EE) — USE THIS
│   │   │   ├── matrix-send.py           # Send (non-E2EE fallback)
│   │   │   ├── matrix-watch.py          # Follow a room's event log
│   │   │   └── matrix-watchd.py         # Daemon: owns the store, follows rooms
│   │   └── references/
│   ├── matrix-administration/  # Synapse Admin API, server ops
│   │   ├── SKILL.md
│   │   ├── scripts/
│   │   │   ├── _lib/                    # stdlib-only shared helpers
│   │   │   ├── synapse-fetch-rooms.py
│   │   │   ├── synapse-rate-rooms.py
│   │   │   ├── synapse-graph.py
│   │   │   ├── synapse-biggest-rooms.py
│   │   │   ├── synapse-join-room.py
│   │   │   ├── synapse-make-admin.py
│   │   │   ├── synapse-add-to-space.py
│   │   │   ├── synapse-migrate-room.py
│   │   │   ├── synapse-deactivate-user.py
│   │   │   ├── synapse-user-admin-rooms.py
│   │   │   ├── synapse-user-rooms.py
│   │   │   ├── synapse-room-member-flow.py
│   │   │   └── synapse-search.py
│   │   └── references/
│   │       ├── synapse-admin-api.md
│   │       ├── room-health-checks.md
│   │       ├── room-graph-pipeline.md
│   │       └── safety-guide.md
│   └── matrix-announcement/    # Content guidance (no scripts)
│       ├── SKILL.md
│       ├── README.md
│       ├── evals/evals.json
│       └── references/
│           ├── html-subset.md
│           ├── structure.md
│           ├── glyphs.md
│           ├── image-cards.md
│           ├── threading.md
│           ├── anti-patterns.md
│           ├── text-templates.md
│           ├── gallery.html              # visual preview of all rules + examples
│           └── templates/
│               ├── release-card.html     # 1200×630
│               ├── weekly-digest.html    # 1200×1500
│               └── comparison.html       # 1200×900
├── docs/
│   ├── ARCHITECTURE.md          # system design and distribution
│   ├── specs/                   # design documents (OKF)
│   └── exec-plans/              # implementation plans
├── LICENSE-MIT           # Code license (MIT)
├── LICENSE-CC-BY-SA-4.0  # Content license (CC-BY-SA-4.0)
└── README.md

Governance and policies

This repository follows the Netresearch organisation policies:

  • Governance: ownership, roles, how decisions are made and disputes resolved, and continuity.
  • Roadmap: planned and explicitly excluded work for the coming year.
  • Handling of dependency and code analysis findings: thresholds, deadlines and the exception process for dependency (SCA) and static analysis (SAST) findings.
  • Secret management: how CI and release credentials are stored, accessed and rotated.
  • Access roster: who holds administrative access to this repository and the organisation.

The security assurance case for these skills (threat model, trust boundaries, where tokens and key material are read, stored and sent, countermeasures and limits) is in docs/SECURITY-ASSURANCE.md.

Checks that run on pull requests in this repository:

  • Every pull request: Skill Validation (lint.yml: skill structure, markdownlint, yamllint, actionlint, JSON syntax, ShellCheck, ruff lint and format), Eval Validation (eval-validate.yml), Unit Tests (tests.yml: every skills/**/test_*.py suite) and Label PR (labeler.yml).
  • Pull requests to main or master: security.yml with Betterleaks (secret scanning), zizmor (workflow static analysis), dependency review (fails on vulnerabilities of severity high or above), Composer Audit and Opengrep SAST (thresholds as in the organisation's static analysis rule); Harness Verification (harness-verify.yml) and Template Drift (check-template-drift.yml).
  • Every pull request, skipped unless Renovate or Dependabot opened it: Auto-merge dependency PRs (auto-merge-deps.yml).
  • Configured outside the workflow files: CodeQL default setup (actions, python), SonarCloud Code Analysis (automatic analysis, settings in .sonarcloud.properties), the DCO check and the CodeRabbit review status. Code scanning also reports each analyser's results as a check run of its own: CodeQL, SonarCloud, zizmor, betterleaks and Opengrep OSS. GitHub secret scanning with push protection is enabled as a repository setting.

License

This project uses split licensing:

  • Code (scripts, workflows, configs): MIT
  • Content (skill definitions, documentation, references): CC-BY-SA-4.0

See the individual license files for full terms.

Author

Netresearch DTT GmbH - https://www.netresearch.de