Skip to main content
Matrix TUI Logo

Matty - Matrix CLI Client

A simple, functional Matrix chat client built with Python, Typer, Pydantic, Nio, and Rich. Every interaction is a single CLI command for easy automation.

PyPI Build Status CodeCov GitHub Repo stars Ruff

Features

  • Fast CLI commands for quick Matrix operations
  • Thread support - view and navigate threaded conversations
  • Reactions support - add and view emoji reactions on messages
  • Message redaction - delete messages with optional reasons
  • AI-friendly - every action is a single CLI command
  • Functional programming style (minimal classes, maximum functions)
  • Environment-based configuration
  • Multiple output formats (rich, simple, JSON)
  • Type-safe with dataclasses and type hints
  • Persistent simple ID mapping for complex Matrix IDs

Installation

uv tool install matty
# or
pipx install matty
# or
pip install matty

For development, clone the repo and install dependencies:

# Clone the repository
git clone https://github.com/basnijholt/matrix-cli
cd matrix-cli

# Install dependencies with uv
uv sync

# Optional: Install pre-commit hooks
uv run pre-commit install

Configuration

Matty can store Matrix access-token credentials in your user config directory:

matty auth sso https://matrix.example.com

If the homeserver advertises multiple SSO providers, list their provider IDs and labels:

matty auth providers https://matrix.example.com

Then pass the provider ID, name, or brand explicitly. Matty resolves labels like github to the canonical provider ID before opening the browser:

matty auth sso https://matrix.example.com --idp-id github

Existing Matrix access token:

matty auth token https://matrix.example.com @alice:example.com "$MATRIX_ACCESS_TOKEN" --device-id DEVICEID

Password auth, when enabled by the homeserver:

matty auth password https://matrix.example.com @alice:example.com

Credentials are stored in the config file reported by:

matty config-path

Remove stored credentials:

matty auth logout

Environment variables are still supported and override stored credentials.

Environment Variables

Variable Description Default Example
MATRIX_HOMESERVER The Matrix homeserver URL to connect to https://matrix.org https://matrix.example.com
MATRIX_USERNAME Your Matrix username (without @ or :server) None (required) alice
MATRIX_PASSWORD Your Matrix account password None (required) secretpassword
MATRIX_USER_ID Full Matrix user ID for access-token auth None @alice:example.com
MATRIX_DEVICE_ID Matrix device ID for access-token auth None DEVICEID
MATRIX_ACCESS_TOKEN Matrix access token None syt_...
MATRIX_SSL_VERIFY Whether to verify SSL certificates true false (for test servers)

Notes:

  • MATRIX_USERNAME should be provided without the @ prefix or :server suffix
  • Set MATRIX_SSL_VERIFY=false when connecting to test servers with self-signed certificates
  • Command-line options (--username, --password) override environment variables

Usage

Available Commands


 Usage: matty [OPTIONS] COMMAND [ARGS]...

 Functional Matrix CLI client

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --install-completion            Install completion for the current shell.              │
│ --show-completion               Show completion for the current shell, to copy it or   │
│                                 customize the installation.                            │
│ --help                -h        Show this message and exit.                            │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Setup ────────────────────────────────────────────────────────────────────────────────╮
│ config-path   Print the path to the Matty credential config file.                      │
│ auth          Manage Matrix authentication credentials.                                │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Browse ───────────────────────────────────────────────────────────────────────────────╮
│ rooms         List all joined rooms. (alias: r)                                        │
│ messages      Show recent messages from a room. (alias: m)                             │
│ users         Show users in a room. (alias: u)                                         │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Messaging ────────────────────────────────────────────────────────────────────────────╮
│ send          Send a message to a room. Supports @mentions. (alias: s)                 │
│ reply         Reply to a specific message using its handle. (alias: re)                │
│ edit          Edit a message using its handle. (alias: e)                              │
│ redact        Delete/redact a message using its handle. (alias: del)                   │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Threads ──────────────────────────────────────────────────────────────────────────────╮
│ threads       List all threads in a room. (alias: t)                                   │
│ thread        Show all messages in a specific thread. (alias: th)                      │
│ thread-start  Start a new thread from a message using its handle. (alias: ts)          │
│ thread-reply  Reply within an existing thread. (alias: tr)                             │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Reactions ────────────────────────────────────────────────────────────────────────────╮
│ react         Add a reaction to a message using its handle. (alias: rx)                │
│ reactions     Show detailed reactions for a specific message. (alias: rxs)             │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Interface ────────────────────────────────────────────────────────────────────────────╮
│ tui           Launch interactive TUI chat interface.                                   │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Rooms Command

