Docs

matrix-agent-claude-code-channel

MCP plugin that delivers Matrix messages to Claude Code as channel notifications and exposes a channel_reply tool.

@northbound-run/matrix-agent-claude-code-channel is an MCP plugin that runs as a subprocess inside Claude Code. It listens for incoming Matrix messages, delivers them as channel notifications, and exposes a channel_reply tool so Claude Code can send responses back to Matrix.

Prerequisites

  • Claude Code installed
  • A Matrix account joined to the room you want to monitor
  • Bun installed

Configure

The plugin resolves credentials from three sources in order. Pick the one that fits your workflow.

Flags

FlagEnv varDescription
--room <id>AGENT_CHANNELS_ROOM_IDMatrix room ID to monitor (e.g. !abc123:matrix.org)
--channel-name <name>AGENT_CHANNELS_CHANNEL_NAMEDisplay name shown in Claude Code notifications

Both are technically optional (the plugin falls back to all rooms / the room ID as the name), but setting them explicitly is strongly recommended to avoid noise from unrelated rooms.

Verify

Restart Claude Code after saving the settings file. Send a message in the Matrix room. Claude Code should display a channel notification. Claude can then reply with channel_reply:

json
{
  "tool": "channel_reply",
  "arguments": {
    "message": "Hello from Claude Code"
  }
}

The roomId argument defaults to the value of --room, so it can be omitted when replying to the monitored room.

Message filters

The plugin does not deliver every Matrix event. It applies four filter criteria before forwarding a message.

Filter 1 — Timing

Only messages received after the plugin started are delivered. No backfill.

  • Messages sent before Claude Code was launched are ignored.
  • If the plugin restarts (e.g. Claude Code restarts), messages sent during downtime are not replayed.

This is intentional — delivering a backlog on every startup would flood Claude Code with stale context.

Filter 2 — Event type

Only m.room.message and m.room.notice event types pass.

Dropped at this stage:

  • m.room.member (join/leave/invite)
  • m.reaction
  • m.room.encrypted (encrypted events that could not be decrypted)
  • m.room.redaction
  • Any other non-message event type

Filter 3 — Content type

Within accepted event types, only m.text and m.notice pass. Media and structural subtypes are dropped:

  • m.image
  • m.audio
  • m.video
  • m.file
  • m.emote

Use matrix_download_media from matrix-agent-mcp for media handling.

Filter 4 — Origin (echo and bridge bot exclusion)

Messages sent by the bot account itself are excluded. Messages from known bridge bots are filtered by display name pattern:

  • slackbot
  • telegrambot
  • signalbot
  • mattermost
  • (and similar bridge bot identifiers)

This prevents bridge-relayed duplicates from triggering notifications. If you are running a bridge and want Claude Code to see bridge-relayed messages, use a dedicated Matrix account for the channel plugin that is not present in bridged rooms.

Composition

code
incoming Matrix event
  → timing check (after plugin start?)
  → event type check (m.room.message or m.room.notice?)
  → content type check (m.text or m.notice msgtype?)
  → origin check (not self, not bridge bot?)
  → delivered to Claude Code as channel notification

A message dropped at any stage produces no notification and no error.