Skip to content

bil9148/opencode-telegram-bridge

Repository files navigation

opencode-telegram-bridge

Control OpenCode from Telegram. The agent runs in an isolated Docker container - it can work on your repo but can't touch anything else on your system.

Telegram  -->  Bridge Container  -->  Agent Container (OpenCode)
                  (Node.js)              (Ubuntu, read-only rootfs)
                                         └── /workspace = your repo

Setup

Prerequisites

  • Docker
  • OpenCode installed on host (pacman -S opencode or however you install it)
  • Authenticated with OpenCode (opencode auth login)
  • A Telegram bot token from @BotFather
  • Your Telegram user ID from @userinfobot

Install

git clone https://github.com/bil9148/opencode-telegram-bridge.git
cd opencode-telegram-bridge

# Copy the opencode binary into the build context
cp $(which opencode) ./opencode

# Configure
cp .env.example .env
# Edit .env with your values

.env

TELEGRAM_BOT_TOKEN=<from @BotFather>
ALLOWED_USER_IDS=<your numeric Telegram user ID>
PROJECT_PATH=/home/you/repos/your-project
PROJECT_NAME=your-project

The agent authenticates using your existing OpenCode OAuth tokens (~/.local/share/opencode/auth.json), mounted read-only. No API key needed. If tokens expire, run opencode auth login on your host.

Build and run

# Build images (use --network host if behind VPN)
docker build --network host -t opencode-telegram-bridge-opencode-agent .
docker build --network host -t opencode-telegram-bridge-telegram-bridge -f Dockerfile.bridge .

# Start
docker compose up -d

# Watch logs
docker compose logs -f telegram-bridge

Or use the start script:

chmod +x start.sh
./start.sh

Commands

Core

Command Description
/code <prompt> Send a prompt to OpenCode
/exec <command> Run a shell command in the container

Model and Agent

Command Description
/model [provider/model] Get or set the model
/models [provider] List available models
/agent [name] Get or set the agent
/agents List available agents
/variant [high|max|minimal] Set reasoning effort

Sessions

Command Description
/session [last|id|new] Get or set the active session
/sessions List recent sessions
/export [session-id] Export session as JSON

Project

Command Description
/workspace [subpath] List files in workspace
/pr <number> Checkout and review a GitHub PR
/stats [days] Token usage and cost stats

System

Command Description
/status Container status and current settings
/auth Check auth status
/mcp List MCP servers
/config Show resolved OpenCode config
/paths Show OpenCode paths

Architecture

Two containers:

  • opencode-agent - Ubuntu with the OpenCode binary. Mounts your repo at /workspace. Read-only root filesystem, all capabilities dropped, no sudo, resource-limited (8 CPU / 16GB RAM).
  • telegram-bridge - Node.js bot that receives Telegram messages and executes commands in the agent container via Docker socket. Also hardened (read-only, caps dropped, 1 CPU / 512MB RAM).

What the agent can access:

  • /workspace (your repo, read-write)
  • OAuth tokens (read-only, for Anthropic API)
  • OpenCode config (read-only)
  • Internet (for API calls, routed through host network)

What the agent cannot access:

  • Your host filesystem (outside the mounted repo)
  • Other Docker containers
  • The Docker socket

Multiple projects

Deploy one instance per project. Clone the repo into separate directories or use different .env files:

# Project A
PROJECT_PATH=/home/you/repos/project-a
PROJECT_NAME=project-a

# Project B (separate .env, separate bot token)
PROJECT_PATH=/home/you/repos/project-b
PROJECT_NAME=project-b

Each gets its own pair of containers (opencode-project-a, bridge-project-a, etc).

VPN (Wireguard/Mullvad)

Both containers use network_mode: host because Docker bridge networks can't route through Wireguard tunnels. This means the containers share the host's network stack. Filesystem isolation is still fully intact.

If you're not using a VPN, you can switch to bridge networking by removing network_mode: host and adding a networks: section. This adds network namespace isolation at the cost of needing DNS configuration.

Security notes

  • The Docker socket is mounted into the bridge container. If the bridge is compromised, an attacker could interact with Docker on your host. The bridge is hardened (read-only, no capabilities, resource-limited) to minimize this risk.
  • OAuth tokens are mounted read-only but readable by the agent. A malicious prompt or repo config could theoretically exfiltrate them. The blast radius is limited to your Anthropic subscription.
  • host network mode means the agent can see your LAN. If this concerns you and you're not on a VPN, use bridge networking instead.
  • The bot refuses to start without ALLOWED_USER_IDS set. Commands are queued one at a time to prevent races.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages