Skip to main content
Glama
paulo-evangelista

telegram-notifier-mcp

README.md
# Telegram Notifier MCP Server

An [MCP](https://modelcontextprotocol.io/) server that lets an LLM send messages and files to a user via a Telegram bot, to a single configured recipient. No external HTTP or Telegram libraries — just the native `fetch` API and the official MCP SDK.

## Quick Start

Install dependencies with `bun install --frozen-lockfile`, then configure your MCP client to run the TypeScript source directly with Bun. No build step is required. The examples below use `/absolute/path/to/telegram-notifier-mcp/src/index.ts`; replace it with your checkout path. Do not use the published npm package to run these local changes.

### 1. Create a Telegram Bot

1. Open Telegram and message [@BotFather](https://t.me/BotFather)
2. Send `/newbot` and follow the prompts to name your bot
3. Copy the **bot token** you receive (e.g., `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`)

### 2. Find Your Chat ID

1. Send any message to your new bot on Telegram
2. Open the following URL in your browser, replacing `YOUR_BOT_TOKEN` with your actual token:
   ```
   https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates
   ```
3. In the JSON response, find `"chat":{"id": 123456789}` — that number is your chat ID

> **Tip:** For group chats, add the bot to the group, send a message, and check the same URL. Group chat IDs are negative numbers (e.g., `-1001234567890`).

### 3. Add to Your MCP Client

#### Claude Desktop

Add this to your Claude Desktop config file:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`

```json
{
  "mcpServers": {
    "telegram-notifier": {
      "command": "bun",
      "args": ["/absolute/path/to/telegram-notifier-mcp/src/index.ts", "--chat-id=your-chat-id-here"],
      "env": {
        "TELEGRAM_BOT_TOKEN": "your-bot-token-here"
      }
    }
  }
}
```

#### Claude Code

Add to your project's `.mcp.json` or `~/.claude.json`:

```json
{
  "mcpServers": {
    "telegram-notifier": {
      "command": "bun",
      "args": ["/absolute/path/to/telegram-notifier-mcp/src/index.ts", "--chat-id=your-chat-id-here"],
      "env": {
        "TELEGRAM_BOT_TOKEN": "your-bot-token-here"
      }
    }
  }
}
```

#### Codex CLI

You can configure Codex CLI in either of these ways:

**Option A: Add it manually in `~/.codex/config.toml`**

```toml
[mcp_servers.telegram-notifier]
command = "bun"
args = ["/absolute/path/to/telegram-notifier-mcp/src/index.ts", "--chat-id=your-chat-id-here"]

[mcp_servers.telegram-notifier.env]
TELEGRAM_BOT_TOKEN = "your-bot-token-here"
```

**Option B: Add it with a CLI command**

```bash
codex mcp add telegram-notifier \
  --env TELEGRAM_BOT_TOKEN=your-bot-token-here \
  -- bun /absolute/path/to/telegram-notifier-mcp/src/index.ts --chat-id=your-chat-id-here
```

That's it — your LLM can now send you Telegram notifications.

## Configuration

The recipient is fixed at startup using `--chat-id=<numeric-id>` (for example `--chat-id=-1001234567890` for a group). `TELEGRAM_CHAT_ID` is supported as a fallback; the command-line argument takes precedence. Tool calls cannot override the recipient.

There are no incoming-message tools, polling, attachment downloads, or offset files.

Environment variables:

| Variable | Required | Description |
|---|---|---|
| `TELEGRAM_BOT_TOKEN` | Yes | Bot token from @BotFather |
| `TELEGRAM_CHAT_ID` | Unless `--chat-id` is set | Fixed numeric recipient chat ID. |

The server exits with an error if the bot token is missing or the recipient is missing or invalid.

## Tools

### `send_message`

Send a text message to a Telegram chat.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `text` | string | Yes | The message text to send |
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
| `disableNotification` | boolean | No | Send silently without notification sound |

### `send_document`

Send a file/document to a Telegram chat.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `filePath` | string | Yes | Absolute path to the file |
| `caption` | string | No | Caption for the document |
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
| `disableNotification` | boolean | No | Send silently without notification sound |

### `send_photo`

Send a photo/image to a Telegram chat.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `filePath` | string | Yes | Absolute path to the image file |
| `caption` | string | No | Caption for the photo |
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
| `disableNotification` | boolean | No | Send silently without notification sound |

### `send_video`

Send a video to a Telegram chat.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `filePath` | string | Yes | Absolute path to the video file |
| `caption` | string | No | Caption for the video |
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
| `disableNotification` | boolean | No | Send silently without notification sound |

### `send_audio`

Send an audio file to a Telegram chat.

| Parameter | Type | Required | Description |
|---|---|---|---|
| `filePath` | string | Yes | Absolute path to the audio file |
| `caption` | string | No | Caption for the audio |
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
| `disableNotification` | boolean | No | Send silently without notification sound |

## Testing with the MCP Inspector

You can test the server interactively using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):

```bash
TELEGRAM_BOT_TOKEN="your-token" TELEGRAM_CHAT_ID="your-chat-id" \
  bunx @modelcontextprotocol/inspector bun /absolute/path/to/telegram-notifier-mcp/src/index.ts
```

This opens a browser UI where you can invoke each tool and see the results.

## Error Handling

The server handles errors gracefully and returns descriptive messages:

| Scenario | Behavior |
|---|---|
| Missing `TELEGRAM_BOT_TOKEN` | Server exits at startup with instructions |
| Missing or invalid startup chat ID | Server exits before connecting |
| File not found | Returns `isError: true` with the file path |
| File exceeds 50 MB | Returns `isError: true` with file size |
| Telegram API error | Returns `isError: true` with Telegram's error description |

All server logs go to **stderr** so they never interfere with the stdio MCP transport on stdout.

## File Size Limits

Telegram enforces a **50 MB** limit for file uploads via the Bot API. The server validates file size before uploading and returns an error if the limit is exceeded.

## Development

```bash
git clone https://github.com/paulo-evangelista/telegram-notifier-mcp
cd telegram-notifier-mcp
bun install --frozen-lockfile
bun test

# Run with TELEGRAM_BOT_TOKEN set in the environment
bun run start --chat-id=123456789

# Watch mode — restarts on file changes
bun run dev --chat-id=123456789
```

## Publishing

Releases are published to npm automatically via GitHub Actions when you create a GitHub release.

**Setup:**
1. Add your npm token as a repository secret named `NPM_TOKEN` in GitHub Settings > Secrets and variables > Actions
2. Bump the version in `package.json`
3. Create a new GitHub release — the workflow will test and publish the Bun entry point to npm

## License

MIT