@tuannvm/telegram-mcp-server 0.0.2

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 ADDED
@@ -0,0 +1,141 @@
1
+ # Telegram MCP Server
2
+
3
+ [![npm version](https://img.shields.io/npm/v/@tuannvm/telegram-mcp-server.svg)](https://www.npmjs.com/package/@tuannvm/telegram-mcp-server)
4
+ [![npm downloads](https://img.shields.io/npm/dm/@tuannvm/telegram-mcp-server.svg)](https://www.npmjs.com/package/@tuannvm/telegram-mcp-server)
5
+ [![license](https://img.shields.io/npm/l/@tuannvm/telegram-mcp-server.svg)](https://www.npmjs.com/package/@tuannvm/telegram-mcp-server)
6
+
7
+ Send Telegram notifications from anywhere — works seamlessly across local machines, remote SSH sessions, and containerized environments.
8
+
9
+ ```mermaid
10
+ graph LR
11
+ A[Claude Code] --> B[Telegram MCP Server]
12
+ B --> C[Telegram Bot API]
13
+ C --> D[Your Telegram Chat]
14
+
15
+ style A fill:#FF6B35
16
+ style B fill:#4A90E2
17
+ style C fill:#0088cc
18
+ style D fill:#00D4AA
19
+ ```
20
+
21
+ ## Quick Start
22
+
23
+ ### 1. Create Telegram Bot
24
+
25
+ ```bash
26
+ # Message @BotFather on Telegram
27
+ /newbot
28
+ # Follow prompts to get your bot token
29
+ ```
30
+
31
+ ### 2. Add to Claude Code
32
+
33
+ ```bash
34
+ export TELEGRAM_BOT_TOKEN="your-bot-token"
35
+ export TELEGRAM_CHAT_ID="your-chat-id"
36
+ claude mcp add telegram -- npx -y @tuannvm/telegram-mcp-server
37
+ ```
38
+
39
+ ### 3. Start Using
40
+
41
+ ```
42
+ Send notification "✅ DONE" to "Deployment complete"
43
+ Send telegram status to check configuration
44
+ ```
45
+
46
+ ## One-Click Install
47
+
48
+ [![VS Code](https://img.shields.io/badge/VS_Code-Install-0098FF?style=flat-square&logo=visualstudiocode&logoColor=white)](https://vscode.dev/redirect/mcp/install?name=telegram&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22@tuannvm/telegram-mcp-server%22%5D%2C%22env%22%3A%7B%22TELEGRAM_BOT_TOKEN%22%3A%22YOUR_BOT_TOKEN%22%2C%22TELEGRAM_CHAT_ID%22%3A%22YOUR_CHAT_ID%22%7D%7D)
49
+ [![VS Code Insiders](https://img.shields.io/badge/VS_Code_Insiders-Install-24bfa5?style=flat-square&logo=visualstudiocode&logoColor=white)](https://insiders.vscode.dev/redirect/mcp/install?name=telegram&config=%7B%22type%22%3A%22stdio%22%2C%22command%22%3A%22npx%22%2C%22args%22%3A%5B%22-y%22%2C%22@tuannvm/telegram-mcp-server%22%5D%2C%22env%22%3A%7B%22TELEGRAM_BOT_TOKEN%22%3A%22YOUR_BOT_TOKEN%22%2C%22TELEGRAM_CHAT_ID%22%3A%22YOUR_CHAT_ID%22%7D%7D)
50
+ [![Cursor](https://img.shields.io/badge/Cursor-Install-00D8FF?style=flat-square&logo=cursor&logoColor=white)](https://cursor.com/en/install-mcp?name=telegram&config=eyJ0eXBlIjoic3RkaW8iLCJjb21tYW5kIjoibnB4IC15IEB0dWFubnZtL3RlbGVncmFtLW1jcC1zZXJ2ZXIiLCJlbnYiOnsiVEVMRUdSQU1fQk9UX1RPS0VOIjoiWU9VUl9CT1RfVE9LRU4iLCJURUxFR1JBTV9DSEFUX0lEIjoiWU9VUl9DSEFUX0lEIn19)
51
+
52
+ ## Tools
53
+
54
+ | Tool | Description |
55
+ |------|-------------|
56
+ | `send_telegram` | Send Telegram notifications with HTML formatting |
57
+ | `telegram_status` | Check if Telegram credentials are configured |
58
+
59
+ ## Examples
60
+
61
+ **Simple notification:**
62
+ ```
63
+ Send notification "✅ DONE" to "Build completed successfully"
64
+ ```
65
+
66
+ **With context:**
67
+ ```
68
+ Send notification "🚫 BLOCKED" to "Need approval to continue
69
+
70
+ 📁 /path/to/project
71
+ 🌿 Branch: feature/new-auth
72
+ 💻 Host: production-server
73
+
74
+ Task: Deploying to production
75
+ Issue: Requires manual approval"
76
+ ```
77
+
78
+ **Error reporting:**
79
+ ```
80
+ Send notification "❌ ERROR" to "Deployment failed
81
+
82
+ Error: Database connection timeout
83
+ Exit code: 1
84
+ Duration: 45s"
85
+ ```
86
+
87
+ **Status check:**
88
+ ```
89
+ Send telegram status to verify configuration
90
+ ```
91
+
92
+ ## Getting Your Chat ID
93
+
94
+ ```bash
95
+ # After creating your bot, send a message to it
96
+ # Then visit this URL in your browser:
97
+ https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates
98
+
99
+ # Look for "chat":{"id":123456789} in the response
100
+ ```
101
+
102
+ ## Requirements
103
+
104
+ - **Telegram Bot Token** — Create a bot via @BotFather on Telegram
105
+ - **Telegram Chat ID** — Your personal Telegram chat ID or group ID
106
+ - **Node.js 18+** — For local development
107
+
108
+ ## Environment Variables
109
+
110
+ | Variable | Description | Required |
111
+ |----------|-------------|----------|
112
+ | `TELEGRAM_BOT_TOKEN` | Your Telegram bot token from @BotFather | Yes |
113
+ | `TELEGRAM_CHAT_ID` | Target chat ID for notifications | Yes |
114
+
115
+ ## Development
116
+
117
+ ```bash
118
+ npm install # Install dependencies
119
+ npm run dev # Development mode
120
+ npm run build # Build for production
121
+ npm test # Run tests
122
+ npm run lint # Run ESLint
123
+ ```
124
+
125
+ ## How It Works
126
+
127
+ This MCP server runs as a separate process communicating via stdio. When you call `send_telegram`:
128
+
129
+ 1. The MCP server receives the request via stdio
130
+ 2. It makes an HTTP request to Telegram's Bot API
131
+ 3. Your notification appears instantly on Telegram
132
+
133
+ This works reliably across:
134
+ - Local development machines
135
+ - Remote SSH sessions
136
+ - Containerized environments
137
+ - CI/CD pipelines
138
+
139
+ ## License
140
+
141
+ ISC
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=server.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,12 @@
1
+ import { TelegramMcpServer } from '../server.js';
2
+ describe('TelegramMcpServer', () => {
3
+ it('should instantiate with correct config', () => {
4
+ const config = {
5
+ name: 'test-server',
6
+ version: '1.0.0',
7
+ };
8
+ const server = new TelegramMcpServer(config);
9
+ expect(server).toBeInstanceOf(TelegramMcpServer);
10
+ });
11
+ });
12
+ //# sourceMappingURL=server.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.test.js","sourceRoot":"","sources":["../../src/__tests__/server.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,wCAAwC,EAAE,GAAG,EAAE;QAChD,MAAM,MAAM,GAAG;YACb,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,OAAO;SACjB,CAAC;QACF,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC7C,MAAM,CAAC,MAAM,CAAC,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,11 @@
1
+ export declare class ToolExecutionError extends Error {
2
+ readonly toolName: string;
3
+ readonly cause?: unknown | undefined;
4
+ constructor(toolName: string, message: string, cause?: unknown | undefined);
5
+ }
6
+ export declare class ValidationError extends Error {
7
+ readonly toolName: string;
8
+ constructor(toolName: string, message: string);
9
+ }
10
+ export declare function handleError(error: unknown, context: string): string;
11
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,kBAAmB,SAAQ,KAAK;aAEzB,QAAQ,EAAE,MAAM;aAEhB,KAAK,CAAC,EAAE,OAAO;gBAFf,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM,EACC,KAAK,CAAC,EAAE,OAAO,YAAA;CAKlC;AAED,qBAAa,eAAgB,SAAQ,KAAK;aAEtB,QAAQ,EAAE,MAAM;gBAAhB,QAAQ,EAAE,MAAM,EAChC,OAAO,EAAE,MAAM;CAKlB;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKnE"}
package/dist/errors.js ADDED
@@ -0,0 +1,25 @@
1
+ export class ToolExecutionError extends Error {
2
+ toolName;
3
+ cause;
4
+ constructor(toolName, message, cause) {
5
+ super(`Failed to execute tool "${toolName}": ${message}`);
6
+ this.toolName = toolName;
7
+ this.cause = cause;
8
+ this.name = 'ToolExecutionError';
9
+ }
10
+ }
11
+ export class ValidationError extends Error {
12
+ toolName;
13
+ constructor(toolName, message) {
14
+ super(`Validation failed for tool "${toolName}": ${message}`);
15
+ this.toolName = toolName;
16
+ this.name = 'ValidationError';
17
+ }
18
+ }
19
+ export function handleError(error, context) {
20
+ if (error instanceof Error) {
21
+ return `Error in ${context}: ${error.message}`;
22
+ }
23
+ return `Error in ${context}: ${String(error)}`;
24
+ }
25
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAEzB;IAEA;IAHlB,YACkB,QAAgB,EAChC,OAAe,EACC,KAAe;QAE/B,KAAK,CAAC,2BAA2B,QAAQ,MAAM,OAAO,EAAE,CAAC,CAAC;QAJ1C,aAAQ,GAAR,QAAQ,CAAQ;QAEhB,UAAK,GAAL,KAAK,CAAU;QAG/B,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAC;IACnC,CAAC;CACF;AAED,MAAM,OAAO,eAAgB,SAAQ,KAAK;IAEtB;IADlB,YACkB,QAAgB,EAChC,OAAe;QAEf,KAAK,CAAC,+BAA+B,QAAQ,MAAM,OAAO,EAAE,CAAC,CAAC;QAH9C,aAAQ,GAAR,QAAQ,CAAQ;QAIhC,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,OAAe;IACzD,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;QAC3B,OAAO,YAAY,OAAO,KAAK,KAAK,CAAC,OAAO,EAAE,CAAC;IACjD,CAAC;IACD,OAAO,YAAY,OAAO,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;AACjD,CAAC"}
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Telegram MCP Server
4
+ *
5
+ * Environment variables:
6
+ * TELEGRAM_BOT_TOKEN - Your Telegram bot token
7
+ * TELEGRAM_CHAT_ID - Target chat ID for notifications
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG"}
package/dist/index.js ADDED
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Telegram MCP Server
4
+ *
5
+ * Environment variables:
6
+ * TELEGRAM_BOT_TOKEN - Your Telegram bot token
7
+ * TELEGRAM_CHAT_ID - Target chat ID for notifications
8
+ */
9
+ import chalk from 'chalk';
10
+ import { TelegramMcpServer } from './server.js';
11
+ const SERVER_CONFIG = {
12
+ name: 'telegram-mcp-server',
13
+ version: '1.0.0',
14
+ };
15
+ async function main() {
16
+ try {
17
+ const server = new TelegramMcpServer(SERVER_CONFIG);
18
+ await server.start();
19
+ }
20
+ catch (error) {
21
+ console.error(chalk.red('Failed to start server:'), error);
22
+ process.exit(1);
23
+ }
24
+ }
25
+ main();
26
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,aAAa,GAAG;IACpB,IAAI,EAAE,qBAAqB;IAC3B,OAAO,EAAE,OAAO;CACR,CAAC;AAEX,KAAK,UAAU,IAAI;IACjB,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,iBAAiB,CAAC,aAAa,CAAC,CAAC;QACpD,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,yBAAyB,CAAC,EAAE,KAAK,CAAC,CAAC;QAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type ServerConfig } from './types.js';
2
+ export declare class TelegramMcpServer {
3
+ private readonly server;
4
+ private readonly config;
5
+ constructor(config: ServerConfig);
6
+ private setupHandlers;
7
+ private isValidToolName;
8
+ start(): Promise<void>;
9
+ }
10
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,YAAY,EAKlB,MAAM,YAAY,CAAC;AAKpB,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,YAAY;IAiBhC,OAAO,CAAC,aAAa;IA4DrB,OAAO,CAAC,eAAe;IAIjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
package/dist/server.js ADDED
@@ -0,0 +1,90 @@
1
+ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
4
+ import chalk from 'chalk';
5
+ import { TOOLS, } from './types.js';
6
+ import { handleError } from './errors.js';
7
+ import { toolDefinitions } from './tools/definitions.js';
8
+ import { toolHandlers } from './tools/handlers.js';
9
+ export class TelegramMcpServer {
10
+ server;
11
+ config;
12
+ constructor(config) {
13
+ this.config = config;
14
+ this.server = new Server({
15
+ name: config.name,
16
+ version: config.version,
17
+ }, {
18
+ capabilities: {
19
+ tools: {},
20
+ },
21
+ });
22
+ this.setupHandlers();
23
+ }
24
+ setupHandlers() {
25
+ // List tools handler
26
+ this.server.setRequestHandler(ListToolsRequestSchema, async () => {
27
+ return { tools: toolDefinitions };
28
+ });
29
+ // Call tool handler
30
+ this.server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
31
+ const { name, arguments: args } = request.params;
32
+ const progressToken = request.params._meta?.progressToken;
33
+ // Create progress sender that uses MCP notifications
34
+ const createProgressContext = () => {
35
+ let progressCount = 0;
36
+ return {
37
+ progressToken,
38
+ sendProgress: async (message, progress, total) => {
39
+ if (!progressToken)
40
+ return;
41
+ progressCount++;
42
+ try {
43
+ await extra.sendNotification({
44
+ method: 'notifications/progress',
45
+ params: {
46
+ progressToken,
47
+ progress: progress ?? progressCount,
48
+ total,
49
+ message,
50
+ },
51
+ });
52
+ }
53
+ catch (err) {
54
+ // Log but don't fail the operation if progress notification fails
55
+ console.error(chalk.yellow('Failed to send progress notification:'), err);
56
+ }
57
+ },
58
+ };
59
+ };
60
+ try {
61
+ if (!this.isValidToolName(name)) {
62
+ throw new Error(`Unknown tool: ${name}`);
63
+ }
64
+ const handler = toolHandlers[name];
65
+ const context = createProgressContext();
66
+ return await handler.execute(args, context);
67
+ }
68
+ catch (error) {
69
+ return {
70
+ content: [
71
+ {
72
+ type: 'text',
73
+ text: handleError(error, `tool "${name}"`),
74
+ },
75
+ ],
76
+ isError: true,
77
+ };
78
+ }
79
+ });
80
+ }
81
+ isValidToolName(name) {
82
+ return Object.values(TOOLS).includes(name);
83
+ }
84
+ async start() {
85
+ const transport = new StdioServerTransport();
86
+ await this.server.connect(transport);
87
+ console.error(chalk.green(`${this.config.name} started successfully`));
88
+ }
89
+ }
90
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { type ToolDefinition } from '../types.js';
2
+ export declare const toolDefinitions: ToolDefinition[];
3
+ //# sourceMappingURL=definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAEzD,eAAO,MAAM,eAAe,EAAE,cAAc,EA6C3C,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { TOOLS } from '../types.js';
2
+ export const toolDefinitions = [
3
+ {
4
+ name: TOOLS.SEND_TELEGRAM,
5
+ description: 'Send a Telegram notification. Use for alerts, completion notices, or when blocked awaiting input.',
6
+ inputSchema: {
7
+ type: 'object',
8
+ properties: {
9
+ header: {
10
+ type: 'string',
11
+ description: 'Message header/title. Use emoji + status like: ✅ DONE, 🚫 BLOCKED, ❌ ERROR',
12
+ },
13
+ body: {
14
+ type: 'string',
15
+ description: 'Optional message body with details. Can be multiline. Supports basic context like PWD, branch, host.',
16
+ },
17
+ },
18
+ required: ['header'],
19
+ },
20
+ annotations: {
21
+ title: 'Send Telegram',
22
+ readOnlyHint: true,
23
+ destructiveHint: false,
24
+ idempotentHint: false,
25
+ openWorldHint: true,
26
+ },
27
+ },
28
+ {
29
+ name: TOOLS.TELEGRAM_STATUS,
30
+ description: 'Check if Telegram credentials are configured',
31
+ inputSchema: {
32
+ type: 'object',
33
+ properties: {},
34
+ required: [],
35
+ },
36
+ annotations: {
37
+ title: 'Telegram Status',
38
+ readOnlyHint: true,
39
+ destructiveHint: false,
40
+ idempotentHint: true,
41
+ openWorldHint: false,
42
+ },
43
+ },
44
+ ];
45
+ //# sourceMappingURL=definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAuB,MAAM,aAAa,CAAC;AAEzD,MAAM,CAAC,MAAM,eAAe,GAAqB;IAC/C;QACE,IAAI,EAAE,KAAK,CAAC,aAAa;QACzB,WAAW,EACT,mGAAmG;QACrG,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,MAAM,EAAE;oBACN,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,4EAA4E;iBAC/E;gBACD,IAAI,EAAE;oBACJ,IAAI,EAAE,QAAQ;oBACd,WAAW,EACT,sGAAsG;iBACzG;aACF;YACD,QAAQ,EAAE,CAAC,QAAQ,CAAC;SACrB;QACD,WAAW,EAAE;YACX,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,KAAK;YACrB,aAAa,EAAE,IAAI;SACpB;KACF;IACD;QACE,IAAI,EAAE,KAAK,CAAC,eAAe;QAC3B,WAAW,EAAE,8CAA8C;QAC3D,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE;YACd,QAAQ,EAAE,EAAE;SACb;QACD,WAAW,EAAE;YACX,KAAK,EAAE,iBAAiB;YACxB,YAAY,EAAE,IAAI;YAClB,eAAe,EAAE,KAAK;YACtB,cAAc,EAAE,IAAI;YACpB,aAAa,EAAE,KAAK;SACrB;KACF;CACF,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type ToolResult, type ToolHandlerContext } from '../types.js';
2
+ export declare class SendTelegramToolHandler {
3
+ execute(args: unknown, _context?: ToolHandlerContext): Promise<ToolResult>;
4
+ }
5
+ export declare class TelegramStatusToolHandler {
6
+ execute(args: unknown, _context?: ToolHandlerContext): Promise<ToolResult>;
7
+ }
8
+ export declare const toolHandlers: {
9
+ readonly send_telegram: SendTelegramToolHandler;
10
+ readonly telegram_status: TelegramStatusToolHandler;
11
+ };
12
+ //# sourceMappingURL=handlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,UAAU,EACf,KAAK,kBAAkB,EAKxB,MAAM,aAAa,CAAC;AA0HrB,qBAAa,uBAAuB;IAC5B,OAAO,CACX,IAAI,EAAE,OAAO,EACb,QAAQ,GAAE,kBAAmC,GAC5C,OAAO,CAAC,UAAU,CAAC;CA6BvB;AAED,qBAAa,yBAAyB;IAC9B,OAAO,CACX,IAAI,EAAE,OAAO,EACb,QAAQ,GAAE,kBAAmC,GAC5C,OAAO,CAAC,UAAU,CAAC;CA4BvB;AAGD,eAAO,MAAM,YAAY;;;CAGf,CAAC"}
@@ -0,0 +1,154 @@
1
+ import { TOOLS, SendTelegramToolSchema, TelegramStatusToolSchema, } from '../types.js';
2
+ import { ToolExecutionError, ValidationError } from '../errors.js';
3
+ import { ZodError } from 'zod';
4
+ // Default no-op context for handlers that don't need progress
5
+ const defaultContext = {
6
+ sendProgress: async () => { },
7
+ };
8
+ /**
9
+ * Escape HTML special characters to prevent injection
10
+ */
11
+ function escapeHtml(text) {
12
+ const htmlEscapeMap = {
13
+ '&': '&amp;',
14
+ '<': '&lt;',
15
+ '>': '&gt;',
16
+ };
17
+ return text.replace(/[&<>]/g, (char) => htmlEscapeMap[char]);
18
+ }
19
+ /**
20
+ * Get Telegram configuration at runtime
21
+ */
22
+ function getTelegramConfig() {
23
+ return {
24
+ botToken: process.env.TELEGRAM_BOT_TOKEN,
25
+ chatId: process.env.TELEGRAM_CHAT_ID,
26
+ };
27
+ }
28
+ async function sendTelegramMessage(header, body) {
29
+ const { botToken, chatId } = getTelegramConfig();
30
+ if (!botToken || !chatId) {
31
+ return {
32
+ success: false,
33
+ error: 'Missing TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID environment variables',
34
+ };
35
+ }
36
+ // Escape HTML special characters to prevent injection
37
+ const escapedHeader = escapeHtml(header);
38
+ const escapedBody = body ? escapeHtml(body) : undefined;
39
+ const message = escapedBody
40
+ ? `<b>${escapedHeader}</b>\n\n${escapedBody}`
41
+ : escapedHeader;
42
+ // Setup timeout for fetch request
43
+ const controller = new AbortController();
44
+ const timeoutId = setTimeout(() => controller.abort(), 10000); // 10s timeout
45
+ try {
46
+ const response = await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
47
+ method: 'POST',
48
+ headers: { 'Content-Type': 'application/json' },
49
+ body: JSON.stringify({
50
+ chat_id: chatId,
51
+ text: message,
52
+ parse_mode: 'HTML',
53
+ disable_web_page_preview: true,
54
+ }),
55
+ signal: controller.signal,
56
+ });
57
+ // Clear timeout as request completed
58
+ clearTimeout(timeoutId);
59
+ // Check HTTP status code
60
+ if (!response.ok) {
61
+ return {
62
+ success: false,
63
+ error: `HTTP ${response.status}: ${response.statusText}`,
64
+ };
65
+ }
66
+ // Handle non-JSON responses
67
+ const contentType = response.headers.get('content-type');
68
+ if (!contentType?.includes('application/json')) {
69
+ const text = await response.text();
70
+ return {
71
+ success: false,
72
+ error: `Unexpected response type: ${contentType || 'unknown'}. Response: ${text.slice(0, 200)}`,
73
+ };
74
+ }
75
+ const data = (await response.json());
76
+ if (data.ok) {
77
+ return { success: true, messageId: data.result?.message_id };
78
+ }
79
+ else {
80
+ return { success: false, error: data.description || 'Unknown error' };
81
+ }
82
+ }
83
+ catch (error) {
84
+ // Clear timeout if still active
85
+ clearTimeout(timeoutId);
86
+ // Handle timeout specifically
87
+ if (error instanceof Error && error.name === 'AbortError') {
88
+ return {
89
+ success: false,
90
+ error: 'Request timeout (10s)',
91
+ };
92
+ }
93
+ return {
94
+ success: false,
95
+ error: error instanceof Error ? error.message : 'Network error',
96
+ };
97
+ }
98
+ }
99
+ export class SendTelegramToolHandler {
100
+ async execute(args, _context = defaultContext) {
101
+ try {
102
+ const { header, body } = SendTelegramToolSchema.parse(args);
103
+ const result = await sendTelegramMessage(header, body);
104
+ return {
105
+ content: [
106
+ {
107
+ type: 'text',
108
+ text: result.success
109
+ ? `✓ Telegram sent (ID: ${result.messageId})`
110
+ : `✗ Failed: ${result.error}`,
111
+ },
112
+ ],
113
+ isError: !result.success,
114
+ };
115
+ }
116
+ catch (error) {
117
+ if (error instanceof ZodError) {
118
+ throw new ValidationError(TOOLS.SEND_TELEGRAM, error.message);
119
+ }
120
+ throw new ToolExecutionError(TOOLS.SEND_TELEGRAM, 'Failed to send Telegram message', error);
121
+ }
122
+ }
123
+ }
124
+ export class TelegramStatusToolHandler {
125
+ async execute(args, _context = defaultContext) {
126
+ try {
127
+ // Handle undefined args for no-argument tools
128
+ TelegramStatusToolSchema.parse(args ?? {});
129
+ const { botToken, chatId } = getTelegramConfig();
130
+ const hasToken = !!botToken;
131
+ const hasChatId = !!chatId;
132
+ return {
133
+ content: [
134
+ {
135
+ type: 'text',
136
+ text: `Telegram Config:\n BOT_TOKEN: ${hasToken ? '✓ Set' : '✗ Missing'}\n CHAT_ID: ${hasChatId ? '✓ Set' : '✗ Missing'}`,
137
+ },
138
+ ],
139
+ };
140
+ }
141
+ catch (error) {
142
+ if (error instanceof ZodError) {
143
+ throw new ValidationError(TOOLS.TELEGRAM_STATUS, error.message);
144
+ }
145
+ throw new ToolExecutionError(TOOLS.TELEGRAM_STATUS, 'Failed to check Telegram status', error);
146
+ }
147
+ }
148
+ }
149
+ // Tool handler registry
150
+ export const toolHandlers = {
151
+ [TOOLS.SEND_TELEGRAM]: new SendTelegramToolHandler(),
152
+ [TOOLS.TELEGRAM_STATUS]: new TelegramStatusToolHandler(),
153
+ };
154
+ //# sourceMappingURL=handlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,60 @@
1
+ import { z } from 'zod';
2
+ export declare const TOOLS: {
3
+ readonly SEND_TELEGRAM: "send_telegram";
4
+ readonly TELEGRAM_STATUS: "telegram_status";
5
+ };
6
+ export type ToolName = typeof TOOLS[keyof typeof TOOLS];
7
+ export interface ToolAnnotations {
8
+ title?: string;
9
+ readOnlyHint?: boolean;
10
+ destructiveHint?: boolean;
11
+ idempotentHint?: boolean;
12
+ openWorldHint?: boolean;
13
+ }
14
+ export interface ToolDefinition {
15
+ name: ToolName;
16
+ description: string;
17
+ inputSchema: {
18
+ type: 'object';
19
+ properties: Record<string, unknown>;
20
+ required: string[];
21
+ };
22
+ annotations?: ToolAnnotations;
23
+ }
24
+ export interface ToolResult {
25
+ content: Array<{
26
+ type: 'text';
27
+ text: string;
28
+ }>;
29
+ isError?: boolean;
30
+ _meta?: Record<string, unknown>;
31
+ }
32
+ export interface ServerConfig {
33
+ name: string;
34
+ version: string;
35
+ }
36
+ export interface TelegramResponse {
37
+ ok: boolean;
38
+ description?: string;
39
+ result?: {
40
+ message_id: number;
41
+ };
42
+ }
43
+ export interface SendTelegramResult {
44
+ success: boolean;
45
+ messageId?: number;
46
+ error?: string;
47
+ }
48
+ export type ProgressToken = string | number;
49
+ export interface ToolHandlerContext {
50
+ progressToken?: ProgressToken;
51
+ sendProgress: (message: string, progress?: number, total?: number) => Promise<void>;
52
+ }
53
+ export declare const SendTelegramToolSchema: z.ZodObject<{
54
+ header: z.ZodString;
55
+ body: z.ZodOptional<z.ZodString>;
56
+ }, z.core.$strip>;
57
+ export declare const TelegramStatusToolSchema: z.ZodObject<{}, z.core.$strip>;
58
+ export type SendTelegramToolArgs = z.infer<typeof SendTelegramToolSchema>;
59
+ export type TelegramStatusToolArgs = z.infer<typeof TelegramStatusToolSchema>;
60
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,eAAO,MAAM,KAAK;;;CAGR,CAAC;AAEX,MAAM,MAAM,QAAQ,GAAG,OAAO,KAAK,CAAC,MAAM,OAAO,KAAK,CAAC,CAAC;AAGxD,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAGD,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,EAAE,MAAM,EAAE,CAAC;KACpB,CAAC;IACF,WAAW,CAAC,EAAE,eAAe,CAAC;CAC/B;AAGD,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,KAAK,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AAGD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAGD,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,OAAO,CAAC;IACZ,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE;QACP,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;CACH;AAGD,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAGD,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAG5C,MAAM,WAAW,kBAAkB;IACjC,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,YAAY,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrF;AAGD,eAAO,MAAM,sBAAsB;;;iBAGjC,CAAC;AAEH,eAAO,MAAM,wBAAwB,gCAAe,CAAC;AAErD,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAC1E,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
package/dist/types.js ADDED
@@ -0,0 +1,13 @@
1
+ import { z } from 'zod';
2
+ // Tool constants
3
+ export const TOOLS = {
4
+ SEND_TELEGRAM: 'send_telegram',
5
+ TELEGRAM_STATUS: 'telegram_status',
6
+ };
7
+ // Zod schemas for tool arguments
8
+ export const SendTelegramToolSchema = z.object({
9
+ header: z.string().describe('Message header/title. Use emoji + status like: ✅ DONE, 🚫 BLOCKED, ❌ ERROR'),
10
+ body: z.string().optional().describe('Optional message body with details. Can be multiline. Supports basic context like PWD, branch, host.'),
11
+ });
12
+ export const TelegramStatusToolSchema = z.object({});
13
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,iBAAiB;AACjB,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,aAAa,EAAE,eAAe;IAC9B,eAAe,EAAE,iBAAiB;CAC1B,CAAC;AAkEX,iCAAiC;AACjC,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,4EAA4E,CAAC;IACzG,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,sGAAsG,CAAC;CAC7I,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@tuannvm/telegram-mcp-server",
3
+ "version": "0.0.2",
4
+ "description": "MCP server for Telegram notifications - send notifications from Claude Code to Telegram",
5
+ "main": "dist/index.js",
6
+ "bin": {
7
+ "telegram-mcp-server": "dist/index.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "directories": {
13
+ "doc": "docs"
14
+ },
15
+ "scripts": {
16
+ "build": "tsc",
17
+ "start": "node dist/index.js",
18
+ "dev": "tsx src/index.ts",
19
+ "test": "jest",
20
+ "test:watch": "jest --watch",
21
+ "test:coverage": "jest --coverage",
22
+ "lint": "eslint src/**/*.ts",
23
+ "lint:fix": "eslint src/**/*.ts --fix",
24
+ "format": "prettier --write src/**/*.ts",
25
+ "format:check": "prettier --check src/**/*.ts",
26
+ "clean": "rm -rf dist"
27
+ },
28
+ "repository": {
29
+ "type": "git",
30
+ "url": "git+https://github.com/tuannvm/telegram-mcp-server.git"
31
+ },
32
+ "keywords": [
33
+ "mcp",
34
+ "telegram",
35
+ "notifications",
36
+ "claude",
37
+ "ai",
38
+ "cli"
39
+ ],
40
+ "author": "",
41
+ "license": "ISC",
42
+ "type": "module",
43
+ "bugs": {
44
+ "url": "https://github.com/tuannvm/telegram-mcp-server/issues"
45
+ },
46
+ "homepage": "https://github.com/tuannvm/telegram-mcp-server#readme",
47
+ "dependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.0.0",
49
+ "chalk": "^5.6.0",
50
+ "zod": "^4.0.17"
51
+ },
52
+ "devDependencies": {
53
+ "@types/jest": "^30.0.0",
54
+ "@types/node": "^20.0.0",
55
+ "@typescript-eslint/eslint-plugin": "^8.39.1",
56
+ "@typescript-eslint/parser": "^8.39.1",
57
+ "eslint": "^9.33.0",
58
+ "jest": "^30.0.5",
59
+ "prettier": "^3.6.2",
60
+ "ts-jest": "^29.4.1",
61
+ "tsx": "^4.20.4",
62
+ "typescript": "^5.0.0"
63
+ }
64
+ }