@northbound-run/matrix-agent-claude-code-channel
v0.3.7
Published
Claude Code Channel plugin for Agent Channels — bridge chat platforms into Claude Code
Readme
@northbound-run/matrix-agent-claude-code-channel
MCP server that bridges Matrix messages into Claude Code. This plugin runs as a subprocess in Claude Code, listens for incoming Matrix messages, and delivers them as channel notifications. Claude Code replies via the channel_reply tool, which sends messages back to Matrix.
Overview
@northbound-run/matrix-agent-claude-code-channel connects Claude Code to a Matrix homeserver. The plugin maintains a persistent sync connection, filters messages, and delivers them to Claude Code in real time as notifications/claude/channel MCP notifications. Messages are then sent back to Matrix via the channel_reply tool.
Quick Start
Using environment variables:
MATRIX_ACCESS_TOKEN=<token> \
MATRIX_USER_ID=@bot:matrix.org \
MATRIX_DEVICE_ID=CLAUDE \
MATRIX_HOMESERVER_URL=https://matrix.org \
bunx @northbound-run/matrix-agent-claude-code-channel \
--room '!roomid:matrix.org' \
--channel-name team-chatUsing a credentials file:
bunx @northbound-run/matrix-agent-claude-code-channel \
--credentials ./creds.json \
--room '!roomid:matrix.org' \
--channel-name team-chatUsing FileStore (after matrix-agent login):
bunx @northbound-run/matrix-agent-claude-code-channel \
--room '!roomid:matrix.org' \
--channel-name team-chatConfiguration Reference
CLI Flags
| Flag | Env Var | Description | Default |
|---|---|---|---|
| --credentials <path> | — | Path to JSON credentials file | — |
| --homeserver <url> | — | Override homeserver URL from credentials | — |
| --room <id> | AGENT_CHANNELS_ROOM_ID | Filter to a single Matrix room ID | all rooms |
| --channel-name <name> | AGENT_CHANNELS_CHANNEL_NAME | Display name shown in Claude Code | room ID or "matrix" |
| --store-path <path> | — | Credential store directory | ~/.matrix-agent |
| --mention-mode <mode> | AGENT_CHANNELS_MENTION_MODE | mention_required_in_channels (default) or always | mention_required_in_channels |
| --auto-thread / --no-auto-thread | AGENT_CHANNELS_AUTO_THREAD_CHANNEL_REPLIES | Auto-thread replies to channel @mentions | true |
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 (required unless in credentials file) |
| AGENT_CHANNELS_ROOM_ID | Matrix room ID to monitor (overrides --room) |
| AGENT_CHANNELS_CHANNEL_NAME | Channel display name in Claude Code (overrides --channel-name) |
Credential Loading
The plugin uses a 3-tier fallback for credential resolution:
--credentials <path>→ JSON file containing a single credentials object:{ "accessToken": "syt_...", "userId": "@bot:matrix.org", "deviceId": "CLAUDE", "homeserverUrl": "https://matrix.org" }Environment variables → Reads
MATRIX_ACCESS_TOKEN,MATRIX_USER_ID,MATRIX_DEVICE_ID,MATRIX_HOMESERVER_URLFileStore fallback → Searches
~/.matrix-agent/accounts/*/credentials.json(created bymatrix-agent login)
Message Filtering
The plugin only delivers messages that match these criteria:
- Timing: Messages received after the plugin started (no backfill of old messages)
- Type: Only
m.room.messageandm.room.noticeevents - Content: Text/notice plus media (image/audio/video/file) downloaded to the inbox
- Origin: Excludes echo messages from self and known bridge bots (slackbot, telegrambot, signalbot, mattermost, etc.)
- Mention mode (Slack-bridged rooms only): When
mentionMode === "mention_required_in_channels"(default), channel messages where the bot is NOT @mentioned are dropped. DMs and group DMs always deliver. Non-Slack rooms ignore this filter.
Slack Bot Smart Defaults — well-mannered bot
When connected to a Slack-bridged room (via mautrix-slack), the plugin behaves like a well-mannered bot out of the box:
| Situation | Behavior (defaults) |
|---|---|
| Channel chatter (no @mention) | dropped — the bot stays quiet |
| Channel @mention of the bot | delivered with [MENTIONED] prefix; reply auto-threads to the original message (renders as a Slack thread reply) |
| DM | delivered normally; reply posts as a top-level DM message (no thread) |
These defaults are powered by the m.bridge state event mautrix-slack writes — the plugin reads com.beeper.room_type.v2 to know whether the room is channel / dm / group_dm (see docs/bridges/mautrix-slack-state.md).
To opt out (revert to the original "deliver everything, never auto-thread" behavior):
--mention-mode always --no-auto-thread
# or
AGENT_CHANNELS_MENTION_MODE=always AGENT_CHANNELS_AUTO_THREAD_CHANNEL_REPLIES=falseFor non-Slack rooms (Matrix-native, Discord-bridged, etc.) the mention filter is bypassed automatically because the necessary metadata isn't present — behavior matches the pre-0.2.0 release.
Tool Reference
channel_reply
Send a message from Claude Code back to Matrix. By default, replies to channel @mentions auto-thread; DM replies post normally.
Parameters:
| Parameter | Type | Required | Description |
|---|---|---|---|
| message | string | one of message/filePath | The message text to send |
| filePath | string | one of message/filePath | Absolute path to a local file attachment |
| roomId | string | no | Target Matrix room ID (defaults to --room flag) |
| threadEventId | string | no | Explicit event ID to thread under. Always honored when set. |
| noThread | boolean | no | Force a top-level reply (skip auto-threading). Ignored when threadEventId is set. |
When --auto-thread is on (default) and the most recent inbound message in the room was a channel @mention of the bot, that message becomes the auto-thread root for the next reply. DMs and group DMs never auto-thread.
Response:
{
"success": true,
"eventId": "$event_id_hash"
}Example:
{
"tool": "channel_reply",
"arguments": {
"message": "Hello from Claude Code",
"roomId": "!abc123:matrix.org"
}
}Claude Code Configuration
Add the plugin to .claude/settings.json (local project) or ~/.claude.json (global):
With Environment Variables
{
"mcpServers": {
"matrix-channel": {
"command": "bunx",
"args": [
"@northbound-run/matrix-agent-claude-code-channel",
"--room", "!yourroom:matrix.agentchannels.dev",
"--channel-name", "team-chat"
],
"env": {
"MATRIX_ACCESS_TOKEN": "your-token",
"MATRIX_USER_ID": "@bot:matrix.agentchannels.dev",
"MATRIX_DEVICE_ID": "CLAUDE",
"MATRIX_HOMESERVER_URL": "https://matrix.agentchannels.dev"
}
}
}
}With FileStore (after matrix-agent login)
{
"mcpServers": {
"matrix-channel": {
"command": "bunx",
"args": [
"@northbound-run/matrix-agent-claude-code-channel",
"--room", "!yourroom:matrix.agentchannels.dev",
"--channel-name", "team-chat"
]
}
}
}With Credentials File
{
"mcpServers": {
"matrix-channel": {
"command": "bunx",
"args": [
"@northbound-run/matrix-agent-claude-code-channel",
"--credentials", "/path/to/credentials.json",
"--room", "!yourroom:matrix.org",
"--channel-name", "team-chat"
]
}
}
}Build
bun run buildThis produces dist/agentchannels-channel, a static binary executable via bun build --compile.
Dependencies
@northbound-run/matrix-agent-sdk— Matrix client and credential handling@modelcontextprotocol/sdk— MCP protocol implementationzod— Schema validation for CLI arguments
Runtime: Bun
License
MIT
