npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@northbound-run/matrix-agent-mcp

v0.6.1

Published

MCP server for Matrix messaging. Exposes Matrix rooms, messages, members, and media as MCP tools and resources so AI agents can read and write to Matrix over the [Model Context Protocol](https://modelcontextprotocol.io/).

Downloads

2,087

Readme

@northbound-run/matrix-agent-mcp

MCP server for Matrix messaging. Exposes Matrix rooms, messages, members, and media as MCP tools and resources so AI agents can read and write to Matrix over the Model Context Protocol.

Overview

@northbound-run/matrix-agent-mcp connects an MCP client (Claude Desktop, Cursor, or any MCP-compatible host) to one or more Matrix accounts. The server maintains a persistent sync connection to each account and exposes 31 tools covering messaging, room management, membership, room state, media, and account operations.

Events stream in real time via MCP resource subscriptions. Agents can subscribe to agentchannels://events to receive all Matrix events, or filter to a specific room with agentchannels://events/{roomId}. The current room list is available at agentchannels://rooms.

Quick Start

Using environment variables (single account):

MATRIX_ACCESS_TOKEN=<token> \
MATRIX_USER_ID=@bot:matrix.org \
MATRIX_DEVICE_ID=MYDEVICE \
MATRIX_HOMESERVER_URL=https://matrix.org \
bunx @northbound-run/matrix-agent-mcp

Using a credentials file:

bunx @northbound-run/matrix-agent-mcp --credentials ./creds.json

The server starts on http://0.0.0.0:3100/mcp by default.

Configuration Reference

CLI Flags

| Flag | Description | Default | |---|---|---| | --credentials <path> | Path to a JSON credentials file (single object or array) | — | | --homeserver <url> | Matrix homeserver URL | https://matrix.agentchannels.dev | | --port <n> | HTTP port to listen on | 3100 | | --host <addr> | HTTP host to bind to | 0.0.0.0 | | --store-path <path> | Path to the credential store directory | ~/.matrix-agent | | --hosted | Enable hosted mode (Bearer token auth required) | false | | --bearer-token <token> | Bearer token for hosted mode auth | — |

Environment Variables

| Variable | Description | |---|---| | MATRIX_ACCESS_TOKEN | Access token for a Matrix account | | MATRIX_USER_ID | Full Matrix user ID (e.g. @bot:matrix.org) | | MATRIX_DEVICE_ID | Device ID for the session | | MATRIX_HOMESERVER_URL | Homeserver URL (optional, defaults to https://matrix.agentchannels.dev) | | PORT | HTTP port (overridden by --port) | | HOSTED_MODE | Set to true to enable hosted mode | | MCP_BEARER_TOKEN | Bearer token for hosted mode (overridden by --bearer-token) |

Tool Reference

Messaging (7 tools)

| Tool | Description | |---|---| | matrix_send | Send a message to a room. Supports text, HTML, notice, emote, image, audio, video, and file types. | | matrix_edit_message | Edit a previously sent message. | | matrix_redact_message | Redact (delete) a message from a room. | | matrix_react | Add an emoji reaction to a message. | | matrix_mark_read | Mark a message as read, advancing the read receipt. | | matrix_typing | Send or stop a typing indicator. | | matrix_get_messages | Retrieve recent messages from a room with optional pagination. |

Rooms (8 tools)

| Tool | Description | |---|---| | matrix_list_rooms | List all rooms the account is a member of. | | matrix_create_room | Create a new room with optional name, topic, preset, and initial invites. | | matrix_join_room | Join a room by ID or alias. | | matrix_leave_room | Leave a room. | | matrix_invite | Invite a user to a room. | | matrix_get_room_info | Get name, topic, member count, and encryption status for a room. | | matrix_set_room_topic | Update the room topic. | | matrix_set_room_name | Update the room display name. |

Members (5 tools)

| Tool | Description | |---|---| | matrix_list_members | List all members of a room with their membership state. | | matrix_kick | Kick a user from a room (requires moderator power level). | | matrix_ban | Ban a user from a room (requires moderator power level). | | matrix_unban | Unban a previously banned user. | | matrix_set_power_level | Set a user's power level in a room (requires admin). |

State (3 tools)

| Tool | Description | |---|---| | matrix_get_state | Read a specific state event by type and optional state key. | | matrix_set_state | Write a state event (requires appropriate power level). | | matrix_get_all_state | Get all current state events for a room. |

Media (3 tools)

| Tool | Description | |---|---| | matrix_upload_media | Upload a base64-encoded file to the homeserver. Returns an MXC URL. | | matrix_download_media | Download media by MXC URL, returned as base64. | | matrix_get_media_url | Convert an MXC URL to an HTTPS URL without downloading the file. |

Account (4–5 tools)

| Tool | Description | |---|---| | matrix_get_profile | Get profile info (display name, avatar) for any user. | | matrix_set_display_name | Set the display name for the current account. | | matrix_set_avatar | Set the avatar using an MXC URL. | | matrix_set_presence | Set presence state: online, offline, or unavailable. | | matrix_login | Log in with username and password. Returns credentials. Disabled in hosted mode. |

Multi-Account Setup

Pass an array in your credentials file to connect multiple accounts simultaneously. Each tool accepts an optional account parameter (a Matrix user ID) to select which account to use. If omitted, the first account in the list is used.

credentials.json (array):

[
  {
    "accessToken": "token_for_bot1",
    "userId": "@bot1:matrix.org",
    "deviceId": "BOT1DEV",
    "homeserverUrl": "https://matrix.org"
  },
  {
    "accessToken": "token_for_bot2",
    "userId": "@bot2:matrix.org",
    "deviceId": "BOT2DEV",
    "homeserverUrl": "https://matrix.org"
  }
]

Tool call with explicit account:

{
  "tool": "matrix_send",
  "arguments": {
    "roomId": "!abc:matrix.org",
    "message": "Hello from bot2",
    "account": "@bot2:matrix.org"
  }
}

Resource Subscriptions

The server exposes three MCP resources that stream live Matrix data:

| URI | Description | |---|---| | agentchannels://events | All events across all accounts (last 50). | | agentchannels://events/{roomId} | Events filtered to a specific room (last 50). | | agentchannels://rooms | Current list of joined rooms for all accounts. |

Each resource sends an MCP ResourceUpdated notification when new data arrives, so subscribed clients receive updates without polling.

Event types included: message, message.edit, message.redact, reaction, reaction.redact, room.join, room.leave, room.invite, room.update, room.encrypted, member.join, member.leave, member.invite, typing, receipt, connection, sync.

Error Handling

All tool errors return a structured MCP error response with a human-readable message. Common errors:

| Error | Message pattern | |---|---| | Token expired | Access token expired. Re-authenticate. | | Rate limited | Rate limited. Retry after Nms. | | Room not found | Room not found: !roomId:server | | Not in room | Not a member of room: !roomId:server | | Insufficient power level | Insufficient permissions in room: !roomId:server | | Network error | Network error: <details> | | Homeserver error | Homeserver error (500): <details> |

Non-Matrix errors (e.g. invalid tool arguments) are re-thrown and handled by the MCP SDK.

Hosted Mode

Hosted mode enables Bearer token authentication on the /mcp endpoint. This is intended for deployments where the MCP server is exposed over a network and must be protected.

HOSTED_MODE=true \
MCP_BEARER_TOKEN=your-secret-token \
bunx @northbound-run/matrix-agent-mcp --credentials ./creds.json

Or via flags:

bunx @northbound-run/matrix-agent-mcp \
  --hosted \
  --bearer-token your-secret-token \
  --credentials ./creds.json

In hosted mode:

  • All /mcp requests must include Authorization: Bearer <token>
  • The /health endpoint is always unauthenticated
  • matrix_login is disabled (credentials are managed externally)

Health Check

curl http://localhost:3100/health

Returns JSON with status ok, degraded, or error, plus per-account sync state. HTTP 503 is returned when status is error.

Multi-tenant Hosted Mode

Multi-tenant hosted mode runs the same binary as a shared endpoint where each caller authenticates with their own Matrix access token per request. No shared bot account is needed. This is the mode used by mcp.agentchannels.dev.

Enable it by setting MCP_MULTI_TENANT=true. In this mode the server skips all boot-time credential loading and instead validates each incoming request against the Matrix homeserver via /_matrix/client/v3/account/whoami.

Required Headers

Every request to /mcp must include:

| Header | Required | Description | |---|---|---| | Authorization: Bearer <matrix_access_token> | Yes | Your Matrix access token from the homeserver named in MATRIX_HOMESERVER_URL. Validated via /whoami on each request (with a short positive cache). | | X-Matrix-Homeserver: <url> | No | If sent, must equal the server's configured MATRIX_HOMESERVER_URL (case-insensitive, trailing-slash tolerant). If omitted, the configured URL is used. Send it only if your client allows custom headers and you want explicit homeserver pinning. | | Mcp-Session-Id: <uuid> | No | Managed by the MCP Streamable HTTP transport. Round-trip whatever the server returns in this header — omitting it causes each request to be treated as a new session. |

Error Codes

Authentication and rate-limiting errors return a JSON body:

{ "errcode": "M_MISSING_TOKEN", "error": "Missing or malformed Authorization header" }

| Code | HTTP Status | Meaning | |---|---|---| | M_MISSING_TOKEN | 401 | Authorization header absent or malformed | | M_UNKNOWN_TOKEN | 401 | Token rejected by homeserver whoami | | AC_HOMESERVER_NOT_ALLOWED | 403 | X-Matrix-Homeserver does not match the server's configured MATRIX_HOMESERVER_URL | | M_UPSTREAM_ERROR | 502 | Homeserver unreachable or returned an unexpected error during whoami | | AC_RATE_LIMITED | 429 | Per-token rate limit exceeded; Retry-After header indicates seconds to wait |

Warm-sync Semantics

Default: stateless. Each tool call issues direct HTTP requests to the homeserver. No /sync loop runs. This keeps resource usage low and latency predictable for the common case of tool invocations.

Warm sessions (opt-in). Some functionality — specifically the agentchannels://events* resources — requires a running /sync loop to receive real-time events. When a client subscribes to those resources, the server promotes the session to "warm" and starts /sync for that token.

V1 limitation. The MCP SDK does not expose the resources/subscribe lifecycle event to handler code (this is the gap described in US-010). As a result, warm promotion on subscribe is not automatic in V1. The agentchannels://events* resource URI is registered and accessible, but live event streaming may not function in V1 — it is available for future iteration once the SDK exposes the necessary hook.

Sync-token persistence. When REDIS_URL is set, warm-session sync tokens are persisted under the key mcp:synctoken:<token_hash> with a 24-hour TTL. This means warm sessions resume from where they left off after a container restart, avoiding a full timeline re-bootstrap. If REDIS_URL is unset or Redis is unreachable, the server falls back to in-memory storage automatically (single-instance only; tokens are lost on restart).

Idle eviction. Warm sessions that receive no tool calls for longer than MCP_IDLE_SESSION_TTL_MS (default 15 minutes) are reaped automatically. The /sync loop is stopped and the token persisted to Redis before eviction.

E2EE Not Supported

Hosted multi-tenant mode does not support end-to-end encrypted rooms. Tools that target an encrypted room return a clear error message rather than silently returning ciphertext. Users who require E2EE should run the local single-tenant package (bunx @northbound-run/matrix-agent-mcp) with their own credentials, where the full encryption stack is available.

Configuration

| Variable | Default | Description | |---|---|---| | MCP_MULTI_TENANT | — | Set to true to enable multi-tenant hosted mode | | MATRIX_HOMESERVER_URL | https://matrix.agentchannels.dev | The only homeserver accepted for token validation and tool calls | | REDIS_URL | — | Redis connection URL for sync-token persistence. Falls back to in-memory if unset. | | MCP_RATE_LIMIT_RPS | 5 | Per-token sustained request rate (requests per second) | | MCP_RATE_LIMIT_BURST | 30 | Per-token burst capacity (initial token-bucket size) | | MCP_WHOAMI_CACHE_TTL_MS | 300000 | Whoami positive-cache TTL in milliseconds (5 minutes) | | MCP_IDLE_SESSION_TTL_MS | 900000 | Idle warm-session eviction TTL in milliseconds (15 minutes) | | MCP_MAX_WARM_SESSIONS | 200 | Maximum concurrent warm /sync sessions (LRU cap) | | PORT | 3100 / 3300 | HTTP bind port (3100 for local installs, 3300 inside the docker-compose container) |

Mode-Precedence Rule

If both HOSTED_MODE=true and MCP_MULTI_TENANT=true are set simultaneously, multi-tenant wins. The static MCP_BEARER_TOKEN is ignored, matrix_login remains disabled, and /mcp requires per-request Matrix tokens. The server logs the precedence applied at boot:

mode-precedence: multi-tenant overrides static bearer gate

In multi-tenant mode, the account parameter is removed from all tool input schemas. The active Matrix account is determined entirely by the request's bearer token — passing an account argument returns M_INVALID_PARAM.

MCP Client Configuration

Claude Desktop

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "matrix": {
      "command": "bunx",
      "args": ["@northbound-run/matrix-agent-mcp"],
      "env": {
        "MATRIX_ACCESS_TOKEN": "your-access-token",
        "MATRIX_USER_ID": "@yourbot:matrix.org",
        "MATRIX_DEVICE_ID": "CLAUDE_BOT",
        "MATRIX_HOMESERVER_URL": "https://matrix.org"
      }
    }
  }
}

Cursor

Add to your Cursor MCP settings:

{
  "mcpServers": {
    "matrix": {
      "command": "bunx",
      "args": [
        "@northbound-run/matrix-agent-mcp",
        "--credentials",
        "/path/to/creds.json"
      ]
    }
  }
}

Remote / Hosted Deployment

For a server already running with hosted mode enabled:

{
  "mcpServers": {
    "matrix": {
      "url": "https://your-server.example.com/mcp",
      "headers": {
        "Authorization": "Bearer your-secret-token"
      }
    }
  }
}

License

MIT