Skip to content
ALL PROJECTS

...MAIN PROJECT... / 01

opencode-telegram

Active

Your coding agent can now tap you on the shoulder.

ROLE
Creator & maintainer
YEAR
2026
STATUS
Active
LANGUAGE
Go
GoTelegram Bot APISSERESTBash

...OVERVIEW...

What it is

Long-running coding sessions have an awkward shape. You start an agent on a refactor, watch the first few steps, then go make coffee. By the time you come back it has either finished, failed, or stopped to ask a question forty minutes ago.

opencode-telegram closes that gap. A small Go daemon runs beside OpenCode, listens to the live event stream for every session, and sends the moments that need a human to a Telegram bot you control. Notifications are the default; acting from Telegram is a switch you have to turn on.

...LIVE DEMO...

Agent, meet phone.

Pick an interaction and watch an OpenCode session hand off to Telegram. The phone is live: answer the agent, approve a permission, or send a prompt.

...LIVE SIMULATION...

01 / Session finished

running
opencode — ~/projects/postal
OpenCode
postal-ui

·enable JavaScript to run the simulation

❯
~/projects/postal Telegram on shift+tab agents ctrl+p commands
session idle
09:41
OpenCode

opencode-telegram

bot

enable JavaScript to run the simulation
OpenCode

opencode-telegram · now

Session finished

A completed run lands on your phone.

...CHOOSE AN INTERACTION...

Try a scenario

The phone is live. Click the buttons inside the chat when a scenario asks you to.

w GitHub Source, issues and releases.

Simulation only. In the real daemon, notifications are off by default, and prompting or custom answers are opt-in.

...WHAT YOU ARE WATCHING...

01 / OPENCODE

The session emits SSE events: finished, failed, questions, permissions and retries.

02 / DAEMON

The Go daemon filters events through the allowlist and turns the ones that need you into messages.

03 / TELEGRAM

Your allowlisted chat gets the notification. When you answer, the decision travels back to the session.

Why a daemon instead of a plugin

A plugin only lives as long as the TUI is open. A daemon can keep listening while you close the terminal, switch projects, or leave the machine running. It discovers the local OpenCode service from service.json, authenticates with its password, and subscribes to the filtered SSE event stream.

When the connection drops it reconnects with backoff, then reconciles any forms and permissions that arrived while it was away. That reconciliation matters: a missed permission request is the difference between an agent that keeps working and one that sits still.

What reaches your phone

  • 01

    Session events

    Finished, failed, interrupted, and optionally provider retries. Child sessions stay quiet by default because subagents finish constantly.

  • 02

    Questions

    When OpenCode shows a form that needs a human answer, the notification includes the options. With custom answers disabled — the default — you can only choose what the form offers.

  • 03

    Permissions

    Approve or deny the same permission prompt you would see in the TUI. Telegram is not trusted by default; the allowlist and the security switches decide what it can do.

  • 04

    Output and thinking

    Notifications can include the last assistant message. Long output is split at paragraph boundaries instead of being silently truncated, and buttons can summarize the output or reasoning without polluting the session history.

Security is the design constraint

A Telegram account is not a trusted prompt source, so the daemon is deliberately boring about access. The allowlist requires both the sending user and the chat. A missing or corrupt allowlist file denies everyone. Custom form answers, new prompts and model switching are off unless you enable them. Unauthorized updates are dropped silently.

The companion OpenCode plugin exposes /telegram in the TUI to turn notifications on or off and to edit the daemon settings through a loopback HTTP API. The daemon itself never exposes that API beyond localhost.

Small details that make it usable

An installer builds the binary, copies it to ~/.local/share/opencode-telegram, and creates a launcher in ~/.local/bin. A --systemd flag writes a user service. Rich Telegram messages render headings, lists and code blocks, with a plain-text fallback when the server does not support them. A status command reports the daemon and OpenCode connection state.