Skip to main content
Glama
GG-QandV

MCP-TG

by GG-QandV
README.md
# MCP-TG — Telegram MCP Server with Reactive Daemon

Isolated fork of [45telega](https://github.com/sergekostenchuk/45telega) — rewritten as a standalone daemon + proxy architecture for multi-agent use. Independent repository: [`GG-QandV/MCP-TG`](https://github.com/GG-QandV/MCP-TG).

[![License: MIT](https://img.shields.io/github/license/GG-QandV/MCP-TG)](LICENSE)
[![Python 3.9+](https://img.shields.io/badge/python-3.9%2B-blue)](setup.py)
[![MCP](https://img.shields.io/badge/MCP-stdio-green)](#)

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 `Telethon` client, persistent MTProto session, `InboxEngine` with per-topic buffers + disk persistence.
* **tg-mcp-proxy** — thin stateless stdio↔IPC bridge per agent (env `TG_TOPIC_ID` isolates topics).
* **Reactive inbox v3** — `asyncio.Event` wake-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    Agent4
```

### v3 — 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 + ack
```

* `InboxStore` — per `(chat_id, topic_id)` JSONL in `/home/gg/tgmcpd/inbox_store`, `ack` via `tmp→replace` (atomic), survives restarts.
* `InboxEngine` — `defaultdict(deque)` buffers + `defaultdict(asyncio.Event)` per topic, `restore_from_store()` on daemon start.
* `proxy inbox_read` — blocking `inbox_wait` (25s) + `inbox_ack` after 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](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](WINDOWS_WSL_SETUP.md)

## Quick Start

```bash
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-in
```

### Run daemon (systemd)

```bash
sudo cp scripts/tgmcpd.user.service ~/.config/systemd/user/tgmcpd.service
systemctl --user daemon-reload
systemctl --user enable --now tgmcpd
systemctl --user status tgmcpd
```

Daemon socket: `/run/tgmcpd/tgmcpd.sock`, store: `~/tgmcpd/inbox_store`.

### Run proxy per topic (opencode)

```bash
TG_CHAT_ID=-1003998609906 TG_TOPIC_ID=205 tg-mcp-proxy
```

`opencode.json` example:

```json
{
  "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)

```bash
docker build -t mcp-tg .
docker-compose up -d
```

## Configuration

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=205
```

Entry 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.py
```

## Development

```bash
pytest
pytest tests/unit/test_inbox_bridge.py
black src && ruff check src && mypy src
```

Inbox protocol for agents: see [AGENTS.md](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](LICENSE).