@fre4x/telegram 1.1.2 → 1.1.4

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 +10 -5
  2. package/dist/index.js +53 -15
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -4,7 +4,7 @@ Telegram MCP server implementing Claude Code Channels for bidirectional communic
4
4
 
5
5
  ## Features
6
6
 
7
- - **Push Notifications:** Sends incoming Telegram messages directly to the Claude Code session via `notifications/push_event`.
7
+ - **Push Notifications:** Sends incoming Telegram messages to the connected MCP client via `notifications/message` (claude/channel protocol).
8
8
  - **Bidirectional Chat:** Allows Claude to send messages to Telegram using the `send_telegram_message` tool.
9
9
  - **Security:** Filters incoming messages based on an allowed user ID.
10
10
  - **Remote Control:** (Planned) Approve or deny Claude's tool-use prompts from your mobile device.
@@ -62,14 +62,19 @@ If you are using this plugin as a bidirectional Claude Code channel rather than
62
62
  claude --channels plugin:telegram --dangerously-load-development-channels
63
63
  ```
64
64
 
65
- ## Development
65
+ ## Mock Mode
66
+
67
+ Run without a real bot token (returns fixture data of identical shape):
66
68
 
67
69
  ```bash
68
- npm run dev
70
+ MOCK=true npx @fre4x/telegram
69
71
  ```
70
72
 
71
- Run the MCP Inspector:
73
+ ## Development
72
74
 
73
75
  ```bash
74
- npm run inspector
76
+ npm run dev # tsx, no build
77
+ npm run build # esbuild → dist/
78
+ npm test # vitest unit tests (MOCK=true)
79
+ npm run inspector # MCP Inspector (MOCK=true)
75
80
  ```
package/dist/index.js CHANGED
@@ -28398,22 +28398,26 @@ import { JSDOM } from "jsdom";
28398
28398
  // ../packages/shared/dist/errors.js
28399
28399
  function createApiError(message, statusCode) {
28400
28400
  let hint = "Check your network connection and retry.";
28401
+ let type = "Service Error";
28401
28402
  if (statusCode === 429) {
28402
- hint = "Rate limit exceeded. Suggestion: Wait for 60 seconds (Exponential Backoff) before retrying or reduce concurrent calls.";
28403
+ type = "Rate Limit";
28404
+ hint = "Request volume is too high. Suggestion: Wait briefly before retrying or reduce concurrent calls.";
28403
28405
  } else if (statusCode === 401 || statusCode === 403) {
28404
- hint = "Authentication failed. Suggestion: Verify your API key or token in the environment configuration.";
28406
+ type = "Authentication Error";
28407
+ hint = "The request could not be authorized. Suggestion: Verify your API key or token in the environment configuration.";
28405
28408
  } else if (statusCode && statusCode >= 500) {
28406
- hint = "Upstream service is having issues. Suggestion: This is a temporary external error. Try again in a few minutes.";
28409
+ type = "Upstream Error";
28410
+ hint = "The remote service is experiencing temporary issues. Suggestion: Try again in a few minutes.";
28407
28411
  } else if (statusCode === 404) {
28408
- hint = "The requested resource was not found. Suggestion: Check if the ID or Ticker is correct, or search for it first.";
28412
+ type = "Not Found";
28413
+ hint = "The requested information could not be found. Suggestion: Check if the ID, Ticker, or query parameters are correct.";
28409
28414
  }
28410
- const detail = statusCode ? ` (HTTP ${statusCode})` : "";
28411
28415
  return {
28412
28416
  isError: true,
28413
28417
  content: [
28414
28418
  {
28415
28419
  type: "text",
28416
- text: `API Error${detail}: ${message}
28420
+ text: `${type}: ${message}
28417
28421
 
28418
28422
  **Next Action**: ${hint}`
28419
28423
  }
@@ -28471,7 +28475,8 @@ _Showing ${start}\u2013${end} of ${total}. Use \`offset: ${offset + limit}\` for
28471
28475
  }
28472
28476
 
28473
28477
  // ../packages/shared/dist/pagination.js
28474
- var z2 = external_exports3 || zod_default || zod_exports;
28478
+ var zodCompat = zod_exports;
28479
+ var z2 = zodCompat.z ?? zodCompat.default?.z ?? zodCompat.default ?? zodCompat;
28475
28480
  var paginationSchema = z2.object({
28476
28481
  limit: z2.number().int().min(1).max(100).default(20).describe("Maximum results to return (1\u2013100, default 20)"),
28477
28482
  offset: z2.number().int().min(0).default(0).describe("Number of results to skip for pagination (default 0)")
@@ -28617,10 +28622,24 @@ var server = new Server(
28617
28622
  },
28618
28623
  {
28619
28624
  capabilities: {
28620
- tools: {}
28621
- }
28625
+ tools: {},
28626
+ logging: {},
28627
+ // Required by SDK for notifications/message
28628
+ experimental: {
28629
+ "claude/channel": {
28630
+ description: "Telegram events are delivered via channel notifications"
28631
+ }
28632
+ }
28633
+ },
28634
+ instructions: "Telegram MCP server. Delivers inbound Telegram messages as channel notifications via notifications/message."
28622
28635
  }
28623
28636
  );
28637
+ var isInitialized = false;
28638
+ server.oninitialized = () => {
28639
+ isInitialized = true;
28640
+ };
28641
+ var seenMessageIds = /* @__PURE__ */ new Set();
28642
+ var MAX_SEEN_IDS = 500;
28624
28643
  var isImage = (filePath) => {
28625
28644
  const ext = path.extname(filePath).toLowerCase();
28626
28645
  return [".jpg", ".jpeg", ".png", ".gif", ".webp", ".bmp"].includes(ext);
@@ -28957,18 +28976,37 @@ if (bot) {
28957
28976
  if (messageHistory.length > MAX_HISTORY) {
28958
28977
  messageHistory.shift();
28959
28978
  }
28979
+ if (!isInitialized) {
28980
+ console.warn(
28981
+ `[telegram] Pre-init notification dropped (message_id=${metadata.message_id})`
28982
+ );
28983
+ return;
28984
+ }
28985
+ const msgId = metadata.message_id;
28986
+ if (seenMessageIds.has(msgId)) {
28987
+ return;
28988
+ }
28989
+ if (seenMessageIds.size >= MAX_SEEN_IDS) {
28990
+ seenMessageIds.delete(seenMessageIds.values().next().value);
28991
+ }
28992
+ seenMessageIds.add(msgId);
28960
28993
  try {
28961
28994
  await server.notification({
28962
- method: "notifications/push_event",
28995
+ method: "notifications/message",
28963
28996
  params: {
28964
- type: "message",
28965
- senderId,
28966
- content: messageContent,
28967
- metadata
28997
+ _meta: {
28998
+ channel: "telegram"
28999
+ },
29000
+ content: [
29001
+ {
29002
+ type: "text",
29003
+ text: `New message from ${senderId} in ${chatTitle} (${chatId}): ${messageContent}`
29004
+ }
29005
+ ]
28968
29006
  }
28969
29007
  });
28970
29008
  } catch (error48) {
28971
- console.error("Failed to push notification:", error48);
29009
+ console.error("Failed to push channel notification:", error48);
28972
29010
  }
28973
29011
  });
28974
29012
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fre4x/telegram",
3
- "version": "1.1.2",
3
+ "version": "1.1.4",
4
4
  "description": "Telegram MCP server implementing Claude Code Channels for bidirectional communication and remote permission relay.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",