├── .gitignore ├── .npmignore ├── LIBRARY.md ├── LICENSE ├── README.md ├── client.js ├── mcp-server.js ├── package-lock.json ├── package.json └── telegram-client.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # TypeScript cache 46 | *.tsbuildinfo 47 | 48 | # Optional npm cache directory 49 | .npm 50 | 51 | # Optional eslint cache 52 | .eslintcache 53 | 54 | # Optional stylelint cache 55 | .stylelintcache 56 | 57 | # Microbundle cache 58 | .rpt2_cache/ 59 | .rts2_cache_cjs/ 60 | .rts2_cache_es/ 61 | .rts2_cache_umd/ 62 | 63 | # Optional REPL history 64 | .node_repl_history 65 | 66 | # Output of 'npm pack' 67 | *.tgz 68 | 69 | # Yarn Integrity file 70 | .yarn-integrity 71 | 72 | # dotenv environment variable files 73 | .env 74 | .env.development.local 75 | .env.test.local 76 | .env.production.local 77 | .env.local 78 | 79 | # parcel-bundler cache (https://parceljs.org/) 80 | .cache 81 | .parcel-cache 82 | 83 | # Next.js build output 84 | .next 85 | out 86 | 87 | # Nuxt.js build / generate output 88 | .nuxt 89 | dist 90 | 91 | # Gatsby files 92 | .cache/ 93 | # Comment in the public line in if your project uses Gatsby and not Next.js 94 | # https://nextjs.org/blog/next-9-1#public-directory-support 95 | # public 96 | 97 | # vuepress build output 98 | .vuepress/dist 99 | 100 | # vuepress v2.x temp and cache directory 101 | .temp 102 | .cache 103 | 104 | # Docusaurus cache and generated files 105 | .docusaurus 106 | 107 | # Serverless directories 108 | .serverless/ 109 | 110 | # FuseBox cache 111 | .fusebox/ 112 | 113 | # DynamoDB Local files 114 | .dynamodb/ 115 | 116 | # TernJS port file 117 | .tern-port 118 | 119 | # Stores VSCode versions used for testing VSCode extensions 120 | .vscode-test 121 | 122 | # yarn v2 123 | .yarn/cache 124 | .yarn/unplugged 125 | .yarn/build-state.yml 126 | .yarn/install-state.gz 127 | .pnp.* 128 | 129 | # Custom ignores 130 | data/ 131 | .private -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Development and environment files 2 | .git 3 | .gitignore 4 | .env* 5 | node_modules/ 6 | .vscode/ 7 | .idea/ 8 | 9 | # Data files (potentially containing sensitive information) 10 | data/ 11 | *.log 12 | 13 | # Tests 14 | test/ 15 | tests/ 16 | __tests__/ 17 | 18 | # CI/CD 19 | .github/ 20 | .gitlab-ci.yml 21 | 22 | # Documentation that shouldn't be published 23 | docs/ 24 | examples/ 25 | contributing.md 26 | 27 | # Source maps and build artifacts 28 | *.map 29 | .nyc_output 30 | coverage/ -------------------------------------------------------------------------------- /LIBRARY.md: -------------------------------------------------------------------------------- 1 | # Telegram Client Library 2 | 3 | This library (`telegram-client.js`) enables programmatic interaction with Telegram via the user client API (not bot API). 4 | 5 | ## Features 6 | 7 | - Authentication with Telegram (including 2FA support) 8 | - Session management (automatic reuse of existing sessions) 9 | - Retrieving chats/dialogs (with caching) 10 | - Fetching messages from specific chats (using cached IDs) 11 | - Filtering messages by pattern (e.g., regex) 12 | 13 | ## Usage 14 | 15 | ```javascript 16 | // Example using the client library (see client.js for a more complete example) 17 | import TelegramClient from "./telegram-client.js"; 18 | import dotenv from "dotenv"; 19 | 20 | dotenv.config(); 21 | 22 | async function main() { 23 | // Create a new client instance 24 | const client = new TelegramClient( 25 | process.env.TELEGRAM_API_ID, 26 | process.env.TELEGRAM_API_HASH, 27 | process.env.TELEGRAM_PHONE_NUMBER 28 | // Optional: specify session path, default is './data/session.json' 29 | ); 30 | 31 | // Login to Telegram (will prompt for code/password if needed) 32 | await client.login(); 33 | 34 | // Load dialog cache (optional, but recommended for performance) 35 | // Or use getAllDialogs() to fetch and populate the cache 36 | await client.loadDialogCache(); // Default path: './data/dialog_cache.json' 37 | if (client.dialogCache.size === 0) { 38 | console.log("Cache empty, fetching all dialogs to build cache..."); 39 | await client.getAllDialogs(); // Fetches all dialogs and populates cache 40 | await client.saveDialogCache(); // Save cache for next time 41 | } 42 | 43 | // Get dialogs from the cache 44 | const dialogs = Array.from(client.dialogCache.values()); 45 | 46 | // Print all cached chats 47 | dialogs.forEach((chat) => { 48 | if (chat.title) { 49 | console.log(`Chat: ${chat.title} (ID: ${chat.id})`); 50 | } 51 | }); 52 | 53 | // Example: Get messages (replace 'your_channel_id' with an actual ID from the cache) 54 | // const messages = await client.getMessagesByChannelId('your_channel_id', 50); 55 | // console.log(messages); 56 | } 57 | 58 | main().catch(console.error); 59 | ``` 60 | 61 | Run the standalone client example: 62 | 63 | ```bash 64 | node client.js 65 | ``` 66 | 67 | ## API Reference 68 | 69 | ### TelegramClient 70 | 71 | #### Constructor 72 | 73 | ```javascript 74 | const client = new TelegramClient(apiId, apiHash, phoneNumber, sessionPath); 75 | ``` 76 | 77 | - `apiId`: Your Telegram API ID 78 | - `apiHash`: Your Telegram API Hash 79 | - `phoneNumber`: Your phone number in international format 80 | - `sessionPath`: (Optional) Path to save the session file (default: './data/session.json') 81 | 82 | #### Methods 83 | 84 | - `login()`: Authenticates with Telegram (handles new logins, 2FA, and session reuse). 85 | - `hasSession()`: Checks if a valid session file exists. 86 | - `getDialogs(limit, offset)`: Gets a batch of dialogs (chats) directly from Telegram API. 87 | - `getAllDialogs(batchSize)`: Fetches all dialogs progressively, populating the internal cache (`dialogCache`). 88 | - `_updateDialogCache(chats)`: Internal method to update the cache. 89 | - `getPeerInputById(id)`: Gets the necessary `InputPeer` object from the cache for API calls. 90 | - `getChatMessages(chatObject, limit)`: Gets messages from a specific chat _object_ (less commonly used now). 91 | - `getMessagesByChannelId(channelId, limit)`: Gets messages from a specific chat/channel using its ID (uses cached peer info). 92 | - `filterMessagesByPattern(messages, pattern)`: Filters an array of message _strings_ by a regex pattern. 93 | - `saveDialogCache(cachePath)`: Saves the internal `dialogCache` Map to a JSON file (default: `./data/dialog_cache.json`). 94 | - `loadDialogCache(cachePath)`: Loads the `dialogCache` Map from a JSON file. 95 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Konstantin Fastov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Telegram MCP Server 2 | 3 | An MCP server allowing AI assistants (like Claude) to interact with your Telegram account using the user client API (not the bot API). Built with `@mtproto/core` and the **FastMCP** framework. 4 | 5 | ## Features 6 | 7 | ### Tools 8 | 9 | - `listChannels` 10 | 11 | - Lists available Telegram channels/chats accessible by the account, based on the server's cache. 12 | - Parameters: 13 | - `limit` (number, optional): Maximum number of channels to return (default: 50). 14 | - Output: A list of channels/chats with their ID, title, type, and access hash (if applicable). 15 | 16 | - `searchChannels` 17 | 18 | - Searches the cached channels/chats by keywords in their names. 19 | - Parameters: 20 | - `keywords` (string): Keywords to search for in channel names. 21 | - `limit` (number, optional): Maximum number of results to return (default: 100). 22 | - Output: A list of matching channels/chats. 23 | 24 | - `getChannelMessages` 25 | - Retrieves recent messages from a specific channel/chat using its ID. 26 | - Parameters: 27 | - `channelId` (number): The numeric ID of the channel/chat (obtained from `listChannels` or `searchChannels`). 28 | - `limit` (number, optional): Maximum number of messages to return (default: 100). 29 | - `filterPattern` (string, optional): A JavaScript-compatible regular expression to filter messages by their text content. 30 | - Output: A list of messages containing ID, date, text, and sender ID. 31 | 32 | ## Prerequisites 33 | 34 | 1. **Node.js:** Version 18 or later recommended. 35 | 2. **Telegram Account:** 36 | - You need an active Telegram account. 37 | - **Two-Step Verification (2FA)** must be enabled on your account (Settings → Privacy and Security → Two-Step Verification). 38 | 3. **Telegram API Credentials:** 39 | - Obtain an `api_id` and `api_hash` by creating a new application at [https://core.telegram.org/api/obtaining_api_id](https://core.telegram.org/api/obtaining_api_id). 40 | 41 | ## Installation 42 | 43 | 1. Clone this repository: 44 | ```bash 45 | git clone https://github.com/your-username/telegram-mcp-server.git # Replace with your repo URL 46 | cd telegram-mcp-server 47 | ``` 48 | 2. Install dependencies: 49 | ```bash 50 | npm install 51 | ``` 52 | 53 | ## Configuration 54 | 55 | There are two separate configurations that need to be set up: 56 | 57 | 1. **MCP Server Configuration:** 58 | 59 | Configure the Telegram MCP server using environment variables (in a `.env` file or directly in your environment): 60 | 61 | ```dotenv 62 | TELEGRAM_API_ID=YOUR_API_ID 63 | TELEGRAM_API_HASH=YOUR_API_HASH 64 | TELEGRAM_PHONE_NUMBER=YOUR_PHONE_NUMBER_WITH_COUNTRY_CODE # e.g., +15551234567 65 | ``` 66 | 67 | Replace the placeholder values with your actual credentials. 68 | 69 | 2. **MCP Client Configuration:** 70 | 71 | Configure client software (Claude Desktop, Cursor, etc.) to connect to the MCP server by modifying their configuration files: 72 | 73 | ```json 74 | { 75 | "mcpServers": { 76 | "telegram": { 77 | "url": "http://localhost:8080/sse", 78 | "disabled": false, 79 | "timeout": 30 80 | } 81 | } 82 | } 83 | ``` 84 | 85 | For Claude Desktop, the config file is located at: 86 | 87 | - On macOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 88 | - On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 89 | 90 | **Important:** Restart your MCP client to apply the changes. 91 | 92 | ## Running the Server 93 | 94 | 1. **Initial Login (Important First Step):** 95 | The first time you run the server (or if your session expires/is invalid), it needs to authenticate with Telegram. Run it directly from your terminal: 96 | 97 | ```bash 98 | npm start 99 | ``` 100 | 101 | - The server will use the credentials from your `.env` file. 102 | - It will prompt you in the terminal to enter the login code sent to your Telegram account and your 2FA password if required. 103 | - Upon successful login, a session file (`./data/session.json`) will be created. This file allows the server to log in automatically in the future without requiring codes/passwords. 104 | - The server will also attempt to build or load a cache of your chats (`./data/dialog_cache.json`). This can take some time on the first run, especially with many chats. Subsequent starts will be faster if the cache exists. 105 | 106 | 2. **Normal Operation:** 107 | You'll need to start the server manually by running `npm start` in the project directory. 108 | 109 | Once the server is running, your MCP client (e.g., Claude Desktop) will connect to it via the URL specified in its configuration (`http://localhost:8080/sse` by default). 110 | 111 | ## Troubleshooting 112 | 113 | - **Login Prompts:** If the server keeps prompting for login codes/passwords when started by the MCP client, ensure the `data/session.json` file exists and is valid. You might need to run `npm start` manually once to refresh the session. Also, check that the file permissions allow the user running the MCP client to read/write the `data` directory. 114 | - **Cache Issues:** If channels seem outdated or missing, you can delete `./data/dialog_cache.json` and restart the server (run `npm start` manually) to force a full refresh. This might take time. 115 | - **Cannot Find Module:** Ensure you run `npm install` in the project directory. If the MCP client starts the server, make sure the working directory is set correctly or use absolute paths. 116 | - **Other Issues:** If you encounter any other problems, feel free to open an issue in [this server repo](https://github.com/kfastov/telegram-mcp-server). 117 | 118 | ## Telegram Client Library 119 | 120 | This repository also contains the underlying `telegram-client.js` library used by the MCP server. For details on using the library directly (e.g., for custom scripting), see [LIBRARY.md](LIBRARY.md). 121 | 122 | ## License 123 | 124 | This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details. 125 | -------------------------------------------------------------------------------- /client.js: -------------------------------------------------------------------------------- 1 | import dotenv from 'dotenv'; 2 | import TelegramClient from './telegram-client.js'; 3 | 4 | // Load environment variables from .env file 5 | dotenv.config(); 6 | 7 | // Example usage of the TelegramClient class 8 | async function main() { 9 | // Create a new TelegramClient instance 10 | const client = new TelegramClient( 11 | process.env.TELEGRAM_API_ID, 12 | process.env.TELEGRAM_API_HASH, 13 | process.env.TELEGRAM_PHONE_NUMBER, 14 | './data/session.json' 15 | ); 16 | 17 | // Log in to Telegram 18 | const loggedIn = await client.login(); 19 | if (!loggedIn) { 20 | console.error('Failed to log in. Exiting...'); 21 | return; 22 | } 23 | 24 | try { 25 | // Get all dialogs (chats) 26 | const dialogsResult = await client.getDialogs(100, 0); 27 | console.log(`Found ${dialogsResult.chats.length} chats`); 28 | 29 | // Example: Find a specific chat by title 30 | const findChatByTitle = (title) => { 31 | const chat = dialogsResult.chats.find(chat => 32 | chat.title && chat.title.includes(title) 33 | ); 34 | 35 | if (chat) { 36 | console.log(`Found chat "${chat.title}" (ID: ${chat.id})`); 37 | } else { 38 | console.log(`No chat found with "${title}" in the title.`); 39 | } 40 | 41 | return chat; 42 | }; 43 | 44 | // Example: Get messages from a specific chat 45 | const getMessagesFromChat = async (chatTitle) => { 46 | const chat = findChatByTitle(chatTitle); 47 | if (!chat) return []; 48 | 49 | const messages = await client.getChatMessages(chat, 100); 50 | console.log(`Retrieved ${messages.length} messages from "${chat.title}"`); 51 | return messages; 52 | }; 53 | 54 | // Example: Filter messages by a pattern (e.g., UUIDs) 55 | const filterMessagesWithUUIDs = async (chatTitle) => { 56 | const messages = await getMessagesFromChat(chatTitle); 57 | 58 | // UUID regex pattern 59 | const uuidPattern = '[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}'; 60 | const filteredMessages = client.filterMessagesByPattern(messages, uuidPattern); 61 | 62 | console.log(`Found ${filteredMessages.length} messages containing UUIDs`); 63 | return filteredMessages; 64 | }; 65 | 66 | // Example usage: Replace 'YOUR_CHAT_NAME' with the chat you want to search 67 | // const uuidMessages = await filterMessagesWithUUIDs('YOUR_CHAT_NAME'); 68 | // console.log('Messages with UUIDs:', uuidMessages); 69 | 70 | // List all chats 71 | console.log('Available chats:'); 72 | dialogsResult.chats.forEach((chat, index) => { 73 | if (chat.title) { 74 | console.log(`${index + 1}. ${chat.title} (ID: ${chat.id})`); 75 | } 76 | }); 77 | 78 | } catch (error) { 79 | console.error('Error in client application:', error); 80 | } 81 | } 82 | 83 | // Run the main function 84 | main().catch(console.error); -------------------------------------------------------------------------------- /mcp-server.js: -------------------------------------------------------------------------------- 1 | import { FastMCP } from "fastmcp"; 2 | import { z } from "zod"; // Or any validation library that supports Standard Schema 3 | import TelegramClient from './telegram-client.js'; 4 | import dotenv from 'dotenv'; 5 | 6 | // Load environment variables 7 | dotenv.config(); 8 | 9 | // Cache path for dialog data 10 | const DIALOG_CACHE_PATH = './data/dialog_cache.json'; 11 | 12 | // Initialize Telegram client 13 | const telegramClient = new TelegramClient( 14 | process.env.TELEGRAM_API_ID, 15 | process.env.TELEGRAM_API_HASH, 16 | process.env.TELEGRAM_PHONE_NUMBER, 17 | './data/session.json' 18 | ); 19 | 20 | const server = new FastMCP({ 21 | name: "My Server", 22 | version: "1.0.0", 23 | }); 24 | 25 | // Telegram tools 26 | server.addTool({ 27 | name: "listChannels", 28 | description: "Lists available Telegram channels/chats accessible by the account.", 29 | parameters: z.object({ 30 | limit: z.number().optional().describe("Maximum number of channels to return (default: 50)"), 31 | }), 32 | execute: async (args) => { 33 | await telegramClient.ensureLogin(); 34 | 35 | const limit = args.limit || 50; 36 | // Get from cache instead of making a new request 37 | const chatEntries = Array.from(telegramClient.dialogCache.entries()).slice(0, limit); 38 | const formattedChats = chatEntries.map(([id, chat]) => ({ 39 | id: id, 40 | title: chat.title || 'Unknown', 41 | type: chat.type, 42 | access_hash: chat.access_hash || 'N/A' 43 | })); 44 | 45 | return `Retrieved ${formattedChats.length} channels/chats from cache (total in cache: ${telegramClient.dialogCache.size}).\n${JSON.stringify(formattedChats, null, 2)}`; 46 | }, 47 | }); 48 | 49 | server.addTool({ 50 | name: "searchChannels", 51 | description: "Searches for channels/chats by keywords in their names.", 52 | parameters: z.object({ 53 | keywords: z.string().describe("Keywords to search for in channel names"), 54 | limit: z.number().optional().describe("Maximum number of results to return (default: 100)"), 55 | }), 56 | execute: async (args) => { 57 | await telegramClient.ensureLogin(); 58 | 59 | const keywords = args.keywords.toLowerCase(); 60 | const searchLimit = args.limit || 100; 61 | 62 | // Search from cache instead of making a new request 63 | const chatEntries = Array.from(telegramClient.dialogCache.entries()); 64 | const matchingChats = chatEntries 65 | .filter(([_, chat]) => chat.title && chat.title.toLowerCase().includes(keywords)) 66 | .slice(0, searchLimit) 67 | .map(([id, chat]) => ({ 68 | id: id, 69 | title: chat.title || 'Unknown', 70 | type: chat.type, 71 | access_hash: chat.access_hash || 'N/A' 72 | })); 73 | 74 | return `Found ${matchingChats.length} channels/chats matching "${args.keywords}" in the cache (total in cache: ${telegramClient.dialogCache.size}).\n${JSON.stringify(matchingChats, null, 2)}`; 75 | }, 76 | }); 77 | 78 | server.addTool({ 79 | name: "getChannelMessages", 80 | description: "Retrieves messages from a specific channel/chat by its ID.", 81 | parameters: z.object({ 82 | channelId: z.number().describe("The numeric ID of the channel/chat to fetch messages from"), 83 | limit: z.number().optional().describe("Maximum number of messages to return (default: 100)"), 84 | filterPattern: z.string().optional().describe("Optional regex pattern to filter messages by content"), 85 | }), 86 | execute: async (args) => { 87 | await telegramClient.ensureLogin(); 88 | 89 | const channelId = args.channelId; 90 | const limit = args.limit || 100; 91 | const filterPattern = args.filterPattern; 92 | 93 | try { 94 | // Use the new getMessagesByChannelId method which uses the cache 95 | const messages = await telegramClient.getMessagesByChannelId(channelId, limit); 96 | 97 | // Get channel details from cache 98 | const cachedChat = telegramClient.dialogCache.get(`${channelId}`); 99 | if (!cachedChat) { 100 | throw new Error(`Channel with ID ${channelId} not found in cache.`); 101 | } 102 | 103 | // Extract relevant info and handle potential missing fields 104 | let formattedMessages = messages.map(msg => ({ 105 | id: msg.id, 106 | date: msg.date ? new Date(msg.date * 1000).toISOString() : 'unknown', 107 | text: msg.message || '', 108 | from_id: msg.from_id?.user_id 109 | || msg.from_id?.channel_id 110 | || msg.peer_id?.user_id 111 | || msg.peer_id?.channel_id 112 | || msg.peer_id?.chat_id 113 | || 'unknown' 114 | })); 115 | 116 | let resultText = `Retrieved ${formattedMessages.length} messages from "${cachedChat.title}".`; 117 | 118 | if (filterPattern) { 119 | try { 120 | const regex = new RegExp(filterPattern); 121 | const originalCount = formattedMessages.length; 122 | formattedMessages = formattedMessages.filter(msg => msg.text && regex.test(msg.text)); 123 | resultText = `Retrieved ${originalCount} messages from "${cachedChat.title}", filtered down to ${formattedMessages.length} matching pattern "${filterPattern}".`; 124 | } catch (e) { 125 | resultText += ` (Failed to apply filter: Invalid regex pattern: ${e.message})`; 126 | } 127 | } 128 | 129 | return `${resultText}\n${JSON.stringify(formattedMessages, null, 2)}`; 130 | } catch (error) { 131 | // If cache-based method fails, log error and throw 132 | console.error(`Error fetching messages using cache: ${error.message}`); 133 | throw error; 134 | } 135 | }, 136 | }); 137 | 138 | // Initialize dialog cache at server startup 139 | console.log('Starting server and initializing Telegram dialog cache...'); 140 | telegramClient.initializeDialogCache(DIALOG_CACHE_PATH).then(success => { 141 | if (success) { 142 | console.log('Dialog cache initialization complete, starting server...'); 143 | server.start({ 144 | transportType: "sse", 145 | sse: {endpoint: "/sse", port: 8080}, 146 | }); 147 | } else { 148 | console.error('Failed to initialize dialog cache. Exiting...'); 149 | process.exit(1); // Exit with a non-zero code indicating failure 150 | } 151 | }); -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "telegram-mcp-server", 3 | "version": "1.0.0", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "telegram-mcp-server", 9 | "version": "1.0.0", 10 | "dependencies": { 11 | "@modelcontextprotocol/sdk": "^1.9.0", 12 | "@mtproto/core": "^6.3.0", 13 | "dotenv": "^16.5.0", 14 | "fastmcp": "^1.21.0" 15 | } 16 | }, 17 | "node_modules/@modelcontextprotocol/sdk": { 18 | "version": "1.9.0", 19 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.9.0.tgz", 20 | "integrity": "sha512-Jq2EUCQpe0iyO5FGpzVYDNFR6oR53AIrwph9yWl7uSc7IWUMsrmpmSaTGra5hQNunXpM+9oit85p924jWuHzUA==", 21 | "license": "MIT", 22 | "dependencies": { 23 | "content-type": "^1.0.5", 24 | "cors": "^2.8.5", 25 | "cross-spawn": "^7.0.3", 26 | "eventsource": "^3.0.2", 27 | "express": "^5.0.1", 28 | "express-rate-limit": "^7.5.0", 29 | "pkce-challenge": "^5.0.0", 30 | "raw-body": "^3.0.0", 31 | "zod": "^3.23.8", 32 | "zod-to-json-schema": "^3.24.1" 33 | }, 34 | "engines": { 35 | "node": ">=18" 36 | } 37 | }, 38 | "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { 39 | "version": "2.0.0", 40 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", 41 | "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", 42 | "license": "MIT", 43 | "dependencies": { 44 | "mime-types": "^3.0.0", 45 | "negotiator": "^1.0.0" 46 | }, 47 | "engines": { 48 | "node": ">= 0.6" 49 | } 50 | }, 51 | "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { 52 | "version": "2.1.0", 53 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.1.0.tgz", 54 | "integrity": "sha512-/hPxh61E+ll0Ujp24Ilm64cykicul1ypfwjVttduAiEdtnJFvLePSrIPk+HMImtNv5270wOGCb1Tns2rybMkoQ==", 55 | "license": "MIT", 56 | "dependencies": { 57 | "bytes": "^3.1.2", 58 | "content-type": "^1.0.5", 59 | "debug": "^4.4.0", 60 | "http-errors": "^2.0.0", 61 | "iconv-lite": "^0.5.2", 62 | "on-finished": "^2.4.1", 63 | "qs": "^6.14.0", 64 | "raw-body": "^3.0.0", 65 | "type-is": "^2.0.0" 66 | }, 67 | "engines": { 68 | "node": ">=18" 69 | } 70 | }, 71 | "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/debug": { 72 | "version": "4.4.0", 73 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 74 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 75 | "license": "MIT", 76 | "dependencies": { 77 | "ms": "^2.1.3" 78 | }, 79 | "engines": { 80 | "node": ">=6.0" 81 | }, 82 | "peerDependenciesMeta": { 83 | "supports-color": { 84 | "optional": true 85 | } 86 | } 87 | }, 88 | "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/ms": { 89 | "version": "2.1.3", 90 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 91 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 92 | "license": "MIT" 93 | }, 94 | "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser/node_modules/qs": { 95 | "version": "6.14.0", 96 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", 97 | "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", 98 | "license": "BSD-3-Clause", 99 | "dependencies": { 100 | "side-channel": "^1.1.0" 101 | }, 102 | "engines": { 103 | "node": ">=0.6" 104 | }, 105 | "funding": { 106 | "url": "https://github.com/sponsors/ljharb" 107 | } 108 | }, 109 | "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { 110 | "version": "1.0.0", 111 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", 112 | "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", 113 | "license": "MIT", 114 | "dependencies": { 115 | "safe-buffer": "5.2.1" 116 | }, 117 | "engines": { 118 | "node": ">= 0.6" 119 | } 120 | }, 121 | "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { 122 | "version": "1.2.2", 123 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", 124 | "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", 125 | "license": "MIT", 126 | "engines": { 127 | "node": ">=6.6.0" 128 | } 129 | }, 130 | "node_modules/@modelcontextprotocol/sdk/node_modules/debug": { 131 | "version": "4.3.6", 132 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.6.tgz", 133 | "integrity": "sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg==", 134 | "license": "MIT", 135 | "dependencies": { 136 | "ms": "2.1.2" 137 | }, 138 | "engines": { 139 | "node": ">=6.0" 140 | }, 141 | "peerDependenciesMeta": { 142 | "supports-color": { 143 | "optional": true 144 | } 145 | } 146 | }, 147 | "node_modules/@modelcontextprotocol/sdk/node_modules/express": { 148 | "version": "5.0.1", 149 | "resolved": "https://registry.npmjs.org/express/-/express-5.0.1.tgz", 150 | "integrity": "sha512-ORF7g6qGnD+YtUG9yx4DFoqCShNMmUKiXuT5oWMHiOvt/4WFbHC6yCwQMTSBMno7AqntNCAzzcnnjowRkTL9eQ==", 151 | "license": "MIT", 152 | "dependencies": { 153 | "accepts": "^2.0.0", 154 | "body-parser": "^2.0.1", 155 | "content-disposition": "^1.0.0", 156 | "content-type": "~1.0.4", 157 | "cookie": "0.7.1", 158 | "cookie-signature": "^1.2.1", 159 | "debug": "4.3.6", 160 | "depd": "2.0.0", 161 | "encodeurl": "~2.0.0", 162 | "escape-html": "~1.0.3", 163 | "etag": "~1.8.1", 164 | "finalhandler": "^2.0.0", 165 | "fresh": "2.0.0", 166 | "http-errors": "2.0.0", 167 | "merge-descriptors": "^2.0.0", 168 | "methods": "~1.1.2", 169 | "mime-types": "^3.0.0", 170 | "on-finished": "2.4.1", 171 | "once": "1.4.0", 172 | "parseurl": "~1.3.3", 173 | "proxy-addr": "~2.0.7", 174 | "qs": "6.13.0", 175 | "range-parser": "~1.2.1", 176 | "router": "^2.0.0", 177 | "safe-buffer": "5.2.1", 178 | "send": "^1.1.0", 179 | "serve-static": "^2.1.0", 180 | "setprototypeof": "1.2.0", 181 | "statuses": "2.0.1", 182 | "type-is": "^2.0.0", 183 | "utils-merge": "1.0.1", 184 | "vary": "~1.1.2" 185 | }, 186 | "engines": { 187 | "node": ">= 18" 188 | } 189 | }, 190 | "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { 191 | "version": "2.1.0", 192 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", 193 | "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", 194 | "license": "MIT", 195 | "dependencies": { 196 | "debug": "^4.4.0", 197 | "encodeurl": "^2.0.0", 198 | "escape-html": "^1.0.3", 199 | "on-finished": "^2.4.1", 200 | "parseurl": "^1.3.3", 201 | "statuses": "^2.0.1" 202 | }, 203 | "engines": { 204 | "node": ">= 0.8" 205 | } 206 | }, 207 | "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler/node_modules/debug": { 208 | "version": "4.4.0", 209 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 210 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 211 | "license": "MIT", 212 | "dependencies": { 213 | "ms": "^2.1.3" 214 | }, 215 | "engines": { 216 | "node": ">=6.0" 217 | }, 218 | "peerDependenciesMeta": { 219 | "supports-color": { 220 | "optional": true 221 | } 222 | } 223 | }, 224 | "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler/node_modules/ms": { 225 | "version": "2.1.3", 226 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 227 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 228 | "license": "MIT" 229 | }, 230 | "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { 231 | "version": "2.0.0", 232 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", 233 | "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", 234 | "license": "MIT", 235 | "engines": { 236 | "node": ">= 0.8" 237 | } 238 | }, 239 | "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { 240 | "version": "0.5.2", 241 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.2.tgz", 242 | "integrity": "sha512-kERHXvpSaB4aU3eANwidg79K8FlrN77m8G9V+0vOR3HYaRifrlwMEpT7ZBJqLSEIHnEgJTHcWK82wwLwwKwtag==", 243 | "license": "MIT", 244 | "dependencies": { 245 | "safer-buffer": ">= 2.1.2 < 3" 246 | }, 247 | "engines": { 248 | "node": ">=0.10.0" 249 | } 250 | }, 251 | "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { 252 | "version": "1.1.0", 253 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", 254 | "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", 255 | "license": "MIT", 256 | "engines": { 257 | "node": ">= 0.8" 258 | } 259 | }, 260 | "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { 261 | "version": "2.0.0", 262 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", 263 | "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", 264 | "license": "MIT", 265 | "engines": { 266 | "node": ">=18" 267 | }, 268 | "funding": { 269 | "url": "https://github.com/sponsors/sindresorhus" 270 | } 271 | }, 272 | "node_modules/@modelcontextprotocol/sdk/node_modules/mime-db": { 273 | "version": "1.53.0", 274 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.53.0.tgz", 275 | "integrity": "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg==", 276 | "license": "MIT", 277 | "engines": { 278 | "node": ">= 0.6" 279 | } 280 | }, 281 | "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { 282 | "version": "3.0.0", 283 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.0.tgz", 284 | "integrity": "sha512-XqoSHeCGjVClAmoGFG3lVFqQFRIrTVw2OH3axRqAcfaw+gHWIfnASS92AV+Rl/mk0MupgZTRHQOjxY6YVnzK5w==", 285 | "license": "MIT", 286 | "dependencies": { 287 | "mime-db": "^1.53.0" 288 | }, 289 | "engines": { 290 | "node": ">= 0.6" 291 | } 292 | }, 293 | "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { 294 | "version": "1.0.0", 295 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", 296 | "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", 297 | "license": "MIT", 298 | "engines": { 299 | "node": ">= 0.6" 300 | } 301 | }, 302 | "node_modules/@modelcontextprotocol/sdk/node_modules/send": { 303 | "version": "1.1.0", 304 | "resolved": "https://registry.npmjs.org/send/-/send-1.1.0.tgz", 305 | "integrity": "sha512-v67WcEouB5GxbTWL/4NeToqcZiAWEq90N888fczVArY8A79J0L4FD7vj5hm3eUMua5EpoQ59wa/oovY6TLvRUA==", 306 | "license": "MIT", 307 | "dependencies": { 308 | "debug": "^4.3.5", 309 | "destroy": "^1.2.0", 310 | "encodeurl": "^2.0.0", 311 | "escape-html": "^1.0.3", 312 | "etag": "^1.8.1", 313 | "fresh": "^0.5.2", 314 | "http-errors": "^2.0.0", 315 | "mime-types": "^2.1.35", 316 | "ms": "^2.1.3", 317 | "on-finished": "^2.4.1", 318 | "range-parser": "^1.2.1", 319 | "statuses": "^2.0.1" 320 | }, 321 | "engines": { 322 | "node": ">= 18" 323 | } 324 | }, 325 | "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/fresh": { 326 | "version": "0.5.2", 327 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 328 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 329 | "license": "MIT", 330 | "engines": { 331 | "node": ">= 0.6" 332 | } 333 | }, 334 | "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/mime-db": { 335 | "version": "1.52.0", 336 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 337 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 338 | "license": "MIT", 339 | "engines": { 340 | "node": ">= 0.6" 341 | } 342 | }, 343 | "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/mime-types": { 344 | "version": "2.1.35", 345 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 346 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 347 | "license": "MIT", 348 | "dependencies": { 349 | "mime-db": "1.52.0" 350 | }, 351 | "engines": { 352 | "node": ">= 0.6" 353 | } 354 | }, 355 | "node_modules/@modelcontextprotocol/sdk/node_modules/send/node_modules/ms": { 356 | "version": "2.1.3", 357 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 358 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 359 | "license": "MIT" 360 | }, 361 | "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { 362 | "version": "2.1.0", 363 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.1.0.tgz", 364 | "integrity": "sha512-A3We5UfEjG8Z7VkDv6uItWw6HY2bBSBJT1KtVESn6EOoOr2jAxNhxWCLY3jDE2WcuHXByWju74ck3ZgLwL8xmA==", 365 | "license": "MIT", 366 | "dependencies": { 367 | "encodeurl": "^2.0.0", 368 | "escape-html": "^1.0.3", 369 | "parseurl": "^1.3.3", 370 | "send": "^1.0.0" 371 | }, 372 | "engines": { 373 | "node": ">= 18" 374 | } 375 | }, 376 | "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { 377 | "version": "2.0.0", 378 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.0.tgz", 379 | "integrity": "sha512-gd0sGezQYCbWSbkZr75mln4YBidWUN60+devscpLF5mtRDUpiaTvKpBNrdaCvel1NdR2k6vclXybU5fBd2i+nw==", 380 | "license": "MIT", 381 | "dependencies": { 382 | "content-type": "^1.0.5", 383 | "media-typer": "^1.1.0", 384 | "mime-types": "^3.0.0" 385 | }, 386 | "engines": { 387 | "node": ">= 0.6" 388 | } 389 | }, 390 | "node_modules/@mtproto/core": { 391 | "version": "6.3.0", 392 | "resolved": "https://registry.npmjs.org/@mtproto/core/-/core-6.3.0.tgz", 393 | "integrity": "sha512-uhHtyty53d/KdyJ/3ZcigMyMr3jO7S7Nuzt/6CSBfikX6Wv7i2a6Ru0xtiNdluw62cAyTJTbeGLivL32eZBpZQ==", 394 | "license": "GPL-3.0", 395 | "dependencies": { 396 | "aes-js": "3.1.2", 397 | "big-integer": "1.6.51", 398 | "configstore": "5.0.1", 399 | "debug": "4.3.3", 400 | "events": "3.3.0", 401 | "leemon": "6.2.0", 402 | "lodash.debounce": "4.0.8", 403 | "pako": "2.1.0" 404 | }, 405 | "engines": { 406 | "node": ">=18" 407 | } 408 | }, 409 | "node_modules/@mtproto/core/node_modules/debug": { 410 | "version": "4.3.3", 411 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", 412 | "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", 413 | "license": "MIT", 414 | "dependencies": { 415 | "ms": "2.1.2" 416 | }, 417 | "engines": { 418 | "node": ">=6.0" 419 | }, 420 | "peerDependenciesMeta": { 421 | "supports-color": { 422 | "optional": true 423 | } 424 | } 425 | }, 426 | "node_modules/@sec-ant/readable-stream": { 427 | "version": "0.4.1", 428 | "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz", 429 | "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==", 430 | "license": "MIT" 431 | }, 432 | "node_modules/@sindresorhus/merge-streams": { 433 | "version": "4.0.0", 434 | "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz", 435 | "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==", 436 | "license": "MIT", 437 | "engines": { 438 | "node": ">=18" 439 | }, 440 | "funding": { 441 | "url": "https://github.com/sponsors/sindresorhus" 442 | } 443 | }, 444 | "node_modules/@standard-schema/spec": { 445 | "version": "1.0.0", 446 | "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", 447 | "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", 448 | "license": "MIT" 449 | }, 450 | "node_modules/@tokenizer/inflate": { 451 | "version": "0.2.7", 452 | "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz", 453 | "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==", 454 | "license": "MIT", 455 | "dependencies": { 456 | "debug": "^4.4.0", 457 | "fflate": "^0.8.2", 458 | "token-types": "^6.0.0" 459 | }, 460 | "engines": { 461 | "node": ">=18" 462 | }, 463 | "funding": { 464 | "type": "github", 465 | "url": "https://github.com/sponsors/Borewit" 466 | } 467 | }, 468 | "node_modules/@tokenizer/token": { 469 | "version": "0.3.0", 470 | "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", 471 | "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", 472 | "license": "MIT" 473 | }, 474 | "node_modules/accepts": { 475 | "version": "1.3.8", 476 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", 477 | "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", 478 | "license": "MIT", 479 | "peer": true, 480 | "dependencies": { 481 | "mime-types": "~2.1.34", 482 | "negotiator": "0.6.3" 483 | }, 484 | "engines": { 485 | "node": ">= 0.6" 486 | } 487 | }, 488 | "node_modules/aes-js": { 489 | "version": "3.1.2", 490 | "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", 491 | "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", 492 | "license": "MIT" 493 | }, 494 | "node_modules/ansi-regex": { 495 | "version": "5.0.1", 496 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", 497 | "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", 498 | "license": "MIT", 499 | "engines": { 500 | "node": ">=8" 501 | } 502 | }, 503 | "node_modules/ansi-styles": { 504 | "version": "4.3.0", 505 | "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", 506 | "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", 507 | "license": "MIT", 508 | "dependencies": { 509 | "color-convert": "^2.0.1" 510 | }, 511 | "engines": { 512 | "node": ">=8" 513 | }, 514 | "funding": { 515 | "url": "https://github.com/chalk/ansi-styles?sponsor=1" 516 | } 517 | }, 518 | "node_modules/array-flatten": { 519 | "version": "1.1.1", 520 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", 521 | "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", 522 | "license": "MIT", 523 | "peer": true 524 | }, 525 | "node_modules/big-integer": { 526 | "version": "1.6.51", 527 | "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz", 528 | "integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==", 529 | "license": "Unlicense", 530 | "engines": { 531 | "node": ">=0.6" 532 | } 533 | }, 534 | "node_modules/body-parser": { 535 | "version": "1.20.3", 536 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", 537 | "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", 538 | "license": "MIT", 539 | "peer": true, 540 | "dependencies": { 541 | "bytes": "3.1.2", 542 | "content-type": "~1.0.5", 543 | "debug": "2.6.9", 544 | "depd": "2.0.0", 545 | "destroy": "1.2.0", 546 | "http-errors": "2.0.0", 547 | "iconv-lite": "0.4.24", 548 | "on-finished": "2.4.1", 549 | "qs": "6.13.0", 550 | "raw-body": "2.5.2", 551 | "type-is": "~1.6.18", 552 | "unpipe": "1.0.0" 553 | }, 554 | "engines": { 555 | "node": ">= 0.8", 556 | "npm": "1.2.8000 || >= 1.4.16" 557 | } 558 | }, 559 | "node_modules/body-parser/node_modules/debug": { 560 | "version": "2.6.9", 561 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 562 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 563 | "license": "MIT", 564 | "peer": true, 565 | "dependencies": { 566 | "ms": "2.0.0" 567 | } 568 | }, 569 | "node_modules/body-parser/node_modules/ms": { 570 | "version": "2.0.0", 571 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 572 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 573 | "license": "MIT", 574 | "peer": true 575 | }, 576 | "node_modules/body-parser/node_modules/raw-body": { 577 | "version": "2.5.2", 578 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", 579 | "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", 580 | "license": "MIT", 581 | "peer": true, 582 | "dependencies": { 583 | "bytes": "3.1.2", 584 | "http-errors": "2.0.0", 585 | "iconv-lite": "0.4.24", 586 | "unpipe": "1.0.0" 587 | }, 588 | "engines": { 589 | "node": ">= 0.8" 590 | } 591 | }, 592 | "node_modules/bytes": { 593 | "version": "3.1.2", 594 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 595 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 596 | "license": "MIT", 597 | "engines": { 598 | "node": ">= 0.8" 599 | } 600 | }, 601 | "node_modules/call-bind-apply-helpers": { 602 | "version": "1.0.2", 603 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 604 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 605 | "license": "MIT", 606 | "dependencies": { 607 | "es-errors": "^1.3.0", 608 | "function-bind": "^1.1.2" 609 | }, 610 | "engines": { 611 | "node": ">= 0.4" 612 | } 613 | }, 614 | "node_modules/call-bound": { 615 | "version": "1.0.4", 616 | "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", 617 | "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", 618 | "license": "MIT", 619 | "dependencies": { 620 | "call-bind-apply-helpers": "^1.0.2", 621 | "get-intrinsic": "^1.3.0" 622 | }, 623 | "engines": { 624 | "node": ">= 0.4" 625 | }, 626 | "funding": { 627 | "url": "https://github.com/sponsors/ljharb" 628 | } 629 | }, 630 | "node_modules/cliui": { 631 | "version": "8.0.1", 632 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", 633 | "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", 634 | "license": "ISC", 635 | "dependencies": { 636 | "string-width": "^4.2.0", 637 | "strip-ansi": "^6.0.1", 638 | "wrap-ansi": "^7.0.0" 639 | }, 640 | "engines": { 641 | "node": ">=12" 642 | } 643 | }, 644 | "node_modules/color-convert": { 645 | "version": "2.0.1", 646 | "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", 647 | "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", 648 | "license": "MIT", 649 | "dependencies": { 650 | "color-name": "~1.1.4" 651 | }, 652 | "engines": { 653 | "node": ">=7.0.0" 654 | } 655 | }, 656 | "node_modules/color-name": { 657 | "version": "1.1.4", 658 | "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", 659 | "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", 660 | "license": "MIT" 661 | }, 662 | "node_modules/configstore": { 663 | "version": "5.0.1", 664 | "resolved": "https://registry.npmjs.org/configstore/-/configstore-5.0.1.tgz", 665 | "integrity": "sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==", 666 | "license": "BSD-2-Clause", 667 | "dependencies": { 668 | "dot-prop": "^5.2.0", 669 | "graceful-fs": "^4.1.2", 670 | "make-dir": "^3.0.0", 671 | "unique-string": "^2.0.0", 672 | "write-file-atomic": "^3.0.0", 673 | "xdg-basedir": "^4.0.0" 674 | }, 675 | "engines": { 676 | "node": ">=8" 677 | } 678 | }, 679 | "node_modules/content-disposition": { 680 | "version": "0.5.4", 681 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", 682 | "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", 683 | "license": "MIT", 684 | "peer": true, 685 | "dependencies": { 686 | "safe-buffer": "5.2.1" 687 | }, 688 | "engines": { 689 | "node": ">= 0.6" 690 | } 691 | }, 692 | "node_modules/content-type": { 693 | "version": "1.0.5", 694 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 695 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 696 | "license": "MIT", 697 | "engines": { 698 | "node": ">= 0.6" 699 | } 700 | }, 701 | "node_modules/cookie": { 702 | "version": "0.7.1", 703 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", 704 | "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", 705 | "license": "MIT", 706 | "engines": { 707 | "node": ">= 0.6" 708 | } 709 | }, 710 | "node_modules/cookie-signature": { 711 | "version": "1.0.6", 712 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", 713 | "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", 714 | "license": "MIT", 715 | "peer": true 716 | }, 717 | "node_modules/cors": { 718 | "version": "2.8.5", 719 | "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", 720 | "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", 721 | "license": "MIT", 722 | "dependencies": { 723 | "object-assign": "^4", 724 | "vary": "^1" 725 | }, 726 | "engines": { 727 | "node": ">= 0.10" 728 | } 729 | }, 730 | "node_modules/cross-spawn": { 731 | "version": "7.0.6", 732 | "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", 733 | "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", 734 | "license": "MIT", 735 | "dependencies": { 736 | "path-key": "^3.1.0", 737 | "shebang-command": "^2.0.0", 738 | "which": "^2.0.1" 739 | }, 740 | "engines": { 741 | "node": ">= 8" 742 | } 743 | }, 744 | "node_modules/crypto-random-string": { 745 | "version": "2.0.0", 746 | "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-2.0.0.tgz", 747 | "integrity": "sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==", 748 | "license": "MIT", 749 | "engines": { 750 | "node": ">=8" 751 | } 752 | }, 753 | "node_modules/debug": { 754 | "version": "4.4.0", 755 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", 756 | "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", 757 | "license": "MIT", 758 | "dependencies": { 759 | "ms": "^2.1.3" 760 | }, 761 | "engines": { 762 | "node": ">=6.0" 763 | }, 764 | "peerDependenciesMeta": { 765 | "supports-color": { 766 | "optional": true 767 | } 768 | } 769 | }, 770 | "node_modules/debug/node_modules/ms": { 771 | "version": "2.1.3", 772 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 773 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 774 | "license": "MIT" 775 | }, 776 | "node_modules/depd": { 777 | "version": "2.0.0", 778 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 779 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 780 | "license": "MIT", 781 | "engines": { 782 | "node": ">= 0.8" 783 | } 784 | }, 785 | "node_modules/destroy": { 786 | "version": "1.2.0", 787 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", 788 | "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", 789 | "license": "MIT", 790 | "engines": { 791 | "node": ">= 0.8", 792 | "npm": "1.2.8000 || >= 1.4.16" 793 | } 794 | }, 795 | "node_modules/dot-prop": { 796 | "version": "5.3.0", 797 | "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", 798 | "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", 799 | "license": "MIT", 800 | "dependencies": { 801 | "is-obj": "^2.0.0" 802 | }, 803 | "engines": { 804 | "node": ">=8" 805 | } 806 | }, 807 | "node_modules/dotenv": { 808 | "version": "16.5.0", 809 | "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", 810 | "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", 811 | "license": "BSD-2-Clause", 812 | "engines": { 813 | "node": ">=12" 814 | }, 815 | "funding": { 816 | "url": "https://dotenvx.com" 817 | } 818 | }, 819 | "node_modules/dunder-proto": { 820 | "version": "1.0.1", 821 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 822 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 823 | "license": "MIT", 824 | "dependencies": { 825 | "call-bind-apply-helpers": "^1.0.1", 826 | "es-errors": "^1.3.0", 827 | "gopd": "^1.2.0" 828 | }, 829 | "engines": { 830 | "node": ">= 0.4" 831 | } 832 | }, 833 | "node_modules/ee-first": { 834 | "version": "1.1.1", 835 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", 836 | "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", 837 | "license": "MIT" 838 | }, 839 | "node_modules/emoji-regex": { 840 | "version": "8.0.0", 841 | "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", 842 | "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", 843 | "license": "MIT" 844 | }, 845 | "node_modules/encodeurl": { 846 | "version": "2.0.0", 847 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", 848 | "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", 849 | "license": "MIT", 850 | "engines": { 851 | "node": ">= 0.8" 852 | } 853 | }, 854 | "node_modules/es-define-property": { 855 | "version": "1.0.1", 856 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 857 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 858 | "license": "MIT", 859 | "engines": { 860 | "node": ">= 0.4" 861 | } 862 | }, 863 | "node_modules/es-errors": { 864 | "version": "1.3.0", 865 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 866 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 867 | "license": "MIT", 868 | "engines": { 869 | "node": ">= 0.4" 870 | } 871 | }, 872 | "node_modules/es-object-atoms": { 873 | "version": "1.1.1", 874 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 875 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 876 | "license": "MIT", 877 | "dependencies": { 878 | "es-errors": "^1.3.0" 879 | }, 880 | "engines": { 881 | "node": ">= 0.4" 882 | } 883 | }, 884 | "node_modules/escalade": { 885 | "version": "3.2.0", 886 | "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", 887 | "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", 888 | "license": "MIT", 889 | "engines": { 890 | "node": ">=6" 891 | } 892 | }, 893 | "node_modules/escape-html": { 894 | "version": "1.0.3", 895 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", 896 | "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", 897 | "license": "MIT" 898 | }, 899 | "node_modules/etag": { 900 | "version": "1.8.1", 901 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", 902 | "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", 903 | "license": "MIT", 904 | "engines": { 905 | "node": ">= 0.6" 906 | } 907 | }, 908 | "node_modules/events": { 909 | "version": "3.3.0", 910 | "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", 911 | "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", 912 | "license": "MIT", 913 | "engines": { 914 | "node": ">=0.8.x" 915 | } 916 | }, 917 | "node_modules/eventsource": { 918 | "version": "3.0.5", 919 | "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.5.tgz", 920 | "integrity": "sha512-LT/5J605bx5SNyE+ITBDiM3FxffBiq9un7Vx0EwMDM3vg8sWKx/tO2zC+LMqZ+smAM0F2hblaDZUVZF0te2pSw==", 921 | "license": "MIT", 922 | "dependencies": { 923 | "eventsource-parser": "^3.0.0" 924 | }, 925 | "engines": { 926 | "node": ">=18.0.0" 927 | } 928 | }, 929 | "node_modules/eventsource-parser": { 930 | "version": "3.0.0", 931 | "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.0.tgz", 932 | "integrity": "sha512-T1C0XCUimhxVQzW4zFipdx0SficT651NnkR0ZSH3yQwh+mFMdLfgjABVi4YtMTtaL4s168593DaoaRLMqryavA==", 933 | "license": "MIT", 934 | "engines": { 935 | "node": ">=18.0.0" 936 | } 937 | }, 938 | "node_modules/execa": { 939 | "version": "9.5.2", 940 | "resolved": "https://registry.npmjs.org/execa/-/execa-9.5.2.tgz", 941 | "integrity": "sha512-EHlpxMCpHWSAh1dgS6bVeoLAXGnJNdR93aabr4QCGbzOM73o5XmRfM/e5FUqsw3aagP8S8XEWUWFAxnRBnAF0Q==", 942 | "license": "MIT", 943 | "dependencies": { 944 | "@sindresorhus/merge-streams": "^4.0.0", 945 | "cross-spawn": "^7.0.3", 946 | "figures": "^6.1.0", 947 | "get-stream": "^9.0.0", 948 | "human-signals": "^8.0.0", 949 | "is-plain-obj": "^4.1.0", 950 | "is-stream": "^4.0.1", 951 | "npm-run-path": "^6.0.0", 952 | "pretty-ms": "^9.0.0", 953 | "signal-exit": "^4.1.0", 954 | "strip-final-newline": "^4.0.0", 955 | "yoctocolors": "^2.0.0" 956 | }, 957 | "engines": { 958 | "node": "^18.19.0 || >=20.5.0" 959 | }, 960 | "funding": { 961 | "url": "https://github.com/sindresorhus/execa?sponsor=1" 962 | } 963 | }, 964 | "node_modules/express": { 965 | "version": "4.21.2", 966 | "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", 967 | "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", 968 | "license": "MIT", 969 | "peer": true, 970 | "dependencies": { 971 | "accepts": "~1.3.8", 972 | "array-flatten": "1.1.1", 973 | "body-parser": "1.20.3", 974 | "content-disposition": "0.5.4", 975 | "content-type": "~1.0.4", 976 | "cookie": "0.7.1", 977 | "cookie-signature": "1.0.6", 978 | "debug": "2.6.9", 979 | "depd": "2.0.0", 980 | "encodeurl": "~2.0.0", 981 | "escape-html": "~1.0.3", 982 | "etag": "~1.8.1", 983 | "finalhandler": "1.3.1", 984 | "fresh": "0.5.2", 985 | "http-errors": "2.0.0", 986 | "merge-descriptors": "1.0.3", 987 | "methods": "~1.1.2", 988 | "on-finished": "2.4.1", 989 | "parseurl": "~1.3.3", 990 | "path-to-regexp": "0.1.12", 991 | "proxy-addr": "~2.0.7", 992 | "qs": "6.13.0", 993 | "range-parser": "~1.2.1", 994 | "safe-buffer": "5.2.1", 995 | "send": "0.19.0", 996 | "serve-static": "1.16.2", 997 | "setprototypeof": "1.2.0", 998 | "statuses": "2.0.1", 999 | "type-is": "~1.6.18", 1000 | "utils-merge": "1.0.1", 1001 | "vary": "~1.1.2" 1002 | }, 1003 | "engines": { 1004 | "node": ">= 0.10.0" 1005 | }, 1006 | "funding": { 1007 | "type": "opencollective", 1008 | "url": "https://opencollective.com/express" 1009 | } 1010 | }, 1011 | "node_modules/express-rate-limit": { 1012 | "version": "7.5.0", 1013 | "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz", 1014 | "integrity": "sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg==", 1015 | "license": "MIT", 1016 | "engines": { 1017 | "node": ">= 16" 1018 | }, 1019 | "funding": { 1020 | "url": "https://github.com/sponsors/express-rate-limit" 1021 | }, 1022 | "peerDependencies": { 1023 | "express": "^4.11 || 5 || ^5.0.0-beta.1" 1024 | } 1025 | }, 1026 | "node_modules/express/node_modules/debug": { 1027 | "version": "2.6.9", 1028 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1029 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1030 | "license": "MIT", 1031 | "peer": true, 1032 | "dependencies": { 1033 | "ms": "2.0.0" 1034 | } 1035 | }, 1036 | "node_modules/express/node_modules/ms": { 1037 | "version": "2.0.0", 1038 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1039 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 1040 | "license": "MIT", 1041 | "peer": true 1042 | }, 1043 | "node_modules/fastmcp": { 1044 | "version": "1.21.0", 1045 | "resolved": "https://registry.npmjs.org/fastmcp/-/fastmcp-1.21.0.tgz", 1046 | "integrity": "sha512-q4edIA6Mxo8/63JCvdZqnD2IfWVGXfLteZRDwewnr4BVmdv9TylaV+KBBPngf73KdAWc47UtXzDqUQUPL9vxOA==", 1047 | "license": "MIT", 1048 | "dependencies": { 1049 | "@modelcontextprotocol/sdk": "^1.6.0", 1050 | "@standard-schema/spec": "^1.0.0", 1051 | "execa": "^9.5.2", 1052 | "file-type": "^20.3.0", 1053 | "fuse.js": "^7.1.0", 1054 | "mcp-proxy": "^2.10.4", 1055 | "strict-event-emitter-types": "^2.0.0", 1056 | "undici": "^7.4.0", 1057 | "uri-templates": "^0.2.0", 1058 | "xsschema": "0.2.0-beta.2", 1059 | "yargs": "^17.7.2", 1060 | "zod": "^3.24.2", 1061 | "zod-to-json-schema": "^3.24.5" 1062 | }, 1063 | "bin": { 1064 | "fastmcp": "dist/bin/fastmcp.js" 1065 | } 1066 | }, 1067 | "node_modules/fflate": { 1068 | "version": "0.8.2", 1069 | "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz", 1070 | "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==", 1071 | "license": "MIT" 1072 | }, 1073 | "node_modules/figures": { 1074 | "version": "6.1.0", 1075 | "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz", 1076 | "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==", 1077 | "license": "MIT", 1078 | "dependencies": { 1079 | "is-unicode-supported": "^2.0.0" 1080 | }, 1081 | "engines": { 1082 | "node": ">=18" 1083 | }, 1084 | "funding": { 1085 | "url": "https://github.com/sponsors/sindresorhus" 1086 | } 1087 | }, 1088 | "node_modules/file-type": { 1089 | "version": "20.4.1", 1090 | "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.4.1.tgz", 1091 | "integrity": "sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==", 1092 | "license": "MIT", 1093 | "dependencies": { 1094 | "@tokenizer/inflate": "^0.2.6", 1095 | "strtok3": "^10.2.0", 1096 | "token-types": "^6.0.0", 1097 | "uint8array-extras": "^1.4.0" 1098 | }, 1099 | "engines": { 1100 | "node": ">=18" 1101 | }, 1102 | "funding": { 1103 | "url": "https://github.com/sindresorhus/file-type?sponsor=1" 1104 | } 1105 | }, 1106 | "node_modules/finalhandler": { 1107 | "version": "1.3.1", 1108 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", 1109 | "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", 1110 | "license": "MIT", 1111 | "peer": true, 1112 | "dependencies": { 1113 | "debug": "2.6.9", 1114 | "encodeurl": "~2.0.0", 1115 | "escape-html": "~1.0.3", 1116 | "on-finished": "2.4.1", 1117 | "parseurl": "~1.3.3", 1118 | "statuses": "2.0.1", 1119 | "unpipe": "~1.0.0" 1120 | }, 1121 | "engines": { 1122 | "node": ">= 0.8" 1123 | } 1124 | }, 1125 | "node_modules/finalhandler/node_modules/debug": { 1126 | "version": "2.6.9", 1127 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1128 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1129 | "license": "MIT", 1130 | "peer": true, 1131 | "dependencies": { 1132 | "ms": "2.0.0" 1133 | } 1134 | }, 1135 | "node_modules/finalhandler/node_modules/ms": { 1136 | "version": "2.0.0", 1137 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1138 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 1139 | "license": "MIT", 1140 | "peer": true 1141 | }, 1142 | "node_modules/forwarded": { 1143 | "version": "0.2.0", 1144 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", 1145 | "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", 1146 | "license": "MIT", 1147 | "engines": { 1148 | "node": ">= 0.6" 1149 | } 1150 | }, 1151 | "node_modules/fresh": { 1152 | "version": "0.5.2", 1153 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", 1154 | "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", 1155 | "license": "MIT", 1156 | "peer": true, 1157 | "engines": { 1158 | "node": ">= 0.6" 1159 | } 1160 | }, 1161 | "node_modules/function-bind": { 1162 | "version": "1.1.2", 1163 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 1164 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 1165 | "license": "MIT", 1166 | "funding": { 1167 | "url": "https://github.com/sponsors/ljharb" 1168 | } 1169 | }, 1170 | "node_modules/fuse.js": { 1171 | "version": "7.1.0", 1172 | "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz", 1173 | "integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==", 1174 | "license": "Apache-2.0", 1175 | "engines": { 1176 | "node": ">=10" 1177 | } 1178 | }, 1179 | "node_modules/get-caller-file": { 1180 | "version": "2.0.5", 1181 | "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", 1182 | "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", 1183 | "license": "ISC", 1184 | "engines": { 1185 | "node": "6.* || 8.* || >= 10.*" 1186 | } 1187 | }, 1188 | "node_modules/get-intrinsic": { 1189 | "version": "1.3.0", 1190 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 1191 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 1192 | "license": "MIT", 1193 | "dependencies": { 1194 | "call-bind-apply-helpers": "^1.0.2", 1195 | "es-define-property": "^1.0.1", 1196 | "es-errors": "^1.3.0", 1197 | "es-object-atoms": "^1.1.1", 1198 | "function-bind": "^1.1.2", 1199 | "get-proto": "^1.0.1", 1200 | "gopd": "^1.2.0", 1201 | "has-symbols": "^1.1.0", 1202 | "hasown": "^2.0.2", 1203 | "math-intrinsics": "^1.1.0" 1204 | }, 1205 | "engines": { 1206 | "node": ">= 0.4" 1207 | }, 1208 | "funding": { 1209 | "url": "https://github.com/sponsors/ljharb" 1210 | } 1211 | }, 1212 | "node_modules/get-proto": { 1213 | "version": "1.0.1", 1214 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 1215 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 1216 | "license": "MIT", 1217 | "dependencies": { 1218 | "dunder-proto": "^1.0.1", 1219 | "es-object-atoms": "^1.0.0" 1220 | }, 1221 | "engines": { 1222 | "node": ">= 0.4" 1223 | } 1224 | }, 1225 | "node_modules/get-stream": { 1226 | "version": "9.0.1", 1227 | "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz", 1228 | "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==", 1229 | "license": "MIT", 1230 | "dependencies": { 1231 | "@sec-ant/readable-stream": "^0.4.1", 1232 | "is-stream": "^4.0.1" 1233 | }, 1234 | "engines": { 1235 | "node": ">=18" 1236 | }, 1237 | "funding": { 1238 | "url": "https://github.com/sponsors/sindresorhus" 1239 | } 1240 | }, 1241 | "node_modules/gopd": { 1242 | "version": "1.2.0", 1243 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 1244 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 1245 | "license": "MIT", 1246 | "engines": { 1247 | "node": ">= 0.4" 1248 | }, 1249 | "funding": { 1250 | "url": "https://github.com/sponsors/ljharb" 1251 | } 1252 | }, 1253 | "node_modules/graceful-fs": { 1254 | "version": "4.2.11", 1255 | "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", 1256 | "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", 1257 | "license": "ISC" 1258 | }, 1259 | "node_modules/has-symbols": { 1260 | "version": "1.1.0", 1261 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 1262 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 1263 | "license": "MIT", 1264 | "engines": { 1265 | "node": ">= 0.4" 1266 | }, 1267 | "funding": { 1268 | "url": "https://github.com/sponsors/ljharb" 1269 | } 1270 | }, 1271 | "node_modules/hasown": { 1272 | "version": "2.0.2", 1273 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 1274 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 1275 | "license": "MIT", 1276 | "dependencies": { 1277 | "function-bind": "^1.1.2" 1278 | }, 1279 | "engines": { 1280 | "node": ">= 0.4" 1281 | } 1282 | }, 1283 | "node_modules/http-errors": { 1284 | "version": "2.0.0", 1285 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1286 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1287 | "license": "MIT", 1288 | "dependencies": { 1289 | "depd": "2.0.0", 1290 | "inherits": "2.0.4", 1291 | "setprototypeof": "1.2.0", 1292 | "statuses": "2.0.1", 1293 | "toidentifier": "1.0.1" 1294 | }, 1295 | "engines": { 1296 | "node": ">= 0.8" 1297 | } 1298 | }, 1299 | "node_modules/human-signals": { 1300 | "version": "8.0.1", 1301 | "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz", 1302 | "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==", 1303 | "license": "Apache-2.0", 1304 | "engines": { 1305 | "node": ">=18.18.0" 1306 | } 1307 | }, 1308 | "node_modules/iconv-lite": { 1309 | "version": "0.4.24", 1310 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", 1311 | "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", 1312 | "license": "MIT", 1313 | "peer": true, 1314 | "dependencies": { 1315 | "safer-buffer": ">= 2.1.2 < 3" 1316 | }, 1317 | "engines": { 1318 | "node": ">=0.10.0" 1319 | } 1320 | }, 1321 | "node_modules/ieee754": { 1322 | "version": "1.2.1", 1323 | "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", 1324 | "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", 1325 | "funding": [ 1326 | { 1327 | "type": "github", 1328 | "url": "https://github.com/sponsors/feross" 1329 | }, 1330 | { 1331 | "type": "patreon", 1332 | "url": "https://www.patreon.com/feross" 1333 | }, 1334 | { 1335 | "type": "consulting", 1336 | "url": "https://feross.org/support" 1337 | } 1338 | ], 1339 | "license": "BSD-3-Clause" 1340 | }, 1341 | "node_modules/imurmurhash": { 1342 | "version": "0.1.4", 1343 | "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", 1344 | "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", 1345 | "license": "MIT", 1346 | "engines": { 1347 | "node": ">=0.8.19" 1348 | } 1349 | }, 1350 | "node_modules/inherits": { 1351 | "version": "2.0.4", 1352 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1353 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1354 | "license": "ISC" 1355 | }, 1356 | "node_modules/ipaddr.js": { 1357 | "version": "1.9.1", 1358 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", 1359 | "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", 1360 | "license": "MIT", 1361 | "engines": { 1362 | "node": ">= 0.10" 1363 | } 1364 | }, 1365 | "node_modules/is-fullwidth-code-point": { 1366 | "version": "3.0.0", 1367 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", 1368 | "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", 1369 | "license": "MIT", 1370 | "engines": { 1371 | "node": ">=8" 1372 | } 1373 | }, 1374 | "node_modules/is-obj": { 1375 | "version": "2.0.0", 1376 | "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", 1377 | "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", 1378 | "license": "MIT", 1379 | "engines": { 1380 | "node": ">=8" 1381 | } 1382 | }, 1383 | "node_modules/is-plain-obj": { 1384 | "version": "4.1.0", 1385 | "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", 1386 | "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", 1387 | "license": "MIT", 1388 | "engines": { 1389 | "node": ">=12" 1390 | }, 1391 | "funding": { 1392 | "url": "https://github.com/sponsors/sindresorhus" 1393 | } 1394 | }, 1395 | "node_modules/is-promise": { 1396 | "version": "4.0.0", 1397 | "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", 1398 | "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", 1399 | "license": "MIT" 1400 | }, 1401 | "node_modules/is-stream": { 1402 | "version": "4.0.1", 1403 | "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz", 1404 | "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==", 1405 | "license": "MIT", 1406 | "engines": { 1407 | "node": ">=18" 1408 | }, 1409 | "funding": { 1410 | "url": "https://github.com/sponsors/sindresorhus" 1411 | } 1412 | }, 1413 | "node_modules/is-typedarray": { 1414 | "version": "1.0.0", 1415 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 1416 | "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", 1417 | "license": "MIT" 1418 | }, 1419 | "node_modules/is-unicode-supported": { 1420 | "version": "2.1.0", 1421 | "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz", 1422 | "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==", 1423 | "license": "MIT", 1424 | "engines": { 1425 | "node": ">=18" 1426 | }, 1427 | "funding": { 1428 | "url": "https://github.com/sponsors/sindresorhus" 1429 | } 1430 | }, 1431 | "node_modules/isexe": { 1432 | "version": "2.0.0", 1433 | "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", 1434 | "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", 1435 | "license": "ISC" 1436 | }, 1437 | "node_modules/leemon": { 1438 | "version": "6.2.0", 1439 | "resolved": "https://registry.npmjs.org/leemon/-/leemon-6.2.0.tgz", 1440 | "integrity": "sha512-a5ieuGSGEb5ezCL6UNds5//cVFaKpeexVK0VDCE8/eOF0r0/9Og94LQ33U2Px5dUcHVCDPWQY8gXLgDlDJnyyg==", 1441 | "license": "MIT" 1442 | }, 1443 | "node_modules/lodash.debounce": { 1444 | "version": "4.0.8", 1445 | "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", 1446 | "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", 1447 | "license": "MIT" 1448 | }, 1449 | "node_modules/make-dir": { 1450 | "version": "3.1.0", 1451 | "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", 1452 | "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", 1453 | "license": "MIT", 1454 | "dependencies": { 1455 | "semver": "^6.0.0" 1456 | }, 1457 | "engines": { 1458 | "node": ">=8" 1459 | }, 1460 | "funding": { 1461 | "url": "https://github.com/sponsors/sindresorhus" 1462 | } 1463 | }, 1464 | "node_modules/math-intrinsics": { 1465 | "version": "1.1.0", 1466 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1467 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1468 | "license": "MIT", 1469 | "engines": { 1470 | "node": ">= 0.4" 1471 | } 1472 | }, 1473 | "node_modules/mcp-proxy": { 1474 | "version": "2.12.0", 1475 | "resolved": "https://registry.npmjs.org/mcp-proxy/-/mcp-proxy-2.12.0.tgz", 1476 | "integrity": "sha512-hL2Y6EtK7vkgAOZxOQe9M4Z9g5xEnvR4ZYBKqFi/5tjhz/1jyNEz5NL87Uzv46k8iZQPVNEof/T6arEooBU5bQ==", 1477 | "license": "MIT", 1478 | "dependencies": { 1479 | "@modelcontextprotocol/sdk": "^1.6.0", 1480 | "eventsource": "^3.0.5", 1481 | "yargs": "^17.7.2" 1482 | }, 1483 | "bin": { 1484 | "mcp-proxy": "dist/bin/mcp-proxy.js" 1485 | } 1486 | }, 1487 | "node_modules/media-typer": { 1488 | "version": "0.3.0", 1489 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", 1490 | "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", 1491 | "license": "MIT", 1492 | "peer": true, 1493 | "engines": { 1494 | "node": ">= 0.6" 1495 | } 1496 | }, 1497 | "node_modules/merge-descriptors": { 1498 | "version": "1.0.3", 1499 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", 1500 | "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", 1501 | "license": "MIT", 1502 | "peer": true, 1503 | "funding": { 1504 | "url": "https://github.com/sponsors/sindresorhus" 1505 | } 1506 | }, 1507 | "node_modules/methods": { 1508 | "version": "1.1.2", 1509 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", 1510 | "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", 1511 | "license": "MIT", 1512 | "engines": { 1513 | "node": ">= 0.6" 1514 | } 1515 | }, 1516 | "node_modules/mime": { 1517 | "version": "1.6.0", 1518 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", 1519 | "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", 1520 | "license": "MIT", 1521 | "peer": true, 1522 | "bin": { 1523 | "mime": "cli.js" 1524 | }, 1525 | "engines": { 1526 | "node": ">=4" 1527 | } 1528 | }, 1529 | "node_modules/mime-db": { 1530 | "version": "1.52.0", 1531 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1532 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1533 | "license": "MIT", 1534 | "peer": true, 1535 | "engines": { 1536 | "node": ">= 0.6" 1537 | } 1538 | }, 1539 | "node_modules/mime-types": { 1540 | "version": "2.1.35", 1541 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1542 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1543 | "license": "MIT", 1544 | "peer": true, 1545 | "dependencies": { 1546 | "mime-db": "1.52.0" 1547 | }, 1548 | "engines": { 1549 | "node": ">= 0.6" 1550 | } 1551 | }, 1552 | "node_modules/ms": { 1553 | "version": "2.1.2", 1554 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 1555 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", 1556 | "license": "MIT" 1557 | }, 1558 | "node_modules/negotiator": { 1559 | "version": "0.6.3", 1560 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", 1561 | "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", 1562 | "license": "MIT", 1563 | "peer": true, 1564 | "engines": { 1565 | "node": ">= 0.6" 1566 | } 1567 | }, 1568 | "node_modules/npm-run-path": { 1569 | "version": "6.0.0", 1570 | "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz", 1571 | "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==", 1572 | "license": "MIT", 1573 | "dependencies": { 1574 | "path-key": "^4.0.0", 1575 | "unicorn-magic": "^0.3.0" 1576 | }, 1577 | "engines": { 1578 | "node": ">=18" 1579 | }, 1580 | "funding": { 1581 | "url": "https://github.com/sponsors/sindresorhus" 1582 | } 1583 | }, 1584 | "node_modules/npm-run-path/node_modules/path-key": { 1585 | "version": "4.0.0", 1586 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", 1587 | "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", 1588 | "license": "MIT", 1589 | "engines": { 1590 | "node": ">=12" 1591 | }, 1592 | "funding": { 1593 | "url": "https://github.com/sponsors/sindresorhus" 1594 | } 1595 | }, 1596 | "node_modules/object-assign": { 1597 | "version": "4.1.1", 1598 | "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", 1599 | "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", 1600 | "license": "MIT", 1601 | "engines": { 1602 | "node": ">=0.10.0" 1603 | } 1604 | }, 1605 | "node_modules/object-inspect": { 1606 | "version": "1.13.4", 1607 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", 1608 | "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", 1609 | "license": "MIT", 1610 | "engines": { 1611 | "node": ">= 0.4" 1612 | }, 1613 | "funding": { 1614 | "url": "https://github.com/sponsors/ljharb" 1615 | } 1616 | }, 1617 | "node_modules/on-finished": { 1618 | "version": "2.4.1", 1619 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", 1620 | "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", 1621 | "license": "MIT", 1622 | "dependencies": { 1623 | "ee-first": "1.1.1" 1624 | }, 1625 | "engines": { 1626 | "node": ">= 0.8" 1627 | } 1628 | }, 1629 | "node_modules/once": { 1630 | "version": "1.4.0", 1631 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 1632 | "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", 1633 | "license": "ISC", 1634 | "dependencies": { 1635 | "wrappy": "1" 1636 | } 1637 | }, 1638 | "node_modules/pako": { 1639 | "version": "2.1.0", 1640 | "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", 1641 | "integrity": "sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==", 1642 | "license": "(MIT AND Zlib)" 1643 | }, 1644 | "node_modules/parse-ms": { 1645 | "version": "4.0.0", 1646 | "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz", 1647 | "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==", 1648 | "license": "MIT", 1649 | "engines": { 1650 | "node": ">=18" 1651 | }, 1652 | "funding": { 1653 | "url": "https://github.com/sponsors/sindresorhus" 1654 | } 1655 | }, 1656 | "node_modules/parseurl": { 1657 | "version": "1.3.3", 1658 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", 1659 | "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", 1660 | "license": "MIT", 1661 | "engines": { 1662 | "node": ">= 0.8" 1663 | } 1664 | }, 1665 | "node_modules/path-key": { 1666 | "version": "3.1.1", 1667 | "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", 1668 | "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", 1669 | "license": "MIT", 1670 | "engines": { 1671 | "node": ">=8" 1672 | } 1673 | }, 1674 | "node_modules/path-to-regexp": { 1675 | "version": "0.1.12", 1676 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", 1677 | "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", 1678 | "license": "MIT", 1679 | "peer": true 1680 | }, 1681 | "node_modules/peek-readable": { 1682 | "version": "7.0.0", 1683 | "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-7.0.0.tgz", 1684 | "integrity": "sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==", 1685 | "license": "MIT", 1686 | "engines": { 1687 | "node": ">=18" 1688 | }, 1689 | "funding": { 1690 | "type": "github", 1691 | "url": "https://github.com/sponsors/Borewit" 1692 | } 1693 | }, 1694 | "node_modules/pkce-challenge": { 1695 | "version": "5.0.0", 1696 | "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", 1697 | "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", 1698 | "license": "MIT", 1699 | "engines": { 1700 | "node": ">=16.20.0" 1701 | } 1702 | }, 1703 | "node_modules/pretty-ms": { 1704 | "version": "9.2.0", 1705 | "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz", 1706 | "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", 1707 | "license": "MIT", 1708 | "dependencies": { 1709 | "parse-ms": "^4.0.0" 1710 | }, 1711 | "engines": { 1712 | "node": ">=18" 1713 | }, 1714 | "funding": { 1715 | "url": "https://github.com/sponsors/sindresorhus" 1716 | } 1717 | }, 1718 | "node_modules/proxy-addr": { 1719 | "version": "2.0.7", 1720 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", 1721 | "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", 1722 | "license": "MIT", 1723 | "dependencies": { 1724 | "forwarded": "0.2.0", 1725 | "ipaddr.js": "1.9.1" 1726 | }, 1727 | "engines": { 1728 | "node": ">= 0.10" 1729 | } 1730 | }, 1731 | "node_modules/qs": { 1732 | "version": "6.13.0", 1733 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", 1734 | "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", 1735 | "license": "BSD-3-Clause", 1736 | "dependencies": { 1737 | "side-channel": "^1.0.6" 1738 | }, 1739 | "engines": { 1740 | "node": ">=0.6" 1741 | }, 1742 | "funding": { 1743 | "url": "https://github.com/sponsors/ljharb" 1744 | } 1745 | }, 1746 | "node_modules/range-parser": { 1747 | "version": "1.2.1", 1748 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", 1749 | "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", 1750 | "license": "MIT", 1751 | "engines": { 1752 | "node": ">= 0.6" 1753 | } 1754 | }, 1755 | "node_modules/raw-body": { 1756 | "version": "3.0.0", 1757 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 1758 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 1759 | "license": "MIT", 1760 | "dependencies": { 1761 | "bytes": "3.1.2", 1762 | "http-errors": "2.0.0", 1763 | "iconv-lite": "0.6.3", 1764 | "unpipe": "1.0.0" 1765 | }, 1766 | "engines": { 1767 | "node": ">= 0.8" 1768 | } 1769 | }, 1770 | "node_modules/raw-body/node_modules/iconv-lite": { 1771 | "version": "0.6.3", 1772 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1773 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1774 | "license": "MIT", 1775 | "dependencies": { 1776 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1777 | }, 1778 | "engines": { 1779 | "node": ">=0.10.0" 1780 | } 1781 | }, 1782 | "node_modules/require-directory": { 1783 | "version": "2.1.1", 1784 | "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", 1785 | "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", 1786 | "license": "MIT", 1787 | "engines": { 1788 | "node": ">=0.10.0" 1789 | } 1790 | }, 1791 | "node_modules/router": { 1792 | "version": "2.1.0", 1793 | "resolved": "https://registry.npmjs.org/router/-/router-2.1.0.tgz", 1794 | "integrity": "sha512-/m/NSLxeYEgWNtyC+WtNHCF7jbGxOibVWKnn+1Psff4dJGOfoXP+MuC/f2CwSmyiHdOIzYnYFp4W6GxWfekaLA==", 1795 | "license": "MIT", 1796 | "dependencies": { 1797 | "is-promise": "^4.0.0", 1798 | "parseurl": "^1.3.3", 1799 | "path-to-regexp": "^8.0.0" 1800 | }, 1801 | "engines": { 1802 | "node": ">= 18" 1803 | } 1804 | }, 1805 | "node_modules/router/node_modules/path-to-regexp": { 1806 | "version": "8.2.0", 1807 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", 1808 | "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", 1809 | "license": "MIT", 1810 | "engines": { 1811 | "node": ">=16" 1812 | } 1813 | }, 1814 | "node_modules/safe-buffer": { 1815 | "version": "5.2.1", 1816 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", 1817 | "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", 1818 | "funding": [ 1819 | { 1820 | "type": "github", 1821 | "url": "https://github.com/sponsors/feross" 1822 | }, 1823 | { 1824 | "type": "patreon", 1825 | "url": "https://www.patreon.com/feross" 1826 | }, 1827 | { 1828 | "type": "consulting", 1829 | "url": "https://feross.org/support" 1830 | } 1831 | ], 1832 | "license": "MIT" 1833 | }, 1834 | "node_modules/safer-buffer": { 1835 | "version": "2.1.2", 1836 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1837 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1838 | "license": "MIT" 1839 | }, 1840 | "node_modules/semver": { 1841 | "version": "6.3.1", 1842 | "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", 1843 | "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", 1844 | "license": "ISC", 1845 | "bin": { 1846 | "semver": "bin/semver.js" 1847 | } 1848 | }, 1849 | "node_modules/send": { 1850 | "version": "0.19.0", 1851 | "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", 1852 | "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", 1853 | "license": "MIT", 1854 | "peer": true, 1855 | "dependencies": { 1856 | "debug": "2.6.9", 1857 | "depd": "2.0.0", 1858 | "destroy": "1.2.0", 1859 | "encodeurl": "~1.0.2", 1860 | "escape-html": "~1.0.3", 1861 | "etag": "~1.8.1", 1862 | "fresh": "0.5.2", 1863 | "http-errors": "2.0.0", 1864 | "mime": "1.6.0", 1865 | "ms": "2.1.3", 1866 | "on-finished": "2.4.1", 1867 | "range-parser": "~1.2.1", 1868 | "statuses": "2.0.1" 1869 | }, 1870 | "engines": { 1871 | "node": ">= 0.8.0" 1872 | } 1873 | }, 1874 | "node_modules/send/node_modules/debug": { 1875 | "version": "2.6.9", 1876 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 1877 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 1878 | "license": "MIT", 1879 | "peer": true, 1880 | "dependencies": { 1881 | "ms": "2.0.0" 1882 | } 1883 | }, 1884 | "node_modules/send/node_modules/debug/node_modules/ms": { 1885 | "version": "2.0.0", 1886 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 1887 | "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", 1888 | "license": "MIT", 1889 | "peer": true 1890 | }, 1891 | "node_modules/send/node_modules/encodeurl": { 1892 | "version": "1.0.2", 1893 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", 1894 | "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", 1895 | "license": "MIT", 1896 | "peer": true, 1897 | "engines": { 1898 | "node": ">= 0.8" 1899 | } 1900 | }, 1901 | "node_modules/send/node_modules/ms": { 1902 | "version": "2.1.3", 1903 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", 1904 | "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", 1905 | "license": "MIT", 1906 | "peer": true 1907 | }, 1908 | "node_modules/serve-static": { 1909 | "version": "1.16.2", 1910 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", 1911 | "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", 1912 | "license": "MIT", 1913 | "peer": true, 1914 | "dependencies": { 1915 | "encodeurl": "~2.0.0", 1916 | "escape-html": "~1.0.3", 1917 | "parseurl": "~1.3.3", 1918 | "send": "0.19.0" 1919 | }, 1920 | "engines": { 1921 | "node": ">= 0.8.0" 1922 | } 1923 | }, 1924 | "node_modules/setprototypeof": { 1925 | "version": "1.2.0", 1926 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1927 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 1928 | "license": "ISC" 1929 | }, 1930 | "node_modules/shebang-command": { 1931 | "version": "2.0.0", 1932 | "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", 1933 | "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", 1934 | "license": "MIT", 1935 | "dependencies": { 1936 | "shebang-regex": "^3.0.0" 1937 | }, 1938 | "engines": { 1939 | "node": ">=8" 1940 | } 1941 | }, 1942 | "node_modules/shebang-regex": { 1943 | "version": "3.0.0", 1944 | "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", 1945 | "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", 1946 | "license": "MIT", 1947 | "engines": { 1948 | "node": ">=8" 1949 | } 1950 | }, 1951 | "node_modules/side-channel": { 1952 | "version": "1.1.0", 1953 | "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", 1954 | "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", 1955 | "license": "MIT", 1956 | "dependencies": { 1957 | "es-errors": "^1.3.0", 1958 | "object-inspect": "^1.13.3", 1959 | "side-channel-list": "^1.0.0", 1960 | "side-channel-map": "^1.0.1", 1961 | "side-channel-weakmap": "^1.0.2" 1962 | }, 1963 | "engines": { 1964 | "node": ">= 0.4" 1965 | }, 1966 | "funding": { 1967 | "url": "https://github.com/sponsors/ljharb" 1968 | } 1969 | }, 1970 | "node_modules/side-channel-list": { 1971 | "version": "1.0.0", 1972 | "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", 1973 | "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", 1974 | "license": "MIT", 1975 | "dependencies": { 1976 | "es-errors": "^1.3.0", 1977 | "object-inspect": "^1.13.3" 1978 | }, 1979 | "engines": { 1980 | "node": ">= 0.4" 1981 | }, 1982 | "funding": { 1983 | "url": "https://github.com/sponsors/ljharb" 1984 | } 1985 | }, 1986 | "node_modules/side-channel-map": { 1987 | "version": "1.0.1", 1988 | "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", 1989 | "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", 1990 | "license": "MIT", 1991 | "dependencies": { 1992 | "call-bound": "^1.0.2", 1993 | "es-errors": "^1.3.0", 1994 | "get-intrinsic": "^1.2.5", 1995 | "object-inspect": "^1.13.3" 1996 | }, 1997 | "engines": { 1998 | "node": ">= 0.4" 1999 | }, 2000 | "funding": { 2001 | "url": "https://github.com/sponsors/ljharb" 2002 | } 2003 | }, 2004 | "node_modules/side-channel-weakmap": { 2005 | "version": "1.0.2", 2006 | "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", 2007 | "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", 2008 | "license": "MIT", 2009 | "dependencies": { 2010 | "call-bound": "^1.0.2", 2011 | "es-errors": "^1.3.0", 2012 | "get-intrinsic": "^1.2.5", 2013 | "object-inspect": "^1.13.3", 2014 | "side-channel-map": "^1.0.1" 2015 | }, 2016 | "engines": { 2017 | "node": ">= 0.4" 2018 | }, 2019 | "funding": { 2020 | "url": "https://github.com/sponsors/ljharb" 2021 | } 2022 | }, 2023 | "node_modules/signal-exit": { 2024 | "version": "4.1.0", 2025 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", 2026 | "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", 2027 | "license": "ISC", 2028 | "engines": { 2029 | "node": ">=14" 2030 | }, 2031 | "funding": { 2032 | "url": "https://github.com/sponsors/isaacs" 2033 | } 2034 | }, 2035 | "node_modules/statuses": { 2036 | "version": "2.0.1", 2037 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 2038 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 2039 | "license": "MIT", 2040 | "engines": { 2041 | "node": ">= 0.8" 2042 | } 2043 | }, 2044 | "node_modules/strict-event-emitter-types": { 2045 | "version": "2.0.0", 2046 | "resolved": "https://registry.npmjs.org/strict-event-emitter-types/-/strict-event-emitter-types-2.0.0.tgz", 2047 | "integrity": "sha512-Nk/brWYpD85WlOgzw5h173aci0Teyv8YdIAEtV+N88nDB0dLlazZyJMIsN6eo1/AR61l+p6CJTG1JIyFaoNEEA==", 2048 | "license": "ISC" 2049 | }, 2050 | "node_modules/string-width": { 2051 | "version": "4.2.3", 2052 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", 2053 | "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", 2054 | "license": "MIT", 2055 | "dependencies": { 2056 | "emoji-regex": "^8.0.0", 2057 | "is-fullwidth-code-point": "^3.0.0", 2058 | "strip-ansi": "^6.0.1" 2059 | }, 2060 | "engines": { 2061 | "node": ">=8" 2062 | } 2063 | }, 2064 | "node_modules/strip-ansi": { 2065 | "version": "6.0.1", 2066 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", 2067 | "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", 2068 | "license": "MIT", 2069 | "dependencies": { 2070 | "ansi-regex": "^5.0.1" 2071 | }, 2072 | "engines": { 2073 | "node": ">=8" 2074 | } 2075 | }, 2076 | "node_modules/strip-final-newline": { 2077 | "version": "4.0.0", 2078 | "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz", 2079 | "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==", 2080 | "license": "MIT", 2081 | "engines": { 2082 | "node": ">=18" 2083 | }, 2084 | "funding": { 2085 | "url": "https://github.com/sponsors/sindresorhus" 2086 | } 2087 | }, 2088 | "node_modules/strtok3": { 2089 | "version": "10.2.2", 2090 | "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.2.2.tgz", 2091 | "integrity": "sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==", 2092 | "license": "MIT", 2093 | "dependencies": { 2094 | "@tokenizer/token": "^0.3.0", 2095 | "peek-readable": "^7.0.0" 2096 | }, 2097 | "engines": { 2098 | "node": ">=18" 2099 | }, 2100 | "funding": { 2101 | "type": "github", 2102 | "url": "https://github.com/sponsors/Borewit" 2103 | } 2104 | }, 2105 | "node_modules/toidentifier": { 2106 | "version": "1.0.1", 2107 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 2108 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 2109 | "license": "MIT", 2110 | "engines": { 2111 | "node": ">=0.6" 2112 | } 2113 | }, 2114 | "node_modules/token-types": { 2115 | "version": "6.0.0", 2116 | "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz", 2117 | "integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==", 2118 | "license": "MIT", 2119 | "dependencies": { 2120 | "@tokenizer/token": "^0.3.0", 2121 | "ieee754": "^1.2.1" 2122 | }, 2123 | "engines": { 2124 | "node": ">=14.16" 2125 | }, 2126 | "funding": { 2127 | "type": "github", 2128 | "url": "https://github.com/sponsors/Borewit" 2129 | } 2130 | }, 2131 | "node_modules/type-is": { 2132 | "version": "1.6.18", 2133 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", 2134 | "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", 2135 | "license": "MIT", 2136 | "peer": true, 2137 | "dependencies": { 2138 | "media-typer": "0.3.0", 2139 | "mime-types": "~2.1.24" 2140 | }, 2141 | "engines": { 2142 | "node": ">= 0.6" 2143 | } 2144 | }, 2145 | "node_modules/typedarray-to-buffer": { 2146 | "version": "3.1.5", 2147 | "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", 2148 | "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", 2149 | "license": "MIT", 2150 | "dependencies": { 2151 | "is-typedarray": "^1.0.0" 2152 | } 2153 | }, 2154 | "node_modules/uint8array-extras": { 2155 | "version": "1.4.0", 2156 | "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz", 2157 | "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==", 2158 | "license": "MIT", 2159 | "engines": { 2160 | "node": ">=18" 2161 | }, 2162 | "funding": { 2163 | "url": "https://github.com/sponsors/sindresorhus" 2164 | } 2165 | }, 2166 | "node_modules/undici": { 2167 | "version": "7.8.0", 2168 | "resolved": "https://registry.npmjs.org/undici/-/undici-7.8.0.tgz", 2169 | "integrity": "sha512-vFv1GA99b7eKO1HG/4RPu2Is3FBTWBrmzqzO0mz+rLxN3yXkE4mqRcb8g8fHxzX4blEysrNZLqg5RbJLqX5buA==", 2170 | "license": "MIT", 2171 | "engines": { 2172 | "node": ">=20.18.1" 2173 | } 2174 | }, 2175 | "node_modules/unicorn-magic": { 2176 | "version": "0.3.0", 2177 | "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", 2178 | "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", 2179 | "license": "MIT", 2180 | "engines": { 2181 | "node": ">=18" 2182 | }, 2183 | "funding": { 2184 | "url": "https://github.com/sponsors/sindresorhus" 2185 | } 2186 | }, 2187 | "node_modules/unique-string": { 2188 | "version": "2.0.0", 2189 | "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-2.0.0.tgz", 2190 | "integrity": "sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==", 2191 | "license": "MIT", 2192 | "dependencies": { 2193 | "crypto-random-string": "^2.0.0" 2194 | }, 2195 | "engines": { 2196 | "node": ">=8" 2197 | } 2198 | }, 2199 | "node_modules/unpipe": { 2200 | "version": "1.0.0", 2201 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 2202 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 2203 | "license": "MIT", 2204 | "engines": { 2205 | "node": ">= 0.8" 2206 | } 2207 | }, 2208 | "node_modules/uri-templates": { 2209 | "version": "0.2.0", 2210 | "resolved": "https://registry.npmjs.org/uri-templates/-/uri-templates-0.2.0.tgz", 2211 | "integrity": "sha512-EWkjYEN0L6KOfEoOH6Wj4ghQqU7eBZMJqRHQnxQAq+dSEzRPClkWjf8557HkWQXF6BrAUoLSAyy9i3RVTliaNg==", 2212 | "license": "http://geraintluff.github.io/tv4/LICENSE.txt" 2213 | }, 2214 | "node_modules/utils-merge": { 2215 | "version": "1.0.1", 2216 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", 2217 | "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", 2218 | "license": "MIT", 2219 | "engines": { 2220 | "node": ">= 0.4.0" 2221 | } 2222 | }, 2223 | "node_modules/vary": { 2224 | "version": "1.1.2", 2225 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", 2226 | "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", 2227 | "license": "MIT", 2228 | "engines": { 2229 | "node": ">= 0.8" 2230 | } 2231 | }, 2232 | "node_modules/which": { 2233 | "version": "2.0.2", 2234 | "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", 2235 | "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", 2236 | "license": "ISC", 2237 | "dependencies": { 2238 | "isexe": "^2.0.0" 2239 | }, 2240 | "bin": { 2241 | "node-which": "bin/node-which" 2242 | }, 2243 | "engines": { 2244 | "node": ">= 8" 2245 | } 2246 | }, 2247 | "node_modules/wrap-ansi": { 2248 | "version": "7.0.0", 2249 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", 2250 | "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", 2251 | "license": "MIT", 2252 | "dependencies": { 2253 | "ansi-styles": "^4.0.0", 2254 | "string-width": "^4.1.0", 2255 | "strip-ansi": "^6.0.0" 2256 | }, 2257 | "engines": { 2258 | "node": ">=10" 2259 | }, 2260 | "funding": { 2261 | "url": "https://github.com/chalk/wrap-ansi?sponsor=1" 2262 | } 2263 | }, 2264 | "node_modules/wrappy": { 2265 | "version": "1.0.2", 2266 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 2267 | "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", 2268 | "license": "ISC" 2269 | }, 2270 | "node_modules/write-file-atomic": { 2271 | "version": "3.0.3", 2272 | "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", 2273 | "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", 2274 | "license": "ISC", 2275 | "dependencies": { 2276 | "imurmurhash": "^0.1.4", 2277 | "is-typedarray": "^1.0.0", 2278 | "signal-exit": "^3.0.2", 2279 | "typedarray-to-buffer": "^3.1.5" 2280 | } 2281 | }, 2282 | "node_modules/write-file-atomic/node_modules/signal-exit": { 2283 | "version": "3.0.7", 2284 | "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", 2285 | "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", 2286 | "license": "ISC" 2287 | }, 2288 | "node_modules/xdg-basedir": { 2289 | "version": "4.0.0", 2290 | "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", 2291 | "integrity": "sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==", 2292 | "license": "MIT", 2293 | "engines": { 2294 | "node": ">=8" 2295 | } 2296 | }, 2297 | "node_modules/xsschema": { 2298 | "version": "0.2.0-beta.2", 2299 | "resolved": "https://registry.npmjs.org/xsschema/-/xsschema-0.2.0-beta.2.tgz", 2300 | "integrity": "sha512-yaU1SLQVQNboZHHK7iXpCoHzF+sbWvkygAKG6qMKvnpbNdm0SMWAIIj1uasDpCQ21HspPTdEYGg0c0qZYXVQFg==", 2301 | "license": "MIT", 2302 | "peerDependencies": { 2303 | "@valibot/to-json-schema": "^1.0.0", 2304 | "arktype": "^2.1.13", 2305 | "effect": "^3.14.2", 2306 | "zod-to-json-schema": "^3.24.5" 2307 | }, 2308 | "peerDependenciesMeta": { 2309 | "@valibot/to-json-schema": { 2310 | "optional": true 2311 | }, 2312 | "arktype": { 2313 | "optional": true 2314 | }, 2315 | "effect": { 2316 | "optional": true 2317 | }, 2318 | "zod-to-json-schema": { 2319 | "optional": true 2320 | } 2321 | } 2322 | }, 2323 | "node_modules/y18n": { 2324 | "version": "5.0.8", 2325 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", 2326 | "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", 2327 | "license": "ISC", 2328 | "engines": { 2329 | "node": ">=10" 2330 | } 2331 | }, 2332 | "node_modules/yargs": { 2333 | "version": "17.7.2", 2334 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", 2335 | "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", 2336 | "license": "MIT", 2337 | "dependencies": { 2338 | "cliui": "^8.0.1", 2339 | "escalade": "^3.1.1", 2340 | "get-caller-file": "^2.0.5", 2341 | "require-directory": "^2.1.1", 2342 | "string-width": "^4.2.3", 2343 | "y18n": "^5.0.5", 2344 | "yargs-parser": "^21.1.1" 2345 | }, 2346 | "engines": { 2347 | "node": ">=12" 2348 | } 2349 | }, 2350 | "node_modules/yargs-parser": { 2351 | "version": "21.1.1", 2352 | "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", 2353 | "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", 2354 | "license": "ISC", 2355 | "engines": { 2356 | "node": ">=12" 2357 | } 2358 | }, 2359 | "node_modules/yoctocolors": { 2360 | "version": "2.1.1", 2361 | "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz", 2362 | "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==", 2363 | "license": "MIT", 2364 | "engines": { 2365 | "node": ">=18" 2366 | }, 2367 | "funding": { 2368 | "url": "https://github.com/sponsors/sindresorhus" 2369 | } 2370 | }, 2371 | "node_modules/zod": { 2372 | "version": "3.24.2", 2373 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 2374 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 2375 | "license": "MIT", 2376 | "funding": { 2377 | "url": "https://github.com/sponsors/colinhacks" 2378 | } 2379 | }, 2380 | "node_modules/zod-to-json-schema": { 2381 | "version": "3.24.5", 2382 | "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz", 2383 | "integrity": "sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g==", 2384 | "license": "ISC", 2385 | "peerDependencies": { 2386 | "zod": "^3.24.1" 2387 | } 2388 | } 2389 | } 2390 | } 2391 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "telegram-mcp-server", 3 | "version": "1.0.0", 4 | "type": "module", 5 | "description": "MCP server for a Telegram client built with the MTProto library and FastMCP framework", 6 | "main": "mcp-server.js", 7 | "scripts": { 8 | "client": "node mcp-client.js", 9 | "start": "node mcp-server.js", 10 | "prepare": "npm run build", 11 | "build": "echo \"No build step required\"", 12 | "prepublishOnly": "npm test", 13 | "test": "echo \"No tests specified yet\"" 14 | }, 15 | "files": [ 16 | "mcp-server.js", 17 | "telegram-client.js", 18 | "LIBRARY.md", 19 | "README.md", 20 | "LICENSE" 21 | ], 22 | "repository": { 23 | "type": "git", 24 | "url": "git+https://github.com/kfastov/telegram-mcp-server.git" 25 | }, 26 | "keywords": [ 27 | "telegram", 28 | "telegram-client", 29 | "mcp", 30 | "mcp-server", 31 | "mtproto", 32 | "fastmcp", 33 | "claude", 34 | "cursor", 35 | "ai-assistant", 36 | "ai-agent" 37 | ], 38 | "author": "Konstantin Fastov", 39 | "license": "MIT", 40 | "bugs": { 41 | "url": "https://github.com/kfastov/telegram-mcp-server/issues" 42 | }, 43 | "homepage": "https://github.com/kfastov/telegram-mcp-server#readme", 44 | "dependencies": { 45 | "@modelcontextprotocol/sdk": "^1.9.0", 46 | "@mtproto/core": "^6.3.0", 47 | "dotenv": "^16.5.0", 48 | "fastmcp": "^1.21.0" 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /telegram-client.js: -------------------------------------------------------------------------------- 1 | import MTProto from '@mtproto/core'; 2 | import path from 'path'; 3 | import fs from 'fs'; 4 | import readline from 'readline'; 5 | import { fileURLToPath } from 'url'; 6 | 7 | // Get current file's directory 8 | const __filename = fileURLToPath(import.meta.url); 9 | const __dirname = path.dirname(__filename); 10 | 11 | class TelegramClient { 12 | constructor(apiId, apiHash, phoneNumber, sessionPath = './data/session.json') { 13 | this.apiId = apiId; 14 | this.apiHash = apiHash; 15 | this.phoneNumber = phoneNumber; 16 | this.sessionPath = path.resolve(sessionPath); 17 | 18 | // Create data directory if it doesn't exist 19 | const dataDir = path.dirname(this.sessionPath); 20 | if (!fs.existsSync(dataDir)) { 21 | fs.mkdirSync(dataDir, { recursive: true }); 22 | } 23 | 24 | // Initialize dialog cache for storing access hashes 25 | this.dialogCache = new Map(); 26 | 27 | // Initialize the MTProto client 28 | this.mtproto = new MTProto({ 29 | api_id: this.apiId, 30 | api_hash: this.apiHash, 31 | storageOptions: { 32 | path: this.sessionPath, 33 | }, 34 | }); 35 | } 36 | 37 | // Helper function to prompt for user input 38 | async _askQuestion(query) { 39 | const rl = readline.createInterface({ 40 | input: process.stdin, 41 | output: process.stdout, 42 | }); 43 | 44 | return new Promise(resolve => rl.question(query, answer => { 45 | rl.close(); 46 | resolve(answer); 47 | })); 48 | } 49 | 50 | // Check if session exists 51 | hasSession() { 52 | return fs.existsSync(this.sessionPath); 53 | } 54 | 55 | // Log in to Telegram 56 | async login() { 57 | try { 58 | // Check if session file exists 59 | if (this.hasSession()) { 60 | console.log('Session file found, attempting to validate session.'); 61 | try { 62 | // Attempt a simple API call to validate the session 63 | await this.mtproto.call('users.getUsers', { 64 | id: [{ _: 'inputUserSelf' }], 65 | }); 66 | console.log('Existing session is valid.'); 67 | return true; // Session is valid 68 | } catch (error) { 69 | console.warn(`Session validation failed: ${error.message || JSON.stringify(error)}. Assuming session is invalid.`); 70 | // Delete the invalid session file 71 | try { 72 | fs.unlinkSync(this.sessionPath); 73 | console.log('Deleted invalid session file.'); 74 | } catch (unlinkError) { 75 | console.error('Error deleting invalid session file:', unlinkError); 76 | } 77 | // Proceed to log in again 78 | } 79 | } 80 | 81 | console.log('No valid session found. Starting login process...'); 82 | // Request to send a code to the user's phone 83 | const { phone_code_hash } = await this.mtproto.call('auth.sendCode', { 84 | phone_number: this.phoneNumber, 85 | settings: { 86 | _: 'codeSettings', 87 | }, 88 | }); 89 | 90 | // Ask the user to enter the code they received 91 | const code = await this._askQuestion('Enter the code you received: '); 92 | 93 | let signInResult; 94 | try { 95 | // Attempt to sign in using the code 96 | signInResult = await this.mtproto.call('auth.signIn', { 97 | phone_number: this.phoneNumber, 98 | phone_code_hash, 99 | phone_code: code, 100 | }); 101 | } catch (error) { 102 | if (error.error_message === 'SESSION_PASSWORD_NEEDED') { 103 | // If 2FA is enabled, ask for the password 104 | const password = await this._askQuestion('Enter your 2FA password: '); 105 | 106 | // Get the password hash 107 | const { srp_id, current_algo, srp_B } = await this.mtproto.call('account.getPassword'); 108 | const { g, p, salt1, salt2 } = current_algo; 109 | 110 | // Compute the password hash 111 | const { A, M1 } = await this.mtproto.crypto.getSRPParams({ 112 | g, 113 | p, 114 | salt1, 115 | salt2, 116 | gB: srp_B, 117 | password, 118 | }); 119 | 120 | // Complete the sign-in process with the password 121 | signInResult = await this.mtproto.call('auth.checkPassword', { 122 | password: { 123 | _: 'inputCheckPasswordSRP', 124 | srp_id, 125 | A, 126 | M1, 127 | }, 128 | }); 129 | } else { 130 | throw error; 131 | } 132 | } 133 | 134 | console.log('Logged in successfully!'); 135 | return true; 136 | } catch (error) { 137 | console.error('Error during login:', error); 138 | return false; 139 | } 140 | } 141 | 142 | // Get all dialogs (chats) 143 | async getDialogs(limit = 100, offset = 0) { 144 | try { 145 | console.log(`Fetching up to ${limit} dialogs with offset ${offset}`); 146 | 147 | const result = await this.mtproto.call('messages.getDialogs', { 148 | offset, 149 | limit, 150 | offset_peer: { _: 'inputPeerSelf' }, 151 | }); 152 | 153 | console.log(`Retrieved ${result.chats.length} chats`); 154 | 155 | // Update dialog cache with the received chats 156 | this._updateDialogCache(result.chats); 157 | 158 | return { 159 | chats: result.chats, 160 | users: result.users, 161 | messages: result.messages, 162 | dialogs: result.dialogs 163 | }; 164 | } catch (error) { 165 | console.error('Error fetching dialogs:', error); 166 | throw error; 167 | } 168 | } 169 | 170 | // Get all dialogs by making multiple requests 171 | async getAllDialogs(batchSize = 100) { 172 | try { 173 | console.log('Fetching all dialogs...'); 174 | 175 | let allChats = []; 176 | let allUsers = []; 177 | let allMessages = []; 178 | let allDialogs = []; 179 | 180 | let offset = 0; 181 | let hasMore = true; 182 | 183 | while (hasMore) { 184 | const result = await this.mtproto.call('messages.getDialogs', { 185 | offset, 186 | limit: batchSize, 187 | offset_peer: { _: 'inputPeerSelf' }, 188 | }); 189 | 190 | allChats = [...allChats, ...result.chats]; 191 | allUsers = [...allUsers, ...result.users]; 192 | allMessages = [...allMessages, ...result.messages]; 193 | allDialogs = [...allDialogs, ...result.dialogs]; 194 | 195 | // Update the dialog cache with the received chats 196 | this._updateDialogCache(result.chats); 197 | 198 | // Check if we received fewer dialogs than requested, which means we've reached the end 199 | if (result.dialogs.length < batchSize) { 200 | hasMore = false; 201 | } else { 202 | offset += batchSize; 203 | } 204 | 205 | console.log(`Retrieved ${result.chats.length} chats at offset ${offset}`); 206 | } 207 | 208 | console.log(`Total chats retrieved: ${allChats.length}`); 209 | 210 | return { 211 | chats: allChats, 212 | users: allUsers, 213 | messages: allMessages, 214 | dialogs: allDialogs 215 | }; 216 | } catch (error) { 217 | console.error('Error fetching all dialogs:', error); 218 | throw error; 219 | } 220 | } 221 | 222 | // Update the dialog cache with chat information 223 | _updateDialogCache(chats) { 224 | if (!chats || !Array.isArray(chats)) return; 225 | 226 | for (const chat of chats) { 227 | if (!chat || !chat.id) continue; 228 | 229 | // Store only channels and users that have access_hash 230 | if ((chat._ === 'channel' || chat._ === 'user') && chat.access_hash) { 231 | this.dialogCache.set(chat.id, { 232 | type: chat._, 233 | id: chat.id, 234 | access_hash: chat.access_hash, 235 | title: chat.title || chat.username || chat.first_name 236 | }); 237 | } else if (chat._ === 'chat') { 238 | this.dialogCache.set(chat.id, { 239 | type: chat._, 240 | id: chat.id, 241 | title: chat.title 242 | }); 243 | } 244 | } 245 | } 246 | 247 | // Get peer input for a chat by ID 248 | getPeerInputById(id) { 249 | const cachedChat = this.dialogCache.get(`${id}`); 250 | 251 | if (!cachedChat) { 252 | throw new Error(`Chat with ID ${id} not found in cache. Run getAllDialogs first.`); 253 | } 254 | 255 | if (cachedChat.type === 'channel') { 256 | return { 257 | _: 'inputPeerChannel', 258 | channel_id: cachedChat.id, 259 | access_hash: cachedChat.access_hash, 260 | }; 261 | } else if (cachedChat.type === 'chat') { 262 | return { 263 | _: 'inputPeerChat', 264 | chat_id: cachedChat.id, 265 | }; 266 | } else if (cachedChat.type === 'user') { 267 | return { 268 | _: 'inputPeerUser', 269 | user_id: cachedChat.id, 270 | access_hash: cachedChat.access_hash, 271 | }; 272 | } 273 | 274 | throw new Error(`Unsupported chat type: ${cachedChat.type}`); 275 | } 276 | 277 | // Get messages from a specific chat 278 | async getChatMessages(chat, limit = 100) { 279 | try { 280 | if (!chat || !chat.id) { 281 | throw new Error('Invalid chat object provided'); 282 | } 283 | 284 | // Determine the correct peer type based on chat properties 285 | let peer; 286 | if (chat._ === 'channel' || chat._ === 'channelForbidden') { 287 | peer = { 288 | _: 'inputPeerChannel', 289 | channel_id: chat.id, 290 | access_hash: chat.access_hash, 291 | }; 292 | } else if (chat._ === 'chat' || chat._ === 'chatForbidden') { 293 | peer = { 294 | _: 'inputPeerChat', 295 | chat_id: chat.id, 296 | }; 297 | } else if (chat._ === 'user') { 298 | peer = { 299 | _: 'inputPeerUser', 300 | user_id: chat.id, 301 | access_hash: chat.access_hash, 302 | }; 303 | } else { 304 | throw new Error(`Unsupported chat type: ${chat._}`); 305 | } 306 | 307 | console.log(`Fetching up to ${limit} messages from chat: ${chat.title || chat.id}`); 308 | 309 | const messagesResult = await this.mtproto.call('messages.getHistory', { 310 | peer, 311 | offset_id: 0, 312 | offset_date: 0, 313 | add_offset: 0, 314 | limit, 315 | max_id: 0, 316 | min_id: 0, 317 | hash: 0, 318 | }); 319 | 320 | return messagesResult.messages; 321 | } catch (error) { 322 | console.error('Error fetching chat messages:', error); 323 | throw error; 324 | } 325 | } 326 | 327 | // Filter messages by a regex pattern 328 | filterMessagesByPattern(messages, pattern) { 329 | if (!messages || !Array.isArray(messages)) { 330 | return []; 331 | } 332 | 333 | const regex = new RegExp(pattern); 334 | return messages 335 | .map(msg => msg.message || '') 336 | .filter(msg => regex.test(msg)); 337 | } 338 | 339 | // Get messages from a specific chat using ID 340 | async getMessagesByChannelId(channelId, limit = 100) { 341 | try { 342 | // Convert string IDs to numbers if necessary 343 | const id = typeof channelId === 'string' ? parseInt(channelId, 10) : channelId; 344 | 345 | if (isNaN(id)) { 346 | throw new Error('Invalid channel ID provided'); 347 | } 348 | 349 | // Get peer input from cache 350 | const peer = this.getPeerInputById(id); 351 | const cachedChat = this.dialogCache.get(`${id}`); 352 | 353 | console.log(`Fetching up to ${limit} messages from channel ID ${id} (${cachedChat.title || 'Unknown'})`); 354 | 355 | const messagesResult = await this.mtproto.call('messages.getHistory', { 356 | peer, 357 | offset_id: 0, 358 | offset_date: 0, 359 | add_offset: 0, 360 | limit, 361 | max_id: 0, 362 | min_id: 0, 363 | hash: 0, 364 | }); 365 | 366 | return messagesResult.messages; 367 | } catch (error) { 368 | console.error('Error fetching channel messages:', error); 369 | throw error; 370 | } 371 | } 372 | 373 | // Save dialog cache to file 374 | async saveDialogCache(cachePath = './data/dialog_cache.json') { 375 | try { 376 | const resolvedPath = path.resolve(cachePath); 377 | const cacheDir = path.dirname(resolvedPath); 378 | 379 | // Create directory if it doesn't exist 380 | if (!fs.existsSync(cacheDir)) { 381 | fs.mkdirSync(cacheDir, { recursive: true }); 382 | } 383 | 384 | // Convert Map to object for serialization 385 | const cacheObject = Object.fromEntries(this.dialogCache); 386 | 387 | fs.writeFileSync(resolvedPath, JSON.stringify(cacheObject, null, 2)); 388 | console.log(`Dialog cache saved to ${resolvedPath}`); 389 | 390 | return true; 391 | } catch (error) { 392 | console.error('Error saving dialog cache:', error); 393 | return false; 394 | } 395 | } 396 | 397 | // Load dialog cache from file 398 | async loadDialogCache(cachePath = './data/dialog_cache.json') { 399 | try { 400 | const resolvedPath = path.resolve(cachePath); 401 | 402 | if (!fs.existsSync(resolvedPath)) { 403 | console.log(`Dialog cache file not found at ${resolvedPath}`); 404 | return false; 405 | } 406 | 407 | const cacheData = JSON.parse(fs.readFileSync(resolvedPath, 'utf8')); 408 | 409 | // Convert object back to Map 410 | this.dialogCache = new Map(Object.entries(cacheData)); 411 | 412 | console.log(`Dialog cache loaded from ${resolvedPath} with ${this.dialogCache.size} entries`); 413 | 414 | return true; 415 | } catch (error) { 416 | console.error('Error loading dialog cache:', error); 417 | return false; 418 | } 419 | } 420 | 421 | // Helper function to add delay between API calls 422 | async delay(ms) { 423 | return new Promise(resolve => setTimeout(resolve, ms)); 424 | } 425 | 426 | // Initialize dialog cache with throttling to avoid FLOOD_WAIT 427 | async initializeDialogCache(dialogCachePath = './data/dialog_cache.json') { 428 | try { 429 | console.log('Initializing dialog cache...'); 430 | 431 | // First, ensure we are logged in 432 | const loginSuccess = await this.login(); 433 | if (!loginSuccess) { 434 | // Throw an error specifically for login failure 435 | throw new Error('Failed to login to Telegram. Cannot proceed.'); 436 | } 437 | 438 | // Try to load existing cache 439 | let cacheLoaded = false; 440 | try { 441 | cacheLoaded = await this.loadDialogCache(dialogCachePath); 442 | console.log(`Dialog cache ${cacheLoaded ? 'loaded successfully' : 'not found or empty'}`); 443 | } catch (error) { 444 | console.log('Error loading dialog cache:', error.message); 445 | } 446 | 447 | // If cache is empty or couldn't be loaded, fetch dialogs with careful throttling 448 | if (!cacheLoaded || this.dialogCache.size === 0) { 449 | console.log('Fetching all dialogs with throttling...'); 450 | 451 | let allChats = new Map(); // Use Map to prevent duplicates 452 | let lastDate = 0; // Use date-based pagination 453 | let lastMsgId = 0; // Track last message ID for pagination 454 | let lastPeer = null; // Last peer for offset 455 | let hasMore = true; 456 | let batchSize = 100; 457 | let retryCount = 0; 458 | let batchCount = 0; 459 | const MAX_RETRIES = 3; 460 | 461 | while (hasMore && retryCount < MAX_RETRIES) { 462 | try { 463 | batchCount++; 464 | console.log(`Fetching dialogs batch #${batchCount} with date offset ${lastDate || 'none'}...`); 465 | 466 | // Call Telegram API with throttling and proper pagination 467 | const result = await this.mtproto.call('messages.getDialogs', { 468 | offset_date: lastDate, 469 | offset_id: lastMsgId, 470 | offset_peer: lastPeer || { _: 'inputPeerEmpty' }, 471 | limit: batchSize, 472 | hash: 0 473 | }); 474 | 475 | // Process the results 476 | if (result && result.chats && result.chats.length > 0) { 477 | const newChatCount = result.chats.length; 478 | const prevSize = allChats.size; 479 | 480 | // Add chats to our Map to de-duplicate 481 | result.chats.forEach(chat => { 482 | if (chat && chat.id) { 483 | allChats.set(chat.id, chat); 484 | } 485 | }); 486 | 487 | // Update dialog cache 488 | this._updateDialogCache(result.chats); 489 | 490 | console.log(`Retrieved ${newChatCount} chats (${allChats.size - prevSize} new), total unique now: ${allChats.size}`); 491 | 492 | // Check if we've reached the end based on received count or no dialogs 493 | if (!result.dialogs || result.dialogs.length === 0 || result.dialogs.length < batchSize) { 494 | hasMore = false; 495 | console.log('Reached end of dialogs (received less than requested)'); 496 | } else if (result.dialogs.length > 0) { 497 | // Update pagination parameters from the last dialog 498 | const lastDialog = result.dialogs[result.dialogs.length - 1]; 499 | const lastMessage = result.messages.find(m => m.id === lastDialog.top_message); 500 | 501 | if (lastMessage) { 502 | lastDate = lastMessage.date; 503 | lastMsgId = lastMessage.id; 504 | lastPeer = lastDialog.peer; 505 | 506 | console.log(`Updated pagination: last_date=${lastDate}, last_msg_id=${lastMsgId}`); 507 | } else { 508 | console.log('Could not find last message for pagination, stopping'); 509 | hasMore = false; 510 | } 511 | 512 | // Add delay to avoid rate limiting 513 | console.log(`Waiting 2 seconds before next batch...`); 514 | await this.delay(2000); 515 | } else { 516 | // No more dialogs 517 | hasMore = false; 518 | } 519 | 520 | // Safety check - if we get the same chats multiple times, stop 521 | if (batchCount > 1 && newChatCount === allChats.size && newChatCount === prevSize) { 522 | console.log('No new chats in this batch, likely reached the end'); 523 | hasMore = false; 524 | } 525 | } else { 526 | // No results or unexpected response 527 | hasMore = false; 528 | console.log('No chats in response or unexpected response format'); 529 | } 530 | 531 | // Reset retry counter on success 532 | retryCount = 0; 533 | } catch (error) { 534 | console.error(`Error fetching dialogs: ${error.message || JSON.stringify(error)}`); 535 | 536 | // Handle FLOOD_WAIT errors by waiting the specified time 537 | if (error.error_code === 420 && error.error_message) { 538 | const waitMatch = error.error_message.match(/FLOOD_WAIT_(\d+)/); 539 | if (waitMatch && waitMatch[1]) { 540 | const waitSeconds = parseInt(waitMatch[1], 10); 541 | console.log(`Rate limited, waiting ${waitSeconds} seconds before retrying...`); 542 | await this.delay(waitSeconds * 1000); 543 | retryCount++; 544 | } else { 545 | // Unknown flood wait, use exponential backoff 546 | const backoff = Math.pow(2, retryCount) * 5; 547 | console.log(`Unknown rate limit, backing off for ${backoff} seconds...`); 548 | await this.delay(backoff * 1000); 549 | retryCount++; 550 | } 551 | } else { 552 | // For other errors, back off and retry 553 | retryCount++; 554 | await this.delay(5000 * retryCount); 555 | } 556 | } 557 | } 558 | 559 | // Extract chats from Map for final count 560 | const finalChats = Array.from(allChats.values()); 561 | console.log(`Finished fetching dialogs. Found ${finalChats.length} unique chats.`); 562 | 563 | // Save the cache after successful fetch 564 | try { 565 | await this.saveDialogCache(dialogCachePath); 566 | } catch (error) { 567 | console.error('Error saving dialog cache:', error.message); 568 | } 569 | } 570 | 571 | console.log(`Dialog cache initialized with ${this.dialogCache.size} entries`); 572 | return true; 573 | } catch (error) { 574 | console.error('Failed to initialize dialog cache:', error); 575 | return false; 576 | } 577 | } 578 | 579 | // Simplified login check 580 | async ensureLogin() { 581 | // Just verify we have a session 582 | if (!this.hasSession()) { 583 | throw new Error('Not logged in to Telegram. Please restart the server.'); 584 | } 585 | return true; 586 | } 587 | } 588 | 589 | export default TelegramClient; --------------------------------------------------------------------------------