{"id":49103376,"url":"https://github.com/ywatanabe1989/claude-code-telegrammer","last_synced_at":"2026-04-21T00:12:28.694Z","repository":{"id":349741735,"uuid":"1203708760","full_name":"ywatanabe1989/claude-code-telegrammer","owner":"ywatanabe1989","description":"Screen-based auto-responder watchdog for Claude Code TUI — autonomous Telegram agent with just GNU Screen and Bash","archived":false,"fork":false,"pushed_at":"2026-04-07T11:25:28.000Z","size":393,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-07T11:31:42.635Z","etag":null,"topics":["automation","claude-code","screen","telegram","watchdog"],"latest_commit_sha":null,"homepage":null,"language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ywatanabe1989.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-07T09:46:53.000Z","updated_at":"2026-04-07T10:20:07.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/ywatanabe1989/claude-code-telegrammer","commit_stats":null,"previous_names":["ywatanabe1989/claude-code-telegrammer"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/ywatanabe1989/claude-code-telegrammer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fclaude-code-telegrammer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fclaude-code-telegrammer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fclaude-code-telegrammer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fclaude-code-telegrammer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ywatanabe1989","download_url":"https://codeload.github.com/ywatanabe1989/claude-code-telegrammer/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ywatanabe1989%2Fclaude-code-telegrammer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32071073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T21:26:33.338Z","status":"ssl_error","status_checked_at":"2026-04-20T21:26:22.081Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","claude-code","screen","telegram","watchdog"],"created_at":"2026-04-21T00:12:27.797Z","updated_at":"2026-04-21T00:12:28.667Z","avatar_url":"https://github.com/ywatanabe1989.png","language":"Shell","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- ---\n!-- Timestamp: 2026-04-10 18:13:14\n!-- Author: ywatanabe\n!-- File: /home/ywatanabe/proj/claude-code-telegrammer/README.md\n!-- --- --\u003e\n\n\u003c!-- SciTeX Convention: Header (logo, tagline, badges) --\u003e\n# claude-code-telegrammer\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://scitex.ai\"\u003e\n    \u003cimg src=\"docs/scitex-logo-blue-cropped.png\" alt=\"SciTeX\" width=\"400\"\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\u003cb\u003eCustom Telegram MCP server + TUI auto-responder for running Claude Code as an autonomous Telegram agent\u003c/b\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://badge.fury.io/py/claude-code-telegrammer\"\u003e\u003cimg src=\"https://badge.fury.io/py/claude-code-telegrammer.svg\" alt=\"PyPI version\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://claude-code-telegrammer.readthedocs.io/\"\u003e\u003cimg src=\"https://readthedocs.org/projects/claude-code-telegrammer/badge/?version=latest\" alt=\"Documentation\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/ywatanabe1989/claude-code-telegrammer/actions/workflows/test.yml\"\u003e\u003cimg src=\"https://github.com/ywatanabe1989/claude-code-telegrammer/actions/workflows/test.yml/badge.svg\" alt=\"Tests\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.gnu.org/licenses/agpl-3.0\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-AGPL--3.0-blue.svg\" alt=\"License: AGPL-3.0\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://claude-code-telegrammer.readthedocs.io/\"\u003eDocumentation\u003c/a\u003e ·\n  \u003ccode\u003epip install claude-code-telegrammer\u003c/code\u003e\n\u003c/p\u003e\n\n---\n\n## Problem and Solution\n\n\u003ctable\u003e\n\u003ctr\u003e\n  \u003cth align=\"center\"\u003e#\u003c/th\u003e\n  \u003cth\u003eProblem\u003c/th\u003e\n  \u003cth\u003eSolution\u003c/th\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e1\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eHardcoded paths\u003c/h4\u003eThe official plugin hardcodes \u003ccode\u003e~/.claude/\u003c/code\u003e as its state directory (\u003ca href=\"https://github.com/anthropics/claude-code/issues/851\"\u003e#851\u003c/a\u003e), making it impossible to run multiple bots or customize where access.json lives.\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eConfigurable state directory\u003c/h4\u003eAll state (DB, lock, access config) lives under \u003ccode\u003eCLAUDE_CODE_TELEGRAMMER_TELEGRAM_STATE_DIR\u003c/code\u003e. Run as many bots as you want, each with its own isolated state.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e2\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003e409 Conflict crashes\u003c/h4\u003eNo single-instance guard — multiple sessions polling the same bot get 409 errors and crash each other (\u003ca href=\"https://github.com/anthropics/claude-code/issues/1075\"\u003e#1075\u003c/a\u003e).\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003ePID-based lock\u003c/h4\u003eAutomatic single-instance enforcement via PID lock file. Second instance detects the conflict and waits instead of crashing.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e3\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eZombie CPU consumption\u003c/h4\u003eAfter session ends, the plugin process lingers at 100% CPU — requires manual kill (\u003ca href=\"https://github.com/anthropics/claude-code/issues/1146\"\u003e#1146\u003c/a\u003e).\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eClean shutdown\u003c/h4\u003eExits gracefully on stdin close, SIGTERM, or SIGINT. No zombies, no manual cleanup.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e4\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eOnly 3 basic tools\u003c/h4\u003eThe official plugin provides just send, get_updates, and set_reaction — no history, no search, no file handling, no message editing.\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003e10 MCP tools\u003c/h4\u003ereply, react, edit_message, get_history, get_unread, mark_read, download_attachment, send_document, search_messages, get_context — everything an autonomous agent needs.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e5\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eNo message persistence\u003c/h4\u003eMessages vanish after delivery. No way to search past conversations, track read status, or build context from history.\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eSQLite message store\u003c/h4\u003eAll messages persisted in WAL-mode SQLite with full-text search, reply threading (reply_to_message_id), read/replied tracking, and attachment metadata.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e6\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eNo access control for groups\u003c/h4\u003eBasic allowlist only — no per-group policies, no hot-reload when config changes.\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eDM + group policies\u003c/h4\u003eAllowlist-based access control with separate DM and group chat policies via \u003ccode\u003eaccess.json\u003c/code\u003e, hot-reloaded on file change (mtime-based).\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e7\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eNo attachment support\u003c/h4\u003eCannot download inbound files or upload documents to chats.\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eFull attachment handling\u003c/h4\u003eInbound photos, documents, voice, audio, and video are auto-downloaded. Upload local files via \u003ccode\u003esend_document\u003c/code\u003e tool.\u003c/td\u003e\n\u003c/tr\u003e\n\u003ctr valign=\"top\"\u003e\n  \u003ctd align=\"center\"\u003e8\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eSessions stall unattended\u003c/h4\u003eClaude Code halts at permission prompts or idle states with no way to recover — the agent just stops working.\u003c/td\u003e\n  \u003ctd\u003e\u003ch4\u003eTUI Watchdog\u003c/h4\u003ePolls GNU Screen buffer, detects TUI state via pattern matching, sends keystrokes to auto-accept prompts and re-engage on idle. Throttled with burst limits.\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003cp align=\"center\"\u003e\u003csub\u003e\u003cb\u003eTable 1.\u003c/b\u003e Eight issues with the official Telegram plugin (as of April 2026) and how claude-code-telegrammer addresses each. These problems make the official plugin unusable for production autonomous agents.\u003c/sub\u003e\u003c/p\u003e\n\n### Architecture\n\n1. **Custom Telegram MCP Server** (`ts/`) -- Self-contained Bun + MCP server. 10 tools, SQLite persistence, allowlist access control, attachment handling, reaction support. Incoming messages acknowledged with 📩. Built-in responsiveness policy directs the agent to reply immediately and delegate heavy work to background subagents.\n\n2. **TUI Watchdog** (`lib/`) -- Polls a GNU Screen session, detects Claude Code's TUI state via pattern matching, and sends keystrokes to keep the agent running unattended (auto-accepts permission prompts, re-engages on idle). Throttled with burst limits to prevent runaway responses. Orchestration handled by [scitex-agent-container](https://github.com/ywatanabe1989/scitex-agent-container).\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMCP Tools (10)\u003c/strong\u003e\u003c/summary\u003e\n\n| Tool | Description |\n|------|-------------|\n| `reply` | Reply on Telegram. Supports threading (`reply_to`), auto-marks inbound as read. Inbound reply-to-message references are tracked and forwarded. |\n| `react` | Add an emoji reaction to a message. Inbound reactions (`message_reaction`) are also delivered as channel notifications. |\n| `edit_message` | Edit a previously sent bot message. |\n| `get_history` | Retrieve message history for a chat from local SQLite. |\n| `get_unread` | List unread inbound messages, optionally filtered by `chat_id`. |\n| `mark_read` | Mark messages as read by `chat_id` or `message_ids`. |\n| `download_attachment` | Download a Telegram file by `file_id`, returns local path. |\n| `send_document` | Upload a local file to a Telegram chat. |\n| `search_messages` | Text search across stored messages. |\n| `get_context` | Recent conversation formatted as compact text for LLM context. |\n\n\u003c/details\u003e\n\n### Important: Bot Token Exclusivity\n\nThis MCP server **must be the sole consumer** of its configured Telegram bot token. The Telegram Bot API allows only one `getUpdates` long-polling connection per token.\n\n**What happens with duplicate consumers:**\n\n| Scenario | Symptom | Detection |\n|----------|---------|-----------|\n| Two pollers start simultaneously | One gets 409, the other wins silently | The loser sees `409 Conflict` in logs |\n| Two pollers start sequentially | Both appear to work, but only one receives messages | **No error** — the other poller gets empty responses forever |\n| Webhook active + poller | Poller gets nothing | **No error** — Telegram ignores `getUpdates` when webhook is set |\n\n**Why 409 detection alone is insufficient:** The Telegram API does not reliably return 409 for all conflict cases. When two consumers poll sequentially (not overlapping), both connections succeed — one simply receives all messages while the other gets none, with no error. The server performs a `timeout=3` preflight check at startup to catch overlapping polls, but this cannot detect the sequential case.\n\n**If messages aren't arriving:**\n1. Check if another process is polling the same token: `ps aux | grep telegram-server`\n2. Check if a webhook is set: `curl https://api.telegram.org/bot\u003cTOKEN\u003e/getWebhookInfo`\n3. Use a separate bot token per component (recommended)\n4. Or disable the other consumer\n\n**Alternative: Webhook mode via scitex-orochi.** If you run [scitex-orochi](https://github.com/ywatanabe1989/scitex-orochi), it supports Telegram webhook mode (`POST /webhook/telegram/`) which eliminates polling conflicts entirely. Telegram pushes updates to a single HTTPS endpoint instead of competing pollers. See `SCITEX_OROCHI_TELEGRAM_WEBHOOK_URL` in the orochi documentation.\n\n## Installation\n\n### Prerequisites\n\n- [Bun](https://bun.sh/) \u003e= 1.0 (for the MCP server)\n- GNU Screen (for watchdog, optional)\n\n### Install\n\n```bash\ngit clone https://github.com/ywatanabe1989/claude-code-telegrammer.git\ncd claude-code-telegrammer/ts \u0026\u0026 bun install\n```\n\n## Quickstart\n\n### Get a Telegram Bot Token\n\n1. Open Telegram and message [@BotFather](https://t.me/BotFather)\n2. Send `/newbot`, then enter a name (e.g., `Claude Code Telegrammer`) and a username (e.g., `ClaudeCodeTelegrammerBot`)\n3. BotFather replies with your token: `123456789:AAH...`\n4. Verify your token works:\n   ```bash\n   curl -s \"https://api.telegram.org/bot\u003cYOUR_TOKEN\u003e/getMe\"\n   # Should return {\"ok\":true,\"result\":{\"is_bot\":true,...}}\n   ```\n5. Open your bot (e.g., [t.me/ClaudeCodeTelegrammerBot](https://t.me/ClaudeCodeTelegrammerBot)) and send any message to start a conversation\n\n### Register MCP Server with Claude Code\n\nCopy the example and fill in your values (`.mcp.json` is gitignored):\n\n```json\n{\n  \"mcpServers\": {\n    \"claude-code-telegrammer\": {\n      \"type\": \"stdio\",\n      \"command\": \"bun\",\n      \"args\": [\"run\", \"/path/to/claude-code-telegrammer/ts/telegram-server.ts\"],\n      \"env\": {\n        \"CLAUDE_CODE_TELEGRAMMER_TELEGRAM_BOT_TOKEN\": \"123456789:AAH...\",\n        \"CLAUDE_CODE_TELEGRAMMER_TELEGRAM_ALLOWED_USERS\": \"YOUR_TELEGRAM_USER_ID\",\n        \"CLAUDE_CODE_TELEGRAMMER_TELEGRAM_STATE_DIR\": \"~/.claude-code-telegrammer\"\n      }\n    }\n  }\n}\n```\n\n```bash\ncp .mcp.json.example .mcp.json\n# Edit .mcp.json with your token, user ID, and paths\n```\n\nFind your Telegram user ID by messaging [@userinfobot](https://t.me/userinfobot).\n\n### Run\n\n```bash\nclaude \\\n    --dangerously-skip-permissions \\\n    --dangerously-load-development-channels server:claude-code-telegrammer\n```\n\nYou should see `Listening for channel messages from: server:claude-code-telegrammer` in the Claude Code TUI. Send a message from Telegram to your bot — Claude Code will receive it as a channel notification.\n\n## Interfaces\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eMCP Server -- for AI Agents\u003c/strong\u003e\u003c/summary\u003e\n\nStart command:\n```bash\nbun run ts/telegram-server.ts\n```\n\n10 tools exposed via MCP stdio protocol. See [MCP Tools](#solution) above. The server's MCP instructions include a responsiveness policy that directs the agent to acknowledge messages immediately and delegate heavy work to background subagents.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSkills -- for AI Agent Discovery\u003c/strong\u003e\u003c/summary\u003e\n\nSkills are bundled at `src/claude_code_telegrammer/_skills/claude-code-telegrammer/SKILL.md`.\n\n\u003c/details\u003e\n\n## Architecture\n\n```\nUser (Telegram)\n    |\n    |  Bot API (getUpdates long-polling)\n    v\n┌──────────────────────────────────────────────────────────────┐\n│  Custom Telegram MCP Server (ts/telegram-server.ts)          │\n│    Bun + @modelcontextprotocol/sdk                           │\n│                                                              │\n│    ┌─────────┐  ┌─────────┐  ┌──────────┐  ┌────────────┐    │\n│    │ Poller  │  │  Store  │  │  Tools   │  │ Attachments│    │\n│    │ (long   │  │ (SQLite │  │ (10 MCP  │  │ (download  │    │\n│    │  poll)  │  │  WAL)   │  │  tools)  │  │  queue)    │    │\n│    └─────────┘  └─────────┘  └──────────┘  └────────────┘    │\n│    ┌─────────┐  ┌─────────┐  ┌──────────┐                    │\n│    │ Access  │  │  Config │  │   Lock   │                    │\n│    │ (allow- │  │ (env    │  │ (PID     │                    │\n│    │  list)  │  │  vars)  │  │  file)   │                    │\n│    └─────────┘  └─────────┘  └──────────┘                    │\n└──────────────────────┬───────────────────────────────────────┘\n                       │ MCP stdio\n                       v\n┌──────────────────────────────────────────────────────────────┐\n│  Claude Code (in GNU Screen session)                         │\n│    --mcp-config points to the custom MCP server              │\n└──────────────────────┬───────────────────────────────────────┘\n                       │ screen buffer\n                       v\n┌──────────────────────────────────────────────────────────────┐\n│  Watchdog (claude-code-telegrammer-watchdog)                 │\n│    Polls screen buffer every 1.5s                            │\n│    Detects: y/n prompt -\u003e \"1\", y/y/n -\u003e \"2\", idle -\u003e cmd     │\n│    Throttled: burst limit, same-state delay, min interval    │\n└──────────────────────────────────────────────────────────────┘\n```\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eState Detection\u003c/strong\u003e\u003c/summary\u003e\n\n| State | Pattern | Response |\n|-------|---------|----------|\n| `running` | `(esc to interrupt)`, `tokens ·`, `ing...` | No action |\n| `y_n` | `1. Yes` + `3. No` (two-choice prompt) | Send `1` (accept) |\n| `y_y_n` | `2. Yes, and...` / `2. Yes, allow...` / `2. Yes, don't ask...` | Send `2` (accept all) |\n| `waiting` | Cooking puns (`Crafted for`, etc.), empty `\u003e` prompt, idle hints | Send configurable command |\n\nResponse throttling: minimum interval between responses, burst limit (10 in 3s window), same-state delay.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eConfiguration (Environment Variables)\u003c/strong\u003e\u003c/summary\u003e\n\n**MCP Server:**\n\n| Variable | Required | Default | Description |\n|----------|----------|---------|-------------|\n| `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_BOT_TOKEN` | Yes | -- | Telegram Bot API token |\n| `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_STATE_DIR` | No | `~/.claude-code-telegrammer` | Directory for SQLite DB, access.json, lock file |\n| `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_ALLOWED_USERS` | No | -- | Comma-separated Telegram user IDs for DM allowlist |\n| `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_HOST_NAME` | No | `os.hostname()` | Hostname stored with each message |\n| `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_PROJECT` | No | `process.cwd()` | Project path stored with each message |\n| `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_AGENT_ID` | No | `'telegram'` | Agent identifier stored with each message |\n\n**Watchdog:**\n\n| Variable | Default | Description |\n|----------|---------|-------------|\n| `CLAUDE_CODE_TELEGRAMMER_SESSION` | `claude-code-telegrammer` | GNU Screen session name |\n| `CLAUDE_CODE_TELEGRAMMER_WATCHDOG_INTERVAL` | `1.5` | Poll interval in seconds |\n| `CLAUDE_CODE_TELEGRAMMER_RESP_Y_N` | `1` | Response for y/n prompts |\n| `CLAUDE_CODE_TELEGRAMMER_RESP_Y_Y_N` | `2` | Response for y/y/n prompts |\n| `CLAUDE_CODE_TELEGRAMMER_RESP_WAITING` | `/speak-and-call` | Response when idle/waiting |\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eSQLite Schema (v2)\u003c/strong\u003e\u003c/summary\u003e\n\nAll messages persisted in `$CLAUDE_CODE_TELEGRAMMER_TELEGRAM_STATE_DIR/messages.db` using WAL mode.\n\n**messages table:** direction, chat_id, message_id, user_id, username, text, timestamps (telegram_ts, received_at, read_at, replied_at), threading (reply_to_message_id, reply_to_row_id), identity (host, project, agent_id, bot_token_hash), raw_json.\n\n**attachments table:** message_row_id (FK), kind, file_id, file_name, mime_type, file_size, local_path, downloaded_at.\n\n**meta table:** key-value store for schema_version, update_offset.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eIntegration with scitex-agent-container\u003c/strong\u003e\u003c/summary\u003e\n\nFor YAML-based agent orchestration (screen sessions, watchdog lifecycle, restart policies), see [scitex-agent-container](https://github.com/ywatanabe1989/scitex-agent-container).\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eAccess Control\u003c/strong\u003e\u003c/summary\u003e\n\nManaged via `access.json` in `$CLAUDE_CODE_TELEGRAMMER_TELEGRAM_STATE_DIR`:\n\n```json\n{\n  \"dmPolicy\": \"allowlist\",\n  \"allowFrom\": [\"123456789\"],\n  \"groups\": {\n    \"-100123456\": {\n      \"requireMention\": true,\n      \"allowFrom\": [\"123456789\"]\n    }\n  }\n}\n```\n\nMerged with `CLAUDE_CODE_TELEGRAMMER_TELEGRAM_ALLOWED_USERS` env var at runtime. Mtime-based caching means edits take effect without restart.\n\n\u003c/details\u003e\n\n\u003c!-- SciTeX Convention: Ecosystem --\u003e\n## Part of SciTeX\n\nclaude-code-telegrammer is part of [**SciTeX**](https://scitex.ai). It provides the Telegram communication layer and TUI watchdog used by [scitex-agent-container](https://github.com/ywatanabe1989/scitex-agent-container) for autonomous agent operation.\n\n```\n┌─────────────────────────────────────────────────────────┐\n│ scitex-orochi         — agent definitions, dashboard    │\n└──────────────────────────┬──────────────────────────────┘\n                           v\n┌─────────────────────────────────────────────────────────┐\n│ scitex-agent-container  — lifecycle, health, restart    │\n└──────────────────────────┬──────────────────────────────┘\n                           v\n┌─────────────────────────────────────────────────────────┐\n│ claude-code-telegrammer  \u003c-- YOU ARE HERE               │\n│   MCP server: Telegram API, message DB, 10 tools        │\n│   Watchdog: TUI auto-response, screen polling           │\n└─────────────────────────────────────────────────────────┘\n```\n\n## References\n\n- [Claude Code Channels](https://docs.anthropic.com/en/docs/claude-code/channels) -- Official documentation for Claude Code's channel system\n- [Official Telegram Plugin](https://github.com/anthropics/claude-code/tree/main/plugins/telegram) -- The `plugin:telegram@claude-plugins-official` source code\n- [#851: STATE_DIR not respected](https://github.com/anthropics/claude-code/issues/851) -- Hardcoded access.json path\n- [#1075: 409 Conflict errors](https://github.com/anthropics/claude-code/issues/1075) -- Multiple instances polling the same bot\n- [#1146: Zombie CPU consumption](https://github.com/anthropics/claude-code/issues/1146) -- Runaway process after session ends\n- [Telegram BotFather](https://t.me/BotFather) -- Create and manage Telegram bots\n- [Telegram Bot API](https://core.telegram.org/bots/api) -- Official Bot API documentation\n- [MCP Specification](https://modelcontextprotocol.io/) -- Model Context Protocol standard\n- [claude-code-telegrammer Issues](https://github.com/ywatanabe1989/claude-code-telegrammer/issues) -- Bug reports and feature requests\n- [claude-code-telegrammer Pull Requests](https://github.com/ywatanabe1989/claude-code-telegrammer/pulls) -- Contributions\n\n\u003c!-- SciTeX Convention: Footer (Four Freedoms + icon) --\u003e\n\u003eFour Freedoms for Research\n\u003e\n\u003e0. The freedom to **run** your research anywhere -- your machine, your terms.\n\u003e1. The freedom to **study** how every step works -- from raw data to final manuscript.\n\u003e2. The freedom to **redistribute** your workflows, not just your papers.\n\u003e3. The freedom to **modify** any module and share improvements with the community.\n\u003e\n\u003eAGPL-3.0 -- because we believe research infrastructure deserves the same freedoms as the software it runs on.\n\n---\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://scitex.ai\" target=\"_blank\"\u003e\u003cimg src=\"docs/scitex-icon-navy-inverted.png\" alt=\"SciTeX\" width=\"40\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c!-- EOF --\u003e","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fywatanabe1989%2Fclaude-code-telegrammer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fywatanabe1989%2Fclaude-code-telegrammer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fywatanabe1989%2Fclaude-code-telegrammer/lists"}