Metadata-Version: 2.4
Name: telegram-mcp-bridge
Version: 0.1.4
Summary: Added new tools
License: MIT
Requires-Python: >=3.10
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp>=1.22.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: aiohttp>=3.9.0
Dynamic: license-file

# Telegram MCP Bridge

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python 3.10+](https://img.shields.io/badge/python-3.10+-blue.svg)](https://www.python.org/downloads/)

Telegram MCP bridge for Claude Code — get notifications, ask questions, and interact with your Claude Code sessions
through Telegram.

Each Claude Code session gets its own thread (topic) in a Telegram group, so you can monitor multiple sessions at once.

## Features

- **Send messages** — progress updates, final reports, notifications
- **Ask and wait** — ask questions in Telegram and get answers back in Claude Code
- **Inline buttons** — present options for the user to choose from
- **Send files** — share screenshots, logs, documents
- **Real-time monitoring** — watch for incoming Telegram messages
- **Multi-session** — each Claude Code session gets its own Telegram thread

## Architecture

```
Telegram group (is_forum: true, with Topics)
  └── Thread per session ("{project} #{pid} — {time}")
        │
  daemon.py  (single process, launchd, port 8765)
  aiohttp HTTP API + single Telegram long-polling via httpx
        │
  proxy.py  (stdio MCP, spawned by Claude Code)
  Thin FastMCP proxy: lazy registration on first tool call
        │
  Claude Code (any number of sessions)
```

**Why two processes?** Telegram Bot API allows only one `getUpdates` polling per token. The daemon centralizes polling
and distributes messages to sessions via HTTP.

## Quick Start

### 1. Create a Telegram bot and group

1. Create a bot via [@BotFather](https://t.me/BotFather) — save the token
2. Create a Telegram group, enable **Topics** (group settings → Topics)
3. Add the bot to the group as admin (needs "Manage Topics" permission)
4. Get the group chat ID (send a message, then check `https://api.telegram.org/bot<TOKEN>/getUpdates`)

### 2. Install

```bash
pip install telegram-mcp-bridge
```

Or from source:

```bash
git clone https://github.com/OlegPrivet/telegram-mcp-bridge.git
cd telegram-mcp-bridge
pip install -e .
```

### 3. Configure

```bash
mkdir -p ~/.claude/channels/telegram-daemon
cat > ~/.claude/channels/telegram-daemon/.env << EOF
TELEGRAM_BOT_TOKEN=your-bot-token
TELEGRAM_CHAT_ID=-100your-group-id
DAEMON_PORT=8765
EOF
```

### 4. Start the daemon

```bash
tg-mcp-daemon
```

For **macOS**, use launchd for auto-start:

```bash
cd telegram-mcp-bridge
./launchd/generate-plist.sh
cp launchd/com.claude.tg-mcp-daemon.plist ~/Library/LaunchAgents/
launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.claude.tg-mcp-daemon.plist
```

For **Windows**, use Task Scheduler for auto-start:

```powershell
# Create a scheduled task that starts the daemon at logon
schtasks /create /tn "TelegramMCPDaemon" /tr "tg-mcp-daemon" /sc onlogon /rl limited

# Or if installed from source:
schtasks /create /tn "TelegramMCPDaemon" /tr "python -m telegram_mcp_bridge.daemon" /sc onlogon /rl limited

# Start it now without rebooting
schtasks /run /tn "TelegramMCPDaemon"
```

> **Note (Windows):** The config directory is `%USERPROFILE%\.claude\channels\telegram-daemon\.env`. Create it with:
> ```powershell
> mkdir "$env:USERPROFILE\.claude\channels\telegram-daemon" -Force
> @"
> TELEGRAM_BOT_TOKEN=your-bot-token
> TELEGRAM_CHAT_ID=-100your-group-id
> DAEMON_PORT=8765
> "@ | Set-Content "$env:USERPROFILE\.claude\channels\telegram-daemon\.env"
> ```

### 5. Register MCP in Claude Code

```bash
claude mcp add telegram -s user -- tg-mcp-proxy
```

Or if installed from source:

```bash
claude mcp add telegram -s user -- python3 -m telegram_mcp_bridge.proxy
```

## MCP Tools

| Tool                                               | Description                                 |
|----------------------------------------------------|---------------------------------------------|
| `send_message(message)`                            | Send a message (fire-and-forget)            |
| `send_file(file_path, caption?)`                   | Send a file/screenshot to the thread        |
| `send_and_wait(message)`                           | Send and wait for a reply (5 min timeout)   |
| `send_and_wait_with_options(message, options)`     | Send with inline buttons                    |
| `monitor_chat()`                                   | Wait for incoming message (30 min timeout)  |
| `check_inbox()`                                    | Check for unread messages (non-blocking)    |
| `list_sessions()`                                  | List active sessions                        |
| `schedule_project_check(path, interval_hours=6, interval_minutes=None)` | Schedule checks of a local Rust/Git project |
| `run_project_check_now()`                          | Start a check in the background             |
| `get_project_check_status()`                       | Show schedule and current state             |
| `get_project_check_history(limit=10)`              | Read saved results and errors               |
| `pause_project_check()` / `resume_project_check()` | Control automatic runs                      |
| `delete_project_check()`                           | Remove the scheduled project               |

## Scheduled project checks

Ask the MCP client to call `schedule_project_check` with an absolute path to a Git repository containing `Cargo.toml`.
Set `interval_minutes=30` for a half-hour interval, or `interval_hours=2` for two hours. Specify only one unit; the
default is six hours. Valid intervals are 1–10080 minutes or 1–168 hours. The bridge supports one configured project
check. Intervals are measured from the end of the previous run; the first automatic run is one interval after
configuration. Use `run_project_check_now` for an immediate first run. Scheduling another path replaces the configured
project, including when it is paused. `delete_project_check` removes the schedule while keeping past run history.

The daemon runs `cargo fmt --all -- --check`, `cargo test --locked`, and
`cargo clippy --locked --all-targets --all-features -- -D warnings`. It also records Git changes, commits since the
previous check, and TODO/FIXME counts in Rust source files. Each Cargo command has a ten-minute timeout. The daemon
stores the schedule and history in `~/.claude/channels/telegram-daemon/project_checks.sqlite3` and sends a summary after
every run to a dedicated Telegram topic. The topic and schedule survive MCP session exits and daemon restarts. If
Telegram delivery fails, the run remains available through `get_project_check_history` with a notification error.

The check uses locally installed Rust tools and needs no LLM or additional API key. The daemon must remain running for
scheduled execution; the supplied `launchd` service starts it automatically on macOS.

## Management

### Daemon

```bash
# Health check
curl -s http://127.0.0.1:8765/api/health

# Active sessions
curl -s http://127.0.0.1:8765/api/sessions | python3 -m json.tool

# Restart (macOS launchd)
launchctl kickstart -k gui/$(id -u)/com.claude.tg-mcp-daemon

# Stop (macOS launchd)
launchctl bootout gui/$(id -u)/com.claude.tg-mcp-daemon

# Restart (Windows Task Scheduler)
schtasks /end /tn "TelegramMCPDaemon" & schtasks /run /tn "TelegramMCPDaemon"

# Stop (Windows Task Scheduler)
schtasks /end /tn "TelegramMCPDaemon"

# Delete scheduled task (Windows)
schtasks /delete /tn "TelegramMCPDaemon" /f

# Logs
tail -f ~/.claude/channels/telegram-daemon/daemon.log
```

### Proxy

Proxy processes are spawned automatically by Claude Code — one per session. They unregister gracefully on exit.

```bash
# Proxy logs
tail -f /tmp/tg_mcp_proxy.log
```

## Configuration

| Variable             | Default | Description                          |
|----------------------|---------|--------------------------------------|
| `TELEGRAM_BOT_TOKEN` | —       | Bot token from @BotFather (required) |
| `TELEGRAM_CHAT_ID`   | —       | Group chat ID with topics (required) |
| `DAEMON_PORT`        | `8765`  | HTTP API port for daemon             |
| `SESSION_NAME`       | auto    | Custom session name for the thread   |

## License

MIT
