bn-telegram-mcp-server 0.0.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 (99) hide show
  1. package/README.md +1031 -0
  2. package/dist/debug-middleware.d.ts +12 -0
  3. package/dist/debug-middleware.d.ts.map +1 -0
  4. package/dist/debug-middleware.js +36 -0
  5. package/dist/debug-middleware.js.map +1 -0
  6. package/dist/encryption.d.ts +11 -0
  7. package/dist/encryption.d.ts.map +1 -0
  8. package/dist/encryption.js +26 -0
  9. package/dist/encryption.js.map +1 -0
  10. package/dist/helpers.d.ts +27 -0
  11. package/dist/helpers.d.ts.map +1 -0
  12. package/dist/helpers.js +103 -0
  13. package/dist/helpers.js.map +1 -0
  14. package/dist/index.d.ts +3 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +176 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/logger.d.ts +29 -0
  19. package/dist/logger.d.ts.map +1 -0
  20. package/dist/logger.js +114 -0
  21. package/dist/logger.js.map +1 -0
  22. package/dist/request-context.d.ts +24 -0
  23. package/dist/request-context.d.ts.map +1 -0
  24. package/dist/request-context.js +32 -0
  25. package/dist/request-context.js.map +1 -0
  26. package/dist/resolvers.d.ts +36 -0
  27. package/dist/resolvers.d.ts.map +1 -0
  28. package/dist/resolvers.js +252 -0
  29. package/dist/resolvers.js.map +1 -0
  30. package/dist/schemas.d.ts +150 -0
  31. package/dist/schemas.d.ts.map +1 -0
  32. package/dist/schemas.js +216 -0
  33. package/dist/schemas.js.map +1 -0
  34. package/dist/telegram-client.d.ts +19 -0
  35. package/dist/telegram-client.d.ts.map +1 -0
  36. package/dist/telegram-client.js +112 -0
  37. package/dist/telegram-client.js.map +1 -0
  38. package/dist/tool-loader.d.ts +31 -0
  39. package/dist/tool-loader.d.ts.map +1 -0
  40. package/dist/tool-loader.js +121 -0
  41. package/dist/tool-loader.js.map +1 -0
  42. package/dist/tool-registry.d.ts +47 -0
  43. package/dist/tool-registry.d.ts.map +1 -0
  44. package/dist/tool-registry.js +58 -0
  45. package/dist/tool-registry.js.map +1 -0
  46. package/dist/tools/getChat.d.ts +28 -0
  47. package/dist/tools/getChat.d.ts.map +1 -0
  48. package/dist/tools/getChat.js +69 -0
  49. package/dist/tools/getChat.js.map +1 -0
  50. package/dist/tools/getChatMembers.d.ts +34 -0
  51. package/dist/tools/getChatMembers.d.ts.map +1 -0
  52. package/dist/tools/getChatMembers.js +150 -0
  53. package/dist/tools/getChatMembers.js.map +1 -0
  54. package/dist/tools/getContacts.d.ts +28 -0
  55. package/dist/tools/getContacts.d.ts.map +1 -0
  56. package/dist/tools/getContacts.js +73 -0
  57. package/dist/tools/getContacts.js.map +1 -0
  58. package/dist/tools/getFile.d.ts +21 -0
  59. package/dist/tools/getFile.d.ts.map +1 -0
  60. package/dist/tools/getFile.js +33 -0
  61. package/dist/tools/getFile.js.map +1 -0
  62. package/dist/tools/getGroup.d.ts +27 -0
  63. package/dist/tools/getGroup.d.ts.map +1 -0
  64. package/dist/tools/getGroup.js +100 -0
  65. package/dist/tools/getGroup.js.map +1 -0
  66. package/dist/tools/getMe.d.ts +17 -0
  67. package/dist/tools/getMe.d.ts.map +1 -0
  68. package/dist/tools/getMe.js +20 -0
  69. package/dist/tools/getMe.js.map +1 -0
  70. package/dist/tools/getMessageContext.d.ts +21 -0
  71. package/dist/tools/getMessageContext.d.ts.map +1 -0
  72. package/dist/tools/getMessageContext.js +164 -0
  73. package/dist/tools/getMessageContext.js.map +1 -0
  74. package/dist/tools/getMessages.d.ts +38 -0
  75. package/dist/tools/getMessages.d.ts.map +1 -0
  76. package/dist/tools/getMessages.js +123 -0
  77. package/dist/tools/getMessages.js.map +1 -0
  78. package/dist/tools/getUser.d.ts +22 -0
  79. package/dist/tools/getUser.d.ts.map +1 -0
  80. package/dist/tools/getUser.js +38 -0
  81. package/dist/tools/getUser.js.map +1 -0
  82. package/dist/tools/index.d.ts +11 -0
  83. package/dist/tools/index.d.ts.map +1 -0
  84. package/dist/tools/index.js +12 -0
  85. package/dist/tools/index.js.map +1 -0
  86. package/dist/tools/sendMessage.d.ts +39 -0
  87. package/dist/tools/sendMessage.d.ts.map +1 -0
  88. package/dist/tools/sendMessage.js +116 -0
  89. package/dist/tools/sendMessage.js.map +1 -0
  90. package/dist/transformers.d.ts +133 -0
  91. package/dist/transformers.d.ts.map +1 -0
  92. package/dist/transformers.js +335 -0
  93. package/dist/transformers.js.map +1 -0
  94. package/dist/types.d.ts +55 -0
  95. package/dist/types.d.ts.map +1 -0
  96. package/dist/types.js +2 -0
  97. package/dist/types.js.map +1 -0
  98. package/package.json +45 -0
  99. package/tools.json +252 -0