List all joined Matrix rooms:


 Usage: matty rooms [OPTIONS]

 List all joined rooms. (alias: r)

╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --username  -u      TEXT                Matrix username (overrides MATRIX_USERNAME env │
│                                         var)                                           │
│ --password  -p      TEXT                Matrix password (overrides MATRIX_PASSWORD env │
│                                         var)                                           │
│ --format    -f      [rich|simple|json]  Output format (rich/simple/json)               │
│                                         [default: rich]                                │
│ --help      -h                          Show this message and exit.                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Messages Command

Get recent messages from a room:


 Usage: matty messages [OPTIONS] [ROOM]

 Show recent messages from a room. (alias: m)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room      [ROOM]  Room ID or name                                                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --limit     -l      INTEGER             [default: 20]                                  │
│ --username  -u      TEXT                Matrix username (overrides MATRIX_USERNAME env │
│                                         var)                                           │
│ --password  -p      TEXT                Matrix password (overrides MATRIX_PASSWORD env │
│                                         var)                                           │
│ --format    -f      [rich|simple|json]  Output format (rich/simple/json)               │
│                                         [default: rich]                                │
│ --help      -h                          Show this message and exit.                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Users Command

List users in a room:


 Usage: matty users [OPTIONS] [ROOM]

 Show users in a room. (alias: u)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room      [ROOM]  Room ID or name                                                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --username  -u      TEXT                Matrix username (overrides MATRIX_USERNAME env │
│                                         var)                                           │
│ --password  -p      TEXT                Matrix password (overrides MATRIX_PASSWORD env │
│                                         var)                                           │
│ --format    -f      [rich|simple|json]  Output format (rich/simple/json)               │
│                                         [default: rich]                                │
│ --help      -h                          Show this message and exit.                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Thread Commands

View and interact with threads:


 Usage: matty threads [OPTIONS] [ROOM]

 List all threads in a room. (alias: t)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room      [ROOM]  Room ID or name                                                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --limit     -l      INTEGER             Number of messages to check [default: 50]      │
│ --username  -u      TEXT                Matrix username (overrides MATRIX_USERNAME env │
│                                         var)                                           │
│ --password  -p      TEXT                Matrix password (overrides MATRIX_PASSWORD env │
│                                         var)                                           │
│ --format    -f      [rich|simple|json]  Output format (rich/simple/json)               │
│                                         [default: rich]                                │
│ --help      -h                          Show this message and exit.                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯


 Usage: matty thread [OPTIONS] [ROOM] [THREAD_ID]

 Show all messages in a specific thread. (alias: th)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room           [ROOM]       Room ID or name                                          │
│   thread_id      [THREAD_ID]  Thread ID (t1, t2, etc.) or full Matrix ID               │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --limit     -l      INTEGER             Number of messages to fetch [default: 50]      │
│ --username  -u      TEXT                Matrix username (overrides MATRIX_USERNAME env │
│                                         var)                                           │
│ --password  -p      TEXT                Matrix password (overrides MATRIX_PASSWORD env │
│                                         var)                                           │
│ --format    -f      [rich|simple|json]  Output format (rich/simple/json)               │
│                                         [default: rich]                                │
│ --help      -h                          Show this message and exit.                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Send Command

