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
| Flag | Env var | Description |
|---|---|---|
--room <id> | AGENT_CHANNELS_ROOM_ID | Matrix room ID to monitor (e.g. !abc123:matrix.org) |
--channel-name <name> | AGENT_CHANNELS_CHANNEL_NAME | Display 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:
{
"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.reactionm.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.imagem.audiom.videom.filem.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:
slackbottelegrambotsignalbotmattermost- (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
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.