@@ -0,0 +1,12 @@
1
+ import type { ToolResponse } from "./types.js";
2
+ export declare const DEBUG_MODE: boolean;
3
+ /**
4
+ * Wraps a tool execution with debug metadata when DEBUG mode is enabled.
5
+ *
6
+ * @param toolName - Name of the tool being executed
7
+ * @param toolInput - Input arguments passed to the tool
8
+ * @param executeToolFn - Async function that executes the tool and returns data
9
+ * @returns ToolResponse with data and optional debug metadata
10
+ */
11
+ export declare function wrapWithDebug<T>(toolName: string, toolInput: unknown, executeToolFn: () => Promise<T>): Promise<ToolResponse<T>>;
12
+ //# sourceMappingURL=debug-middleware.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-middleware.d.ts","sourceRoot":"","sources":["../src/debug-middleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,YAAY,CAAC;AAG9D,eAAO,MAAM,UAAU,SAA+B,CAAC;AAEvD;;;;;;;GAOG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,aAAa,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CA0B1B"}
@@ -0,0 +1,36 @@
1
+ // Check if DEBUG mode is enabled via environment variable
2
+ export const DEBUG_MODE = process.env.DEBUG === "true";
3
+ /**
4
+ * Wraps a tool execution with debug metadata when DEBUG mode is enabled.
5
+ *
6
+ * @param toolName - Name of the tool being executed
7
+ * @param toolInput - Input arguments passed to the tool
8
+ * @param executeToolFn - Async function that executes the tool and returns data
9
+ * @returns ToolResponse with data and optional debug metadata
10
+ */
11
+ export async function wrapWithDebug(toolName, toolInput, executeToolFn) {
12
+ const startTime = performance.now();
13
+ try {
14
+ const data = await executeToolFn();
15
+ const endTime = performance.now();
16
+ const toolCallTime = endTime - startTime;
17
+ if (DEBUG_MODE) {
18
+ return {
19
+ data,
20
+ debug: {
21
+ toolName,
22
+ toolInput,
23
+ toolCallTime,
24
+ timestamp: new Date().toISOString(),
25
+ },
26
+ };
27
+ }
28
+ // In non-debug mode, return just the data wrapped
29
+ return { data };
30
+ }
31
+ catch (error) {
32
+ // Re-throw the error to be handled by caller
33
+ throw error;
34
+ }
35
+ }
36
+ //# sourceMappingURL=debug-middleware.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"debug-middleware.js","sourceRoot":"","sources":["../src/debug-middleware.ts"],"names":[],"mappings":"AAEA,0DAA0D;AAC1D,MAAM,CAAC,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC;AAEvD;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,SAAkB,EAClB,aAA+B;IAE/B,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAEpC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;QAClC,MAAM,YAAY,GAAG,OAAO,GAAG,SAAS,CAAC;QAEzC,IAAI,UAAU,EAAE,CAAC;YACf,OAAO;gBACL,IAAI;gBACJ,KAAK,EAAE;oBACL,QAAQ;oBACR,SAAS;oBACT,YAAY;oBACZ,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;iBACpC;aACF,CAAC;QACJ,CAAC;QAED,kDAAkD;QAClD,OAAO,EAAE,IAAI,EAAE,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,6CAA6C;QAC7C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Decode the binlog from base64 format
3
+ *
4
+ * BlueNexus stores the TDLib binlog as raw base64 in providerData.binlog.
5
+ * This function simply decodes the base64 string to get the raw binlog bytes.
6
+ *
7
+ * @param base64Binlog - The base64-encoded binlog from the request body
8
+ * @returns Decoded binlog as Buffer
9
+ */
10
+ export declare function decodeBinlog(base64Binlog: string): Buffer;
11
+ //# sourceMappingURL=encryption.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.d.ts","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAmBzD"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Decode the binlog from base64 format
3
+ *
4
+ * BlueNexus stores the TDLib binlog as raw base64 in providerData.binlog.
5
+ * This function simply decodes the base64 string to get the raw binlog bytes.
6
+ *
7
+ * @param base64Binlog - The base64-encoded binlog from the request body
8
+ * @returns Decoded binlog as Buffer
9
+ */
10
+ export function decodeBinlog(base64Binlog) {
11
+ if (!base64Binlog || base64Binlog.trim() === "") {
12
+ throw new Error("Invalid binlog: empty or missing");
13
+ }
14
+ // Validate base64 format
15
+ const base64Regex = /^[A-Za-z0-9+/]*={0,2}$/;
16
+ if (!base64Regex.test(base64Binlog)) {
17
+ throw new Error("Invalid binlog: not a valid base64 string");
18
+ }
19
+ // Decode the base64 string to get raw binlog bytes
20
+ const buffer = Buffer.from(base64Binlog, "base64");
21
+ if (buffer.length === 0) {
22
+ throw new Error("Invalid binlog: decoded to empty buffer");
23
+ }
24
+ return buffer;
25
+ }
26
+ //# sourceMappingURL=encryption.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encryption.js","sourceRoot":"","sources":["../src/encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,YAAoB;IAC/C,IAAI,CAAC,YAAY,IAAI,YAAY,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAC;IACtD,CAAC;IAED,yBAAyB;IACzB,MAAM,WAAW,GAAG,wBAAwB,CAAC;IAC7C,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,mDAAmD;IACnD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;IAEnD,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,27 @@
1
+ import type { Request } from "express";
2
+ import type { Client } from "tdl";
3
+ /**
4
+ * Get a TDLib client for the current request
5
+ *
6
+ * This function:
7
+ * 1. Extracts credentials and config from request headers
8
+ * 2. Generates a session ID from the access token
9
+ * 3. Decodes the base64-encoded binlog
10
+ * 4. Creates a TDLib client with the restored session
11
+ *
12
+ * @param req - Express request object
13
+ * @returns Object containing the TDLib client and session ID
14
+ */
15
+ export declare function getClientForRequest(req: Request): Promise<{
16
+ client: Client;
17
+ sessionId: string;
18
+ }>;
19
+ /**
20
+ * Execute a tool with automatic client cleanup
21
+ *
22
+ * @param req - Express request object
23
+ * @param toolFn - Function to execute with the client
24
+ * @returns Result of the tool function
25
+ */
26
+ export declare function withClient<T>(req: Request, toolFn: (client: Client) => Promise<T>): Promise<T>;
27
+ //# sourceMappingURL=helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAIvC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAwElC;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC;IAC/D,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAkBD;AAED;;;;;;GAMG;AACH,wBAAsB,UAAU,CAAC,CAAC,EAChC,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,GACrC,OAAO,CAAC,CAAC,CAAC,CA0BZ"}
@@ -0,0 +1,103 @@
1
+ import crypto from "crypto";
2
+ import { decodeBinlog } from "./encryption.js";
3
+ import { createTelegramClient, cleanupSession } from "./telegram-client.js";
4
+ import { createLogger } from "./logger.js";
5
+ const logger = createLogger("Helpers");
6
+ /**
7
+ * Extract Telegram credentials and config from request
8
+ *
9
+ * Expected headers:
10
+ * - Authorization: Bearer <accessToken>
11
+ * - X-Telegram-Api-Id: <API ID> (or fallback to env TELEGRAM_API_ID)
12
+ * - X-Telegram-Api-Hash: <API Hash> (or fallback to env TELEGRAM_API_HASH)
13
+ *
14
+ * The binlog is passed in the request body as _telegramBinlog but
15
+ * extracted and stored on req._telegramBinlog by index.ts before SDK processing
16
+ * (the MCP SDK's Zod validation rejects unrecognized keys in the body).
17
+ * The binlog is base64-encoded (NOT encrypted).
18
+ */
19
+ function extractCredentials(req) {
20
+ const authHeader = req.headers.authorization;
21
+ if (!authHeader?.toLowerCase().startsWith("bearer ")) {
22
+ throw new Error("Missing or invalid Authorization header. Expected format: Bearer <token>");
23
+ }
24
+ const accessToken = authHeader.substring(7).trim();
25
+ // Get binlog from request object (extracted from body by index.ts)
26
+ const binlog = req._telegramBinlog;
27
+ if (!binlog) {
28
+ throw new Error("Missing _telegramBinlog. This field must be sent in the request body and contains the base64-encoded TDLib session binlog.");
29
+ }
30
+ // Get API credentials from headers first, then fallback to env vars
31
+ const apiIdHeader = req.headers["x-telegram-api-id"];
32
+ const apiHashHeader = req.headers["x-telegram-api-hash"];
33
+ const apiId = parseInt(apiIdHeader || process.env.TELEGRAM_API_ID || "0", 10);
34
+ const apiHash = apiHashHeader || process.env.TELEGRAM_API_HASH || "";
35
+ // Validate required config
36
+ if (!apiId || apiId === 0) {
37
+ throw new Error("Telegram API ID not provided. Set X-Telegram-Api-Id header or TELEGRAM_API_ID environment variable.");
38
+ }
39
+ if (!apiHash) {
40
+ throw new Error("Telegram API Hash not provided. Set X-Telegram-Api-Hash header or TELEGRAM_API_HASH environment variable.");
41
+ }
42
+ return { apiId, apiHash, accessToken, binlog };
43
+ }
44
+ /**
45
+ * Get a TDLib client for the current request
46
+ *
47
+ * This function:
48
+ * 1. Extracts credentials and config from request headers
49
+ * 2. Generates a session ID from the access token
50
+ * 3. Decodes the base64-encoded binlog
51
+ * 4. Creates a TDLib client with the restored session
52
+ *
53
+ * @param req - Express request object
54
+ * @returns Object containing the TDLib client and session ID
55
+ */
56
+ export async function getClientForRequest(req) {
57
+ const { apiId, apiHash, accessToken, binlog: base64Binlog } = extractCredentials(req);
58
+ // Generate session ID from access token (for temp directory isolation)
59
+ const sessionId = crypto
60
+ .createHash("sha256")
61
+ .update(accessToken)
62
+ .digest("hex")
63
+ .substring(0, 16);
64
+ // Decode base64-encoded binlog
65
+ const binlog = decodeBinlog(base64Binlog);
66
+ // Create TDLib client with restored session
67
+ const client = await createTelegramClient(sessionId, binlog, apiId, apiHash);
68
+ return { client, sessionId };
69
+ }
70
+ /**
71
+ * Execute a tool with automatic client cleanup
72
+ *
73
+ * @param req - Express request object
74
+ * @param toolFn - Function to execute with the client
75
+ * @returns Result of the tool function
76
+ */
77
+ export async function withClient(req, toolFn) {
78
+ const { client, sessionId } = await getClientForRequest(req);
79
+ try {
80
+ return await toolFn(client);
81
+ }
82
+ finally {
83
+ // Ensure client is fully closed before cleanup
84
+ let clientClosed = false;
85
+ try {
86
+ await client.close();
87
+ clientClosed = true;
88
+ }
89
+ catch (closeError) {
90
+ logger.warn("Failed to close TDLib client", {
91
+ sessionId,
92
+ error: closeError instanceof Error ? closeError : new Error(String(closeError)),
93
+ });
94
+ }
95
+ // Only cleanup session files after client is closed
96
+ // Add a small delay to ensure TDLib releases file handles
97
+ if (clientClosed) {
98
+ await new Promise((resolve) => setTimeout(resolve, 100));
99
+ }
100
+ await cleanupSession(sessionId);
101
+ }
102
+ }
103
+ //# sourceMappingURL=helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"helpers.js","sourceRoot":"","sources":["../src/helpers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
package/dist/index.js ADDED
@@ -0,0 +1,176 @@
1
+ #!/usr/bin/env node
2
+ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
3
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
4
+ import { CallToolRequestSchema, ListToolsRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
5
+ import express from "express";
6
+ import { z } from "zod";
7
+ // Import schemas
8
+ import { GetMeSchema, GetChatSchema, GetMessagesSchema, SendMessageSchema, GetUserSchema, GetContactsSchema, GetFileSchema, GetGroupSchema, GetChatMembersSchema, GetMessageContextSchema, } from "./schemas.js";
9
+ // Import tool handlers
10
+ import { getMe, getChat, getMessages, sendMessage, getUser, getContacts, getFile, getGroup, getChatMembers, getMessageContext, } from "./tools/index.js";
11
+ // Import tool loader
12
+ import { loadToolDefinitions } from "./tool-loader.js";
13
+ // Import tool registry
14
+ import { ToolRegistry } from "./tool-registry.js";
15
+ // Import debug mode flag
16
+ import { DEBUG_MODE } from "./debug-middleware.js";
17
+ // Import logger
18
+ import { createLogger } from "./logger.js";
19
+ // Import request context
20
+ import { runWithRequest, requireCurrentRequest, } from "./request-context.js";
21
+ const logger = createLogger("MCPServer");
22
+ // Create tool registry and register all tools
23
+ const toolRegistry = new ToolRegistry();
24
+ // Register consolidated tools (10 tools total)
25
+ toolRegistry.register("getMe", GetMeSchema, getMe);
26
+ toolRegistry.register("getChat", GetChatSchema, getChat);
27
+ toolRegistry.register("getMessages", GetMessagesSchema, getMessages);
28
+ toolRegistry.register("sendMessage", SendMessageSchema, sendMessage);
29
+ toolRegistry.register("getUser", GetUserSchema, getUser);
30
+ toolRegistry.register("getContacts", GetContactsSchema, getContacts);
31
+ toolRegistry.register("getFile", GetFileSchema, getFile);
32
+ toolRegistry.register("getGroup", GetGroupSchema, getGroup);
33
+ toolRegistry.register("getChatMembers", GetChatMembersSchema, getChatMembers);
34
+ toolRegistry.register("getMessageContext", GetMessageContextSchema, getMessageContext);
35
+ // Create MCP server
36
+ const server = new Server({
37
+ name: "telegram-mcp-server",
38
+ version: "0.0.1",
39
+ }, {
40
+ capabilities: {
41
+ tools: {},
42
+ },
43
+ });
44
+ // Register tool handlers
45
+ server.setRequestHandler(ListToolsRequestSchema, async () => {
46
+ // Load tool definitions from JSON (reloads on each request in dev mode)
47
+ const toolDefinitions = loadToolDefinitions();
48
+ return {
49
+ tools: toolDefinitions,
50
+ };
51
+ });
52
+ server.setRequestHandler(CallToolRequestSchema, async (request) => {
53
+ if (DEBUG_MODE) {
54
+ logger.debug("CallToolRequestSchema handler called", {
55
+ toolName: request.params.name,
56
+ arguments: request.params.arguments,
57
+ });
58
+ }
59
+ // Get current request from AsyncLocalStorage context
60
+ const currentRequest = requireCurrentRequest();
61
+ try {
62
+ // Execute tool via registry (includes automatic validation and debug wrapping)
63
+ const result = await toolRegistry.execute(request.params.name, request.params.arguments, currentRequest);
64
+ if (DEBUG_MODE) {
65
+ logger.debug("Tool execution completed", { toolName: request.params.name });
66
+ }
67
+ // Return formatted response with data and optional debug info
68
+ // Debug info is included in the response when DEBUG mode is enabled
69
+ return {
70
+ content: [
71
+ {
72
+ type: "text",
73
+ text: JSON.stringify(result, null, 2),
74
+ },
75
+ ],
76
+ };
77
+ }
78
+ catch (error) {
79
+ logger.error("Tool execution error", {
80
+ error: error instanceof Error ? error : new Error(String(error)),
81
+ toolName: request.params.name,
82
+ });
83
+ if (error instanceof z.ZodError) {
84
+ throw new Error(`Invalid arguments: ${error.message}`, { cause: error });
85
+ }
86
+ throw error;
87
+ }
88
+ });
89
+ // Create Express app with stateless HTTP transport
90
+ const app = express();
91
+ app.use(express.json());
92
+ // Create stateless transport (no session management)
93
+ const transport = new StreamableHTTPServerTransport({
94
+ sessionIdGenerator: undefined, // Stateless mode
95
+ enableJsonResponse: true,
96
+ });
97
+ // Connect server to transport
98
+ await server.connect(transport);
99
+ // Handle MCP requests
100
+ app.post("/mcp", async (req, res) => {
101
+ try {
102
+ // Log incoming request in DEBUG mode
103
+ if (DEBUG_MODE) {
104
+ logger.debug("Incoming MCP request", {
105
+ method: req.body?.method,
106
+ params: req.body?.params,
107
+ });
108
+ }
109
+ // Extract _telegramBinlog from body before passing to SDK
110
+ // The MCP SDK's Zod validation rejects unrecognized keys, so we strip it here
111
+ // and store it on the request for tool handlers to access
112
+ const { _telegramBinlog, ...cleanBody } = req.body;
113
+ // Store binlog on request object for helpers.ts to access
114
+ const telegramReq = req;
115
+ telegramReq._telegramBinlog = _telegramBinlog;
116
+ if (DEBUG_MODE) {
117
+ logger.debug("Binlog status", {
118
+ hasBinlog: !!_telegramBinlog,
119
+ binlogLength: _telegramBinlog?.length,
120
+ });
121
+ }
122
+ // Run the request handler within AsyncLocalStorage context
123
+ // This ensures proper request isolation for concurrent requests
124
+ await runWithRequest(telegramReq, async () => {
125
+ try {
126
+ await transport.handleRequest(req, res, cleanBody);
127
+ if (DEBUG_MODE) {
128
+ logger.debug("Request handled successfully");
129
+ }
130
+ }
131
+ catch (transportError) {
132
+ logger.error("Transport error", {
133
+ error: transportError instanceof Error ? transportError : new Error(String(transportError)),
134
+ });
135
+ throw transportError;
136
+ }
137
+ });
138
+ }
139
+ catch (error) {
140
+ logger.error("Error handling MCP request", {
141
+ error: error instanceof Error ? error : new Error(String(error)),
142
+ });
143
+ res.status(500).json({
144
+ error: "Internal server error",
145
+ message: error instanceof Error ? error.message : "Unknown error",
146
+ });
147
+ }
148
+ });
149
+ // Health check endpoint
150
+ app.get("/health", (_req, res) => {
151
+ res.json({
152
+ status: "healthy",
153
+ server: "telegram-mcp-server",
154
+ version: "0.0.1",
155
+ stateless: true,
156
+ debug: DEBUG_MODE,
157
+ registeredTools: toolRegistry.getToolNames(),
158
+ });
159
+ });
160
+ // Start server
161
+ const PORT = process.env.PORT || 30001;
162
+ app.listen(PORT, () => {
163
+ logger.info("Server started", {
164
+ port: PORT,
165
+ mcpEndpoint: `http://localhost:${PORT}/mcp`,
166
+ healthEndpoint: `http://localhost:${PORT}/health`,
167
+ mode: "Stateless",
168
+ debug: DEBUG_MODE,
169
+ });
170
+ if (DEBUG_MODE) {
171
+ logger.debug("Registered tools", {
172
+ tools: toolRegistry.getToolNames().join(", "),
173
+ });
174
+ }
175
+ });
176
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Logger utility with PII sanitization for safe logging
3
+ */
4
+ /**
5
+ * Context object for sanitized logging
6
+ */
7
+ export interface LogContext {
8
+ sessionId?: string;
9
+ userId?: string | number;
10
+ phone?: string;
11
+ token?: string;
12
+ [key: string]: unknown;
13
+ }
14
+ /**
15
+ * Logger class with PII sanitization
16
+ */
17
+ export declare class Logger {
18
+ private readonly component;
19
+ constructor(component: string);
20
+ info(message: string, context?: LogContext): void;
21
+ warn(message: string, context?: LogContext): void;
22
+ error(message: string, context?: LogContext): void;
23
+ debug(message: string, context?: LogContext): void;
24
+ }
25
+ /**
26
+ * Create a logger for a specific component
27
+ */
28
+ export declare function createLogger(component: string): Logger;
29
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwCH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACxB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AA4DD;;GAEG;AACH,qBAAa,MAAM;IACL,OAAO,CAAC,QAAQ,CAAC,SAAS;gBAAT,SAAS,EAAE,MAAM;IAE9C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIjD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;IAIlD,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,UAAU,GAAG,IAAI;CAGnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEtD"}
package/dist/logger.js ADDED
@@ -0,0 +1,114 @@
1
+ /**
2
+ * Logger utility with PII sanitization for safe logging
3
+ */
4
+ /**
5
+ * Sanitize a session ID by showing only the first 4 characters
6
+ */
7
+ function sanitizeSessionId(sessionId) {
8
+ if (sessionId.length <= 4) {
9
+ return "****";
10
+ }
11
+ return `${sessionId.substring(0, 4)}****`;
12
+ }
13
+ /**
14
+ * Sanitize a phone number by masking all but the last 4 digits
15
+ */
16
+ function sanitizePhoneNumber(phone) {
17
+ const digitsOnly = phone.replace(/\D/g, "");
18
+ if (digitsOnly.length <= 4) {
19
+ return "****";
20
+ }
21
+ return `****${digitsOnly.slice(-4)}`;
22
+ }
23
+ /**
24
+ * Sanitize an access token by showing only first 8 characters
25
+ */
26
+ function sanitizeToken(token) {
27
+ if (token.length <= 8) {
28
+ return "****";
29
+ }
30
+ return `${token.substring(0, 8)}****`;
31
+ }
32
+ /**
33
+ * Sanitize user ID by keeping it (IDs are not PII on their own, but can be partially masked if needed)
34
+ */
35
+ function sanitizeUserId(userId) {
36
+ return String(userId);
37
+ }
38
+ /**
39
+ * Sanitize a context object for safe logging
40
+ */
41
+ function sanitizeContext(context) {
42
+ const sanitized = {};
43
+ for (const [key, value] of Object.entries(context)) {
44
+ if (value === undefined || value === null) {
45
+ continue;
46
+ }
47
+ // Apply specific sanitization based on key name
48
+ if (key === "sessionId" && typeof value === "string") {
49
+ sanitized[key] = sanitizeSessionId(value);
50
+ }
51
+ else if (key === "phone" && typeof value === "string") {
52
+ sanitized[key] = sanitizePhoneNumber(value);
53
+ }
54
+ else if ((key === "token" || key === "accessToken" || key === "refreshToken") &&
55
+ typeof value === "string") {
56
+ sanitized[key] = sanitizeToken(value);
57
+ }
58
+ else if (key === "userId") {
59
+ sanitized[key] = sanitizeUserId(value);
60
+ }
61
+ else if (key === "error" && value instanceof Error) {
62
+ // Preserve error objects properly
63
+ sanitized[key] = {
64
+ message: value.message,
65
+ name: value.name,
66
+ stack: value.stack,
67
+ };
68
+ }
69
+ else {
70
+ sanitized[key] = value;
71
+ }
72
+ }
73
+ return sanitized;
74
+ }
75
+ /**
76
+ * Format a log message with optional context
77
+ */
78
+ function formatMessage(level, component, message, context) {
79
+ const timestamp = new Date().toISOString();
80
+ const prefix = `[${timestamp}] [${level}] [${component}]`;
81
+ if (context && Object.keys(context).length > 0) {
82
+ const sanitized = sanitizeContext(context);
83
+ return `${prefix} ${message} ${JSON.stringify(sanitized)}`;
84
+ }
85
+ return `${prefix} ${message}`;
86
+ }
87
+ /**
88
+ * Logger class with PII sanitization
89
+ */
90
+ export class Logger {
91
+ component;
92
+ constructor(component) {
93
+ this.component = component;
94
+ }
95
+ info(message, context) {
96
+ console.log(formatMessage("INFO", this.component, message, context));
97
+ }
98
+ warn(message, context) {
99
+ console.warn(formatMessage("WARN", this.component, message, context));
100
+ }
101
+ error(message, context) {
102
+ console.error(formatMessage("ERROR", this.component, message, context));
103
+ }
104
+ debug(message, context) {
105
+ console.debug(formatMessage("DEBUG", this.component, message, context));
106
+ }
107
+ }
108
+ /**
109
+ * Create a logger for a specific component
110
+ */
111
+ export function createLogger(component) {
112
+ return new Logger(component);
113
+ }
114
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { Request } from "express";
2
+ /**
3
+ * Extended Express Request with Telegram binlog (session data)
4
+ */
5
+ export type TelegramRequest = Request & {
6
+ _telegramBinlog?: string;
7
+ };
8
+ /**
9
+ * Run a callback with request context
10
+ * All async operations within the callback will have access to the request
11
+ *
12
+ * @param req - Express request object
13
+ * @param callback - Async callback to run with request context
14
+ * @returns Result of the callback
15
+ */
16
+ export declare function runWithRequest<T>(req: TelegramRequest, callback: () => Promise<T>): Promise<T>;
17
+ /**
18
+ * Get the current request from context, throwing if not available
19
+ *
20
+ * @returns Current request
21
+ * @throws Error if not in request context
22
+ */
23
+ export declare function requireCurrentRequest(): TelegramRequest;
24
+ //# sourceMappingURL=request-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"request-context.d.ts","sourceRoot":"","sources":["../src/request-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAEvC;;GAEG;AACH,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AASrE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,GAAG,EAAE,eAAe,EACpB,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACzB,OAAO,CAAC,CAAC,CAAC,CAEZ;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,IAAI,eAAe,CAQvD"}