Send messages to rooms:


 Usage: matty send [OPTIONS] [ROOM] [MESSAGE]

 Send a message to a room. Supports @mentions. (alias: s)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room         [ROOM]     Room ID or name                                              │
│   message      [MESSAGE]  Message to send (use @username for mentions)                 │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --stdin                      Read message from stdin                                   │
│ --file         -f      PATH  Read message from file                                    │
│ --no-mentions                Don't parse @mentions in messages                         │
│ --username     -u      TEXT  Matrix username (overrides MATRIX_USERNAME env var)       │
│ --password     -p      TEXT  Matrix password (overrides MATRIX_PASSWORD env var)       │
│ --help         -h            Show this message and exit.                               │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Reply Command

Reply to messages:


 Usage: matty reply [OPTIONS] [ROOM] [HANDLE] [MESSAGE]

 Reply to a specific message using its handle. (alias: re)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room         [ROOM]     Room ID or name                                              │
│   handle       [HANDLE]   Message handle (m1, m2, etc.) to reply to                    │
│   message      [MESSAGE]  Reply message                                                │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --no-mentions                Don't parse @mentions in messages                         │
│ --username     -u      TEXT  Matrix username (overrides MATRIX_USERNAME env var)       │
│ --password     -p      TEXT  Matrix password (overrides MATRIX_PASSWORD env var)       │
│ --help         -h            Show this message and exit.                               │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Thread Start Command

Start a thread from a message:


 Usage: matty thread-start [OPTIONS] [ROOM] [HANDLE] [MESSAGE]

 Start a new thread from a message using its handle. (alias: ts)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room         [ROOM]     Room ID or name                                              │
│   handle       [HANDLE]   Message handle (m1, m2, etc.) to start thread from           │
│   message      [MESSAGE]  First message in the thread                                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --no-mentions                Don't parse @mentions in messages                         │
│ --username     -u      TEXT  Matrix username (overrides MATRIX_USERNAME env var)       │
│ --password     -p      TEXT  Matrix password (overrides MATRIX_PASSWORD env var)       │
│ --help         -h            Show this message and exit.                               │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Thread Reply Command

Reply in a thread:


 Usage: matty thread-reply [OPTIONS] [ROOM] [THREAD_ID] [MESSAGE]

 Reply within an existing thread. (alias: tr)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room           [ROOM]       Room ID or name                                          │
│   thread_id      [THREAD_ID]  Thread ID (t1, t2, etc.) or full Matrix ID               │
│   message        [MESSAGE]    Reply message                                            │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --no-mentions                Don't parse @mentions in messages                         │
│ --username     -u      TEXT  Matrix username (overrides MATRIX_USERNAME env var)       │
│ --password     -p      TEXT  Matrix password (overrides MATRIX_PASSWORD env var)       │
│ --help         -h            Show this message and exit.                               │
╰────────────────────────────────────────────────────────────────────────────────────────╯

React Command

Add reactions to messages:


 Usage: matty react [OPTIONS] [ROOM] [HANDLE] [EMOJI]

 Add a reaction to a message using its handle. (alias: rx)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room        [ROOM]    Room ID or name                                                │
│   handle      [HANDLE]  Message handle (m1, m2, etc.) to react to                      │
│   emoji       [EMOJI]   Emoji reaction (e.g., 👍, ❤️, 😄)                              │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --username  -u      TEXT  Matrix username (overrides MATRIX_USERNAME env var)          │
│ --password  -p      TEXT  Matrix password (overrides MATRIX_PASSWORD env var)          │
│ --help      -h            Show this message and exit.                                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Reactions Command

View reactions on a message:


 Usage: matty reactions [OPTIONS] [ROOM] [HANDLE]

 Show detailed reactions for a specific message. (alias: rxs)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room        [ROOM]    Room ID or name                                                │
