...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.
·enable JavaScript to run the simulation
opencode-telegram
bot
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.
Simulation only. In the real daemon, notifications are off by default, and prompting or custom answers are opt-in.
...WHAT YOU ARE WATCHING...
The session emits SSE events: finished, failed, questions, permissions and retries.
The Go daemon filters events through the allowlist and turns the ones that need you into messages.
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.