MCP-TG
MCP-TG — Telegram MCP Server with Reactive Daemon
Isolated fork of 45telega — rewritten as a standalone daemon + proxy architecture for multi-agent use. Independent repository: GG-QandV/MCP-TG.
Telegram MCP server exposing 50+ tools over the Model Context Protocol. One persistent MTProto connection (tgmcpd daemon) serves N isolated agents via Unix-socket IPC proxies — each agent bound to its own Telegram topic.
Why this fork
Upstream 45telega is a single-process stdio MCP server (one connection per agent). MCP-TG splits it:
tgmcpd daemon — one
Telethonclient, persistent MTProto session,InboxEnginewith per-topic buffers + disk persistence.tg-mcp-proxy — thin stateless stdio↔IPC bridge per agent (env
TG_TOPIC_IDisolates topics).Reactive inbox v3 —
asyncio.Eventwake-up + JSONL store + priority envelope, no polling.
Other providers kept as-is; this repo is detached from the upstream fork (isFork: false).
Architecture
v2 — Daemon + Proxy (L2)
┌────────────────────────────────────────────┐
│ tg-mcpd daemon │
│ ┌─────────────────────┐ ┌──────────────┐ │
│ │ TelegramClient │ │ IPC Server │ │
│ │ (MTProto) │ │ /run/tgmcpd │ │
│ └────────┬────────────┘ └──────┬───────┘ │
│ ┌─────┴─────┐ │ │
│ │ Inbox │ │ │
│ │ topic→buf │ │ │
│ └───────────┘ │ │
└──────────────────────────────────┼─────────┘
┌─────────┬───────────────┼──────────┐
┌────┴────┐ ┌──┴─────┐ ┌──────┴────┐ ┌───┴────┐
│ proxy │ │ proxy │ │ proxy │ │ proxy │
│ topic=205│ │topic=310│ │topic=415 │ │ ... │
│stdio↔IPC│ │stdio↔IPC│ │stdio↔IPC │ │ │
└────┬────┘ └──┬─────┘ └──────┬───┘ └───┬────┘
│ │ │ │
Agent1 Agent2 Agent3 Agent4v3 — Reactive Inbox
Telegram push → Telethon event → InboxEngine.handle()
→ InboxStore.append(JSONL) → buffer[(chat,topic)].append()
→ asyncio.Event[(chat,topic)].set()
→ proxy inbox_wait() wakes → IPC → MCP inbox_read → envelope + ackInboxStore— per(chat_id, topic_id)JSONL in/home/gg/tgmcpd/inbox_store,ackviatmp→replace(atomic), survives restarts.InboxEngine—defaultdict(deque)buffers +defaultdict(asyncio.Event)per topic,restore_from_store()on daemon start.proxy inbox_read— blockinginbox_wait(25s) +inbox_ackafter delivery, returns{priority_rules, messages}.
See docs/architecture-v2.md and docs/tg-mcpd Architecture v3 — Reactive Inbox.md.
Tools — 50 total (MCP stdio, Telethon/MTProto)
Chats — GetAllChats, GetChats, GetChatInfo, GetChatMembers, GetChatAdmins, GetChatOnlineCount, SearchChats, GetChatInviteLink, CheckChatInvite, JoinChatByInvite, LeaveChat, GetFolders, GetChatsFromFolder, GetForumTopics, AddChatMember, BanChatMember, UnbanChatMember, KickChatMember, PromoteToAdmin
Messages — SendMessage, ReplyToMessage, EditMessage, DeleteMessage, ForwardMessage, GetChatHistory, SearchMessages, MarkAsRead, PinMessage, UnpinMessage, SendFile, DownloadMedia
Contacts — GetContacts, AddContact, DeleteContact, SearchContacts, BlockUser, UnblockUser, GetBlockedUsers, SearchGlobal
Users — GetMe, GetUserInfo, GetUserStatus, SearchUsers, ResolveUsername, UpdateProfile
Groups/Channels — CreateGroup, CreateChannel, EditChatTitle
Inbox — InboxPeek, InboxRead (via proxy inbox_read → inbox_peek/inbox_wait + inbox_ack)
Full table: TOOLS_RU.md.
Requirements
Python 3.9+
Telegram
api_id/api_hash(https://my.telegram.org)Linux/macOS (systemd for daemon), Windows via WSL — see WINDOWS_WSL_SETUP.md
Quick Start
git clone https://github.com/GG-QandV/MCP-TG.git
cd MCP-TG
pip install -e .
cp .env.example .env # fill TELEGRAM_API_ID, TELEGRAM_API_HASH
python -m mcp_telegram.qr_auth # or: 45telega sign-inRun daemon (systemd)
sudo cp scripts/tgmcpd.user.service ~/.config/systemd/user/tgmcpd.service
systemctl --user daemon-reload
systemctl --user enable --now tgmcpd
systemctl --user status tgmcpdDaemon socket: /run/tgmcpd/tgmcpd.sock, store: ~/tgmcpd/inbox_store.
Run proxy per topic (opencode)
TG_CHAT_ID=-1003998609906 TG_TOPIC_ID=205 tg-mcp-proxyopencode.json example:
{
"mcpServers": {
"tg-mcp-205": { "command": "tg-mcp-proxy", "env": { "TG_CHAT_ID": "-1003998609906", "TG_TOPIC_ID": "205" } }
}
}Add more proxies with different TG_TOPIC_ID for multi-agent isolation.
Docker (optional)
docker build -t mcp-tg .
docker-compose up -dConfiguration
Env / .env:
TELEGRAM_API_ID=
TELEGRAM_API_HASH=
TELEGRAM_SESSION_PATH=~/.config/mcp-tg/session.session
TGMCPD_SOCK=/run/tgmcpd/tgmcpd.sock
TGMCPD_STORE_DIR=~/tgmcpd/inbox_store
TG_CHAT_ID=-1003998609906
TG_TOPIC_ID=205Entry points (setup.py): 45telega, telega-mcp, tgmcpd, tg-mcp-proxy.
Project Structure
src/mcp_telegram/
daemon.py # tgmcpd entry, Telethon + IPC
inbox.py # InboxEngine (buffers + Events)
inbox_store.py # JSONL persistence
inbox_bridge.py # bridge (deprecated v2)
ipc_server.py # Unix socket JSON-line server
ipc_client.py # proxy side client
proxy.py # MCP stdio ↔ IPC
telegram.py # TelegramSettings, client helpers
tools.py # core 50 tools
server.py # legacy single-process server
docs/
architecture-v2.md
tg-mcpd Architecture v3 — Reactive Inbox.md
scripts/
tgmcpd.user.service
tgmcp-proxy-wrapper.py / tgmcp-proxy-watchdog.pyDevelopment
pytest
pytest tests/unit/test_inbox_bridge.py
black src && ruff check src && mypy srcInbox protocol for agents: see AGENTS.md — on ⚡ INBOX ALERT call inbox_read, then send_message with ack.
Relation to upstream
Forked from sergekostenchuk/45telega at 66e31ac, now standalone (GG-QandV/MCP-TG). Upstream origin removed; GG-QandV/tg-mcp remains as the preserved fork with upstream intact.
License
MIT — see LICENSE.