@overpod/mcp-telegram 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +40 -4
- package/dist/cli.js +0 -0
- package/dist/telegram-client.d.ts +5 -1
- package/dist/telegram-client.js +53 -10
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -173,23 +173,32 @@ const telegramMcp = new MCPClient({
|
|
|
173
173
|
|
|
174
174
|
| Tool | Description |
|
|
175
175
|
|------|-------------|
|
|
176
|
-
| `telegram-list-chats` | List recent dialogs with unread counts |
|
|
176
|
+
| `telegram-list-chats` | List recent dialogs with unread counts, bot/contact markers |
|
|
177
177
|
| `telegram-read-messages` | Read recent messages from a chat |
|
|
178
178
|
| `telegram-search-chats` | Search for chats, users, or channels by name |
|
|
179
179
|
| `telegram-search-messages` | Search messages in a chat by text |
|
|
180
|
-
| `telegram-get-unread` | Get chats with unread messages |
|
|
180
|
+
| `telegram-get-unread` | Get chats with unread messages, bot/contact markers |
|
|
181
|
+
| `telegram-get-contact-requests` | Get incoming messages from non-contacts with preview |
|
|
181
182
|
|
|
182
183
|
### Chat Management
|
|
183
184
|
|
|
184
185
|
| Tool | Description |
|
|
185
186
|
|------|-------------|
|
|
186
187
|
| `telegram-mark-as-read` | Mark a chat as read |
|
|
187
|
-
| `telegram-get-chat-info` | Get detailed info about a chat (name, type, members
|
|
188
|
+
| `telegram-get-chat-info` | Get detailed info about a chat (name, type, members, bot/contact status) |
|
|
188
189
|
| `telegram-get-chat-members` | List members of a group or channel |
|
|
189
190
|
| `telegram-join-chat` | Join a group or channel by username or invite link |
|
|
190
191
|
| `telegram-pin-message` | Pin a message in a chat |
|
|
191
192
|
| `telegram-unpin-message` | Unpin a message in a chat |
|
|
192
193
|
|
|
194
|
+
### Contacts & Moderation
|
|
195
|
+
|
|
196
|
+
| Tool | Description |
|
|
197
|
+
|------|-------------|
|
|
198
|
+
| `telegram-add-contact` | Add a user to your contacts (accept contact request) |
|
|
199
|
+
| `telegram-block-user` | Block a user from sending you messages |
|
|
200
|
+
| `telegram-report-spam` | Report a chat as spam to Telegram |
|
|
201
|
+
|
|
193
202
|
### User Info
|
|
194
203
|
|
|
195
204
|
| Tool | Description |
|
|
@@ -224,7 +233,7 @@ Most tools accept `chatId` as a string -- either a numeric ID (e.g., `"-10012345
|
|
|
224
233
|
|-----------|------|----------|-------------|
|
|
225
234
|
| `limit` | number | no | Number of chats to return (default: 20) |
|
|
226
235
|
| `offsetDate` | number | no | Unix timestamp for pagination |
|
|
227
|
-
| `filterType` | `"private"` / `"group"` / `"channel"` | no | Filter by chat type |
|
|
236
|
+
| `filterType` | `"private"` / `"group"` / `"channel"` / `"contact_requests"` | no | Filter by chat type |
|
|
228
237
|
|
|
229
238
|
### telegram-read-messages
|
|
230
239
|
|
|
@@ -356,6 +365,33 @@ Most tools accept `chatId` as a string -- either a numeric ID (e.g., `"-10012345
|
|
|
356
365
|
|-----------|------|----------|-------------|
|
|
357
366
|
| `limit` | number | no | Number of unread chats (default: 20) |
|
|
358
367
|
|
|
368
|
+
### telegram-get-contact-requests
|
|
369
|
+
|
|
370
|
+
| Parameter | Type | Required | Description |
|
|
371
|
+
|-----------|------|----------|-------------|
|
|
372
|
+
| `limit` | number | no | Number of contact requests (default: 20) |
|
|
373
|
+
|
|
374
|
+
### telegram-add-contact
|
|
375
|
+
|
|
376
|
+
| Parameter | Type | Required | Description |
|
|
377
|
+
|-----------|------|----------|-------------|
|
|
378
|
+
| `userId` | string | yes | User ID or @username to add |
|
|
379
|
+
| `firstName` | string | yes | First name for the contact |
|
|
380
|
+
| `lastName` | string | no | Last name for the contact |
|
|
381
|
+
| `phone` | string | no | Phone number for the contact |
|
|
382
|
+
|
|
383
|
+
### telegram-block-user
|
|
384
|
+
|
|
385
|
+
| Parameter | Type | Required | Description |
|
|
386
|
+
|-----------|------|----------|-------------|
|
|
387
|
+
| `userId` | string | yes | User ID or @username to block |
|
|
388
|
+
|
|
389
|
+
### telegram-report-spam
|
|
390
|
+
|
|
391
|
+
| Parameter | Type | Required | Description |
|
|
392
|
+
|-----------|------|----------|-------------|
|
|
393
|
+
| `chatId` | string | yes | Chat ID or @username to report |
|
|
394
|
+
|
|
359
395
|
## Development
|
|
360
396
|
|
|
361
397
|
```bash
|
package/dist/cli.js
CHANGED
|
File without changes
|
|
@@ -4,9 +4,13 @@ export declare class TelegramService {
|
|
|
4
4
|
private apiHash;
|
|
5
5
|
private sessionString;
|
|
6
6
|
private connected;
|
|
7
|
+
private sessionPath;
|
|
7
8
|
lastError: string;
|
|
8
|
-
constructor(apiId: number, apiHash: string
|
|
9
|
+
constructor(apiId: number, apiHash: string, options?: {
|
|
10
|
+
sessionPath?: string;
|
|
11
|
+
});
|
|
9
12
|
loadSession(): Promise<boolean>;
|
|
13
|
+
private isValidSessionString;
|
|
10
14
|
/** Set session string in memory (for programmatic / hosted use) */
|
|
11
15
|
setSessionString(session: string): void;
|
|
12
16
|
/** Get the current session string (for external persistence) */
|
package/dist/telegram-client.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { existsSync } from "node:fs";
|
|
2
|
-
import { readFile, unlink, writeFile } from "node:fs/promises";
|
|
1
|
+
import { existsSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { chmod, readFile, unlink, writeFile } from "node:fs/promises";
|
|
3
|
+
import { homedir } from "node:os";
|
|
3
4
|
import { dirname, join } from "node:path";
|
|
4
5
|
import { fileURLToPath } from "node:url";
|
|
5
6
|
import bigInt from "big-integer";
|
|
@@ -8,25 +9,66 @@ import { TelegramClient } from "telegram";
|
|
|
8
9
|
import { StringSession } from "telegram/sessions/index.js";
|
|
9
10
|
import { Api } from "telegram/tl/index.js";
|
|
10
11
|
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
11
|
-
const
|
|
12
|
+
const LEGACY_SESSION_FILE = join(__dirname, "..", ".telegram-session");
|
|
13
|
+
const DEFAULT_SESSION_DIR = join(homedir(), ".mcp-telegram");
|
|
14
|
+
const DEFAULT_SESSION_FILE = join(DEFAULT_SESSION_DIR, "session");
|
|
15
|
+
const SESSION_STRING_RE = /^[A-Za-z0-9+/=]+$/;
|
|
16
|
+
const MIN_SESSION_LENGTH = 100;
|
|
17
|
+
function resolveSessionPath(sessionPath) {
|
|
18
|
+
return sessionPath ?? process.env.TELEGRAM_SESSION_PATH ?? DEFAULT_SESSION_FILE;
|
|
19
|
+
}
|
|
20
|
+
function ensureSessionDir(filePath) {
|
|
21
|
+
const dir = dirname(filePath);
|
|
22
|
+
if (!existsSync(dir)) {
|
|
23
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
24
|
+
}
|
|
25
|
+
}
|
|
12
26
|
export class TelegramService {
|
|
13
27
|
client = null;
|
|
14
28
|
apiId;
|
|
15
29
|
apiHash;
|
|
16
30
|
sessionString = "";
|
|
17
31
|
connected = false;
|
|
32
|
+
sessionPath;
|
|
18
33
|
lastError = "";
|
|
19
|
-
constructor(apiId, apiHash) {
|
|
34
|
+
constructor(apiId, apiHash, options) {
|
|
20
35
|
this.apiId = apiId;
|
|
21
36
|
this.apiHash = apiHash;
|
|
37
|
+
this.sessionPath = resolveSessionPath(options?.sessionPath);
|
|
22
38
|
}
|
|
23
39
|
async loadSession() {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
40
|
+
// Try current session path
|
|
41
|
+
if (existsSync(this.sessionPath)) {
|
|
42
|
+
const raw = (await readFile(this.sessionPath, "utf-8")).trim();
|
|
43
|
+
if (this.isValidSessionString(raw)) {
|
|
44
|
+
this.sessionString = raw;
|
|
45
|
+
// Fix permissions on existing files
|
|
46
|
+
try {
|
|
47
|
+
await chmod(this.sessionPath, 0o600);
|
|
48
|
+
}
|
|
49
|
+
catch { }
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
// Migrate from legacy path (inside node_modules / package root)
|
|
54
|
+
if (this.sessionPath === DEFAULT_SESSION_FILE && existsSync(LEGACY_SESSION_FILE)) {
|
|
55
|
+
const raw = (await readFile(LEGACY_SESSION_FILE, "utf-8")).trim();
|
|
56
|
+
if (this.isValidSessionString(raw)) {
|
|
57
|
+
this.sessionString = raw;
|
|
58
|
+
ensureSessionDir(this.sessionPath);
|
|
59
|
+
await writeFile(this.sessionPath, raw, { encoding: "utf-8", mode: 0o600 });
|
|
60
|
+
try {
|
|
61
|
+
await unlink(LEGACY_SESSION_FILE);
|
|
62
|
+
}
|
|
63
|
+
catch { }
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
27
66
|
}
|
|
28
67
|
return false;
|
|
29
68
|
}
|
|
69
|
+
isValidSessionString(value) {
|
|
70
|
+
return value.length >= MIN_SESSION_LENGTH && SESSION_STRING_RE.test(value);
|
|
71
|
+
}
|
|
30
72
|
/** Set session string in memory (for programmatic / hosted use) */
|
|
31
73
|
setSessionString(session) {
|
|
32
74
|
this.sessionString = session;
|
|
@@ -38,7 +80,8 @@ export class TelegramService {
|
|
|
38
80
|
async saveSession(session) {
|
|
39
81
|
this.sessionString = session;
|
|
40
82
|
try {
|
|
41
|
-
|
|
83
|
+
ensureSessionDir(this.sessionPath);
|
|
84
|
+
await writeFile(this.sessionPath, session, { encoding: "utf-8", mode: 0o600 });
|
|
42
85
|
}
|
|
43
86
|
catch {
|
|
44
87
|
// File write may fail in containerized environments — session string is still in memory
|
|
@@ -95,8 +138,8 @@ export class TelegramService {
|
|
|
95
138
|
this.connected = false;
|
|
96
139
|
this.sessionString = "";
|
|
97
140
|
this.client = null;
|
|
98
|
-
if (existsSync(
|
|
99
|
-
await unlink(
|
|
141
|
+
if (existsSync(this.sessionPath)) {
|
|
142
|
+
await unlink(this.sessionPath);
|
|
100
143
|
}
|
|
101
144
|
}
|
|
102
145
|
/** Ensure connection is active, auto-reconnect if session exists */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@overpod/mcp-telegram",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.7.0",
|
|
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",
|
|
@@ -56,8 +56,8 @@
|
|
|
56
56
|
"zod": "^4.3.6"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@biomejs/biome": "^2.4.
|
|
60
|
-
"@types/node": "^25.
|
|
59
|
+
"@biomejs/biome": "^2.4.7",
|
|
60
|
+
"@types/node": "^25.5.0",
|
|
61
61
|
"@types/qrcode": "^1.5.6",
|
|
62
62
|
"tsx": "^4.21.0",
|
|
63
63
|
"typescript": "^5.9.3"
|