telegram-notifier-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +192 -0
- package/build/index.d.ts +2 -0
- package/build/index.js +225 -0
- package/package.json +25 -0
package/README.md
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# Telegram Notifier MCP Server
|
|
2
|
+
|
|
3
|
+
A one-way notification [MCP](https://modelcontextprotocol.io/) server that lets an LLM send messages and files to a user via a Telegram bot. No external HTTP or Telegram libraries — just the native `fetch` API and the official MCP SDK.
|
|
4
|
+
|
|
5
|
+
## Prerequisites
|
|
6
|
+
|
|
7
|
+
- Node.js 18+
|
|
8
|
+
- A Telegram bot token (from [@BotFather](https://t.me/BotFather))
|
|
9
|
+
- Your Telegram chat ID
|
|
10
|
+
|
|
11
|
+
## Setup
|
|
12
|
+
|
|
13
|
+
### 1. Create a Telegram Bot
|
|
14
|
+
|
|
15
|
+
1. Open Telegram and message [@BotFather](https://t.me/BotFather)
|
|
16
|
+
2. Send `/newbot` and follow the prompts to name your bot
|
|
17
|
+
3. Copy the **bot token** you receive (e.g., `123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11`)
|
|
18
|
+
|
|
19
|
+
### 2. Find Your Chat ID
|
|
20
|
+
|
|
21
|
+
1. Send any message to your new bot on Telegram
|
|
22
|
+
2. Open the following URL in your browser, replacing `YOUR_BOT_TOKEN` with your actual token:
|
|
23
|
+
```
|
|
24
|
+
https://api.telegram.org/botYOUR_BOT_TOKEN/getUpdates
|
|
25
|
+
```
|
|
26
|
+
3. In the JSON response, find `"chat":{"id": 123456789}` — that number is your chat ID
|
|
27
|
+
|
|
28
|
+
> **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`).
|
|
29
|
+
|
|
30
|
+
### 3. Install and Build
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
git clone <your-repo-url>
|
|
34
|
+
cd telegram-notifier-mcp
|
|
35
|
+
npm install
|
|
36
|
+
npm run build
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Configuration
|
|
40
|
+
|
|
41
|
+
The server uses two environment variables:
|
|
42
|
+
|
|
43
|
+
| Variable | Required | Description |
|
|
44
|
+
|---|---|---|
|
|
45
|
+
| `TELEGRAM_BOT_TOKEN` | Yes | Bot token from @BotFather |
|
|
46
|
+
| `TELEGRAM_CHAT_ID` | No | Default chat ID. Can be overridden per-tool call via the `chatId` parameter. |
|
|
47
|
+
|
|
48
|
+
The server will exit with an error if `TELEGRAM_BOT_TOKEN` is not set. If `TELEGRAM_CHAT_ID` is not set, you must pass `chatId` to every tool call.
|
|
49
|
+
|
|
50
|
+
## Adding to Your MCP Client
|
|
51
|
+
|
|
52
|
+
### Claude Desktop
|
|
53
|
+
|
|
54
|
+
Add this to your Claude Desktop config file:
|
|
55
|
+
|
|
56
|
+
- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
57
|
+
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"telegram-notifier": {
|
|
63
|
+
"command": "node",
|
|
64
|
+
"args": ["/absolute/path/to/telegram-notifier-mcp/build/index.js"],
|
|
65
|
+
"env": {
|
|
66
|
+
"TELEGRAM_BOT_TOKEN": "your-bot-token-here",
|
|
67
|
+
"TELEGRAM_CHAT_ID": "your-chat-id-here"
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Claude Code
|
|
75
|
+
|
|
76
|
+
Add to your project's `.mcp.json` or global `~/.claude/claude_code_config.json`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"mcpServers": {
|
|
81
|
+
"telegram-notifier": {
|
|
82
|
+
"command": "node",
|
|
83
|
+
"args": ["/absolute/path/to/telegram-notifier-mcp/build/index.js"],
|
|
84
|
+
"env": {
|
|
85
|
+
"TELEGRAM_BOT_TOKEN": "your-bot-token-here",
|
|
86
|
+
"TELEGRAM_CHAT_ID": "your-chat-id-here"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## Tools
|
|
94
|
+
|
|
95
|
+
### `send_message`
|
|
96
|
+
|
|
97
|
+
Send a text message to a Telegram chat.
|
|
98
|
+
|
|
99
|
+
| Parameter | Type | Required | Description |
|
|
100
|
+
|---|---|---|---|
|
|
101
|
+
| `text` | string | Yes | The message text to send |
|
|
102
|
+
| `chatId` | string | No | Target chat ID (overrides `TELEGRAM_CHAT_ID`) |
|
|
103
|
+
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
|
|
104
|
+
| `disableNotification` | boolean | No | Send silently without notification sound |
|
|
105
|
+
|
|
106
|
+
### `send_document`
|
|
107
|
+
|
|
108
|
+
Send a file/document to a Telegram chat.
|
|
109
|
+
|
|
110
|
+
| Parameter | Type | Required | Description |
|
|
111
|
+
|---|---|---|---|
|
|
112
|
+
| `filePath` | string | Yes | Absolute path to the file |
|
|
113
|
+
| `chatId` | string | No | Target chat ID (overrides `TELEGRAM_CHAT_ID`) |
|
|
114
|
+
| `caption` | string | No | Caption for the document |
|
|
115
|
+
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
|
|
116
|
+
| `disableNotification` | boolean | No | Send silently without notification sound |
|
|
117
|
+
|
|
118
|
+
### `send_photo`
|
|
119
|
+
|
|
120
|
+
Send a photo/image to a Telegram chat.
|
|
121
|
+
|
|
122
|
+
| Parameter | Type | Required | Description |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| `filePath` | string | Yes | Absolute path to the image file |
|
|
125
|
+
| `chatId` | string | No | Target chat ID (overrides `TELEGRAM_CHAT_ID`) |
|
|
126
|
+
| `caption` | string | No | Caption for the photo |
|
|
127
|
+
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
|
|
128
|
+
| `disableNotification` | boolean | No | Send silently without notification sound |
|
|
129
|
+
|
|
130
|
+
### `send_video`
|
|
131
|
+
|
|
132
|
+
Send a video to a Telegram chat.
|
|
133
|
+
|
|
134
|
+
| Parameter | Type | Required | Description |
|
|
135
|
+
|---|---|---|---|
|
|
136
|
+
| `filePath` | string | Yes | Absolute path to the video file |
|
|
137
|
+
| `chatId` | string | No | Target chat ID (overrides `TELEGRAM_CHAT_ID`) |
|
|
138
|
+
| `caption` | string | No | Caption for the video |
|
|
139
|
+
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
|
|
140
|
+
| `disableNotification` | boolean | No | Send silently without notification sound |
|
|
141
|
+
|
|
142
|
+
### `send_audio`
|
|
143
|
+
|
|
144
|
+
Send an audio file to a Telegram chat.
|
|
145
|
+
|
|
146
|
+
| Parameter | Type | Required | Description |
|
|
147
|
+
|---|---|---|---|
|
|
148
|
+
| `filePath` | string | Yes | Absolute path to the audio file |
|
|
149
|
+
| `chatId` | string | No | Target chat ID (overrides `TELEGRAM_CHAT_ID`) |
|
|
150
|
+
| `caption` | string | No | Caption for the audio |
|
|
151
|
+
| `parseMode` | string | No | `Markdown`, `MarkdownV2`, or `HTML` |
|
|
152
|
+
| `disableNotification` | boolean | No | Send silently without notification sound |
|
|
153
|
+
|
|
154
|
+
## Testing with the MCP Inspector
|
|
155
|
+
|
|
156
|
+
You can test the server interactively using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector):
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
TELEGRAM_BOT_TOKEN="your-token" TELEGRAM_CHAT_ID="your-chat-id" \
|
|
160
|
+
npx @modelcontextprotocol/inspector node build/index.js
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
This opens a browser UI where you can invoke each tool and see the results.
|
|
164
|
+
|
|
165
|
+
## Error Handling
|
|
166
|
+
|
|
167
|
+
The server handles errors gracefully and returns descriptive messages:
|
|
168
|
+
|
|
169
|
+
| Scenario | Behavior |
|
|
170
|
+
|---|---|
|
|
171
|
+
| Missing `TELEGRAM_BOT_TOKEN` | Server exits at startup with instructions |
|
|
172
|
+
| Missing chat ID (no env var, no parameter) | Returns `isError: true` with message |
|
|
173
|
+
| File not found | Returns `isError: true` with the file path |
|
|
174
|
+
| File exceeds 50 MB | Returns `isError: true` with file size |
|
|
175
|
+
| Telegram API error | Returns `isError: true` with Telegram's error description |
|
|
176
|
+
|
|
177
|
+
All server logs go to **stderr** so they never interfere with the stdio MCP transport on stdout.
|
|
178
|
+
|
|
179
|
+
## File Size Limits
|
|
180
|
+
|
|
181
|
+
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.
|
|
182
|
+
|
|
183
|
+
## Development
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
# Watch mode — rebuilds on file changes
|
|
187
|
+
npm run dev
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## License
|
|
191
|
+
|
|
192
|
+
MIT
|
package/build/index.d.ts
ADDED
package/build/index.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { readFile, stat } from "node:fs/promises";
|
|
6
|
+
import { basename } from "node:path";
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Config
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const TELEGRAM_BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
11
|
+
const DEFAULT_CHAT_ID = process.env.TELEGRAM_CHAT_ID;
|
|
12
|
+
if (!TELEGRAM_BOT_TOKEN) {
|
|
13
|
+
console.error("Error: TELEGRAM_BOT_TOKEN environment variable is required.\n" +
|
|
14
|
+
"Get a token from @BotFather on Telegram.");
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
const TELEGRAM_API = `https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}`;
|
|
18
|
+
const MAX_FILE_SIZE = 50 * 1024 * 1024; // 50 MB
|
|
19
|
+
async function sendMessage(chatId, text, parseMode, disableNotification) {
|
|
20
|
+
const body = { chat_id: chatId, text };
|
|
21
|
+
if (parseMode)
|
|
22
|
+
body.parse_mode = parseMode;
|
|
23
|
+
if (disableNotification)
|
|
24
|
+
body.disable_notification = true;
|
|
25
|
+
const res = await fetch(`${TELEGRAM_API}/sendMessage`, {
|
|
26
|
+
method: "POST",
|
|
27
|
+
headers: { "Content-Type": "application/json" },
|
|
28
|
+
body: JSON.stringify(body),
|
|
29
|
+
});
|
|
30
|
+
return (await res.json());
|
|
31
|
+
}
|
|
32
|
+
const FILE_FIELD = {
|
|
33
|
+
sendDocument: "document",
|
|
34
|
+
sendPhoto: "photo",
|
|
35
|
+
sendVideo: "video",
|
|
36
|
+
sendAudio: "audio",
|
|
37
|
+
};
|
|
38
|
+
async function sendFile(method, chatId, filePath, caption, parseMode, disableNotification) {
|
|
39
|
+
// Validate file exists and is within size limit
|
|
40
|
+
let fileStats;
|
|
41
|
+
try {
|
|
42
|
+
fileStats = await stat(filePath);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return { ok: false, description: `File not found: ${filePath}` };
|
|
46
|
+
}
|
|
47
|
+
if (fileStats.size > MAX_FILE_SIZE) {
|
|
48
|
+
return {
|
|
49
|
+
ok: false,
|
|
50
|
+
description: `File exceeds 50 MB limit (${(fileStats.size / 1024 / 1024).toFixed(1)} MB): ${filePath}`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
const fileBuffer = await readFile(filePath);
|
|
54
|
+
const blob = new Blob([fileBuffer]);
|
|
55
|
+
const fileName = basename(filePath);
|
|
56
|
+
const form = new FormData();
|
|
57
|
+
form.append("chat_id", chatId);
|
|
58
|
+
form.append(FILE_FIELD[method], blob, fileName);
|
|
59
|
+
if (caption)
|
|
60
|
+
form.append("caption", caption);
|
|
61
|
+
if (parseMode)
|
|
62
|
+
form.append("parse_mode", parseMode);
|
|
63
|
+
if (disableNotification)
|
|
64
|
+
form.append("disable_notification", "true");
|
|
65
|
+
const res = await fetch(`${TELEGRAM_API}/${method}`, {
|
|
66
|
+
method: "POST",
|
|
67
|
+
body: form,
|
|
68
|
+
});
|
|
69
|
+
return (await res.json());
|
|
70
|
+
}
|
|
71
|
+
// ---------------------------------------------------------------------------
|
|
72
|
+
// Helpers
|
|
73
|
+
// ---------------------------------------------------------------------------
|
|
74
|
+
function resolveChatId(overrideChatId) {
|
|
75
|
+
return overrideChatId || DEFAULT_CHAT_ID || null;
|
|
76
|
+
}
|
|
77
|
+
function successResult(text) {
|
|
78
|
+
return { content: [{ type: "text", text }] };
|
|
79
|
+
}
|
|
80
|
+
function errorResult(text) {
|
|
81
|
+
return { content: [{ type: "text", text }], isError: true };
|
|
82
|
+
}
|
|
83
|
+
function telegramResult(res, successMsg) {
|
|
84
|
+
if (res.ok)
|
|
85
|
+
return successResult(successMsg);
|
|
86
|
+
return errorResult(`Telegram API error: ${res.description ?? "Unknown error"}`);
|
|
87
|
+
}
|
|
88
|
+
// ---------------------------------------------------------------------------
|
|
89
|
+
// MCP Server
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
const server = new McpServer({
|
|
92
|
+
name: "telegram-notifier",
|
|
93
|
+
version: "1.0.0",
|
|
94
|
+
});
|
|
95
|
+
// -- send_message -----------------------------------------------------------
|
|
96
|
+
server.tool("send_message", "Send a text message to a Telegram chat", {
|
|
97
|
+
text: z.string().describe("The message text to send"),
|
|
98
|
+
chatId: z
|
|
99
|
+
.string()
|
|
100
|
+
.optional()
|
|
101
|
+
.describe("Target chat ID (overrides TELEGRAM_CHAT_ID env var)"),
|
|
102
|
+
parseMode: z
|
|
103
|
+
.enum(["Markdown", "MarkdownV2", "HTML"])
|
|
104
|
+
.optional()
|
|
105
|
+
.describe("Message formatting mode"),
|
|
106
|
+
disableNotification: z
|
|
107
|
+
.boolean()
|
|
108
|
+
.optional()
|
|
109
|
+
.describe("Send silently without notification sound"),
|
|
110
|
+
}, async ({ text, chatId, parseMode, disableNotification }) => {
|
|
111
|
+
const resolvedChatId = resolveChatId(chatId);
|
|
112
|
+
if (!resolvedChatId) {
|
|
113
|
+
return errorResult("No chat ID provided. Set TELEGRAM_CHAT_ID env var or pass chatId parameter.");
|
|
114
|
+
}
|
|
115
|
+
const res = await sendMessage(resolvedChatId, text, parseMode, disableNotification);
|
|
116
|
+
return telegramResult(res, `Message sent to chat ${resolvedChatId}.`);
|
|
117
|
+
});
|
|
118
|
+
// -- send_document ----------------------------------------------------------
|
|
119
|
+
server.tool("send_document", "Send a file/document to a Telegram chat", {
|
|
120
|
+
filePath: z.string().describe("Absolute path to the file to send"),
|
|
121
|
+
chatId: z
|
|
122
|
+
.string()
|
|
123
|
+
.optional()
|
|
124
|
+
.describe("Target chat ID (overrides TELEGRAM_CHAT_ID env var)"),
|
|
125
|
+
caption: z.string().optional().describe("Caption for the document"),
|
|
126
|
+
parseMode: z
|
|
127
|
+
.enum(["Markdown", "MarkdownV2", "HTML"])
|
|
128
|
+
.optional()
|
|
129
|
+
.describe("Caption formatting mode"),
|
|
130
|
+
disableNotification: z
|
|
131
|
+
.boolean()
|
|
132
|
+
.optional()
|
|
133
|
+
.describe("Send silently without notification sound"),
|
|
134
|
+
}, async ({ filePath, chatId, caption, parseMode, disableNotification }) => {
|
|
135
|
+
const resolvedChatId = resolveChatId(chatId);
|
|
136
|
+
if (!resolvedChatId) {
|
|
137
|
+
return errorResult("No chat ID provided. Set TELEGRAM_CHAT_ID env var or pass chatId parameter.");
|
|
138
|
+
}
|
|
139
|
+
const res = await sendFile("sendDocument", resolvedChatId, filePath, caption, parseMode, disableNotification);
|
|
140
|
+
return telegramResult(res, `Document sent to chat ${resolvedChatId}.`);
|
|
141
|
+
});
|
|
142
|
+
// -- send_photo -------------------------------------------------------------
|
|
143
|
+
server.tool("send_photo", "Send a photo/image to a Telegram chat", {
|
|
144
|
+
filePath: z.string().describe("Absolute path to the image file to send"),
|
|
145
|
+
chatId: z
|
|
146
|
+
.string()
|
|
147
|
+
.optional()
|
|
148
|
+
.describe("Target chat ID (overrides TELEGRAM_CHAT_ID env var)"),
|
|
149
|
+
caption: z.string().optional().describe("Caption for the photo"),
|
|
150
|
+
parseMode: z
|
|
151
|
+
.enum(["Markdown", "MarkdownV2", "HTML"])
|
|
152
|
+
.optional()
|
|
153
|
+
.describe("Caption formatting mode"),
|
|
154
|
+
disableNotification: z
|
|
155
|
+
.boolean()
|
|
156
|
+
.optional()
|
|
157
|
+
.describe("Send silently without notification sound"),
|
|
158
|
+
}, async ({ filePath, chatId, caption, parseMode, disableNotification }) => {
|
|
159
|
+
const resolvedChatId = resolveChatId(chatId);
|
|
160
|
+
if (!resolvedChatId) {
|
|
161
|
+
return errorResult("No chat ID provided. Set TELEGRAM_CHAT_ID env var or pass chatId parameter.");
|
|
162
|
+
}
|
|
163
|
+
const res = await sendFile("sendPhoto", resolvedChatId, filePath, caption, parseMode, disableNotification);
|
|
164
|
+
return telegramResult(res, `Photo sent to chat ${resolvedChatId}.`);
|
|
165
|
+
});
|
|
166
|
+
// -- send_video -------------------------------------------------------------
|
|
167
|
+
server.tool("send_video", "Send a video to a Telegram chat", {
|
|
168
|
+
filePath: z.string().describe("Absolute path to the video file to send"),
|
|
169
|
+
chatId: z
|
|
170
|
+
.string()
|
|
171
|
+
.optional()
|
|
172
|
+
.describe("Target chat ID (overrides TELEGRAM_CHAT_ID env var)"),
|
|
173
|
+
caption: z.string().optional().describe("Caption for the video"),
|
|
174
|
+
parseMode: z
|
|
175
|
+
.enum(["Markdown", "MarkdownV2", "HTML"])
|
|
176
|
+
.optional()
|
|
177
|
+
.describe("Caption formatting mode"),
|
|
178
|
+
disableNotification: z
|
|
179
|
+
.boolean()
|
|
180
|
+
.optional()
|
|
181
|
+
.describe("Send silently without notification sound"),
|
|
182
|
+
}, async ({ filePath, chatId, caption, parseMode, disableNotification }) => {
|
|
183
|
+
const resolvedChatId = resolveChatId(chatId);
|
|
184
|
+
if (!resolvedChatId) {
|
|
185
|
+
return errorResult("No chat ID provided. Set TELEGRAM_CHAT_ID env var or pass chatId parameter.");
|
|
186
|
+
}
|
|
187
|
+
const res = await sendFile("sendVideo", resolvedChatId, filePath, caption, parseMode, disableNotification);
|
|
188
|
+
return telegramResult(res, `Video sent to chat ${resolvedChatId}.`);
|
|
189
|
+
});
|
|
190
|
+
// -- send_audio -------------------------------------------------------------
|
|
191
|
+
server.tool("send_audio", "Send an audio file to a Telegram chat", {
|
|
192
|
+
filePath: z.string().describe("Absolute path to the audio file to send"),
|
|
193
|
+
chatId: z
|
|
194
|
+
.string()
|
|
195
|
+
.optional()
|
|
196
|
+
.describe("Target chat ID (overrides TELEGRAM_CHAT_ID env var)"),
|
|
197
|
+
caption: z.string().optional().describe("Caption for the audio"),
|
|
198
|
+
parseMode: z
|
|
199
|
+
.enum(["Markdown", "MarkdownV2", "HTML"])
|
|
200
|
+
.optional()
|
|
201
|
+
.describe("Caption formatting mode"),
|
|
202
|
+
disableNotification: z
|
|
203
|
+
.boolean()
|
|
204
|
+
.optional()
|
|
205
|
+
.describe("Send silently without notification sound"),
|
|
206
|
+
}, async ({ filePath, chatId, caption, parseMode, disableNotification }) => {
|
|
207
|
+
const resolvedChatId = resolveChatId(chatId);
|
|
208
|
+
if (!resolvedChatId) {
|
|
209
|
+
return errorResult("No chat ID provided. Set TELEGRAM_CHAT_ID env var or pass chatId parameter.");
|
|
210
|
+
}
|
|
211
|
+
const res = await sendFile("sendAudio", resolvedChatId, filePath, caption, parseMode, disableNotification);
|
|
212
|
+
return telegramResult(res, `Audio sent to chat ${resolvedChatId}.`);
|
|
213
|
+
});
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
// Start
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
async function main() {
|
|
218
|
+
const transport = new StdioServerTransport();
|
|
219
|
+
await server.connect(transport);
|
|
220
|
+
console.error("Telegram Notifier MCP server running on stdio");
|
|
221
|
+
}
|
|
222
|
+
main().catch((error) => {
|
|
223
|
+
console.error("Fatal error:", error);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "telegram-notifier-mcp",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for sending notifications via Telegram Bot API",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"telegram-notifier-mcp": "build/index.js"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"build"
|
|
11
|
+
],
|
|
12
|
+
"scripts": {
|
|
13
|
+
"build": "tsc",
|
|
14
|
+
"dev": "tsc --watch",
|
|
15
|
+
"prepublishOnly": "npm run build"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
19
|
+
"zod": "^3.24.2"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"typescript": "^5.7.3",
|
|
23
|
+
"@types/node": "^22.13.4"
|
|
24
|
+
}
|
|
25
|
+
}
|