@overpod/mcp-telegram 1.11.0 → 1.11.1

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.
Files changed (3) hide show
  1. package/README.md +30 -2
  2. package/dist/index.js +15 -11
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  [![npm](https://img.shields.io/npm/v/@overpod/mcp-telegram)](https://www.npmjs.com/package/@overpod/mcp-telegram)
4
4
  [![npm downloads](https://img.shields.io/npm/dm/@overpod/mcp-telegram)](https://www.npmjs.com/package/@overpod/mcp-telegram)
5
5
  [![Node.js](https://img.shields.io/badge/Node.js-18%2B-339933.svg?logo=node.js&logoColor=white)](https://nodejs.org/)
6
- [![TypeScript](https://img.shields.io/badge/TypeScript-5.9-blue.svg?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
6
+ [![TypeScript](https://img.shields.io/badge/TypeScript-6.0-blue.svg?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)
7
7
  [![MCP SDK](https://img.shields.io/badge/MCP%20SDK-1.27-green.svg)](https://modelcontextprotocol.io/)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
9
9
  [![mcp-telegram MCP server](https://glama.ai/mcp/servers/overpod/mcp-telegram/badges/score.svg)](https://glama.ai/mcp/servers/overpod/mcp-telegram)
@@ -208,6 +208,7 @@ const telegramMcp = new MCPClient({
208
208
  | `telegram-read-messages` | Read recent messages from a chat |
209
209
  | `telegram-search-chats` | Search for chats, users, or channels by name |
210
210
  | `telegram-search-messages` | Search messages in a chat by text |
211
+ | `telegram-search-global` | Search messages across all public chats and channels |
211
212
  | `telegram-get-unread` | Get chats with unread messages; forums show per-topic unread breakdown |
212
213
  | `telegram-get-contact-requests` | Get incoming messages from non-contacts with preview |
213
214
 
@@ -243,6 +244,8 @@ const telegramMcp = new MCPClient({
243
244
  |------|-------------|
244
245
  | `telegram-get-contacts` | Get your contacts list with phone numbers |
245
246
  | `telegram-get-profile` | Get detailed profile info for a user (bio, photo, last seen) |
247
+ | `telegram-get-profile-photo` | Get a user's or chat's profile photo (inline or file) |
248
+ | `telegram-get-reactions` | Get reactions on a specific message with user details |
246
249
 
247
250
  ### Media
248
251
 
@@ -357,7 +360,8 @@ Most tools accept `chatId` as a string -- either a numeric ID (e.g., `"-10012345
357
360
  |-----------|------|----------|-------------|
358
361
  | `chatId` | string | yes | Chat ID or @username |
359
362
  | `messageId` | number | yes | Message ID to react to |
360
- | `emoji` | string | no | Reaction emoji (e.g. 👍❤️🔥😂🎉). Omit to remove reaction |
363
+ | `emoji` | string \| string[] | no | Single emoji `"👍"` or array `["👍","🔥"]`. Omit to remove all reactions |
364
+ | `addToExisting` | boolean | no | Add to existing reactions instead of replacing (default: false) |
361
365
 
362
366
  ### telegram-send-scheduled
363
367
 
@@ -388,6 +392,15 @@ Most tools accept `chatId` as a string -- either a numeric ID (e.g., `"-10012345
388
392
  | `query` | string | yes | Search text |
389
393
  | `limit` | number | no | Max results (default: 20) |
390
394
 
395
+ ### telegram-search-global
396
+
397
+ | Parameter | Type | Required | Description |
398
+ |-----------|------|----------|-------------|
399
+ | `query` | string | yes | Search text |
400
+ | `limit` | number | no | Max results (default: 20) |
401
+ | `minDate` | number | no | Unix timestamp: only messages after this date |
402
+ | `maxDate` | number | no | Unix timestamp: only messages before this date |
403
+
391
404
  ### telegram-search-chats
392
405
 
393
406
  | Parameter | Type | Required | Description |
@@ -414,6 +427,21 @@ Most tools accept `chatId` as a string -- either a numeric ID (e.g., `"-10012345
414
427
  |-----------|------|----------|-------------|
415
428
  | `userId` | string | yes | User ID or @username |
416
429
 
430
+ ### telegram-get-profile-photo
431
+
432
+ | Parameter | Type | Required | Description |
433
+ |-----------|------|----------|-------------|
434
+ | `entityId` | string | yes | User/Chat/Channel ID or username |
435
+ | `savePath` | string | no | Absolute path to save file. If omitted, returns inline base64 image |
436
+ | `size` | `"small"` / `"big"` | no | Photo size: small (160x160) or big (640x640). Default: big |
437
+
438
+ ### telegram-get-reactions
439
+
440
+ | Parameter | Type | Required | Description |
441
+ |-----------|------|----------|-------------|
442
+ | `chatId` | string | yes | Chat ID or @username |
443
+ | `messageId` | number | yes | Message ID to get reactions for |
444
+
417
445
  ### telegram-get-unread
418
446
 
419
447
  | Parameter | Type | Required | Description |
package/dist/index.js CHANGED
@@ -18,6 +18,10 @@ if (!API_ID || !API_HASH) {
18
18
  process.exit(1);
19
19
  }
20
20
  const telegram = new TelegramService(API_ID, API_HASH);
21
+ /** Remove unpaired UTF-16 surrogates that break JSON serialization */
22
+ function sanitize(text) {
23
+ return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
24
+ }
21
25
  /** Format reactions array into compact text like: [👍×5 ❤️×3(me) 🔥×1] */
22
26
  function formatReactions(reactions) {
23
27
  if (!reactions?.length)
@@ -153,7 +157,7 @@ server.tool("telegram-list-chats", "List Telegram chats", {
153
157
  return `${prefix} ${d.name} (${d.id})${botTag}${contactTag}${unread}`;
154
158
  })
155
159
  .join("\n");
156
- return { content: [{ type: "text", text: text || "No chats" }] };
160
+ return { content: [{ type: "text", text: sanitize(text) || "No chats" }] };
157
161
  }
158
162
  catch (e) {
159
163
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -174,7 +178,7 @@ server.tool("telegram-read-messages", "Read recent messages from a Telegram chat
174
178
  const text = messages
175
179
  .map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
176
180
  .join("\n\n");
177
- return { content: [{ type: "text", text: text || "No messages" }] };
181
+ return { content: [{ type: "text", text: sanitize(text) || "No messages" }] };
178
182
  }
179
183
  catch (e) {
180
184
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -192,7 +196,7 @@ server.tool("telegram-search-chats", "Search for Telegram chats/users/channels b
192
196
  const text = results
193
197
  .map((c) => `${c.type === "group" ? "G" : c.type === "channel" ? "C" : "P"} ${c.name}${c.username ? ` (@${c.username})` : ""} (${c.id})${c.membersCount ? ` [${c.membersCount} members]` : ""}${c.description ? ` — ${c.description.split("\n")[0].slice(0, 100)}` : ""}`)
194
198
  .join("\n");
195
- return { content: [{ type: "text", text: text || "No results" }] };
199
+ return { content: [{ type: "text", text: sanitize(text) || "No results" }] };
196
200
  }
197
201
  catch (e) {
198
202
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -212,7 +216,7 @@ server.tool("telegram-search-global", "Search messages globally across all publi
212
216
  const text = messages
213
217
  .map((m) => `[#${m.id}] [${m.date}] [${m.chat.type === "channel" ? "C" : m.chat.type === "group" ? "G" : "P"} ${m.chat.name}${m.chat.username ? ` @${m.chat.username}` : ""}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
214
218
  .join("\n\n");
215
- return { content: [{ type: "text", text: text || "No messages found" }] };
219
+ return { content: [{ type: "text", text: sanitize(text) || "No messages found" }] };
216
220
  }
217
221
  catch (e) {
218
222
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -233,7 +237,7 @@ server.tool("telegram-search-messages", "Search messages in a Telegram chat by t
233
237
  const text = messages
234
238
  .map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
235
239
  .join("\n\n");
236
- return { content: [{ type: "text", text: text || "No messages found" }] };
240
+ return { content: [{ type: "text", text: sanitize(text) || "No messages found" }] };
237
241
  }
238
242
  catch (e) {
239
243
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -261,7 +265,7 @@ server.tool("telegram-get-unread", "Get unread Telegram chats", {
261
265
  return line;
262
266
  })
263
267
  .join("\n");
264
- return { content: [{ type: "text", text: text || "No unread chats" }] };
268
+ return { content: [{ type: "text", text: sanitize(text) || "No unread chats" }] };
265
269
  }
266
270
  catch (e) {
267
271
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -429,7 +433,7 @@ server.tool("telegram-get-contacts", "Get Telegram contacts list", {
429
433
  const text = contacts
430
434
  .map((c) => `P ${c.name}${c.username ? ` (@${c.username})` : ""} (${c.id})${c.phone ? ` +${c.phone}` : ""}`)
431
435
  .join("\n");
432
- return { content: [{ type: "text", text: text || "No contacts" }] };
436
+ return { content: [{ type: "text", text: sanitize(text) || "No contacts" }] };
433
437
  }
434
438
  catch (e) {
435
439
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -445,7 +449,7 @@ server.tool("telegram-get-chat-members", "Get members of a Telegram group or cha
445
449
  try {
446
450
  const members = await telegram.getChatMembers(chatId, limit);
447
451
  const text = members.map((m) => `${m.name}${m.username ? ` (@${m.username})` : ""} (${m.id})`).join("\n");
448
- return { content: [{ type: "text", text: text || "No members found" }] };
452
+ return { content: [{ type: "text", text: sanitize(text) || "No members found" }] };
449
453
  }
450
454
  catch (e) {
451
455
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -656,7 +660,7 @@ server.tool("telegram-get-contact-requests", "Get incoming messages from non-con
656
660
  return `${tag} ${r.name}${username} (${r.id})${unread}${preview}`;
657
661
  })
658
662
  .join("\n");
659
- return { content: [{ type: "text", text: text }] };
663
+ return { content: [{ type: "text", text: sanitize(text) }] };
660
664
  }
661
665
  catch (e) {
662
666
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -726,7 +730,7 @@ server.tool("telegram-list-topics", "List forum topics in a Telegram group with
726
730
  return `# ${t.title} (id: ${t.id})${flagStr}${unread}`;
727
731
  })
728
732
  .join("\n");
729
- return { content: [{ type: "text", text: text || "No topics found" }] };
733
+ return { content: [{ type: "text", text: sanitize(text) || "No topics found" }] };
730
734
  }
731
735
  catch (e) {
732
736
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
@@ -746,7 +750,7 @@ server.tool("telegram-read-topic-messages", "Read messages from a specific forum
746
750
  const text = messages
747
751
  .map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
748
752
  .join("\n\n");
749
- return { content: [{ type: "text", text: text || "No messages in this topic" }] };
753
+ return { content: [{ type: "text", text: sanitize(text) || "No messages in this topic" }] };
750
754
  }
751
755
  catch (e) {
752
756
  return { content: [{ type: "text", text: `Error: ${e.message}` }] };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overpod/mcp-telegram",
3
- "version": "1.11.0",
3
+ "version": "1.11.1",
4
4
  "description": "MCP server for Telegram userbot — messages, media, reactions, polls & more. Built on GramJS/MTProto.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -60,6 +60,6 @@
60
60
  "@types/node": "^25.5.0",
61
61
  "@types/qrcode": "^1.5.6",
62
62
  "tsx": "^4.21.0",
63
- "typescript": "^5.9.3"
63
+ "typescript": "^6.0.2"
64
64
  }
65
65
  }