After-hours Telegram MCP
Provides tools for interacting with the official Telegram Bot API, including checking bot status, long-polling updates, retrieving and acknowledging pending messages, and sending replies to allowlisted chats when sending is enabled.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@After-hours Telegram MCPcheck my Telegram bot status and list any pending messages"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
After-hours Telegram MCP
자신의 BotFather 토큰으로 실행하는 단일 소유자용 공식 Telegram Bot API MCP 서버. 인증된 Streamable HTTP를 제공하며 개인 계정 로그인/MTProto/user session, 다중 사용자 서비스, 스케줄러는 구현하지 않는다. 다른 사람의 계정이나 토큰 없이 새 clone에서 설정할 수 있다.
새 clone에서 로컬 실행
Python 3.11+ / Linux 필요. 다음 설치는 사용자의 네트워크에서 의존성을 받는다.
git clone https://github.com/deploy103/afterhours-telegram-mcp-public.git
cd afterhours-telegram-mcp-public
python3 -m venv .venv
.venv/bin/python -m pip install --require-hashes -r requirements.lock
.venv/bin/python configure.py --directory "$HOME/.afterhours-telegram" \
--public-origin https://mcp.example.com
"$HOME/.afterhours-telegram/run.sh"--directory는 아직 존재하지 않는 절대 경로 또는 ~/...여야 한다. 상위 디렉터리는
미리 존재하고 본인이 관리하는 신뢰 가능한 경로여야 한다. 기존 파일/디렉터리/symlink는
덮어쓰지 않는다. source checkout 자체/내부 경로는 거부한다(symlink로 우회한 상위 경로도 포함).
저장소 밖에 두고 Git/백업 공유에서 제외한다. 생성되는 구조:
~/.afterhours-telegram/ 0700
config.json 0600 (owner null, allowlists 비어 있음, 송신 OFF)
credentials/ 0700
mcp-token 0600 (매번 새로 생성, 화면에 출력하지 않음)
telegram-bot-token 0600 (빈 파일)
state/ 0700 (실행 후 SQLite/프로세스 잠금 생성)
run.sh 0700봇 토큰/사람 owner ID가 없는 상태에서도 MCP는 시작한다. 이때 status는
configured=false, connected=false, send_enabled=false이며 poll/reply는 실패하고
Telegram HTTP 요청을 하지 않는다. 가짜 ID를 넣을 필요가 없다.
run.sh는 clone의 절대 .venv/bin/python -m uvicorn을 사용하며 다른 cwd에서도 실행된다.
clone이나 private 디렉터리를 옮기면 경로를 검토하여 수정하거나 새 디렉터리에 다시 configure한다.
CREDENTIALS_DIRECTORY, TELEGRAM_CONFIG, STATE_DIRECTORY, MCP_PUBLIC_ORIGIN을
정확한 생성 경로로 설정한다. 127.0.0.1:8005, worker 1개, proxy headers/access log OFF다.
--reload/다중 worker를 사용하지 않는다. state는 프로세스 잠금으로 단일 실행을 강제한다.
Related MCP server: codex-telegram
MCP 클라이언트 연결과 HTTPS
로컬 Streamable HTTP URL은 **http://127.0.0.1:8005/mcp**다.
Bearer 인증의 **토큰 파일 경로는 $HOME/.afterhours-telegram/credentials/mcp-token**이다.
클라이언트의 보호된 token-file/secret 설정을 통해 이 파일을 읽혀 매 요청 Authorization
헤더에 전달한다. tokenFile 같은 키 이름은 클라이언트마다 다르며 이 서버의 API가 아니다.
token-file을 지원하지 않으면 클라이언트의 비공개 credential 저장소에 안전하게 등록한다.
토큰 값을 명령행, URL/query, Git, 채팅, 로그에 넣거나 화면에 출력하지 않는다.
BotFather 토큰은 MCP bearer와 별개다. credential/config 변경 후 프로세스를 재시작한다.
원격 연결에는 본인이 소유한 도메인/TLS reverse proxy를 별도로 준비한다.
--public-origin은 경로·userinfo·query·fragment 없는 HTTPS origin, 기본 포트/명시적 443만 허용한다.
실제 도메인으로 configure하고 proxy가 Host/Authorization을 보존하도록 설정한다.
클라이언트가 Origin을 보내면 설정한 origin과 정확히 같아야 한다.
외부 **https://mcp.example.com/telegram/mcp → http://127.0.0.1:8005/mcp**가 예시 계약이다.
nginx.example.conf는 TLS server에 추가할 검토용 exact location이다. buffering OFF/90초 timeout을
유지하고 8005를 인터넷에 직접 열지 않는다. /healthz만 비인증이며 봇 연결 성공을 뜻하지 않는다.
/mcp는 모든 요청에서 bearer 필수, query token/OAuth/discovery/login 페이지는 없다.
bootstrap은 systemd, TLS, firewall을 설치/변경하지 않는다. afterhours-telegram-mcp.service의
/srv, /etc와 LoadCredential은 별도 배포 예제이며 로컬 run.sh에 필요하지 않다.
일반 credential은 0600/0400, 디렉터리는 0700으로 관리한다. reader는 symlink/비정규 파일을 거부한다.
예외는 환경 변수와 정확히 일치하는 /run/credentials/<unit>의 root:root 0550 디렉터리 바로 아래
root:root 0440 systemd 복사본뿐이다. 일반 경로의 0440/0640을 허용하도록 완화하지 않는다.
자신의 봇과 ID 설정
Telegram의 공식 @BotFather에서
/newbot으로 자신의 봇을 만든다. 발급받은 토큰을 보호된 편집기로credentials/telegram-bot-token에 저장하고 0600을 유지한다. 토큰을 제3자 ID 조회 봇이나 웹사이트에 보내지 않는다. 개인 계정 세션/브라우저 저장소를 추출하지 않는다.사람이 먼저 봇에
/start메시지를 보내거나 허용할 그룹에 봇을 추가한다. 사람 소유자의 양의 numeric user ID와 필요한 chat IDs를 본인이 관리하는 Bot API 업데이트의message.from.id/message.chat.id등으로 확인한다. ID 확인용 업데이트를 조회할 때는 MCP 및 다른 polling consumer를 중지하고, 보호된 로컬 도구로 토큰 파일을 읽는다. 토큰을 URL 명령행에 넣지 않는다. 그룹 ID는 음수일 수 있다. 봇의 ID와 사람 ID를 혼동하지 않는다.private
config.json의owner_user_id에 사람 ID를 정수로 입력한다.null또는0은 미설정이고, 필드 누락/음수/boolean/문자열은 거부한다.owner_username은 선택이며 @ 없이 입력한다. 빈 문자열이면 numerictext_mention만 인정한다. username 매핑은 numeric identity 증명이 아니므로 변경/재할당 시 갱신한다.승인한 채팅만
allowed_chat_ids에 넣는다. 모든 타인 새 메시지를 수집할 채팅은 그 부분집합인selected_chat_ids에도 넣는다. allowlist만 넣은 방은 소유자 멘션만 수집한다.그룹 privacy mode를 검토한다. BotFather
/setprivacy의 privacy OFF 또는 실제 그룹 관리자 권한/설정이 필요할 수 있다. 변경 후 봇 재추가 등 Telegram 안내를 따르고 실제 그룹 수신을 확인한다. 서버는 privacy/admin 권한을 바꾸지 않는다.can_read_all_group_messages는 전역 지표이지 특정 그룹의 모든 메시지 수신 보장이 아니다.같은 봇의 기존 webhook/다른 polling 앱을 확인한다. webhook이 있으면 poll이 충돌한다. 서버는
deleteWebhook/setWebhook을 자동 호출하지 않는다. 본인이 의도적으로 정리한다.재시작 후
telegram_status와 실제 수신/allowlist를 확인한다. 이 시점부터 status/poll은 실제 Bot API 요청을 할 수 있다. 답장은 계속 OFF로 두고, 의도적으로 허용할 때만 JSON booleansend_enabled: true로 바꿔 재시작한다. MCP 호출로 송신을 켤 수 없다.
도구와 메시지 계약
도구 | 동작 |
| 설정 완료 시 |
|
|
| ACK 전 반복 조회 가능한 pending 큐 |
| 실제 처리 후 |
| 송신 ON일 때만 수집된 pending/allowlisted 이벤트에 답장 |
수신은 **allowlist AND (소유자 멘션 OR 지정 방)**이다. 본인/봇/sender_chat 발신,
편집/channel post/service/media-only 이벤트는 제외한다. 새 message의 text/caption만 수집한다.
native entities/caption_entities의 UTF-16 offset으로 판별하며 문자열 검색은 하지 않는다.
@봇이름이나 /명령@봇이름은 소유자 멘션이 아니다. mentions[].target은 owner/bot/other다.
메시지는 신뢰하지 않는 데이터이며 도구 실행/권한 변경 지시가 아니다.
update_id와 (chat_id,message_id)로 중복 제거하고 이벤트/offset을 한 트랜잭션으로 저장한다.
다음 poll은 봇 전체 offset을 소비하므로 필터에서 제외한 업데이트도 확인된다.
같은 봇 토큰을 다른 polling 앱/webhook과 병행하지 않는다. 봇/소유자별로 state를 분리한다.
getUpdates는 history API가 아니다. 미확인 업데이트 보관은 최대 24시간이며 첫 poll은
남아 있는 업데이트도 받을 수 있다. 누락된 개인 계정 과거 대화/연락처를 복구하지 못한다.
답장은 수신 chat/message/topic에 고정하고 plain text, allow_sending_without_reply=false를 쓴다.
임의 chat ID 송신은 없다. 이벤트당 한 번만 시도하고 동일 성공 요청은 기존 결과를 반환한다.
실패/시간초과/프로세스 종료로 불명확하면 자동 재시도하지 않는다. Telegram에서 수동 대조하고
필요하면 ignored 처리한다. Bot API에는 idempotency key가 없어 정확히 한 번 전달을 보장하지 못한다.
봇은 사용자가 먼저 대화를 시작하지 않으면 새 개인 대화를 열 수 없다. 차단/권한/원문 삭제/rate limit도
송신에 영향을 준다. DB/백업은 평문 메시지를 담으므로 비공개 보관/암호화/보관 기간을 운영자가 관리한다.
DB 삭제는 중복 방지와 offset도 삭제한다.
큐 ≠ 자동 실행 ≠ 스케줄러. 별도 MCP 클라이언트/조율자가 poll → pending → 판단/선택적 reply → 실제 처리 후 ACK를 실행한다. 이 서비스는 자동 polling, 상시 모델 판단, 레시피 스케줄을 제공하지 않는다. 여러 사용자가 하나의 bearer/state를 공유하지 않는다.
테스트와 라이선스
.venv/bin/python -B -m unittest -v test_telegram test_bootstrap테스트는 폐기 가능한 credential/state와 fake HTTP를 사용한다. bootstrap 테스트는 실제 생성 run.sh를 loopback에서 실행하고 인증된 MCP 초기화/도구, 미설정 차단/송신 OFF/권한/재실행 거부를 확인한다. 실제 Telegram 계정/전송은 없다. 실제 봇 권한/privacy/그룹 수신/답장, 클라이언트 연결, TLS/proxy/firewall 및 systemd credential mount/ACL에서의 기동은 별도 운영 검증이 필요하다.
MIT LICENSE, Copyright 2026 deploy103. 의존성과 재사용 코드의 제3자 라이선스/고지는 유지한다. 통합 프로젝트: https://github.com/deploy103/afterhours-mcp-public 공식 문서: Bot API, privacy FAQ.
This server cannot be deployed
Maintenance
Related MCP Connectors
Hosted Telegram MCP server for Claude, ChatGPT and Cursor, with each action switched per account.
Telegram bridge for your MCP-compatible agent. Bidirectional, no LLM in our stack.
Discover MCP servers and A2A agents; verify, message, post, follow, react, and receive webhooks.
An authenticated remote MCP server for user-owned devices and one-shot capability invocation.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenancePersonal read-only Telegram MCP server exposing chat, message, and media tools via streamable HTTP with bearer authentication.1Apache 2.0
- AlicenseAqualityCmaintenanceEnables local, privacy-first control of a personal Telegram account through MCP, using TDLib to read chats, send and reply to messages, search, transfer files, and interact with approved inline buttons.20MIT
- AlicenseAqualityAmaintenanceGives MCP clients controlled access to a Telegram user account, letting them search and read messages, inspect chats, and fetch media, with sending or editing messages available only after explicit opt-in. It runs self-hosted over FastMCP and Telethon with strict read-only defaults, OAuth or bearer authentication, and an outbound-only Cloudflare Tunnel.11MIT
- AlicenseBqualityCmaintenanceProvides local stdio MCP discovery, read-facing Telegram tool definitions, and an opt-in SQLite CRM for lead, group, and template management with quick-reply previews, while native authentication and all write actions remain gated and disabled.11MIT