Controlling Claude Code from Telegram: How I Ran It for 60 Days with Zero Downtime on Windows
Table of Contents
- Most people's personal AI assistant does not survive a week
- Design choice #1: Telegram is the command console, not an output channel
- Design choice #2: Reliability is layered, not a single point
- Real incident #1: Two bun.exe processes stealing messages
- Real incident #2: Six TG-forgets
- Design choice #3: Two stateless workarounds
- Design choice #4: Lock the channel before you trust it
- Adversarial reviewer: the last line of defense against confirmation bias
- 60 days of real failure records
- Honestly, what this setup does NOT solve
- How to replicate it: the open-source toolkit
- The one-line wrap-up
🔴 Is Claude down right now? This post is about the system design that kept Claude Code running for 60 days with zero downtime. It is not a live status check. To find out in 30 seconds whether the platform is down or you have simply run out of usage, read this: Is Claude down? Check in 30 seconds whether it is the whole service or just you →
Most people's personal AI assistant does not survive a week
If you have used Claude Code, Cursor, or any "desktop AI assistant" for a while, you will notice a common pattern:
The first 3 days after installing it, you are excited. A week later, a small bug or a reboot hits, and the AI suddenly goes offline. Two weeks later, you realise it is only useful "while you are sitting at the computer". Leave the house and it is gone. A month later, you can no longer be bothered to open it.
I kept wondering whether it was just me. Then I talked to other solo founders and found almost everyone was the same. The AI assistant becomes "a window I can open to ask questions", not "a command system I can give orders to at any time".
Two months ago I made a somewhat extreme design choice: I turned Telegram into the main control interface for Claude Code, not just an output channel.
Today marks exactly 60 days. Zero outages (the small incidents were all handled automatically and never reached me). During 7 days of travel in Germany, while asleep in the middle of the night, in the bathroom, while queuing at a restaurant, I could open TG and drive a fleet of 8 AI agents.
This post dumps everything I learned over those 60 days. At the end there is an open-source toolkit (MIT License) you can fork directly.
Design choice #1: Telegram is the command console, not an output channel
Most people use Claude Code as a "tool": sit at the desk, open VS Code, type into the Claude chat panel, read the response. Leave the desk and you lose the AI.
My setup is the opposite: Telegram is the primary interface. Claude reads the TG messages I send through the official telegram MCP plugin and responds with TG replies. The desktop terminal is just one of the possible session runners.
This means I can:
- Type on my phone on the bus
- Type from a hotel room across time zones
- Type on a tablet while cooking
- Type in the terminal while sitting at my desk
All four paths flow through the same channel. There is only one history (the TG chat history), not "fragments of the sessions I had with the AI on different surfaces today".
The downstream consequence: every substantive deliverable Claude produces must be mirrored to TG, not just printed in the terminal. Forgetting this rule is failure mode #1 (later I explain how I detect it automatically).
Design choice #2: Reliability is layered, not a single point
Telegram on Windows can break in many specific ways. No single failure is fatal, but any one of them can take your "command console" out for the day.
My setup stacks 4 defense layers, each blocking a different class of failure:
| Layer | What it protects against |
|---|---|
| Boot script + silent launcher | Claude staying offline forever after a Windows reboot (any .bat in the Startup folder pops up a console; a .vbs hides it) |
zombie-killer.ps1 (scheduled every 2 minutes) |
Two bun.exe processes both polling getUpdates, so inbound messages randomly land in an old zombie process: a silent partial failure |
| Liveness watchdog | A single bun.exe that looks alive while its websocket is stuck, with Telegram getWebhookInfo showing inactive |
tg-mirror-check.py (a hook installed only today) |
Claude answers your TG question in the terminal, but your phone receives nothing |
No single layer blocks everything. The point is layers covering distinct failure classes, not "trying your best to be reliable".
Real incident #1: Two bun.exe processes stealing messages
The first time it happened was one morning. I asked Claude on TG, "What was the conclusion of last night's fleet report?" I waited 10 minutes with no reply and found it odd. Then I sent a second message, "You there?", and waited another 10 minutes.
I opened the terminal and looked at the process list: two bun.exe processes were running. One was a zombie left over from a VS Code Claude session I had opened the night before; the other belonged to the current session. Both were polling Telegram getUpdates, taking turns grabbing my messages. The first message was picked up by the zombie and thrown into nowhere.
The fix is not "kill bun". That only treats the symptom. The real fix is having zombie-killer patrol every 2 minutes and kill the older one whenever it sees more than one wrapper. I wrote 60 lines of PowerShell and have not hit the problem since.
Real incident #2: Six TG-forgets
Today's most satisfying incident: 6 times, after a long stretch of work, I forgot to mirror my answer back to TG. The reason: when switching from a flood of Bash/Edit/Read tool calls to "answering the boss's question", I defaulted to printing markdown in the transcript.
The boss had to catch me every time ("You didn't reply on TG again??"), and that wears down trust.
The fix: I wrote a Stop hook (it runs automatically at the end of every assistant turn):
Condition:
- The previous user message contains <channel source="plugin:telegram:telegram">
- My response did not call mcp__plugin_telegram_telegram__reply
→ Push a ⚠️ warning straight to the user through the TG bot API
On the day it was installed there were 0 missed replies, because knowing a hook was watching brought the discipline straight back. A systemic problem gets a systemic fix.
Design choice #3: Two stateless workarounds
LLM sessions are stateless by nature. Every new Claude Code session starts from zero: it does not remember what you talked about yesterday or know which projects you have on hand.
My setup has two pieces that work with Claude Code's built-in memory file system to get around this:
| Component | What it retains |
|---|---|
tg-log.py inject (SessionStart hook) |
The most recent ~20 TG messages, injected automatically at the start of every new session, so the assistant picks up right where you left off |
Your own markdown files in ~/.claude/projects/<project>/memory/ |
Long-term facts: user identity, feedback corrections, project status, references to external systems. Curated by hand, not generated automatically. |
Together, a new session has at the start: short-term TG history (from the inject hook) + long-term curated memory (from your memory folder). The net effect is an assistant that feels stateful even though it is not.
My memory has grown to 60+ entries so far. They include:
- Who I am (one-person company, language preferences, customer list)
- Past incidents (which PRs should not be opened again, which user has been escalated)
- Project context (the 6/1 spec for a B2B partner project, reflections on the Germany trip, the UltraProbe portfolio)
- Anti-patterns (which framings I do not want to use again, which technical traps not to step into)
Every major incident becomes a memory entry. As they accumulate, the AI's understanding of me gets more and more precise.
Design choice #4: Lock the channel before you trust it
Telegram bots are open by default: anyone who knows the bot's username can DM it. Putting Claude Code on the other end is an invitation to prompt injection attacks.
The official telegram MCP plugin already supports an allowlist (access.json with allowFrom) + a dmPolicy: pairing setting that requires you to manually approve every new conversation. Before you put anything important into the bot, set both.
This is an attack surface that is easy to overlook. I locked it down on day 1. Without it, Claude might today be leaking customer data to a stranger inside some prompt injection that got through.
Adversarial reviewer: the last line of defense against confirmation bias
After I finished the v3 architecture document and shipped it, I asked myself: "Is this professional enough? Nobody is going to see through it, right?"
The problem: when I review my own work, there is always confirmation bias. I can read it 10 times and still not see the bugs.
So I wrote a critic agent. Its single job is "find holes": actually verify every claim with grep / curl / Read / WebFetch. No hand-waving allowed. If it cannot find a problem, it says "found nothing", and it is not allowed to pretend there is one.
The first time I used it was on an OSS repo I had just written myself (the one shared at the end of this post). It caught 2 CRITICAL bugs:
- My hook installation steps wrote the path as
~/.claude/hooks/..., but neither Windows cmd nor Python expands~. Every new user following my docs would get a silent no-op. - I had leaked my own Telegram chat_id
781284060into two files. The first user to fork it would end up configured to alert my phone.
If I had merged directly, this OSS repo would have been hard to use from day one. The critic saved me once.
This was the most meaningful thing this verification showed: would the critic really let something with quality problems through? The answer is no. It set the verdict to BLOCK, and I had to fix things before I could merge. If the critic went easy on my own setup, it would be even less trustworthy on future deliverables.
60 days of real failure records
Finally, the data. These are the failure modes and their frequency over the past 60 days, with all 4 defense layers live:
- TG-forget (6 incidents): I answered the user in the terminal but forgot to mirror. Solved today by installing the hook.
- Phone TG sync problems (2 incidents): Telegram on the phone did not sync for hours. Fix: force-close and manually restart the app. There is no server-side tooling that can fix this.
- Zombie bun processes (~weekly, handled automatically): caught by
zombie-killer.ps1on its every-2-minutes patrol. Not once did one reach the user layer. - Windows reboots (planned + unplanned): the boot script recovers automatically. Zero manual steps.
That is all for 60 days. Everything else is noise.
Honestly, what this setup does NOT solve
To avoid misleading readers:
- Cost / token usage monitoring: this setup does not tell you how many Claude API tokens you have burned. Heavy users need to build their own cost dashboard.
- Multi-device redundancy: if phone TG sync breaks while you are travelling, the command console is offline until you can open a browser or restart the app. Some users solve this with an email mirror / a second Discord channel. I have not done it yet (cow is an existing backup and good enough).
- Output correctness: this setup makes Claude reachable, not right. The critic agent is the tool for that, but you have to invoke it yourself.
Admitting the problems is better than pretending there are none.
How to replicate it: the open-source toolkit
The full toolkit is open source at: https://github.com/ppcvote/claude-tg-windows
claude-tg-windows/
├── boot-scripts/ # Phase 1: boot + silent launcher
├── scripts/ # Phase 1: zombie-killer + health-check
├── hooks/ # Phase 2: tg-log + tg-mirror-check (added today)
├── agents/ # Phase 2: critic.md
├── examples/ # Phase 2: settings.json template
├── docs/ # workflow-architecture.md + setup-walkthrough.md
└── install.ps1 # One-click Phase 1 install
Installation (Phase 1 + Phase 2 together take about 20-25 minutes):
git clone https://github.com/ppcvote/claude-tg-windows.git
cd claude-tg-windows
powershell -ExecutionPolicy Bypass -File .\install.ps1
# Then run the Phase 2 steps in docs/setup-walkthrough.md manually
Prerequisites: Windows 10/11, Claude Code installed with the telegram MCP plugin configured, Bun on PATH, Git for Windows, Python 3.9+.
MIT License. Forks, PRs and bug reports are welcome.
The one-line wrap-up
The root reason personal AI assistants do not survive a week is not weak technology. It is the wrong design choices.
Treat it as a "tool" and it is a tool: useful while it is open, gone once it is closed. Treat it as a "command console" and it is a command console: online 24/7, driven from your pocket.
The difference is 4 design choices + 4 defense layers + 2 stateless workarounds + 1 adversarial reviewer. Under 1,000 lines of code in total.
If you are also a solo founder / one-person company, this setup is worth 25 minutes to install.
(Update, August 2026: if all you need is to drive your own Claude Code session from your phone, the official Remote Control feature now does that without a bridge; see Claude Code Remote Control: setup and a comparison with a Telegram bridge.)
One more thing: this style of writing, with real failure records and data, happens to be exactly the kind of content AI search engines are most willing to cite (Princeton's GEO research measured that adding statistics raises content's visibility in AI answers by roughly 30 to 40 percent in relative terms; the breakdown is in the GEO (Generative Engine Optimization) guide). If you also want ChatGPT and Perplexity to understand and cite your content, you can start with What is AEO.
Min Yi · Founder of Ultra Lab. MDRT (Million Dollar Round Table) member × AI security open-source contributor (7 PRs merged across Microsoft / Cisco / OWASP / UK Gov AISI as of publication on 2026-06-02; first published as 11, corrected on 2026-09-27 against GitHub merge records). Answers customer questions on Telegram 24/7 + drives a fleet of 8 AI agents (as of June 2026).
FAQ
How do I control Claude Code from Telegram?
Through the official telegram MCP plugin: Claude reads the TG messages you send and responds with TG replies, and the desktop terminal is just one of the possible session runners. Commands from your phone, tablet or terminal all flow through the same channel, so there is only one history (the TG chat history).
Is it safe to connect Claude Code to a Telegram bot? How do I prevent prompt injection?
Telegram bots are open by default: anyone who knows the bot's username can DM it. The official telegram MCP plugin already supports an allowlist (allowFrom in access.json) and a dmPolicy: pairing setting that requires you to manually approve every new conversation. Set both before you put anything important into the bot.
Why does Claude Code on Telegram stop receiving messages on Windows?
A common cause is two bun.exe processes both polling getUpdates, so inbound messages randomly land in an old zombie process. This setup has zombie-killer.ps1 patrol every 2 minutes and kill the older one whenever it sees more than one wrapper. A single bun.exe can also look alive while its websocket is stuck, which is what the liveness watchdog layer blocks.
How does a new Claude Code session pick up where the last one left off?
A SessionStart hook runs tg-log.py inject, which automatically injects the most recent 20 or so TG messages at the start of every new session; long-term facts live in your own hand-curated markdown files in ~/.claude/projects/<project>/memory/. Together they make the assistant feel stateful even though it is not.
How long does the Claude Code Telegram toolkit take to install, and what do I need?
The toolkit is open source under the MIT License at github.com/ppcvote/claude-tg-windows, and Phase 1 plus Phase 2 take about 20 to 25 minutes together. Prerequisites: Windows 10/11, Claude Code installed with the telegram MCP plugin configured, Bun on PATH, Git for Windows, and Python 3.9+.