│   handle      [HANDLE]  Message handle (m1, m2, etc.) to show reactions for            │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --username  -u      TEXT                Matrix username (overrides MATRIX_USERNAME env │
│                                         var)                                           │
│ --password  -p      TEXT                Matrix password (overrides MATRIX_PASSWORD env │
│                                         var)                                           │
│ --format    -f      [rich|simple|json]  Output format (rich/simple/json)               │
│                                         [default: rich]                                │
│ --help      -h                          Show this message and exit.                    │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Redact Command

Delete/redact messages:


 Usage: matty redact [OPTIONS] [ROOM] [HANDLE]

 Delete/redact a message using its handle. (alias: del)

╭─ Arguments ────────────────────────────────────────────────────────────────────────────╮
│   room        [ROOM]    Room ID or name                                                │
│   handle      [HANDLE]  Message handle (m1, m2, etc.) to redact/delete                 │
╰────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Options ──────────────────────────────────────────────────────────────────────────────╮
│ --reason    -r      TEXT  Reason for redaction                                         │
│ --username  -u      TEXT  Matrix username (overrides MATRIX_USERNAME env var)          │
│ --password  -p      TEXT  Matrix password (overrides MATRIX_PASSWORD env var)          │
│ --help      -h            Show this message and exit.                                  │
╰────────────────────────────────────────────────────────────────────────────────────────╯

Command Aliases

For faster typing, all commands have short aliases:

  • matty r → matty rooms - List all rooms
  • matty m → matty messages - Show messages from a room
  • matty u → matty users - Show users in a room
  • matty s → matty send - Send a message
  • matty t → matty threads - List threads
  • matty th → matty thread - Show thread messages
  • matty re → matty reply - Reply to a message
  • matty ts → matty thread-start - Start a thread
  • matty tr → matty thread-reply - Reply in a thread
  • matty rx → matty react - Add a reaction to a message
  • matty del → matty redact - Delete/redact a message
  • matty rxs → matty reactions - Show reactions on a message

Examples

Basic Usage

# List all rooms
matty rooms
# or use alias: matty r

# Show users in a room (with mention hints)
matty users lobby
# or: matty u lobby

# Get recent messages from a room
matty messages lobby --limit 10
# or: matty m lobby --limit 10

# Send a message to a room
matty send lobby "Hello from CLI!"
# or: matty s lobby "Hello from CLI!"

# Send a message with mentions
matty send lobby "@alice check this out!"
# or: matty s lobby "@bob @alice meeting at 3pm"

# Use different output formats
matty rooms --format json
matty rooms --format simple
# or: matty r --format json

Working with Threads

# List threads in a room
matty threads lobby

# View messages in a specific thread (using simple ID)
matty thread lobby t1

# Start a thread from a message
matty thread-start lobby m2 "Starting a thread!"

# Reply in a thread (using simple thread ID)
matty thread-reply lobby t1 "Reply in thread"

Reactions and Redaction

# Add a reaction to a message
matty react lobby m3 "👍"
# or: matty rx lobby m3 "🚀"

# View reactions on a message
matty reactions lobby m3
# or: matty rxs lobby m3 --format simple

# Delete/redact a message
matty redact lobby m5 --reason "Accidental message"
# or: matty del lobby m5

Message Handles and Replies

# Reply to a message using handle
matty reply lobby m3 "This is a reply!"

# Reply to the 5th message in a room
matty messages lobby --limit 10
matty reply lobby m5 "Replying to message 5"

Mentions

The CLI supports @mentions in messages:

# Mention a user by username
matty send lobby "@alice can you check this?"

# Multiple mentions
matty send lobby "@bob @alice meeting in 5 minutes"

# List users to see available mentions
matty users lobby  # Shows User IDs and simplified @mentions

# Mentions work in replies and threads too
matty reply lobby m3 "@alice I agree with your point"
matty thread-reply lobby t1 "@bob what do you think?"

The mention system will:

  • Automatically find the full Matrix ID for @username mentions
  • Support full Matrix IDs like @user:server.com
  • Format mentions properly so users get notified

