message-bridge-opencode-plugin is a universal message bridge plugin designed for OpenCode Agent.
It enables AI Agents to connect with multiple messaging platforms through a unified abstraction layer.
The project initially focused on Feishu (Lark) integration. After validation and real-world usage, it has evolved into a general-purpose message bridge, allowing OpenCode Agents to interact with different IM platforms in a consistent way.
-
Feishu / Lark
- Production-ready
- Supports Webhook and WebSocket modes
- Stable message receiving & forwarding
- Fully compatible with OpenCode plugin system
-
Telegram (Bot API / Polling + Webhook)
- Supports incoming text messages
- Supports common media receive (photo/document/video/audio/voice/sticker/animation)
- Supports streamed reply send/edit
- Supports slash-command flow in bridge
-
iMessage (Next priority)
-
Other IM platforms (planned):
- Slack
- Discord
- WhatsApp (subject to API availability)
The architecture is designed to make adding new platforms straightforward and incremental.
-
Universal Message Abstraction
- One OpenCode Agent, multiple messaging platforms
-
Plug & Play
- Fully compatible with OpenCode plugin system
-
Multiple Communication Modes
webhookβ Recommended for productionws(WebSocket) β Ideal for local development (no public IP required)
-
Config-driven
- All credentials and behavior managed via
opencode.json
- All credentials and behavior managed via
-
Extensible Architecture
- New platforms can be added without changing core agent logic
This plugin implements key slash commands via OpenCode APIs, and falls back to session.command for custom commands.
UI-only commands (theme/editor/exit, etc.) are not supported in chat.
From the official TUI docs, the built-in commands include:
/connect/compact(alias:/summarize)/details/editor/exit(aliases:/quit,/q)/export/help/init/models/new(alias:/clear)/reset(alias:/restart)/redo/sessions(aliases:/resume,/continue)/share/theme/thinking/undo/unshare/status/maxFileSize/maxFileRetry/agent
These are implemented directly against OpenCode APIs:
/helpβ list custom commands/modelsβ list providers and models (/models <providerIndex.modelIndex>to switch)/newβ create and bind to a new session/rename <title>β rename current session (auto-add suffix like(2)if duplicated)/abortβ force-abort current session generation/reset//restartβ reset bridge runtime state and create a new session/statusβ show runtime status (session / agent / model / pid / uptime)/status cacheβ show in-memory cache sizes (session maps / pending states / file store / dedupe sets)/sessionsβ list sessions (reply with/sessions <id>or/sessions <index>to bind)/sessions delete 1,2,3β batch delete sessions by index/id/sessions delete allβ delete all sessions except current one/maxFileSize <xmb>β set upload file size limit (default 10MB)/maxFileRetry <n>β set resource download retry count (default 3)/savefileβ ask user to upload file and save directly to local path (without LLM)/sendfile <path>β force-send a local file back via bot/share//unshare/compact(alias/summarize)/init/agentβ list available agents/agent <index|name>β bind agent for future prompts
/connect/details/editor/export/exit(/quit,/q)/theme/thinking
Custom commands are supported via:
opencode.jsonundercommand, or.opencode/commands/*.mdfiles.
Session switching via /sessions is fully supported. The list is returned to the chat, and you can reply with /sessions <id> or /sessions <index> to bind this chat to the chosen session.
Session batch deletion is supported via /sessions delete ..., and /sessions delete all keeps the current active session.
File upload size limit can be adjusted per chat with /maxFileSize <xmb> (default 10MB).
Use /status cache to quickly inspect current cache usage and troubleshoot memory growth.
If your OpenCode setup provides additional slash commands, they will still be forwarded via session.command unless explicitly handled above.
This bridge supports two direct file operations:
/sendfile <path>: force-send a local file by path./savefile: enter upload mode; the next uploaded file is saved to local disk and the saved path is returned.
These flows bypass LLM reasoning and are handled directly by bridge adapters.
The bridge now uses a unified logger and writes logs to file by default.
Environment variables:
BRIDGE_LOG_FILE- custom log file path (default:logs/bridge.log)BRIDGE_LOG_STDOUT- enable/disable terminal log output (trueby default)BRIDGE_DEBUG- enable debug-level logs (falseby default)
Example:
BRIDGE_DEBUG=true BRIDGE_LOG_FILE=/tmp/bridge.log opencode webYou can also check the current log path via /status (logFile field).
The bridge uses bounded in-memory caches to avoid unbounded growth during long-running sessions:
- LRU/TTL caches are used for message mapping and dedupe (platform adapters + event flow).
- File store caches (
seenFiles/pendingFiles) are now pruned by TTL and size: seenFiles: 7 days TTL, up to 4000 entries per chat.pendingFiles: 24 hours TTL, up to 200 entries per chat.- A global tracked-chat cap is applied to both file caches to limit total memory footprint.
/restartnow clears bridge runtime caches more completely (including Feishu/QQ dedupe sets and pending authorization state).
For debugging, run:
/status cacheInside your OpenCode Agent config directory:
npm install message-bridge-opencode-plugin
β οΈ Due to a known OpenCode issue, installing directly from npm may not work at the moment. See Development Mode Usage below.
Important: It is strongly recommended to use string values for all config fields to avoid parsing issues.
You can configure local file return behavior in agent.message-bridge.options:
auto_send_local_files("true"/"false", defaultfalse)auto_send_local_files_max_mb(default20)auto_send_local_files_allow_absolute("true"/"false", defaultfalse)file_store_dir(local directory to save inbound uploaded files; supports relative/absolute/file://paths; default:bridge_files)webhook_listen_port(Telegram webhook local listen port, optional; fallback: callback_url port ->18080)
Due to an existing OpenCode issue:
Issue:
fn3 is not a functionanomalyco/opencode#7792
The plugin must currently be used in local development mode.
git clone https://github.com/YuanG1944/message-bridge-opencode-plugin.gitcd message-bridge-opencode-pluginbun install
bunis recommended, as OpenCodeβs build system is based on it.
pwd
# /your/path/message-bridge-opencode-plugin{
"plugin": ["/your/path/message-bridge-opencode-plugin"],
"agent": {
"message-bridge": {
"options": {
"platform": "feishu",
"mode": "webhook"
}
}
}
}- Feishu / Lark (Production ready)
- iMessage (Next milestone)
- Telegram (Bot API / Polling + Webhook)
- Slack
- Discord
- Unified message reply & threading abstraction
Contributions are welcome!
- New platform adapters
- Bug fixes
- Documentation improvements
- Design discussions
Feel free to open an Issue or Pull Request.
MIT License