mcp-telegram-claudecode 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/LICENSE +21 -0
- package/README.md +195 -0
- package/README_CN.md +195 -0
- package/index.js +308 -0
- package/package.json +35 -0
- package/tsconfig.json +14 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024 EthanSky
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# MCP-Telegram-ClaudeCode
|
|
2
|
+
|
|
3
|
+
An MCP (Model Context Protocol) server that enables Claude Code to send and receive messages via Telegram. This allows you to interact with Claude Code remotely through your Telegram app.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- Send text messages from Claude Code to Telegram
|
|
8
|
+
- Receive messages from Telegram in Claude Code
|
|
9
|
+
- Send photos/screenshots to Telegram
|
|
10
|
+
- Proxy support for regions where Telegram is blocked
|
|
11
|
+
|
|
12
|
+
## Prerequisites
|
|
13
|
+
|
|
14
|
+
- [Node.js](https://nodejs.org/) 18.0.0 or higher
|
|
15
|
+
- [Claude Code](https://claude.ai/code) installed
|
|
16
|
+
- A Telegram account
|
|
17
|
+
|
|
18
|
+
## Quick Start
|
|
19
|
+
|
|
20
|
+
### Step 1: Create a Telegram Bot
|
|
21
|
+
|
|
22
|
+
1. Open Telegram and search for [@BotFather](https://t.me/BotFather)
|
|
23
|
+
2. Send `/newbot` command
|
|
24
|
+
3. Follow the prompts to name your bot
|
|
25
|
+
4. **Save the bot token** - it looks like: `1234567890:ABCdefGHIjklMNOpqrsTUVwxyz`
|
|
26
|
+
|
|
27
|
+
### Step 2: Get Your Chat ID
|
|
28
|
+
|
|
29
|
+
1. Open Telegram and search for [@userinfobot](https://t.me/userinfobot)
|
|
30
|
+
2. Send any message to this bot
|
|
31
|
+
3. **Save the `Id` value** from the response - it looks like: `123456789`
|
|
32
|
+
|
|
33
|
+
### Step 3: Start Your Bot
|
|
34
|
+
|
|
35
|
+
**Important:** Before Claude Code can receive your messages, you must start a conversation with your bot:
|
|
36
|
+
1. Search for your bot by its username in Telegram
|
|
37
|
+
2. Click "Start" or send any message to it
|
|
38
|
+
|
|
39
|
+
### Step 4: Configure Claude Code
|
|
40
|
+
|
|
41
|
+
Add the MCP server to your Claude Code configuration.
|
|
42
|
+
|
|
43
|
+
**Option A: Using Claude Code settings command**
|
|
44
|
+
```bash
|
|
45
|
+
claude /settings
|
|
46
|
+
```
|
|
47
|
+
Then add the MCP server configuration.
|
|
48
|
+
|
|
49
|
+
**Option B: Edit configuration file directly**
|
|
50
|
+
|
|
51
|
+
The configuration file is located at:
|
|
52
|
+
- Windows: `%USERPROFILE%\.claude.json`
|
|
53
|
+
- macOS/Linux: `~/.claude.json`
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Configuration Examples
|
|
58
|
+
|
|
59
|
+
### Without Proxy (US, Europe, etc.)
|
|
60
|
+
|
|
61
|
+
If you can access Telegram directly without a proxy:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"telegram": {
|
|
67
|
+
"command": "npx",
|
|
68
|
+
"args": ["-y", "mcp-telegram-claudecode"],
|
|
69
|
+
"env": {
|
|
70
|
+
"TELEGRAM_BOT_TOKEN": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",
|
|
71
|
+
"TELEGRAM_CHAT_ID": "123456789"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### With Proxy (China, Iran, Russia, etc.)
|
|
79
|
+
|
|
80
|
+
If Telegram is blocked in your region, you need to configure a proxy:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"telegram": {
|
|
86
|
+
"command": "npx",
|
|
87
|
+
"args": ["-y", "mcp-telegram-claudecode"],
|
|
88
|
+
"env": {
|
|
89
|
+
"TELEGRAM_BOT_TOKEN": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",
|
|
90
|
+
"TELEGRAM_CHAT_ID": "123456789",
|
|
91
|
+
"HTTP_PROXY": "http://127.0.0.1:7890"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**Common proxy ports:**
|
|
99
|
+
- Clash: `http://127.0.0.1:7890`
|
|
100
|
+
- V2Ray: `http://127.0.0.1:10808`
|
|
101
|
+
- Shadowsocks: `http://127.0.0.1:1080`
|
|
102
|
+
|
|
103
|
+
Replace with your actual proxy address and port.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## Environment Variables
|
|
108
|
+
|
|
109
|
+
| Variable | Required | Description |
|
|
110
|
+
|----------|----------|-------------|
|
|
111
|
+
| `TELEGRAM_BOT_TOKEN` | Yes | Bot token from @BotFather |
|
|
112
|
+
| `TELEGRAM_CHAT_ID` | Yes | Your chat ID from @userinfobot |
|
|
113
|
+
| `HTTP_PROXY` | No | HTTP proxy URL (e.g., `http://127.0.0.1:7890`) |
|
|
114
|
+
| `HTTPS_PROXY` | No | HTTPS proxy URL (alternative to HTTP_PROXY) |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Available Tools
|
|
119
|
+
|
|
120
|
+
Once configured, Claude Code will have access to these tools:
|
|
121
|
+
|
|
122
|
+
### telegram_send_message
|
|
123
|
+
Send a text message to your Telegram.
|
|
124
|
+
```
|
|
125
|
+
Parameters:
|
|
126
|
+
- message (required): The text message to send
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### telegram_get_messages
|
|
130
|
+
Retrieve recent messages from Telegram.
|
|
131
|
+
```
|
|
132
|
+
Parameters:
|
|
133
|
+
- limit (optional): Maximum number of messages to retrieve (default: 10)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### telegram_check_new
|
|
137
|
+
Quick check if there are new messages.
|
|
138
|
+
```
|
|
139
|
+
No parameters required
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### telegram_send_photo
|
|
143
|
+
Send an image file to Telegram.
|
|
144
|
+
```
|
|
145
|
+
Parameters:
|
|
146
|
+
- photo_path (required): Absolute path to the image file
|
|
147
|
+
- caption (optional): Caption for the photo
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Usage Examples
|
|
153
|
+
|
|
154
|
+
After configuration, you can ask Claude Code to:
|
|
155
|
+
|
|
156
|
+
- "Send me a message on Telegram saying the task is complete"
|
|
157
|
+
- "Check if I sent any new messages on Telegram"
|
|
158
|
+
- "Send a screenshot of the current code to my Telegram"
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Troubleshooting
|
|
163
|
+
|
|
164
|
+
### "TELEGRAM_BOT_TOKEN must be configured"
|
|
165
|
+
Make sure you've added the bot token to your `.claude.json` configuration.
|
|
166
|
+
|
|
167
|
+
### "No new messages" but you sent messages
|
|
168
|
+
1. Make sure you started a conversation with your bot first
|
|
169
|
+
2. Check that your `TELEGRAM_CHAT_ID` is correct
|
|
170
|
+
3. If using a proxy, verify the proxy is working
|
|
171
|
+
|
|
172
|
+
### Connection timeout or network error
|
|
173
|
+
If you're in a region where Telegram is blocked:
|
|
174
|
+
1. Make sure your proxy software is running
|
|
175
|
+
2. Add the `HTTP_PROXY` environment variable to your configuration
|
|
176
|
+
3. Verify the proxy port is correct
|
|
177
|
+
|
|
178
|
+
### Bot not responding
|
|
179
|
+
1. Check that the bot token is correct (no extra spaces)
|
|
180
|
+
2. Make sure you've started a conversation with your bot
|
|
181
|
+
3. Try sending a message to your bot first, then check for messages
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## License
|
|
186
|
+
|
|
187
|
+
MIT License - see [LICENSE](LICENSE) file for details.
|
|
188
|
+
|
|
189
|
+
## Author
|
|
190
|
+
|
|
191
|
+
EthanSky
|
|
192
|
+
|
|
193
|
+
## Repository
|
|
194
|
+
|
|
195
|
+
https://github.com/EthanSky2986/mcp-telegram-claudecode
|
package/README_CN.md
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# MCP-Telegram-ClaudeCode
|
|
2
|
+
|
|
3
|
+
一个 MCP(Model Context Protocol)服务器,让 Claude Code 能够通过 Telegram 发送和接收消息。这样你就可以通过 Telegram 远程与 Claude Code 交互。
|
|
4
|
+
|
|
5
|
+
## 功能特性
|
|
6
|
+
|
|
7
|
+
- 从 Claude Code 发送文字消息到 Telegram
|
|
8
|
+
- 在 Claude Code 中接收 Telegram 消息
|
|
9
|
+
- 发送图片/截图到 Telegram
|
|
10
|
+
- 支持代理(适用于无法直接访问 Telegram 的地区)
|
|
11
|
+
|
|
12
|
+
## 前置要求
|
|
13
|
+
|
|
14
|
+
- [Node.js](https://nodejs.org/) 18.0.0 或更高版本
|
|
15
|
+
- 已安装 [Claude Code](https://claude.ai/code)
|
|
16
|
+
- 一个 Telegram 账号
|
|
17
|
+
|
|
18
|
+
## 快速开始
|
|
19
|
+
|
|
20
|
+
### 第一步:创建 Telegram 机器人
|
|
21
|
+
|
|
22
|
+
1. 打开 Telegram,搜索 [@BotFather](https://t.me/BotFather)
|
|
23
|
+
2. 发送 `/newbot` 命令
|
|
24
|
+
3. 按照提示为你的机器人起名
|
|
25
|
+
4. **保存机器人 Token** - 格式类似:`1234567890:ABCdefGHIjklMNOpqrsTUVwxyz`
|
|
26
|
+
|
|
27
|
+
### 第二步:获取你的 Chat ID
|
|
28
|
+
|
|
29
|
+
1. 打开 Telegram,搜索 [@userinfobot](https://t.me/userinfobot)
|
|
30
|
+
2. 给这个机器人发送任意消息
|
|
31
|
+
3. **保存返回的 `Id` 值** - 格式类似:`123456789`
|
|
32
|
+
|
|
33
|
+
### 第三步:启动你的机器人
|
|
34
|
+
|
|
35
|
+
**重要:** 在 Claude Code 能接收你的消息之前,你必须先和你的机器人开始对话:
|
|
36
|
+
1. 在 Telegram 中搜索你的机器人用户名
|
|
37
|
+
2. 点击"开始"或发送任意消息
|
|
38
|
+
|
|
39
|
+
### 第四步:配置 Claude Code
|
|
40
|
+
|
|
41
|
+
将 MCP 服务器添加到你的 Claude Code 配置中。
|
|
42
|
+
|
|
43
|
+
**方式 A:使用 Claude Code 设置命令**
|
|
44
|
+
```bash
|
|
45
|
+
claude /settings
|
|
46
|
+
```
|
|
47
|
+
然后添加 MCP 服务器配置。
|
|
48
|
+
|
|
49
|
+
**方式 B:直接编辑配置文件**
|
|
50
|
+
|
|
51
|
+
配置文件位置:
|
|
52
|
+
- Windows: `%USERPROFILE%\.claude.json`
|
|
53
|
+
- macOS/Linux: `~/.claude.json`
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 配置示例
|
|
58
|
+
|
|
59
|
+
### 不使用代理(美国、欧洲等地区)
|
|
60
|
+
|
|
61
|
+
如果你可以直接访问 Telegram:
|
|
62
|
+
|
|
63
|
+
```json
|
|
64
|
+
{
|
|
65
|
+
"mcpServers": {
|
|
66
|
+
"telegram": {
|
|
67
|
+
"command": "npx",
|
|
68
|
+
"args": ["-y", "mcp-telegram-claudecode"],
|
|
69
|
+
"env": {
|
|
70
|
+
"TELEGRAM_BOT_TOKEN": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",
|
|
71
|
+
"TELEGRAM_CHAT_ID": "123456789"
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 使用代理(中国、伊朗、俄罗斯等地区)
|
|
79
|
+
|
|
80
|
+
如果你所在的地区无法直接访问 Telegram,需要配置代理:
|
|
81
|
+
|
|
82
|
+
```json
|
|
83
|
+
{
|
|
84
|
+
"mcpServers": {
|
|
85
|
+
"telegram": {
|
|
86
|
+
"command": "npx",
|
|
87
|
+
"args": ["-y", "mcp-telegram-claudecode"],
|
|
88
|
+
"env": {
|
|
89
|
+
"TELEGRAM_BOT_TOKEN": "1234567890:ABCdefGHIjklMNOpqrsTUVwxyz",
|
|
90
|
+
"TELEGRAM_CHAT_ID": "123456789",
|
|
91
|
+
"HTTP_PROXY": "http://127.0.0.1:7890"
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
**常用代理端口:**
|
|
99
|
+
- Clash: `http://127.0.0.1:7890`
|
|
100
|
+
- V2Ray: `http://127.0.0.1:10808`
|
|
101
|
+
- Shadowsocks: `http://127.0.0.1:1080`
|
|
102
|
+
|
|
103
|
+
请替换为你实际的代理地址和端口。
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 环境变量
|
|
108
|
+
|
|
109
|
+
| 变量名 | 是否必需 | 说明 |
|
|
110
|
+
|--------|----------|------|
|
|
111
|
+
| `TELEGRAM_BOT_TOKEN` | 是 | 从 @BotFather 获取的机器人 Token |
|
|
112
|
+
| `TELEGRAM_CHAT_ID` | 是 | 从 @userinfobot 获取的 Chat ID |
|
|
113
|
+
| `HTTP_PROXY` | 否 | HTTP 代理地址(如 `http://127.0.0.1:7890`) |
|
|
114
|
+
| `HTTPS_PROXY` | 否 | HTTPS 代理地址(HTTP_PROXY 的替代选项) |
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## 可用工具
|
|
119
|
+
|
|
120
|
+
配置完成后,Claude Code 将可以使用以下工具:
|
|
121
|
+
|
|
122
|
+
### telegram_send_message
|
|
123
|
+
发送文字消息到你的 Telegram。
|
|
124
|
+
```
|
|
125
|
+
参数:
|
|
126
|
+
- message(必需):要发送的文字消息
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### telegram_get_messages
|
|
130
|
+
获取 Telegram 的最近消息。
|
|
131
|
+
```
|
|
132
|
+
参数:
|
|
133
|
+
- limit(可选):获取消息的最大数量(默认:10)
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### telegram_check_new
|
|
137
|
+
快速检查是否有新消息。
|
|
138
|
+
```
|
|
139
|
+
无需参数
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### telegram_send_photo
|
|
143
|
+
发送图片文件到 Telegram。
|
|
144
|
+
```
|
|
145
|
+
参数:
|
|
146
|
+
- photo_path(必需):图片文件的绝对路径
|
|
147
|
+
- caption(可选):图片说明文字
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## 使用示例
|
|
153
|
+
|
|
154
|
+
配置完成后,你可以让 Claude Code:
|
|
155
|
+
|
|
156
|
+
- "在 Telegram 上给我发消息说任务完成了"
|
|
157
|
+
- "检查一下我在 Telegram 上有没有发新消息"
|
|
158
|
+
- "把当前代码的截图发到我的 Telegram"
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## 常见问题
|
|
163
|
+
|
|
164
|
+
### "TELEGRAM_BOT_TOKEN must be configured"
|
|
165
|
+
确保你已经在 `.claude.json` 配置文件中添加了机器人 Token。
|
|
166
|
+
|
|
167
|
+
### 发了消息但显示"No new messages"
|
|
168
|
+
1. 确保你已经先和机器人开始了对话
|
|
169
|
+
2. 检查 `TELEGRAM_CHAT_ID` 是否正确
|
|
170
|
+
3. 如果使用代理,确认代理正常工作
|
|
171
|
+
|
|
172
|
+
### 连接超时或网络错误
|
|
173
|
+
如果你在无法直接访问 Telegram 的地区:
|
|
174
|
+
1. 确保代理软件正在运行
|
|
175
|
+
2. 在配置中添加 `HTTP_PROXY` 环境变量
|
|
176
|
+
3. 确认代理端口正确
|
|
177
|
+
|
|
178
|
+
### 机器人没有响应
|
|
179
|
+
1. 检查机器人 Token 是否正确(没有多余空格)
|
|
180
|
+
2. 确保你已经和机器人开始了对话
|
|
181
|
+
3. 先给机器人发一条消息,然后再检查消息
|
|
182
|
+
|
|
183
|
+
---
|
|
184
|
+
|
|
185
|
+
## 许可证
|
|
186
|
+
|
|
187
|
+
MIT 许可证 - 详见 [LICENSE](LICENSE) 文件。
|
|
188
|
+
|
|
189
|
+
## 作者
|
|
190
|
+
|
|
191
|
+
EthanSky
|
|
192
|
+
|
|
193
|
+
## 仓库地址
|
|
194
|
+
|
|
195
|
+
https://github.com/EthanSky2986/mcp-telegram-claudecode
|
package/index.js
ADDED
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Telegram Claude MCP Server
|
|
5
|
+
* MCP server for Telegram integration with Claude Code
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const { Server } = require('@modelcontextprotocol/sdk/server/index.js');
|
|
9
|
+
const { StdioServerTransport } = require('@modelcontextprotocol/sdk/server/stdio.js');
|
|
10
|
+
const {
|
|
11
|
+
CallToolRequestSchema,
|
|
12
|
+
ListToolsRequestSchema,
|
|
13
|
+
} = require('@modelcontextprotocol/sdk/types.js');
|
|
14
|
+
const axios = require('axios');
|
|
15
|
+
const { HttpsProxyAgent } = require('https-proxy-agent');
|
|
16
|
+
|
|
17
|
+
// Configuration from environment variables
|
|
18
|
+
const BOT_TOKEN = process.env.TELEGRAM_BOT_TOKEN;
|
|
19
|
+
const CHAT_ID = process.env.TELEGRAM_CHAT_ID;
|
|
20
|
+
const PROXY_URL = process.env.HTTP_PROXY || process.env.HTTPS_PROXY;
|
|
21
|
+
|
|
22
|
+
// Setup axios with proxy if configured
|
|
23
|
+
let axiosInstance = axios;
|
|
24
|
+
if (PROXY_URL) {
|
|
25
|
+
const agent = new HttpsProxyAgent(PROXY_URL);
|
|
26
|
+
axiosInstance = axios.create({
|
|
27
|
+
httpsAgent: agent,
|
|
28
|
+
proxy: false
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const API_BASE = `https://api.telegram.org/bot${BOT_TOKEN}`;
|
|
33
|
+
|
|
34
|
+
// Track last update ID for polling
|
|
35
|
+
let lastUpdateId = 0;
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Send a text message to Telegram
|
|
39
|
+
*/
|
|
40
|
+
async function sendMessage(text) {
|
|
41
|
+
if (!BOT_TOKEN || !CHAT_ID) {
|
|
42
|
+
throw new Error('TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID must be configured');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const response = await axiosInstance.post(`${API_BASE}/sendMessage`, {
|
|
46
|
+
chat_id: CHAT_ID,
|
|
47
|
+
text: text,
|
|
48
|
+
parse_mode: 'Markdown'
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return response.data;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Send a photo to Telegram
|
|
56
|
+
*/
|
|
57
|
+
async function sendPhoto(photoPath, caption = '') {
|
|
58
|
+
if (!BOT_TOKEN || !CHAT_ID) {
|
|
59
|
+
throw new Error('TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID must be configured');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const fs = require('fs');
|
|
63
|
+
const FormData = require('form-data');
|
|
64
|
+
|
|
65
|
+
const form = new FormData();
|
|
66
|
+
form.append('chat_id', CHAT_ID);
|
|
67
|
+
form.append('photo', fs.createReadStream(photoPath));
|
|
68
|
+
if (caption) {
|
|
69
|
+
form.append('caption', caption);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
const response = await axiosInstance.post(`${API_BASE}/sendPhoto`, form, {
|
|
73
|
+
headers: form.getHeaders()
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
return response.data;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Get new messages from Telegram
|
|
81
|
+
*/
|
|
82
|
+
async function getMessages(limit = 10) {
|
|
83
|
+
if (!BOT_TOKEN) {
|
|
84
|
+
throw new Error('TELEGRAM_BOT_TOKEN must be configured');
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
const response = await axiosInstance.get(`${API_BASE}/getUpdates`, {
|
|
88
|
+
params: {
|
|
89
|
+
offset: lastUpdateId + 1,
|
|
90
|
+
limit: limit,
|
|
91
|
+
timeout: 0
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
const messages = [];
|
|
96
|
+
if (response.data.ok && response.data.result.length > 0) {
|
|
97
|
+
for (const update of response.data.result) {
|
|
98
|
+
lastUpdateId = update.update_id;
|
|
99
|
+
if (update.message && update.message.text) {
|
|
100
|
+
// Filter by chat ID if configured
|
|
101
|
+
if (!CHAT_ID || update.message.chat.id.toString() === CHAT_ID) {
|
|
102
|
+
messages.push({
|
|
103
|
+
id: update.message.message_id,
|
|
104
|
+
from: update.message.from.first_name || update.message.from.username,
|
|
105
|
+
text: update.message.text,
|
|
106
|
+
date: new Date(update.message.date * 1000).toISOString()
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
return messages;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Check for new messages (non-blocking)
|
|
118
|
+
*/
|
|
119
|
+
async function checkNewMessages() {
|
|
120
|
+
if (!BOT_TOKEN) {
|
|
121
|
+
throw new Error('TELEGRAM_BOT_TOKEN must be configured');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const response = await axiosInstance.get(`${API_BASE}/getUpdates`, {
|
|
125
|
+
params: {
|
|
126
|
+
offset: lastUpdateId + 1,
|
|
127
|
+
limit: 100,
|
|
128
|
+
timeout: 0
|
|
129
|
+
}
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
let hasNew = false;
|
|
133
|
+
let latestMessage = null;
|
|
134
|
+
|
|
135
|
+
if (response.data.ok && response.data.result.length > 0) {
|
|
136
|
+
for (const update of response.data.result) {
|
|
137
|
+
lastUpdateId = update.update_id;
|
|
138
|
+
if (update.message && update.message.text) {
|
|
139
|
+
if (!CHAT_ID || update.message.chat.id.toString() === CHAT_ID) {
|
|
140
|
+
hasNew = true;
|
|
141
|
+
latestMessage = {
|
|
142
|
+
from: update.message.from.first_name || update.message.from.username,
|
|
143
|
+
text: update.message.text
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return { hasNew, latestMessage, updateId: lastUpdateId };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// Create MCP server
|
|
154
|
+
const server = new Server(
|
|
155
|
+
{
|
|
156
|
+
name: 'telegram-claude-mcp',
|
|
157
|
+
version: '1.0.0',
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
capabilities: {
|
|
161
|
+
tools: {},
|
|
162
|
+
},
|
|
163
|
+
}
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
// Define available tools
|
|
167
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
168
|
+
return {
|
|
169
|
+
tools: [
|
|
170
|
+
{
|
|
171
|
+
name: 'telegram_send_message',
|
|
172
|
+
description: 'Send a text message to the configured Telegram chat. Use this to communicate with the user via Telegram.',
|
|
173
|
+
inputSchema: {
|
|
174
|
+
type: 'object',
|
|
175
|
+
properties: {
|
|
176
|
+
message: {
|
|
177
|
+
type: 'string',
|
|
178
|
+
description: 'The message text to send'
|
|
179
|
+
}
|
|
180
|
+
},
|
|
181
|
+
required: ['message']
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
name: 'telegram_get_messages',
|
|
186
|
+
description: 'Get recent messages from Telegram. Use this to check for new messages from the user.',
|
|
187
|
+
inputSchema: {
|
|
188
|
+
type: 'object',
|
|
189
|
+
properties: {
|
|
190
|
+
limit: {
|
|
191
|
+
type: 'number',
|
|
192
|
+
description: 'Maximum number of messages to retrieve (default: 10)'
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
name: 'telegram_check_new',
|
|
199
|
+
description: 'Quick check if there are new messages from Telegram without retrieving all of them.',
|
|
200
|
+
inputSchema: {
|
|
201
|
+
type: 'object',
|
|
202
|
+
properties: {}
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
name: 'telegram_send_photo',
|
|
207
|
+
description: 'Send a photo/image to the configured Telegram chat.',
|
|
208
|
+
inputSchema: {
|
|
209
|
+
type: 'object',
|
|
210
|
+
properties: {
|
|
211
|
+
photo_path: {
|
|
212
|
+
type: 'string',
|
|
213
|
+
description: 'Absolute path to the image file'
|
|
214
|
+
},
|
|
215
|
+
caption: {
|
|
216
|
+
type: 'string',
|
|
217
|
+
description: 'Optional caption for the photo'
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
required: ['photo_path']
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
};
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// Handle tool calls
|
|
228
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
229
|
+
const { name, arguments: args } = request.params;
|
|
230
|
+
|
|
231
|
+
try {
|
|
232
|
+
switch (name) {
|
|
233
|
+
case 'telegram_send_message': {
|
|
234
|
+
const result = await sendMessage(args.message);
|
|
235
|
+
return {
|
|
236
|
+
content: [
|
|
237
|
+
{
|
|
238
|
+
type: 'text',
|
|
239
|
+
text: `Message sent successfully. Message ID: ${result.result.message_id}`
|
|
240
|
+
}
|
|
241
|
+
]
|
|
242
|
+
};
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
case 'telegram_get_messages': {
|
|
246
|
+
const messages = await getMessages(args.limit || 10);
|
|
247
|
+
return {
|
|
248
|
+
content: [
|
|
249
|
+
{
|
|
250
|
+
type: 'text',
|
|
251
|
+
text: messages.length > 0
|
|
252
|
+
? JSON.stringify(messages, null, 2)
|
|
253
|
+
: 'No new messages'
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
case 'telegram_check_new': {
|
|
260
|
+
const result = await checkNewMessages();
|
|
261
|
+
return {
|
|
262
|
+
content: [
|
|
263
|
+
{
|
|
264
|
+
type: 'text',
|
|
265
|
+
text: result.hasNew
|
|
266
|
+
? `New message from ${result.latestMessage.from}: ${result.latestMessage.text}`
|
|
267
|
+
: 'No new messages'
|
|
268
|
+
}
|
|
269
|
+
]
|
|
270
|
+
};
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
case 'telegram_send_photo': {
|
|
274
|
+
const result = await sendPhoto(args.photo_path, args.caption || '');
|
|
275
|
+
return {
|
|
276
|
+
content: [
|
|
277
|
+
{
|
|
278
|
+
type: 'text',
|
|
279
|
+
text: `Photo sent successfully. Message ID: ${result.result.message_id}`
|
|
280
|
+
}
|
|
281
|
+
]
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
default:
|
|
286
|
+
throw new Error(`Unknown tool: ${name}`);
|
|
287
|
+
}
|
|
288
|
+
} catch (error) {
|
|
289
|
+
return {
|
|
290
|
+
content: [
|
|
291
|
+
{
|
|
292
|
+
type: 'text',
|
|
293
|
+
text: `Error: ${error.message}`
|
|
294
|
+
}
|
|
295
|
+
],
|
|
296
|
+
isError: true
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
// Start the server
|
|
302
|
+
async function main() {
|
|
303
|
+
const transport = new StdioServerTransport();
|
|
304
|
+
await server.connect(transport);
|
|
305
|
+
console.error('Telegram Claude MCP server running');
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
main().catch(console.error);
|
package/package.json
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mcp-telegram-claudecode",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "MCP server for Telegram integration with Claude Code - Send and receive messages via Telegram",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"mcp-telegram-claudecode": "./index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "node index.js"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"mcp",
|
|
14
|
+
"telegram",
|
|
15
|
+
"claude",
|
|
16
|
+
"claude-code",
|
|
17
|
+
"remote-control",
|
|
18
|
+
"bot",
|
|
19
|
+
"anthropic"
|
|
20
|
+
],
|
|
21
|
+
"author": "EthanSky",
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"dependencies": {
|
|
24
|
+
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
25
|
+
"axios": "^1.6.0",
|
|
26
|
+
"https-proxy-agent": "^7.0.2"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18.0.0"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "https://github.com/EthanSky2986/mcp-telegram-claudecode"
|
|
34
|
+
}
|
|
35
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"strict": false,
|
|
6
|
+
"esModuleInterop": true,
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
"forceConsistentCasingInFileNames": true,
|
|
9
|
+
"resolveJsonModule": true,
|
|
10
|
+
"outDir": "./dist"
|
|
11
|
+
},
|
|
12
|
+
"include": ["*.js"],
|
|
13
|
+
"exclude": ["node_modules"]
|
|
14
|
+
}
|