Message Handles and Thread IDs

The CLI uses convenient handles to reference messages and threads:

  • Message handles: m1, m2, m3, etc. - Reference messages by their position
  • Thread IDs: t1, t2, t3, etc. - Reference threads with simple persistent IDs

These IDs are stored in ~/.matrix_cli_ids.json and persist across sessions.

Why Simple IDs?

Matrix uses complex IDs like:

  • Event: $Uj2XuH2a8EqJBh4g:matrix.org
  • Room: !DfQvqvwXYsFjVcfLTp:matrix.org

Our CLI simplifies these to:

  • Messages: m1, m2, m3 (temporary handles for current view)
  • Threads: t1, t2, t3 (persistent IDs across sessions)

Output Formats

The CLI supports three output formats:

  1. Rich (default) - Beautiful terminal UI with tables and colors
  2. Simple - Plain text output, perfect for scripts
  3. JSON - Machine-readable format for automation

Example:

# Pretty tables with colors
matty rooms

# Simple text output
matty rooms --format simple

# JSON for automation
matty rooms --format json | jq '.[] | .name'

Project Structure

matty/
├── matty/                # Package source
│   ├── __init__.py       # Compatibility exports for the historical module API
│   ├── __main__.py       # `python -m matty` entry point
│   ├── cli.py            # Main CLI application (functional style)
│   ├── tui.py            # Interactive TUI application
│   └── matty_tui.tcss    # TUI stylesheet
├── tests/                # Test suite
│   ├── __init__.py
│   ├── conftest.py       # Pytest configuration
│   └── test_matrix_cli.py # Unit tests
├── .github/              # GitHub Actions workflows
│   └── workflows/
│       ├── pytest.yml    # Test runner
│       ├── release.yml   # PyPI release
│       └── markdown-code-runner.yml # README updater
├── .env                  # Your credentials (not in git)
├── .env.example          # Example environment file
├── CLAUDE.md            # Development guidelines
├── pyproject.toml       # Project configuration
└── README.md            # This file

Development

This project follows functional programming principles:

  • Private functions (_function_name) for internal logic
  • Dataclasses over dictionaries for data structures
  • Type hints everywhere for clarity
  • No unnecessary abstractions or class hierarchies
  • Functions over classes where possible

See CLAUDE.md for detailed development guidelines.

Testing

# Run tests
uv run pytest tests/ -v

# Test with coverage
uv run pytest tests/ -v --cov=matty --cov-report=term-missing

# Test connection to Matrix server
uv run python test_client.py

# Run pre-commit checks
uv run pre-commit run --all-files

License

MIT

Metadata

Release files for matty 0.11.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for matty 0.11.1
File Size Uploaded
matty-0.11.1.tar.gz 39.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for matty 0.11.1
File Interpreter ABI Platform
matty-0.11.1-py3-none-any.whl Python 3 none any Details

Total release size: 74.4 kB

Release files / matty-0.11.1.tar.gz

Download URL matty-0.11.1.tar.gz
Size 39.2 kB
Tags Source
SHA-256 checksum
How to use checksums
7f4b1dcafeec62cfecc7329df89757fe03367eae41933dd9871ea27cbd22fb12
BLAKE2b-256 checksum
How to use checksums
3fc63e1d5735883810bb59bcebe61ffba8b5b3167ea1249d27b458e2d7a88eb4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

Release files / matty-0.11.1-py3-none-any.whl

Download URL matty-0.11.1-py3-none-any.whl
Size 35.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b0aac2c1aea9438648d35ae95fe7e6edb2dd75bb9d5bf1d89cc9dfcbff35a37f
BLAKE2b-256 checksum
How to use checksums
357b52f859eba009ef9de716c874668e51c62e78d10c735e9c1e81df9b2967ed
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.11.1 This release

2 release files

0.10.1

2 release files

0.10.0

2 release files

0.9.0

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page