@overpod/mcp-telegram 1.14.0 → 1.15.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 CHANGED
@@ -532,12 +532,31 @@ src/
532
532
  - **[tsx](https://tsx.is/)** -- TypeScript execution without a build step
533
533
  - **[dotenv](https://github.com/motdotla/dotenv)** -- Environment variable management
534
534
 
535
+ ## Troubleshooting
536
+
537
+ ### AUTH_KEY_DUPLICATED
538
+
539
+ A Telegram session can only be used by **one process at a time**. If you get `AUTH_KEY_DUPLICATED`, it means another process is already using the same session file.
540
+
541
+ **Solution**: Create separate sessions for each environment:
542
+
543
+ ```bash
544
+ # Local development
545
+ TELEGRAM_SESSION_PATH=~/.mcp-telegram/session-local npx @overpod/mcp-telegram login
546
+
547
+ # Production server
548
+ TELEGRAM_SESSION_PATH=~/.mcp-telegram/session-prod npx @overpod/mcp-telegram login
549
+ ```
550
+
551
+ Then set `TELEGRAM_SESSION_PATH` in each environment's MCP config accordingly.
552
+
535
553
  ## Security
536
554
 
537
555
  - API credentials are stored in `.env` (gitignored)
538
556
  - Session is stored in `~/.mcp-telegram/session` with `0600` permissions (owner-only access)
539
557
  - Session directory is created with `0700` permissions
540
558
  - Phone number is **not required** -- QR-only authentication
559
+ - **One session per process** -- using the same session in multiple processes simultaneously causes `AUTH_KEY_DUPLICATED` errors (see [Troubleshooting](#troubleshooting))
541
560
  - This is a **userbot** (personal account), not a bot -- respect the [Telegram Terms of Service](https://core.telegram.org/api/terms)
542
561
 
543
562
  ## License
@@ -255,4 +255,16 @@ export declare class TelegramService {
255
255
  title: string;
256
256
  type: string;
257
257
  }>;
258
+ createGroup(options: {
259
+ title: string;
260
+ users: string[];
261
+ supergroup?: boolean;
262
+ forum?: boolean;
263
+ description?: string;
264
+ }): Promise<{
265
+ id: string;
266
+ title: string;
267
+ type: string;
268
+ inviteLink?: string;
269
+ }>;
258
270
  }
@@ -1187,4 +1187,78 @@ export class TelegramService {
1187
1187
  }
1188
1188
  throw new Error("Target is not a group or channel. Use username, @username, or invite link.");
1189
1189
  }
1190
+ async createGroup(options) {
1191
+ if (!this.client)
1192
+ throw new Error("Not connected");
1193
+ const { title, users, supergroup = false, forum = false, description } = options;
1194
+ if (supergroup || forum) {
1195
+ // Create supergroup/channel via channels.CreateChannel
1196
+ const result = await this.client.invoke(new Api.channels.CreateChannel({
1197
+ title,
1198
+ about: description ?? "",
1199
+ megagroup: true,
1200
+ forum: forum || undefined,
1201
+ }));
1202
+ const chat = result.chats?.[0];
1203
+ if (!chat)
1204
+ throw new Error("Failed to create supergroup");
1205
+ const channelId = chat.id.toString();
1206
+ // Invite users
1207
+ if (users.length > 0) {
1208
+ const inputUsers = [];
1209
+ for (const u of users) {
1210
+ try {
1211
+ const entity = await this.client.getEntity(u);
1212
+ if (entity instanceof Api.User) {
1213
+ inputUsers.push(new Api.InputUser({ userId: entity.id, accessHash: entity.accessHash ?? bigInt.zero }));
1214
+ }
1215
+ }
1216
+ catch {
1217
+ // Skip unresolvable users
1218
+ }
1219
+ }
1220
+ if (inputUsers.length > 0) {
1221
+ await this.client.invoke(new Api.channels.InviteToChannel({
1222
+ channel: chat,
1223
+ users: inputUsers,
1224
+ }));
1225
+ }
1226
+ }
1227
+ // Get invite link
1228
+ let inviteLink;
1229
+ try {
1230
+ const exported = await this.client.invoke(new Api.messages.ExportChatInvite({ peer: chat }));
1231
+ if (exported instanceof Api.ChatInviteExported) {
1232
+ inviteLink = exported.link;
1233
+ }
1234
+ }
1235
+ catch { }
1236
+ return { id: channelId, title, type: forum ? "forum" : "supergroup", inviteLink };
1237
+ }
1238
+ // Create basic group via messages.CreateChat
1239
+ const inputUsers = [];
1240
+ for (const u of users) {
1241
+ try {
1242
+ const entity = await this.client.getEntity(u);
1243
+ if (entity instanceof Api.User) {
1244
+ inputUsers.push(new Api.InputUser({ userId: entity.id, accessHash: entity.accessHash ?? bigInt.zero }));
1245
+ }
1246
+ }
1247
+ catch {
1248
+ // Skip unresolvable users
1249
+ }
1250
+ }
1251
+ if (inputUsers.length === 0) {
1252
+ throw new Error("At least one valid user is required to create a basic group");
1253
+ }
1254
+ const result = await this.client.invoke(new Api.messages.CreateChat({
1255
+ title,
1256
+ users: inputUsers,
1257
+ }));
1258
+ const updates = result;
1259
+ const chat = updates.chats?.[0];
1260
+ if (!chat)
1261
+ throw new Error("Failed to create group");
1262
+ return { id: chat.id.toString(), title, type: "group" };
1263
+ }
1190
1264
  }
@@ -100,6 +100,33 @@ export function registerChatTools(server, telegram) {
100
100
  return fail(e);
101
101
  }
102
102
  });
103
+ server.registerTool("telegram-create-group", {
104
+ description: "Create a new Telegram group or supergroup",
105
+ inputSchema: {
106
+ title: z.string().describe("Group name"),
107
+ users: z.array(z.string()).describe("Usernames or IDs to invite"),
108
+ supergroup: z.boolean().default(false).describe("Create as supergroup (supports >200 members, admin features)"),
109
+ forum: z.boolean().default(false).describe("Enable topics (requires supergroup)"),
110
+ description: z.string().optional().describe("Group description"),
111
+ },
112
+ annotations: WRITE,
113
+ }, async ({ title, users, supergroup, forum, description }) => {
114
+ const err = await requireConnection(telegram);
115
+ if (err)
116
+ return fail(new Error(err));
117
+ try {
118
+ const result = await telegram.createGroup({ title, users, supergroup, forum, description });
119
+ const lines = [
120
+ `Created ${result.type}: ${result.title}`,
121
+ `ID: ${result.id}`,
122
+ ...(result.inviteLink ? [`Invite link: ${result.inviteLink}`] : []),
123
+ ];
124
+ return ok(lines.join("\n"));
125
+ }
126
+ catch (e) {
127
+ return fail(e);
128
+ }
129
+ });
103
130
  server.registerTool("telegram-join-chat", {
104
131
  description: "Join a Telegram group or channel by username or invite link",
105
132
  inputSchema: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@overpod/mcp-telegram",
3
- "version": "1.14.0",
3
+ "version": "1.15.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,7 +56,7 @@
56
56
  "zod": "^4.3.6"
57
57
  },
58
58
  "devDependencies": {
59
- "@biomejs/biome": "^2.4.8",
59
+ "@biomejs/biome": "^2.4.9",
60
60
  "@types/node": "^25.5.0",
61
61
  "@types/qrcode": "^1.5.6",
62
62
  "tsx": "^4.21.0",