Custom Telegram MCP server + TUI auto-responder for running Claude Code as an autonomous Telegram agent
Project description
claude-code-telegrammer
Custom Telegram MCP server + TUI auto-responder for running Claude Code as an autonomous Telegram agent
Documentation ·
pip install claude-code-telegrammer
What it is: a self-contained Telegram bridge for Claude Code — a Bun MCP server that turns any Claude Code session into an autonomous agent you talk to over Telegram, plus a TUI watchdog that keeps it running unattended. Each agent runs its own bot, its own message store, and fails loud on misconfiguration.
Problem and Solution
| # | Problem | Solution |
|---|---|---|
| 1 | Hardcoded pathsThe official plugin hardcodes~/.claude/ as its state directory (#851), making it impossible to run multiple bots or customize where access.json lives. |
Configurable state directoryAll state (DB, lock, access config) lives underCLAUDE_CODE_TELEGRAMMER_AGENT_STATE_DIR. Run as many bots as you want, each with its own isolated state. |
| 2 | 409 Conflict crashesNo single-instance guard — multiple sessions polling the same bot get 409 errors and crash each other (#1075). |
PID-based lockAutomatic single-instance enforcement via PID lock file. Second instance detects the conflict and waits instead of crashing. |
| 3 | Zombie CPU consumptionAfter session ends, the plugin process lingers at 100% CPU — requires manual kill (#1146). |
Clean shutdownExits gracefully on stdin close, SIGTERM, or SIGINT. No zombies, no manual cleanup. |
| 4 | Only 3 basic toolsThe official plugin provides just send, get_updates, and set_reaction — no history, no search, no file handling, no message editing. |
10 MCP toolsreply, react, edit_message, get_history, get_unread, mark_read, download_attachment, send_document, search_messages, get_context — everything an autonomous agent needs. |
| 5 | No message persistenceMessages vanish after delivery. No way to search past conversations, track read status, or build context from history. |
SQLite message storeAll messages persisted in WAL-mode SQLite with full-text search, reply threading (reply_to_message_id), read/replied tracking, and attachment metadata. |
| 6 | No access control for groupsBasic allowlist only — no per-group policies, no hot-reload when config changes. |
DM + group policiesAllowlist-based access control with separate DM and group chat policies viaaccess.json, hot-reloaded on file change (mtime-based). |
| 7 | No attachment supportCannot download inbound files or upload documents to chats. |
Full attachment handlingInbound photos, documents, voice, audio, and video are auto-downloaded. Upload local files viasend_document tool. |
| 8 | Sessions stall unattendedClaude Code halts at permission prompts or idle states with no way to recover — the agent just stops working. |
TUI WatchdogPolls GNU Screen buffer, detects TUI state via pattern matching, sends keystrokes to auto-accept prompts and re-engage on idle. Throttled with burst limits. |
Table 1. Eight issues with the official Telegram plugin (as of April 2026) and how claude-code-telegrammer addresses each.
Quickstart
Prerequisites: Bun ≥ 1.0 (MCP server); GNU Screen (watchdog, optional).
git clone https://github.com/ywatanabe1989/claude-code-telegrammer.git
cd claude-code-telegrammer/ts && bun install
1. Get a bot token — message @BotFather, send
/newbot, and copy the token (123456789:AAH...). Open your bot and send it any
message. Verify: curl -s "https://api.telegram.org/bot<TOKEN>/getMe".
2. Register the MCP server with Claude Code — copy .mcp.json.example to
.mcp.json (gitignored) and set CLAUDE_CODE_TELEGRAMMER_BOT_TOKEN +
CLAUDE_CODE_TELEGRAMMER_ALLOWED_USERS (your Telegram user id, from
@userinfobot). Full env reference:
docs/configuration.md.
3. Run:
claude --dangerously-skip-permissions \
--dangerously-load-development-channels server:claude-code-telegrammer
You should see Listening for channel messages from: server:claude-code-telegrammer.
Message your bot from Telegram — Claude Code receives it as a channel notification.
Architecture
flowchart LR
op["Operator<br/>(Telegram app)"]
bot["Telegram Bot API<br/>per-agent bot token"]
op <-->|messages| bot
subgraph agent["One agent — isolated home"]
direction TB
srv["telegram-server.ts<br/>(Bun MCP server)"]
gate{"allowlist gate<br/>CCT_ALLOWED_USERS<br/>+ access.json"}
db[("state dir · per-agent<br/>messages.db · lock<br/>CCT_AGENT_STATE_DIR")]
cc["Claude Code<br/>(the agent)"]
srv -->|inbound| gate
gate -->|"allowed → channel notification"| cc
cc -->|"reply · react · send_document (MCP stdio)"| srv
srv <--> db
end
bot -->|"getUpdates (long-poll)"| srv
srv -->|sendMessage| bot
The MCP server long-polls Telegram, gates inbound messages through the allowlist,
and delivers them to Claude Code as channel notifications; the agent replies
through MCP tools. Each agent is self-contained — its own bot token, its own
per-agent state dir, its own poller — and fails loud at startup on any
misconfiguration (missing/invalid token, unexpanded ${…}, or a renamed env
var). Deep dive: docs/architecture.md.
Interfaces
- MCP server — 11 tools over stdio (
reply,react,edit_message,get_history,get_unread,mark_read,download_attachment,send_document,search_messages,get_context,health) with a built-in responsiveness policy. See docs/interfaces.md. - config probe —
bun run ts/telegram-server.ts config [--check]prints the resolved config as JSON for orchestrator preflight. - health (doctor) —
bun run ts/telegram-server.ts health(also exposed as thehealthMCP tool) runs 10 checks — env hygiene, token presence/validity, webhook absence, poller liveness, allowlist, state dir, DB schema/offset — and prints{package, ok, checks[], summary}; every failing check carries an actionable hint. See docs/interfaces.md. - Skill — bundled at
src/claude_code_telegrammer/_skills/claude-code-telegrammer/SKILL.md.
Part of SciTeX
claude-code-telegrammer is part of SciTeX — the Telegram communication layer and TUI watchdog used by scitex-agent-container (lifecycle, health, restart) and scitex-orochi (agent definitions, dashboard) for autonomous agent operation. See the agent stack.
References
- Claude Code Channels -- Claude Code's channel system
- Official Telegram Plugin -- the
plugin:telegram@claude-plugins-officialsource - #851 · #1075 · #1146 -- the upstream issues this project fixes
- Telegram BotFather · Telegram Bot API · MCP Specification
- Issues · Pull Requests
Four Freedoms for Research
- The freedom to run your research anywhere -- your machine, your terms.
- The freedom to study how every step works -- from raw data to final manuscript.
- The freedom to redistribute your workflows, not just your papers.
- The freedom to modify any module and share improvements with the community.
AGPL-3.0 -- because we believe research infrastructure deserves the same freedoms as the software it runs on.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file claude_code_telegrammer-0.5.6.tar.gz.
File metadata
- Download URL: claude_code_telegrammer-0.5.6.tar.gz
- Upload date:
- Size: 3.1 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25200684bc5ca8c822c0891013b3c722407ed71ba3850bafe949907afe55cc0d
|
|
| MD5 |
6ee5d748c8f32d8ddbdfac0eb2a01284
|
|
| BLAKE2b-256 |
bc0163c2224e5ef924e9ee921d5eb9aa46d50812ba43b00b0f43e53087354bb5
|
Provenance
The following attestation bundles were made for claude_code_telegrammer-0.5.6.tar.gz:
Publisher:
pypi-publish-and-github-release-on-tag.yml on scitex-ai/claude-code-telegrammer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_code_telegrammer-0.5.6.tar.gz -
Subject digest:
25200684bc5ca8c822c0891013b3c722407ed71ba3850bafe949907afe55cc0d - Sigstore transparency entry: 2158235500
- Sigstore integration time:
-
Permalink:
scitex-ai/claude-code-telegrammer@21f99f7db7da3b19e9be21d2247bd79e98ea36de -
Branch / Tag:
refs/tags/v0.5.6 - Owner: https://github.com/scitex-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish-and-github-release-on-tag.yml@21f99f7db7da3b19e9be21d2247bd79e98ea36de -
Trigger Event:
push
-
Statement type:
File details
Details for the file claude_code_telegrammer-0.5.6-py3-none-any.whl.
File metadata
- Download URL: claude_code_telegrammer-0.5.6-py3-none-any.whl
- Upload date:
- Size: 21.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
390c91d533885a7dea99ad74fd51f030a387d5283c15dd6de80eccca5c3ee3e4
|
|
| MD5 |
561b5f82fa69bca15204d5110dc382fd
|
|
| BLAKE2b-256 |
61a6d0547c78a858756623ec61e30796500da562a9d1f280f4f7925c92378d8d
|
Provenance
The following attestation bundles were made for claude_code_telegrammer-0.5.6-py3-none-any.whl:
Publisher:
pypi-publish-and-github-release-on-tag.yml on scitex-ai/claude-code-telegrammer
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
claude_code_telegrammer-0.5.6-py3-none-any.whl -
Subject digest:
390c91d533885a7dea99ad74fd51f030a387d5283c15dd6de80eccca5c3ee3e4 - Sigstore transparency entry: 2158235563
- Sigstore integration time:
-
Permalink:
scitex-ai/claude-code-telegrammer@21f99f7db7da3b19e9be21d2247bd79e98ea36de -
Branch / Tag:
refs/tags/v0.5.6 - Owner: https://github.com/scitex-ai
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pypi-publish-and-github-release-on-tag.yml@21f99f7db7da3b19e9be21d2247bd79e98ea36de -
Trigger Event:
push
-
Statement type: