@overpod/mcp-telegram 1.26.0 → 1.26.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.
- package/dist/index.js +4 -1
- package/dist/rate-limiter.d.ts +1 -1
- package/dist/rate-limiter.js +8 -8
- package/dist/telegram-client.d.ts +6 -470
- package/dist/telegram-client.js +17 -874
- package/dist/telegram-helpers.d.ts +470 -0
- package/dist/telegram-helpers.js +870 -0
- package/dist/tools/account.js +7 -7
- package/dist/tools/boosts.js +4 -4
- package/dist/tools/chats.js +7 -7
- package/dist/tools/contacts.js +3 -3
- package/dist/tools/extras.js +3 -3
- package/dist/tools/group-calls.js +3 -3
- package/dist/tools/messages.js +17 -17
- package/dist/tools/quick-replies.js +3 -3
- package/dist/tools/reactions.js +2 -2
- package/dist/tools/shared.d.ts +3 -3
- package/dist/tools/shared.js +8 -7
- package/dist/tools/stars.js +3 -3
- package/dist/tools/stickers.js +5 -5
- package/dist/tools/stories.js +5 -5
- package/package.json +1 -1
- package/dist/__tests__/admin-log.test.d.ts +0 -1
- package/dist/__tests__/admin-log.test.js +0 -41
- package/dist/__tests__/approve-join-request.test.d.ts +0 -1
- package/dist/__tests__/approve-join-request.test.js +0 -107
- package/dist/__tests__/boosts.test.d.ts +0 -1
- package/dist/__tests__/boosts.test.js +0 -310
- package/dist/__tests__/broadcast-stats.test.d.ts +0 -1
- package/dist/__tests__/broadcast-stats.test.js +0 -172
- package/dist/__tests__/business-chat-links.test.d.ts +0 -1
- package/dist/__tests__/business-chat-links.test.js +0 -102
- package/dist/__tests__/get-message-buttons.test.d.ts +0 -1
- package/dist/__tests__/get-message-buttons.test.js +0 -122
- package/dist/__tests__/group-calls.test.d.ts +0 -1
- package/dist/__tests__/group-calls.test.js +0 -503
- package/dist/__tests__/inline-query-send.test.d.ts +0 -1
- package/dist/__tests__/inline-query-send.test.js +0 -94
- package/dist/__tests__/inline-query.test.d.ts +0 -1
- package/dist/__tests__/inline-query.test.js +0 -115
- package/dist/__tests__/megagroup-stats.test.d.ts +0 -1
- package/dist/__tests__/megagroup-stats.test.js +0 -166
- package/dist/__tests__/press-button.test.d.ts +0 -1
- package/dist/__tests__/press-button.test.js +0 -123
- package/dist/__tests__/quick-replies.test.d.ts +0 -1
- package/dist/__tests__/quick-replies.test.js +0 -245
- package/dist/__tests__/rate-limiter.test.d.ts +0 -1
- package/dist/__tests__/rate-limiter.test.js +0 -81
- package/dist/__tests__/reactions.test.d.ts +0 -1
- package/dist/__tests__/reactions.test.js +0 -23
- package/dist/__tests__/set-chat-permissions-merge.test.d.ts +0 -1
- package/dist/__tests__/set-chat-permissions-merge.test.js +0 -107
- package/dist/__tests__/set-chat-reactions.test.d.ts +0 -1
- package/dist/__tests__/set-chat-reactions.test.js +0 -129
- package/dist/__tests__/stars-status.test.d.ts +0 -1
- package/dist/__tests__/stars-status.test.js +0 -205
- package/dist/__tests__/stars-transactions.test.d.ts +0 -1
- package/dist/__tests__/stars-transactions.test.js +0 -82
- package/dist/__tests__/stories.test.d.ts +0 -1
- package/dist/__tests__/stories.test.js +0 -361
- package/dist/__tests__/toggle-anti-spam.test.d.ts +0 -1
- package/dist/__tests__/toggle-anti-spam.test.js +0 -80
- package/dist/__tests__/toggle-channel-signatures.test.d.ts +0 -1
- package/dist/__tests__/toggle-channel-signatures.test.js +0 -80
- package/dist/__tests__/toggle-forum-mode.test.d.ts +0 -1
- package/dist/__tests__/toggle-forum-mode.test.js +0 -80
- package/dist/__tests__/toggle-prehistory-hidden.test.d.ts +0 -1
- package/dist/__tests__/toggle-prehistory-hidden.test.js +0 -80
- package/dist/__tests__/tools/shared.test.d.ts +0 -1
- package/dist/__tests__/tools/shared.test.js +0 -110
- package/dist/__tests__/updates.test.d.ts +0 -1
- package/dist/__tests__/updates.test.js +0 -221
package/dist/tools/account.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { DESTRUCTIVE, fail, ok, READ_ONLY, requireConnection,
|
|
2
|
+
import { DESTRUCTIVE, fail, ok, READ_ONLY, requireConnection, WRITE } from "./shared.js";
|
|
3
3
|
const MUTE_FOREVER_UNTIL = 2147483647; // max 32-bit signed int
|
|
4
4
|
export function registerAccountTools(server, telegram) {
|
|
5
5
|
server.registerTool("telegram-mute-chat", {
|
|
@@ -58,7 +58,7 @@ export function registerAccountTools(server, telegram) {
|
|
|
58
58
|
const text = folders
|
|
59
59
|
.map((f) => `[${f.id}] ${f.emoticon ? `${f.emoticon} ` : ""}${f.title} (${f.includeCount} chats, ${f.pinnedCount} pinned)`)
|
|
60
60
|
.join("\n");
|
|
61
|
-
return ok(
|
|
61
|
+
return ok(text);
|
|
62
62
|
}
|
|
63
63
|
catch (e) {
|
|
64
64
|
return fail(e);
|
|
@@ -103,7 +103,7 @@ export function registerAccountTools(server, telegram) {
|
|
|
103
103
|
const text = sessions
|
|
104
104
|
.map((s) => `${s.current ? "→ " : " "}${s.device} (${s.platform}) — ${s.appName} ${s.appVersion}\n IP: ${s.ip} (${s.country}) | Last active: ${s.dateActive}${s.current ? " [CURRENT]" : ""}\n Hash: ${s.hash}`)
|
|
105
105
|
.join("\n\n");
|
|
106
|
-
return ok(
|
|
106
|
+
return ok(text);
|
|
107
107
|
}
|
|
108
108
|
catch (e) {
|
|
109
109
|
return fail(e);
|
|
@@ -252,7 +252,7 @@ export function registerAccountTools(server, telegram) {
|
|
|
252
252
|
const text = links
|
|
253
253
|
.map((l) => `${l.link}${l.title ? ` (${l.title})` : ""} — ${l.usageCount} uses${l.expired ? " [EXPIRED]" : ""}${l.revoked ? " [REVOKED]" : ""}`)
|
|
254
254
|
.join("\n");
|
|
255
|
-
return ok(
|
|
255
|
+
return ok(text);
|
|
256
256
|
}
|
|
257
257
|
catch (e) {
|
|
258
258
|
return fail(e);
|
|
@@ -291,7 +291,7 @@ export function registerAccountTools(server, telegram) {
|
|
|
291
291
|
if (drafts.length === 0)
|
|
292
292
|
return ok("No drafts");
|
|
293
293
|
const text = drafts.map((d) => `[${d.chatId}] ${d.chatTitle} (${d.date})\n ${d.text}`).join("\n\n");
|
|
294
|
-
return ok(
|
|
294
|
+
return ok(text);
|
|
295
295
|
}
|
|
296
296
|
catch (e) {
|
|
297
297
|
return fail(e);
|
|
@@ -344,7 +344,7 @@ export function registerAccountTools(server, telegram) {
|
|
|
344
344
|
if (dialogs.length === 0)
|
|
345
345
|
return ok("No saved dialogs");
|
|
346
346
|
const text = dialogs.map((d) => `[${d.peerId}] ${d.peerTitle} — last msg #${d.lastMsgId}`).join("\n");
|
|
347
|
-
return ok(
|
|
347
|
+
return ok(text);
|
|
348
348
|
}
|
|
349
349
|
catch (e) {
|
|
350
350
|
return fail(e);
|
|
@@ -379,7 +379,7 @@ export function registerAccountTools(server, telegram) {
|
|
|
379
379
|
return fail(new Error(err));
|
|
380
380
|
try {
|
|
381
381
|
const result = await telegram.getBusinessChatLinks();
|
|
382
|
-
return ok(
|
|
382
|
+
return ok(JSON.stringify(result));
|
|
383
383
|
}
|
|
384
384
|
catch (e) {
|
|
385
385
|
return fail(e);
|
package/dist/tools/boosts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection } from "./shared.js";
|
|
3
3
|
export function registerBoostTools(server, telegram) {
|
|
4
4
|
server.registerTool("telegram-get-my-boosts", {
|
|
5
5
|
description: "List the user's premium boost slots (premium.GetMyBoosts). Each entry includes slot index, the peer it currently boosts (if any), the date the boost was applied, expiration timestamp, and cooldownUntilDate (when a slot can be reassigned). Premium users have multiple slots; non-Premium users typically have a single slot. Read-only.",
|
|
@@ -11,7 +11,7 @@ export function registerBoostTools(server, telegram) {
|
|
|
11
11
|
return fail(new Error(err));
|
|
12
12
|
try {
|
|
13
13
|
const result = await telegram.getMyBoosts();
|
|
14
|
-
return ok(
|
|
14
|
+
return ok(JSON.stringify(result));
|
|
15
15
|
}
|
|
16
16
|
catch (e) {
|
|
17
17
|
return fail(e);
|
|
@@ -29,7 +29,7 @@ export function registerBoostTools(server, telegram) {
|
|
|
29
29
|
return fail(new Error(err));
|
|
30
30
|
try {
|
|
31
31
|
const result = await telegram.getBoostsStatus(chat);
|
|
32
|
-
return ok(
|
|
32
|
+
return ok(JSON.stringify(result));
|
|
33
33
|
}
|
|
34
34
|
catch (e) {
|
|
35
35
|
return fail(e);
|
|
@@ -56,7 +56,7 @@ export function registerBoostTools(server, telegram) {
|
|
|
56
56
|
return fail(new Error(err));
|
|
57
57
|
try {
|
|
58
58
|
const result = await telegram.getBoostsList(chat, { gifts, offset, limit });
|
|
59
|
-
return ok(
|
|
59
|
+
return ok(JSON.stringify(result));
|
|
60
60
|
}
|
|
61
61
|
catch (e) {
|
|
62
62
|
return fail(e);
|
package/dist/tools/chats.js
CHANGED
|
@@ -27,7 +27,7 @@ export function registerChatTools(server, telegram) {
|
|
|
27
27
|
return `${prefix} ${d.name} (${d.id})${botTag}${contactTag}${unread}`;
|
|
28
28
|
})
|
|
29
29
|
.join("\n");
|
|
30
|
-
return ok(
|
|
30
|
+
return ok(text || "No chats");
|
|
31
31
|
}
|
|
32
32
|
catch (e) {
|
|
33
33
|
return fail(e);
|
|
@@ -49,7 +49,7 @@ export function registerChatTools(server, telegram) {
|
|
|
49
49
|
const text = results
|
|
50
50
|
.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)}` : ""}`)
|
|
51
51
|
.join("\n");
|
|
52
|
-
return ok(
|
|
52
|
+
return ok(text || "No results");
|
|
53
53
|
}
|
|
54
54
|
catch (e) {
|
|
55
55
|
return fail(e);
|
|
@@ -99,7 +99,7 @@ export function registerChatTools(server, telegram) {
|
|
|
99
99
|
return `${m.name}${m.username ? ` (@${m.username})` : ""} (${m.id})${role}`;
|
|
100
100
|
})
|
|
101
101
|
.join("\n");
|
|
102
|
-
return ok(
|
|
102
|
+
return ok(text || "No members found");
|
|
103
103
|
}
|
|
104
104
|
catch (e) {
|
|
105
105
|
return fail(e);
|
|
@@ -386,7 +386,7 @@ export function registerChatTools(server, telegram) {
|
|
|
386
386
|
return `[#${e.id}] [${e.date}] ${e.userName}: ${e.action}${details}`;
|
|
387
387
|
})
|
|
388
388
|
.join("\n");
|
|
389
|
-
return ok(
|
|
389
|
+
return ok(text || "No admin log events");
|
|
390
390
|
}
|
|
391
391
|
catch (e) {
|
|
392
392
|
return fail(e);
|
|
@@ -606,7 +606,7 @@ export function registerChatTools(server, telegram) {
|
|
|
606
606
|
return fail(new Error(err));
|
|
607
607
|
try {
|
|
608
608
|
const topic = await telegram.createForumTopic(chatId, title, iconColor, iconEmojiId);
|
|
609
|
-
return ok(
|
|
609
|
+
return ok(`Created topic "${topic.title}" (id=${topic.id}) in ${chatId}`);
|
|
610
610
|
}
|
|
611
611
|
catch (e) {
|
|
612
612
|
return fail(e);
|
|
@@ -667,7 +667,7 @@ export function registerChatTools(server, telegram) {
|
|
|
667
667
|
return fail(new Error(err));
|
|
668
668
|
try {
|
|
669
669
|
const stats = await telegram.getBroadcastStats(chatId, { dark, includeGraphs });
|
|
670
|
-
return ok(
|
|
670
|
+
return ok(JSON.stringify(stats));
|
|
671
671
|
}
|
|
672
672
|
catch (e) {
|
|
673
673
|
return fail(e);
|
|
@@ -690,7 +690,7 @@ export function registerChatTools(server, telegram) {
|
|
|
690
690
|
return fail(new Error(err));
|
|
691
691
|
try {
|
|
692
692
|
const stats = await telegram.getMegagroupStats(chatId, { dark, includeGraphs });
|
|
693
|
-
return ok(
|
|
693
|
+
return ok(JSON.stringify(stats));
|
|
694
694
|
}
|
|
695
695
|
catch (e) {
|
|
696
696
|
return fail(e);
|
package/dist/tools/contacts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection,
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection, WRITE } from "./shared.js";
|
|
3
3
|
export function registerContactTools(server, telegram) {
|
|
4
4
|
server.registerTool("telegram-get-contacts", {
|
|
5
5
|
description: "Get your Telegram contacts list with phone numbers",
|
|
@@ -14,7 +14,7 @@ export function registerContactTools(server, telegram) {
|
|
|
14
14
|
const text = contacts
|
|
15
15
|
.map((c) => `P ${c.name}${c.username ? ` (@${c.username})` : ""} (${c.id})${c.phone ? ` +${c.phone}` : ""}`)
|
|
16
16
|
.join("\n");
|
|
17
|
-
return ok(
|
|
17
|
+
return ok(text || "No contacts");
|
|
18
18
|
}
|
|
19
19
|
catch (e) {
|
|
20
20
|
return fail(e);
|
|
@@ -73,7 +73,7 @@ export function registerContactTools(server, telegram) {
|
|
|
73
73
|
return `${tag} ${r.name}${username} (${r.id})${unread}${preview}`;
|
|
74
74
|
})
|
|
75
75
|
.join("\n");
|
|
76
|
-
return ok(
|
|
76
|
+
return ok(text);
|
|
77
77
|
}
|
|
78
78
|
catch (e) {
|
|
79
79
|
return fail(e);
|
package/dist/tools/extras.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, formatReactions, ok, READ_ONLY, requireConnection,
|
|
2
|
+
import { fail, formatReactions, ok, READ_ONLY, requireConnection, WRITE } from "./shared.js";
|
|
3
3
|
export function registerExtraTools(server, telegram) {
|
|
4
4
|
server.registerTool("telegram-pin-message", {
|
|
5
5
|
description: "Pin a message in a Telegram chat",
|
|
@@ -122,7 +122,7 @@ export function registerExtraTools(server, telegram) {
|
|
|
122
122
|
return `# ${t.title} (id: ${t.id})${flagStr}${unread}`;
|
|
123
123
|
})
|
|
124
124
|
.join("\n");
|
|
125
|
-
return ok(
|
|
125
|
+
return ok(text || "No topics found");
|
|
126
126
|
}
|
|
127
127
|
catch (e) {
|
|
128
128
|
return fail(e);
|
|
@@ -146,7 +146,7 @@ export function registerExtraTools(server, telegram) {
|
|
|
146
146
|
const text = messages
|
|
147
147
|
.map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
|
|
148
148
|
.join("\n\n");
|
|
149
|
-
return ok(
|
|
149
|
+
return ok(text || "No messages in this topic");
|
|
150
150
|
}
|
|
151
151
|
catch (e) {
|
|
152
152
|
return fail(e);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection } from "./shared.js";
|
|
3
3
|
export function isGroupCallsEnabled() {
|
|
4
4
|
return process.env.MCP_TELEGRAM_ENABLE_GROUP_CALLS === "1";
|
|
5
5
|
}
|
|
@@ -27,7 +27,7 @@ export function registerGroupCallTools(server, telegram) {
|
|
|
27
27
|
return fail(new Error(err));
|
|
28
28
|
try {
|
|
29
29
|
const result = await telegram.getGroupCall(chat, { limit });
|
|
30
|
-
return ok(
|
|
30
|
+
return ok(JSON.stringify(result));
|
|
31
31
|
}
|
|
32
32
|
catch (e) {
|
|
33
33
|
return fail(e);
|
|
@@ -68,7 +68,7 @@ export function registerGroupCallTools(server, telegram) {
|
|
|
68
68
|
return fail(new Error(err));
|
|
69
69
|
try {
|
|
70
70
|
const result = await telegram.getGroupCallParticipants(chat, { ids, sources, offset, limit });
|
|
71
|
-
return ok(
|
|
71
|
+
return ok(JSON.stringify(result));
|
|
72
72
|
}
|
|
73
73
|
catch (e) {
|
|
74
74
|
return fail(e);
|
package/dist/tools/messages.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { DESTRUCTIVE, fail, formatReactions, ok, READ_ONLY, requireConnection,
|
|
2
|
+
import { DESTRUCTIVE, fail, formatReactions, ok, READ_ONLY, requireConnection, WRITE } from "./shared.js";
|
|
3
3
|
export function registerMessageTools(server, telegram) {
|
|
4
4
|
server.registerTool("telegram-send-message", {
|
|
5
5
|
description: "Send a message to a Telegram chat",
|
|
@@ -45,7 +45,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
45
45
|
const text = messages
|
|
46
46
|
.map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
|
|
47
47
|
.join("\n\n");
|
|
48
|
-
return ok(
|
|
48
|
+
return ok(text || "No messages");
|
|
49
49
|
}
|
|
50
50
|
catch (e) {
|
|
51
51
|
return fail(e);
|
|
@@ -70,7 +70,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
70
70
|
const text = messages
|
|
71
71
|
.map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
|
|
72
72
|
.join("\n\n");
|
|
73
|
-
return ok(
|
|
73
|
+
return ok(text || "No messages found");
|
|
74
74
|
}
|
|
75
75
|
catch (e) {
|
|
76
76
|
return fail(e);
|
|
@@ -94,7 +94,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
94
94
|
const text = messages
|
|
95
95
|
.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)}`)
|
|
96
96
|
.join("\n\n");
|
|
97
|
-
return ok(
|
|
97
|
+
return ok(text || "No messages found");
|
|
98
98
|
}
|
|
99
99
|
catch (e) {
|
|
100
100
|
return fail(e);
|
|
@@ -185,7 +185,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
185
185
|
return line;
|
|
186
186
|
})
|
|
187
187
|
.join("\n");
|
|
188
|
-
return ok(
|
|
188
|
+
return ok(text || "No unread chats");
|
|
189
189
|
}
|
|
190
190
|
catch (e) {
|
|
191
191
|
return fail(e);
|
|
@@ -206,7 +206,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
206
206
|
const text = messages
|
|
207
207
|
.map((m) => `[#${m.id}] [${m.date}] ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}`)
|
|
208
208
|
.join("\n\n");
|
|
209
|
-
return ok(
|
|
209
|
+
return ok(text || "No scheduled messages");
|
|
210
210
|
}
|
|
211
211
|
catch (e) {
|
|
212
212
|
return fail(e);
|
|
@@ -252,7 +252,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
252
252
|
const text = messages
|
|
253
253
|
.map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
|
|
254
254
|
.join("\n\n");
|
|
255
|
-
return ok(
|
|
255
|
+
return ok(text || "No replies");
|
|
256
256
|
}
|
|
257
257
|
catch (e) {
|
|
258
258
|
return fail(e);
|
|
@@ -272,7 +272,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
272
272
|
return fail(new Error(err));
|
|
273
273
|
try {
|
|
274
274
|
const link = await telegram.getMessageLink(chatId, messageId, thread);
|
|
275
|
-
return ok(
|
|
275
|
+
return ok(link);
|
|
276
276
|
}
|
|
277
277
|
catch (e) {
|
|
278
278
|
return fail(e);
|
|
@@ -294,7 +294,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
294
294
|
const text = messages
|
|
295
295
|
.map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
|
|
296
296
|
.join("\n\n");
|
|
297
|
-
return ok(
|
|
297
|
+
return ok(text || "No unread mentions");
|
|
298
298
|
}
|
|
299
299
|
catch (e) {
|
|
300
300
|
return fail(e);
|
|
@@ -316,7 +316,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
316
316
|
const text = messages
|
|
317
317
|
.map((m) => `[#${m.id}] [${m.date}] ${m.sender}: ${m.text}${m.media ? ` [${m.media.type}${m.media.fileName ? `: ${m.media.fileName}` : ""}]` : ""}${formatReactions(m.reactions)}`)
|
|
318
318
|
.join("\n\n");
|
|
319
|
-
return ok(
|
|
319
|
+
return ok(text || "No unread reactions");
|
|
320
320
|
}
|
|
321
321
|
catch (e) {
|
|
322
322
|
return fail(e);
|
|
@@ -346,7 +346,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
346
346
|
const text = translations.length === messageIds.length
|
|
347
347
|
? translations.map((t, i) => `[#${messageIds[i]}] ${t}`).join("\n\n")
|
|
348
348
|
: translations.join("\n\n");
|
|
349
|
-
return ok(
|
|
349
|
+
return ok(text || "No translations");
|
|
350
350
|
}
|
|
351
351
|
catch (e) {
|
|
352
352
|
const msg = e.message ?? "";
|
|
@@ -412,7 +412,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
412
412
|
return fail(new Error(err));
|
|
413
413
|
try {
|
|
414
414
|
const res = await telegram.getInlineBotResults(bot, chatId, query, offset);
|
|
415
|
-
return ok(
|
|
415
|
+
return ok(JSON.stringify(res));
|
|
416
416
|
}
|
|
417
417
|
catch (e) {
|
|
418
418
|
return fail(e);
|
|
@@ -464,7 +464,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
464
464
|
return fail(new Error(err));
|
|
465
465
|
try {
|
|
466
466
|
const result = await telegram.getMessageButtons(chatId, messageId);
|
|
467
|
-
return ok(
|
|
467
|
+
return ok(JSON.stringify(result));
|
|
468
468
|
}
|
|
469
469
|
catch (e) {
|
|
470
470
|
return fail(e);
|
|
@@ -506,7 +506,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
506
506
|
buttonIndex: hasIndex ? { row: row, column: column } : undefined,
|
|
507
507
|
data,
|
|
508
508
|
});
|
|
509
|
-
return ok(
|
|
509
|
+
return ok(JSON.stringify(answer));
|
|
510
510
|
}
|
|
511
511
|
catch (e) {
|
|
512
512
|
return fail(e);
|
|
@@ -522,7 +522,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
522
522
|
return fail(new Error(err));
|
|
523
523
|
try {
|
|
524
524
|
const state = await telegram.getUpdatesState();
|
|
525
|
-
return ok(
|
|
525
|
+
return ok(JSON.stringify(state));
|
|
526
526
|
}
|
|
527
527
|
catch (e) {
|
|
528
528
|
return fail(e);
|
|
@@ -556,7 +556,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
556
556
|
return fail(new Error(err));
|
|
557
557
|
try {
|
|
558
558
|
const diff = await telegram.getUpdates({ pts, qts, date, ptsLimit, ptsTotalLimit });
|
|
559
|
-
return ok(
|
|
559
|
+
return ok(JSON.stringify(diff));
|
|
560
560
|
}
|
|
561
561
|
catch (e) {
|
|
562
562
|
return fail(e);
|
|
@@ -580,7 +580,7 @@ export function registerMessageTools(server, telegram) {
|
|
|
580
580
|
return fail(new Error(err));
|
|
581
581
|
try {
|
|
582
582
|
const diff = await telegram.getChannelUpdates(chatId, { pts, limit, force });
|
|
583
|
-
return ok(
|
|
583
|
+
return ok(JSON.stringify(diff));
|
|
584
584
|
}
|
|
585
585
|
catch (e) {
|
|
586
586
|
return fail(e);
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection } from "./shared.js";
|
|
3
3
|
export function isQuickRepliesEnabled() {
|
|
4
4
|
return process.env.MCP_TELEGRAM_ENABLE_QUICK_REPLIES === "1";
|
|
5
5
|
}
|
|
@@ -22,7 +22,7 @@ export function registerQuickRepliesTools(server, telegram) {
|
|
|
22
22
|
return fail(new Error(err));
|
|
23
23
|
try {
|
|
24
24
|
const result = await telegram.getQuickReplies(hash);
|
|
25
|
-
return ok(
|
|
25
|
+
return ok(JSON.stringify(result));
|
|
26
26
|
}
|
|
27
27
|
catch (e) {
|
|
28
28
|
return fail(e);
|
|
@@ -49,7 +49,7 @@ export function registerQuickRepliesTools(server, telegram) {
|
|
|
49
49
|
return fail(new Error(err));
|
|
50
50
|
try {
|
|
51
51
|
const result = await telegram.getQuickReplyMessages(shortcutId, { ids, hash });
|
|
52
|
-
return ok(
|
|
52
|
+
return ok(JSON.stringify(result));
|
|
53
53
|
}
|
|
54
54
|
catch (e) {
|
|
55
55
|
return fail(e);
|
package/dist/tools/reactions.js
CHANGED
|
@@ -92,7 +92,7 @@ export function registerReactionTools(server, telegram) {
|
|
|
92
92
|
const reactions = await telegram.getTopReactions(limit);
|
|
93
93
|
if (reactions.length === 0)
|
|
94
94
|
return ok("No top reactions available");
|
|
95
|
-
return ok(
|
|
95
|
+
return ok(reactions.map((r) => r.emoji).join(" "));
|
|
96
96
|
}
|
|
97
97
|
catch (e) {
|
|
98
98
|
return fail(e);
|
|
@@ -155,7 +155,7 @@ export function registerReactionTools(server, telegram) {
|
|
|
155
155
|
const reactions = await telegram.getRecentReactions(limit);
|
|
156
156
|
if (reactions.length === 0)
|
|
157
157
|
return ok("No recent reactions");
|
|
158
|
-
return ok(
|
|
158
|
+
return ok(reactions.map((r) => r.emoji).join(" "));
|
|
159
159
|
}
|
|
160
160
|
catch (e) {
|
|
161
161
|
return fail(e);
|
package/dist/tools/shared.d.ts
CHANGED
|
@@ -13,7 +13,9 @@ export declare const DESTRUCTIVE: {
|
|
|
13
13
|
readonly destructiveHint: true;
|
|
14
14
|
readonly openWorldHint: true;
|
|
15
15
|
};
|
|
16
|
-
/**
|
|
16
|
+
/** Remove unpaired UTF-16 surrogates that break JSON serialization */
|
|
17
|
+
export declare function sanitize(text: string): string;
|
|
18
|
+
/** Helper: success response — always sanitizes to prevent surrogate crashes */
|
|
17
19
|
export declare function ok(text: string): {
|
|
18
20
|
content: {
|
|
19
21
|
type: "text";
|
|
@@ -28,8 +30,6 @@ export declare function fail(e: unknown): {
|
|
|
28
30
|
}[];
|
|
29
31
|
isError: true;
|
|
30
32
|
};
|
|
31
|
-
/** Remove unpaired UTF-16 surrogates that break JSON serialization */
|
|
32
|
-
export declare function sanitize(text: string): string;
|
|
33
33
|
/** Format reactions array into compact text like: [👍×5 ❤️×3(me) 🔥×1] */
|
|
34
34
|
export declare function formatReactions(reactions?: {
|
|
35
35
|
emoji: string;
|
package/dist/tools/shared.js
CHANGED
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
export const READ_ONLY = { readOnlyHint: true, openWorldHint: true };
|
|
3
3
|
export const WRITE = { readOnlyHint: false, openWorldHint: true };
|
|
4
4
|
export const DESTRUCTIVE = { readOnlyHint: false, destructiveHint: true, openWorldHint: true };
|
|
5
|
-
/**
|
|
5
|
+
/** Remove unpaired UTF-16 surrogates that break JSON serialization */
|
|
6
|
+
export function sanitize(text) {
|
|
7
|
+
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
8
|
+
}
|
|
9
|
+
/** Helper: success response — always sanitizes to prevent surrogate crashes */
|
|
6
10
|
export function ok(text) {
|
|
7
|
-
return { content: [{ type: "text", text }] };
|
|
11
|
+
return { content: [{ type: "text", text: sanitize(text) }] };
|
|
8
12
|
}
|
|
9
13
|
/** Helper: error response with isError flag */
|
|
10
14
|
export function fail(e) {
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
/** Remove unpaired UTF-16 surrogates that break JSON serialization */
|
|
14
|
-
export function sanitize(text) {
|
|
15
|
-
return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "\uFFFD");
|
|
15
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
16
|
+
return { content: [{ type: "text", text: `Error: ${sanitize(msg)}` }], isError: true };
|
|
16
17
|
}
|
|
17
18
|
/** Format reactions array into compact text like: [👍×5 ❤️×3(me) 🔥×1] */
|
|
18
19
|
export function formatReactions(reactions) {
|
package/dist/tools/stars.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection } from "./shared.js";
|
|
3
3
|
export function isStarsEnabled() {
|
|
4
4
|
return process.env.MCP_TELEGRAM_ENABLE_STARS === "1";
|
|
5
5
|
}
|
|
@@ -20,7 +20,7 @@ export function registerStarsTools(server, telegram) {
|
|
|
20
20
|
return fail(new Error(err));
|
|
21
21
|
try {
|
|
22
22
|
const result = await telegram.getStarsStatus(peer);
|
|
23
|
-
return ok(
|
|
23
|
+
return ok(JSON.stringify(result));
|
|
24
24
|
}
|
|
25
25
|
catch (e) {
|
|
26
26
|
return fail(e);
|
|
@@ -62,7 +62,7 @@ export function registerStarsTools(server, telegram) {
|
|
|
62
62
|
offset,
|
|
63
63
|
limit,
|
|
64
64
|
});
|
|
65
|
-
return ok(
|
|
65
|
+
return ok(JSON.stringify(result));
|
|
66
66
|
}
|
|
67
67
|
catch (e) {
|
|
68
68
|
return fail(e);
|
package/dist/tools/stickers.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection,
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection, WRITE } from "./shared.js";
|
|
3
3
|
export function registerStickerTools(server, telegram) {
|
|
4
4
|
server.registerTool("telegram-get-sticker-set", {
|
|
5
5
|
description: "Get all stickers from a sticker set by its short name. Returns each sticker with index and emoji. Use the index with telegram-send-sticker to send a specific sticker",
|
|
@@ -25,7 +25,7 @@ export function registerStickerTools(server, telegram) {
|
|
|
25
25
|
}
|
|
26
26
|
lines.push("");
|
|
27
27
|
lines.push(`Send a sticker: telegram-send-sticker(chatId, stickerSet="${set.shortName}", index=N)`);
|
|
28
|
-
return ok(
|
|
28
|
+
return ok(lines.join("\n"));
|
|
29
29
|
}
|
|
30
30
|
catch (e) {
|
|
31
31
|
return fail(e);
|
|
@@ -54,7 +54,7 @@ export function registerStickerTools(server, telegram) {
|
|
|
54
54
|
}
|
|
55
55
|
lines.push("");
|
|
56
56
|
lines.push("Use telegram-get-sticker-set(shortName) to see individual stickers.");
|
|
57
|
-
return ok(
|
|
57
|
+
return ok(lines.join("\n"));
|
|
58
58
|
}
|
|
59
59
|
catch (e) {
|
|
60
60
|
return fail(e);
|
|
@@ -79,7 +79,7 @@ export function registerStickerTools(server, telegram) {
|
|
|
79
79
|
lines.push(`• ${set.title} — ${set.count} stickers`);
|
|
80
80
|
lines.push(` Short name: ${set.shortName}`);
|
|
81
81
|
}
|
|
82
|
-
return ok(
|
|
82
|
+
return ok(lines.join("\n"));
|
|
83
83
|
}
|
|
84
84
|
catch (e) {
|
|
85
85
|
return fail(e);
|
|
@@ -128,7 +128,7 @@ export function registerStickerTools(server, telegram) {
|
|
|
128
128
|
for (let i = 0; i < stickers.length; i++) {
|
|
129
129
|
lines.push(`[${i}] ${stickers[i].emoji}`);
|
|
130
130
|
}
|
|
131
|
-
return ok(
|
|
131
|
+
return ok(lines.join("\n"));
|
|
132
132
|
}
|
|
133
133
|
catch (e) {
|
|
134
134
|
return fail(e);
|
package/dist/tools/stories.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { fail, ok, READ_ONLY, requireConnection
|
|
2
|
+
import { fail, ok, READ_ONLY, requireConnection } from "./shared.js";
|
|
3
3
|
export function registerStoryTools(server, telegram) {
|
|
4
4
|
server.registerTool("telegram-get-all-stories", {
|
|
5
5
|
description: "Fetch active stories from contacts/channels the user follows. Pagination via 'next' + 'state' — pass the returned state back on the next call with next:true to load more. Use hidden:true to read stories from muted/archived peers. Returns compact story metadata (id, date, expireDate, caption, mediaType, counters) without raw media blobs.",
|
|
@@ -18,7 +18,7 @@ export function registerStoryTools(server, telegram) {
|
|
|
18
18
|
}
|
|
19
19
|
try {
|
|
20
20
|
const result = await telegram.getAllStories({ next, hidden, state });
|
|
21
|
-
return ok(
|
|
21
|
+
return ok(JSON.stringify(result));
|
|
22
22
|
}
|
|
23
23
|
catch (e) {
|
|
24
24
|
return fail(e);
|
|
@@ -40,7 +40,7 @@ export function registerStoryTools(server, telegram) {
|
|
|
40
40
|
const result = await telegram.getPeerStories(chat);
|
|
41
41
|
if (result === null)
|
|
42
42
|
return ok("No active stories found for the specified peer");
|
|
43
|
-
return ok(
|
|
43
|
+
return ok(JSON.stringify(result));
|
|
44
44
|
}
|
|
45
45
|
catch (e) {
|
|
46
46
|
return fail(e);
|
|
@@ -61,7 +61,7 @@ export function registerStoryTools(server, telegram) {
|
|
|
61
61
|
return fail(new Error(err));
|
|
62
62
|
try {
|
|
63
63
|
const result = await telegram.getStoriesById(chat, ids);
|
|
64
|
-
return ok(
|
|
64
|
+
return ok(JSON.stringify(result));
|
|
65
65
|
}
|
|
66
66
|
catch (e) {
|
|
67
67
|
return fail(e);
|
|
@@ -94,7 +94,7 @@ export function registerStoryTools(server, telegram) {
|
|
|
94
94
|
offset,
|
|
95
95
|
limit,
|
|
96
96
|
});
|
|
97
|
-
return ok(
|
|
97
|
+
return ok(JSON.stringify(result));
|
|
98
98
|
}
|
|
99
99
|
catch (e) {
|
|
100
100
|
const msg = e.message ?? "";
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert";
|
|
2
|
-
import { describe, it } from "node:test";
|
|
3
|
-
import { Api } from "telegram/tl/index.js";
|
|
4
|
-
import { describeAdminLogAction, describeAdminLogDetails } from "../telegram-client.js";
|
|
5
|
-
describe("describeAdminLogAction", () => {
|
|
6
|
-
it("converts ChangeTitle to snake_case", () => {
|
|
7
|
-
const action = new Api.ChannelAdminLogEventActionChangeTitle({ prevValue: "a", newValue: "b" });
|
|
8
|
-
assert.strictEqual(describeAdminLogAction(action), "change_title");
|
|
9
|
-
});
|
|
10
|
-
it("converts ParticipantJoin to snake_case", () => {
|
|
11
|
-
const action = new Api.ChannelAdminLogEventActionParticipantJoin();
|
|
12
|
-
assert.strictEqual(describeAdminLogAction(action), "participant_join");
|
|
13
|
-
});
|
|
14
|
-
it("handles ToggleSlowMode", () => {
|
|
15
|
-
const action = new Api.ChannelAdminLogEventActionToggleSlowMode({ prevValue: 0, newValue: 30 });
|
|
16
|
-
assert.strictEqual(describeAdminLogAction(action), "toggle_slow_mode");
|
|
17
|
-
});
|
|
18
|
-
it("handles ChangeHistoryTTL without splitting acronym", () => {
|
|
19
|
-
const action = new Api.ChannelAdminLogEventActionChangeHistoryTTL({ prevValue: 0, newValue: 86400 });
|
|
20
|
-
assert.strictEqual(describeAdminLogAction(action), "change_history_ttl");
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
describe("describeAdminLogDetails", () => {
|
|
24
|
-
const describeUser = (id) => `user_${id.toString()}`;
|
|
25
|
-
it("formats title change", () => {
|
|
26
|
-
const action = new Api.ChannelAdminLogEventActionChangeTitle({ prevValue: "old", newValue: "new" });
|
|
27
|
-
assert.strictEqual(describeAdminLogDetails(action, describeUser), '"old" → "new"');
|
|
28
|
-
});
|
|
29
|
-
it("formats username change", () => {
|
|
30
|
-
const action = new Api.ChannelAdminLogEventActionChangeUsername({ prevValue: "old", newValue: "new" });
|
|
31
|
-
assert.strictEqual(describeAdminLogDetails(action, describeUser), "@old → @new");
|
|
32
|
-
});
|
|
33
|
-
it("formats slow mode change", () => {
|
|
34
|
-
const action = new Api.ChannelAdminLogEventActionToggleSlowMode({ prevValue: 0, newValue: 30 });
|
|
35
|
-
assert.strictEqual(describeAdminLogDetails(action, describeUser), "0s → 30s");
|
|
36
|
-
});
|
|
37
|
-
it("returns empty string for unknown actions", () => {
|
|
38
|
-
const action = new Api.ChannelAdminLogEventActionParticipantJoin();
|
|
39
|
-
assert.strictEqual(describeAdminLogDetails(action, describeUser), "");
|
|
40
|
-
});
|
|
41
|
-
});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|