├── media-tools-server ├── .gitignore ├── tsconfig.json ├── package.json ├── README.md ├── src │ └── index.ts └── package-lock.json ├── information-retrieval-server ├── .gitignore ├── tsconfig.json ├── package.json ├── README.md ├── src │ └── index.ts └── package-lock.json ├── presentation-creator-server ├── .gitignore ├── requirements.txt ├── tsconfig.json ├── package.json ├── README.md ├── presentation_creator_server.py ├── src │ └── index.ts └── package-lock.json ├── pdf-creator-server ├── requirements.txt ├── README.md ├── setup.py └── pdf_creator_server.py ├── .gitignore ├── example_mcp_settings.json ├── PUBLISHED_PACKAGES.md ├── .github └── copilot-instructions.md └── README.md /media-tools-server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | *.log 4 | .env* -------------------------------------------------------------------------------- /information-retrieval-server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | *.log 4 | .env* -------------------------------------------------------------------------------- /presentation-creator-server/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules/ 2 | build/ 3 | *.log 4 | .env* -------------------------------------------------------------------------------- /pdf-creator-server/requirements.txt: -------------------------------------------------------------------------------- 1 | fastmcp 2 | playwright 3 | python-dotenv 4 | Pillow 5 | -------------------------------------------------------------------------------- /presentation-creator-server/requirements.txt: -------------------------------------------------------------------------------- 1 | fastmcp 2 | playwright 3 | python-dotenv 4 | python-pptx 5 | -------------------------------------------------------------------------------- /media-tools-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules"] 15 | } 16 | -------------------------------------------------------------------------------- /information-retrieval-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules"] 15 | } 16 | -------------------------------------------------------------------------------- /presentation-creator-server/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "Node16", 5 | "moduleResolution": "Node16", 6 | "outDir": "./build", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true 12 | }, 13 | "include": ["src/**/*"], 14 | "exclude": ["node_modules"] 15 | } 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Node.js / TypeScript 2 | node_modules/ 3 | dist/ 4 | build/ 5 | *.log 6 | .env* 7 | !.env.example 8 | 9 | # Python 10 | __pycache__/ 11 | *.py[cod] 12 | *$py.class 13 | .venv/ 14 | venv/ 15 | ENV/ 16 | env/ 17 | pip-log.txt 18 | pip-delete-this-directory.txt 19 | .eggs/ 20 | *.egg-info/ 21 | *.egg 22 | 23 | # OS generated files 24 | .DS_Store 25 | Thumbs.db 26 | 27 | # Config files with API keys (DO NOT COMMIT) 28 | npx_mcp_settings_with_keys.json 29 | *_with_keys.json 30 | -------------------------------------------------------------------------------- /pdf-creator-server/README.md: -------------------------------------------------------------------------------- 1 | # PDF Creator Server MCP 2 | 3 | A Model Context Protocol server for creating PDF documents from HTML. 4 | 5 | ## Features 6 | 7 | - Create PDF documents from HTML content 8 | - Fast and efficient PDF generation 9 | - Easy integration with MCP clients 10 | 11 | ## Installation 12 | 13 | ```bash 14 | pip install pdf-creator-server-mcp 15 | ``` 16 | 17 | ## Usage 18 | 19 | To use with Claude Desktop or other MCP clients, add the server config: 20 | 21 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 22 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 23 | 24 | ```json 25 | { 26 | "mcpServers": { 27 | "pdf-creator": { 28 | "command": "pdf-creator-server" 29 | } 30 | } 31 | } 32 | ``` 33 | 34 | ## Development 35 | 36 | Install dependencies: 37 | ```bash 38 | pip install -r requirements.txt 39 | ``` 40 | 41 | ## License 42 | 43 | MIT 44 | -------------------------------------------------------------------------------- /example_mcp_settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "mcpServers": { 3 | "information-retrieval": { 4 | "command": "npx", 5 | "args": ["-y", "information-retrieval-mcp-server"], 6 | "env": { 7 | "GOOGLE_API_KEY": "YOUR_GOOGLE_API_KEY_HERE", 8 | "GOOGLE_CSE_ID": "YOUR_GOOGLE_CUSTOM_SEARCH_ENGINE_ID_HERE" 9 | }, 10 | "disabled": false, 11 | "autoApprove": [] 12 | }, 13 | "media-tools": { 14 | "command": "npx", 15 | "args": ["-y", "media-tools-mcp-server"], 16 | "env": { 17 | "UNSPLASH_ACCESS_KEY": "YOUR_UNSPLASH_API_KEY_HERE", 18 | "GEMINI_API_KEY": "YOUR_GEMINI_API_KEY_HERE" 19 | }, 20 | "disabled": false, 21 | "autoApprove": [], 22 | "alwaysAllow": [ 23 | "image_search", 24 | "download_image", 25 | "video_search", 26 | "video_understanding", 27 | "image_understanding", 28 | "image_generation" 29 | ] 30 | }, 31 | "presentation-creator": { 32 | "command": "npx", 33 | "args": ["-y", "presentation-creator-mcp-server"], 34 | "env": {}, 35 | "disabled": false, 36 | "autoApprove": [] 37 | }, 38 | "pdf-creator": { 39 | "command": "C:/absolute/path/to/unified-mcp-suite/pdf-creator-server/.venv/Scripts/python.exe", 40 | "args": ["C:/absolute/path/to/unified-mcp-suite/pdf-creator-server/pdf_creator_server.py"], 41 | "env": {}, 42 | "disabled": false, 43 | "autoApprove": [], 44 | "alwaysAllow": [] 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /presentation-creator-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "presentation-creator-mcp-server", 3 | "version": "0.1.4", 4 | "description": "MCP server for creating presentations and PDF documents from HTML", 5 | "type": "module", 6 | "author": "Godzilla675", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/Godzilla675/agentic-ai-tool-suite.git", 11 | "directory": "presentation-creator-server" 12 | }, 13 | "keywords": [ 14 | "mcp", 15 | "model-context-protocol", 16 | "presentation", 17 | "pdf", 18 | "powerpoint", 19 | "html-to-pdf" 20 | ], 21 | "bin": { 22 | "presentation-creator-server": "./build/index.js" 23 | }, 24 | "files": [ 25 | "build" 26 | ], 27 | "scripts": { 28 | "build": "tsc && esbuild build/index.js --bundle --platform=node --format=esm --packages=external --outfile=build/index.js --allow-overwrite && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 29 | "prepare": "npm run build", 30 | "watch": "tsc --watch", 31 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 32 | }, 33 | "dependencies": { 34 | "@modelcontextprotocol/sdk": "0.6.0", 35 | "playwright": "^1.51.1", 36 | "pptxgenjs": "^3.12.0", 37 | "zod": "^3.22.4" 38 | }, 39 | "devDependencies": { 40 | "@modelcontextprotocol/sdk": "0.6.0", 41 | "@types/node": "^20.11.24", 42 | "esbuild": "^0.25.11", 43 | "pptxgenjs": "^3.12.0", 44 | "typescript": "^5.3.3", 45 | "zod": "^3.22.4" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /information-retrieval-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "information-retrieval-mcp-server", 3 | "version": "0.1.3", 4 | "description": "MCP server for information retrieval with web search, web crawling, and image search capabilities", 5 | "type": "module", 6 | "author": "Godzilla675", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/Godzilla675/agentic-ai-tool-suite.git", 11 | "directory": "information-retrieval-server" 12 | }, 13 | "keywords": [ 14 | "mcp", 15 | "model-context-protocol", 16 | "web-search", 17 | "web-crawling", 18 | "information-retrieval" 19 | ], 20 | "bin": { 21 | "information-retrieval-server": "./build/index.js" 22 | }, 23 | "files": [ 24 | "build" 25 | ], 26 | "scripts": { 27 | "build": "tsc && esbuild build/index.js --bundle --platform=node --format=esm --packages=external --outfile=build/index.js --allow-overwrite && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 28 | "prepare": "npm run build", 29 | "watch": "tsc --watch", 30 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 31 | }, 32 | "dependencies": { 33 | "@modelcontextprotocol/sdk": "0.6.0", 34 | "axios": "^1.8.4", 35 | "cheerio": "^1.0.0", 36 | "playwright": "^1.51.1", 37 | "zod": "^3.22.4" 38 | }, 39 | "devDependencies": { 40 | "@modelcontextprotocol/sdk": "0.6.0", 41 | "@types/cheerio": "^0.22.35", 42 | "@types/node": "^20.11.24", 43 | "axios": "^1.8.4", 44 | "cheerio": "^1.0.0", 45 | "esbuild": "^0.25.11", 46 | "typescript": "^5.3.3", 47 | "zod": "^3.22.4" 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pdf-creator-server/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | import os 3 | 4 | # Read README 5 | try: 6 | with open("README.md", "r", encoding="utf-8") as fh: 7 | long_description = fh.read() 8 | except FileNotFoundError: 9 | long_description = "MCP server for creating PDF documents from HTML" 10 | 11 | # Read requirements 12 | requirements = ["fastmcp", "playwright", "python-dotenv", "Pillow"] 13 | if os.path.exists("requirements.txt"): 14 | with open("requirements.txt", "r", encoding="utf-8") as fh: 15 | requirements = [line.strip() for line in fh if line.strip() and not line.startswith("#")] 16 | 17 | setup( 18 | name="pdf-creator-server-mcp", 19 | version="0.1.0", 20 | author="Godzilla675", 21 | description="MCP server for creating PDF documents from HTML", 22 | long_description=long_description, 23 | long_description_content_type="text/markdown", 24 | url="https://github.com/Godzilla675/agentic-ai-tool-suite", 25 | packages=find_packages(), 26 | classifiers=[ 27 | "Development Status :: 3 - Alpha", 28 | "Intended Audience :: Developers", 29 | "License :: OSI Approved :: MIT License", 30 | "Programming Language :: Python :: 3", 31 | "Programming Language :: Python :: 3.8", 32 | "Programming Language :: Python :: 3.9", 33 | "Programming Language :: Python :: 3.10", 34 | "Programming Language :: Python :: 3.11", 35 | ], 36 | python_requires=">=3.8", 37 | install_requires=requirements, 38 | py_modules=["pdf_creator_server"], 39 | entry_points={ 40 | "console_scripts": [ 41 | "pdf-creator-server=pdf_creator_server:main", 42 | ], 43 | }, 44 | ) 45 | -------------------------------------------------------------------------------- /media-tools-server/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "media-tools-mcp-server", 3 | "version": "0.1.5", 4 | "description": "MCP server for media operations including image search, video search, and media understanding", 5 | "type": "module", 6 | "author": "Godzilla675", 7 | "license": "MIT", 8 | "repository": { 9 | "type": "git", 10 | "url": "https://github.com/Godzilla675/agentic-ai-tool-suite.git", 11 | "directory": "media-tools-server" 12 | }, 13 | "keywords": [ 14 | "mcp", 15 | "model-context-protocol", 16 | "media", 17 | "image-search", 18 | "video-search", 19 | "youtube" 20 | ], 21 | "bin": { 22 | "media-tools-server": "./build/index.js" 23 | }, 24 | "files": [ 25 | "build" 26 | ], 27 | "scripts": { 28 | "build": "tsc && esbuild build/index.js --bundle --platform=node --format=esm --packages=external --outfile=build/index.js --allow-overwrite && node -e \"require('fs').chmodSync('build/index.js', '755')\"", 29 | "prepare": "npm run build", 30 | "watch": "tsc --watch", 31 | "inspector": "npx @modelcontextprotocol/inspector build/index.js" 32 | }, 33 | "dependencies": { 34 | "@google/generative-ai": "^0.24.0", 35 | "@modelcontextprotocol/sdk": "0.6.0", 36 | "axios": "^1.8.4", 37 | "mime-types": "^3.0.1", 38 | "youtube-transcript": "^1.2.1", 39 | "zod": "^3.22.4" 40 | }, 41 | "devDependencies": { 42 | "@google/generative-ai": "^0.24.0", 43 | "@modelcontextprotocol/sdk": "0.6.0", 44 | "@types/mime-types": "^2.1.4", 45 | "@types/node": "^20.11.24", 46 | "axios": "^1.8.4", 47 | "esbuild": "^0.25.11", 48 | "mime-types": "^3.0.1", 49 | "typescript": "^5.3.3", 50 | "youtube-transcript": "^1.2.1", 51 | "zod": "^3.22.4" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /presentation-creator-server/README.md: -------------------------------------------------------------------------------- 1 | # presentation-creator-server MCP Server 2 | 3 | A Model Context Protocol server for creating PowerPoint presentations and PDF documents from HTML content using Playwright. 4 | 5 | ## Features 6 | 7 | ### Tools 8 | 9 | - **`assemble_presentation`** - Create PowerPoint presentations from HTML slides 10 | - Takes a list of HTML strings (one per slide) 11 | - Screenshots each HTML slide and assembles into PPTX 12 | - Customizable filename 13 | - Outputs to ~/Downloads folder 14 | - Standard 16:9 aspect ratio (800x450 viewport) 15 | 16 | - **`create_pdf_from_html`** - Generate PDF documents from HTML content 17 | - Accepts full HTML document as string 18 | - A4 format with configurable margins 19 | - Includes background colors and images 20 | - Outputs to ~/Downloads folder 21 | 22 | **Note:** This server requires Playwright browsers to be installed. After installation, run: 23 | ```bash 24 | npx playwright install chromium 25 | ``` 26 | 27 | ## Development 28 | 29 | Install dependencies: 30 | ```bash 31 | npm install 32 | ``` 33 | 34 | Build the server: 35 | ```bash 36 | npm run build 37 | ``` 38 | 39 | For development with auto-rebuild: 40 | ```bash 41 | npm run watch 42 | ``` 43 | 44 | ## Installation 45 | 46 | ### Quick Start (Recommended) 47 | 48 | The easiest way to use this MCP server is with `npx`. No installation required! 49 | 50 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 51 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 52 | 53 | ```json 54 | { 55 | "mcpServers": { 56 | "presentation-creator": { 57 | "command": "npx", 58 | "args": ["-y", "presentation-creator-mcp-server"] 59 | } 60 | } 61 | } 62 | ``` 63 | 64 | **Important:** After first use, you may need to install Playwright browsers: 65 | ```bash 66 | npx playwright install chromium 67 | ``` 68 | 69 | ### Alternative: Global Installation 70 | 71 | If you prefer to install the package globally: 72 | 73 | ```bash 74 | npm install -g presentation-creator-mcp-server 75 | npx playwright install chromium 76 | ``` 77 | 78 | Then configure: 79 | 80 | ```json 81 | { 82 | "mcpServers": { 83 | "presentation-creator": { 84 | "command": "presentation-creator-mcp-server" 85 | } 86 | } 87 | } 88 | ``` 89 | 90 | ### Debugging 91 | 92 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script: 93 | 94 | ```bash 95 | npm run inspector 96 | ``` 97 | 98 | The Inspector will provide a URL to access debugging tools in your browser. 99 | -------------------------------------------------------------------------------- /information-retrieval-server/README.md: -------------------------------------------------------------------------------- 1 | # information-retrieval-server MCP Server 2 | 3 | A Model Context Protocol server for web information retrieval using Google Custom Search API and web crawling capabilities. 4 | 5 | ## Features 6 | 7 | ### Tools 8 | 9 | - **`web_search`** - Perform web searches using Google Custom Search API 10 | - Returns titles, links, and snippets for top search results 11 | - Configurable result count (1-10) 12 | 13 | - **`batch_web_search`** - Perform multiple web searches simultaneously 14 | - Execute up to 15 queries in parallel 15 | - Returns titles and links for each query 16 | 17 | - **`google_image_search`** - Search for images using Google Custom Search 18 | - Returns image URLs, titles, and context 19 | - Configurable result count (1-10) 20 | 21 | - **`web_crawl`** - Extract text content from webpages 22 | - Fast HTTP-based content extraction 23 | - Removes scripts, styles, and navigation elements 24 | 25 | - **`advanced_web_crawl`** - Extract content using headless browser 26 | - More robust for JavaScript-heavy sites 27 | - Handles sites that block simple HTTP requests 28 | - Slower but more reliable 29 | 30 | ## Development 31 | 32 | Install dependencies: 33 | ```bash 34 | npm install 35 | ``` 36 | 37 | Build the server: 38 | ```bash 39 | npm run build 40 | ``` 41 | 42 | For development with auto-rebuild: 43 | ```bash 44 | npm run watch 45 | ``` 46 | 47 | ## Installation 48 | 49 | ### Quick Start (Recommended) 50 | 51 | The easiest way to use this MCP server is with `npx`. No installation required! 52 | 53 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 54 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 55 | 56 | ```json 57 | { 58 | "mcpServers": { 59 | "information-retrieval": { 60 | "command": "npx", 61 | "args": ["-y", "information-retrieval-mcp-server"] 62 | } 63 | } 64 | } 65 | ``` 66 | 67 | ### Alternative: Global Installation 68 | 69 | If you prefer to install the package globally: 70 | 71 | ```bash 72 | npm install -g information-retrieval-mcp-server 73 | ``` 74 | 75 | Then configure: 76 | 77 | ```json 78 | { 79 | "mcpServers": { 80 | "information-retrieval": { 81 | "command": "information-retrieval-mcp-server" 82 | } 83 | } 84 | } 85 | ``` 86 | 87 | ### Debugging 88 | 89 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script: 90 | 91 | ```bash 92 | npm run inspector 93 | ``` 94 | 95 | The Inspector will provide a URL to access debugging tools in your browser. 96 | -------------------------------------------------------------------------------- /media-tools-server/README.md: -------------------------------------------------------------------------------- 1 | # media-tools-server MCP Server 2 | 3 | A Model Context Protocol server for media search, download, and understanding using Unsplash, YouTube, and Google Gemini APIs. 4 | 5 | ## Features 6 | 7 | ### Tools 8 | 9 | - **`image_search`** - Search for high-quality images on Unsplash 10 | - Returns image URLs, descriptions, and photographer credits 11 | - Configurable result count (default: 5) 12 | 13 | - **`download_image`** - Download images from URLs to local filesystem 14 | - Supports any image URL 15 | - Saves with custom filename and path 16 | 17 | - **`video_search`** - Search for YouTube videos 18 | - Returns video IDs, titles, descriptions, and channel info 19 | - Configurable result count (default: 5) 20 | 21 | - **`video_understanding`** - Extract transcripts from YouTube videos 22 | - Returns timestamped transcript text 23 | - Useful for content analysis and summarization 24 | - Note: Only works with videos that have transcripts/captions enabled 25 | 26 | - **`image_understanding`** - Analyze images using Google Gemini AI (gemini-2.5-flash) 27 | - Accepts image URLs or local file paths 28 | - Optional custom prompts for guided analysis 29 | - Returns detailed image descriptions 30 | - Powered by Google's latest multimodal AI 31 | 32 | - **`image_generation`** - Generate detailed image descriptions using Google Gemini AI 33 | - Creates highly detailed visual descriptions suitable for image generation 34 | - Descriptions can be used with DALL-E, Midjourney, Stable Diffusion, etc. 35 | - Optional file path to save description as text 36 | - Note: Gemini creates descriptions, not actual image files 37 | 38 | ## Development 39 | 40 | Install dependencies: 41 | ```bash 42 | npm install 43 | ``` 44 | 45 | Build the server: 46 | ```bash 47 | npm run build 48 | ``` 49 | 50 | For development with auto-rebuild: 51 | ```bash 52 | npm run watch 53 | ``` 54 | 55 | ## Installation 56 | 57 | ### Quick Start (Recommended) 58 | 59 | The easiest way to use this MCP server is with `npx`. No installation required! 60 | 61 | On MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 62 | On Windows: `%APPDATA%/Claude/claude_desktop_config.json` 63 | 64 | ```json 65 | { 66 | "mcpServers": { 67 | "media-tools": { 68 | "command": "npx", 69 | "args": ["-y", "media-tools-mcp-server"] 70 | } 71 | } 72 | } 73 | ``` 74 | 75 | **Note:** This server requires a Google Gemini API key for image understanding features. Set it as an environment variable: 76 | 77 | ```json 78 | { 79 | "mcpServers": { 80 | "media-tools": { 81 | "command": "npx", 82 | "args": ["-y", "media-tools-mcp-server"], 83 | "env": { 84 | "GEMINI_API_KEY": "your-api-key-here" 85 | } 86 | } 87 | } 88 | } 89 | ``` 90 | 91 | ### Alternative: Global Installation 92 | 93 | If you prefer to install the package globally: 94 | 95 | ```bash 96 | npm install -g media-tools-mcp-server 97 | ``` 98 | 99 | Then configure: 100 | 101 | ```json 102 | { 103 | "mcpServers": { 104 | "media-tools": { 105 | "command": "media-tools-mcp-server", 106 | "env": { 107 | "GEMINI_API_KEY": "your-api-key-here" 108 | } 109 | } 110 | } 111 | } 112 | ``` 113 | 114 | ### Debugging 115 | 116 | Since MCP servers communicate over stdio, debugging can be challenging. We recommend using the [MCP Inspector](https://github.com/modelcontextprotocol/inspector), which is available as a package script: 117 | 118 | ```bash 119 | npm run inspector 120 | ``` 121 | 122 | The Inspector will provide a URL to access debugging tools in your browser. 123 | -------------------------------------------------------------------------------- /pdf-creator-server/pdf_creator_server.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import logging 5 | import tempfile 6 | import shutil 7 | from pathlib import Path 8 | from mcp.server.fastmcp import FastMCP 9 | from playwright.async_api import async_playwright 10 | from dotenv import load_dotenv 11 | from typing import List, Dict, Any # Import typing helpers 12 | from PIL import Image # Import Pillow 13 | 14 | # Configure logging 15 | logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(asctime)s - %(levelname)s - %(message)s') 16 | 17 | # Load environment variables (though none are strictly needed for this server) 18 | load_dotenv() 19 | 20 | # --- Server Setup --- 21 | mcp = FastMCP( 22 | "pdf-creator-server", 23 | version="0.1.0", 24 | title="PDF Creator Server", 25 | description="Generates PDF documents from HTML content.",) 26 | 27 | 28 | # --- Tool Implementation --- 29 | @mcp.tool() 30 | async def create_pdf_from_html(html_content: str, filename: str = "document") -> str: 31 | """ 32 | Generates a PDF document from a string containing HTML code. 33 | 34 | Args: 35 | html_content: A string containing the full HTML code for the document. 36 | filename: The desired base name for the output PDF file (without extension). 37 | 38 | Returns: 39 | The absolute path to the generated .pdf file or an error message. 40 | """ 41 | logging.info(f"Received request to create PDF: {filename}.pdf") 42 | temp_dir = None 43 | html_path = None 44 | try: 45 | if not isinstance(html_content, str) or not html_content.strip(): 46 | return "Error: html_content must be a non-empty string." 47 | 48 | # Create a temporary directory and file for the HTML 49 | temp_dir = tempfile.mkdtemp(prefix="mcp_pdf_") 50 | html_path = os.path.join(temp_dir, "content.html") 51 | with open(html_path, "w", encoding="utf-8") as f: 52 | f.write(html_content) 53 | logging.info(f"Saved HTML to temporary file: {html_path}") 54 | 55 | # Launch Playwright and generate PDF 56 | async with async_playwright() as p: 57 | browser = await p.chromium.launch() 58 | page = await browser.new_page() 59 | 60 | await page.goto(f"file://{html_path}") 61 | 62 | # Take full page screenshot 63 | img_path = os.path.join(temp_dir, "screenshot.png") 64 | await page.screenshot(path=img_path, full_page=True) 65 | logging.info(f"Screenshot saved to temporary file: {img_path}") 66 | 67 | await browser.close() 68 | 69 | # Convert screenshot image to PDF using Pillow 70 | downloads_path = Path.home() / "Downloads" 71 | downloads_path.mkdir(parents=True, exist_ok=True) 72 | output_filename = f"{filename}.pdf" 73 | output_path = downloads_path / output_filename 74 | 75 | try: 76 | image = Image.open(img_path) 77 | # Ensure image is in RGB mode for saving as PDF 78 | image = image.convert('RGB') 79 | image.save(output_path, "PDF", resolution=100.0) # Save as PDF 80 | except Exception as img_err: 81 | logging.error(f"Error converting image to PDF: {img_err}") 82 | raise img_err # Re-raise to be caught by the main handler 83 | 84 | final_path = str(output_path.resolve()) 85 | logging.info(f"PDF (from screenshot) saved to: {final_path}") 86 | return f"PDF successfully created and saved to: {final_path}" 87 | 88 | except Exception as e: 89 | logging.exception("An error occurred during PDF creation.") 90 | return f"Error creating PDF: {e}" 91 | finally: 92 | # Clean up temporary directory/file 93 | if temp_dir and os.path.exists(temp_dir): 94 | try: 95 | shutil.rmtree(temp_dir) 96 | logging.info(f"Cleaned up temporary directory: {temp_dir}") 97 | except Exception as e: 98 | logging.error(f"Error cleaning up temporary directory {temp_dir}: {e}") 99 | 100 | 101 | # --- Server Execution --- 102 | if __name__ == "__main__": 103 | logging.info("Starting PDF Creator Server...") 104 | mcp.run(transport='stdio') 105 | logging.info("PDF Creator Server stopped.") 106 | -------------------------------------------------------------------------------- /PUBLISHED_PACKAGES.md: -------------------------------------------------------------------------------- 1 | # Published MCP Server Packages 2 | 3 | This document lists all published MCP server packages from the Agentic AI Tool Suite. 4 | 5 | ## 📦 NPM Packages (Published) 6 | 7 | All TypeScript/Node.js servers are available on npm and can be used directly with `npx` - no installation required! 8 | 9 | ### 1. information-retrieval-mcp-server 10 | 11 | **Package**: `information-retrieval-mcp-server` 12 | **Version**: 0.1.0 13 | **NPM**: https://www.npmjs.com/package/information-retrieval-mcp-server 14 | 15 | **Features**: 16 | - Web search using Google Custom Search API 17 | - Batch web search (up to 15 queries) 18 | - Google image search 19 | - Web page crawling (simple and advanced with headless browser) 20 | 21 | **Installation**: 22 | ```bash 23 | # Using npx (recommended) 24 | npx -y information-retrieval-mcp-server 25 | 26 | # Or install globally 27 | npm install -g information-retrieval-mcp-server 28 | ``` 29 | 30 | **Configuration**: 31 | ```json 32 | { 33 | "mcpServers": { 34 | "information-retrieval": { 35 | "command": "npx", 36 | "args": ["-y", "information-retrieval-mcp-server"], 37 | "env": { 38 | "GOOGLE_API_KEY": "your-api-key", 39 | "GOOGLE_CSE_ID": "your-search-engine-id" 40 | } 41 | } 42 | } 43 | } 44 | ``` 45 | 46 | --- 47 | 48 | ### 2. media-tools-mcp-server 49 | 50 | **Package**: `media-tools-mcp-server` 51 | **Version**: 0.1.0 52 | **NPM**: https://www.npmjs.com/package/media-tools-mcp-server 53 | 54 | **Features**: 55 | - Image search (Unsplash) 56 | - Video search (YouTube) 57 | - Image download from URLs 58 | - Image understanding (Google Gemini) 59 | - Video transcript extraction (YouTube) 60 | 61 | **Installation**: 62 | ```bash 63 | # Using npx (recommended) 64 | npx -y media-tools-mcp-server 65 | 66 | # Or install globally 67 | npm install -g media-tools-mcp-server 68 | ``` 69 | 70 | **Configuration**: 71 | ```json 72 | { 73 | "mcpServers": { 74 | "media-tools": { 75 | "command": "npx", 76 | "args": ["-y", "media-tools-mcp-server"], 77 | "env": { 78 | "UNSPLASH_ACCESS_KEY": "your-unsplash-key", 79 | "GEMINI_API_KEY": "your-gemini-key" 80 | } 81 | } 82 | } 83 | } 84 | ``` 85 | 86 | --- 87 | 88 | ### 3. presentation-creator-mcp-server 89 | 90 | **Package**: `presentation-creator-mcp-server` 91 | **Version**: 0.1.0 92 | **NPM**: https://www.npmjs.com/package/presentation-creator-mcp-server 93 | 94 | **Features**: 95 | - Create PowerPoint presentations from HTML slides 96 | - Generate PDF documents from HTML content 97 | - Uses Playwright for rendering 98 | 99 | **Installation**: 100 | ```bash 101 | # Using npx (recommended) 102 | npx -y presentation-creator-mcp-server 103 | 104 | # Install Playwright browsers (required) 105 | npx playwright install chromium 106 | 107 | # Or install globally 108 | npm install -g presentation-creator-mcp-server 109 | npx playwright install chromium 110 | ``` 111 | 112 | **Configuration**: 113 | ```json 114 | { 115 | "mcpServers": { 116 | "presentation-creator": { 117 | "command": "npx", 118 | "args": ["-y", "presentation-creator-mcp-server"] 119 | } 120 | } 121 | } 122 | ``` 123 | 124 | --- 125 | 126 | ## 🐍 Python Packages (Not Yet Published) 127 | 128 | ### 4. pdf-creator-server-mcp 129 | 130 | **Status**: Built but not published to PyPI 131 | **Version**: 0.1.0 132 | 133 | **Features**: 134 | - Generate PDF documents from HTML content 135 | - Uses Playwright and Pillow 136 | 137 | **To Publish**: 138 | The package is ready to be published. Distribution files are in `pdf-creator-server/dist/`. 139 | 140 | To publish to PyPI: 141 | 1. Create a PyPI account at https://pypi.org/account/register/ 142 | 2. Generate an API token at https://pypi.org/manage/account/token/ 143 | 3. Run: `python -m twine upload dist/*` 144 | 4. Username: `__token__` 145 | 5. Password: Your API token 146 | 147 | **Installation (after publishing)**: 148 | ```bash 149 | pip install pdf-creator-server-mcp 150 | ``` 151 | 152 | --- 153 | 154 | ## 🔑 Required API Keys 155 | 156 | | Server | API Keys Required | Get Key Here | 157 | |--------|------------------|--------------| 158 | | **information-retrieval** | Google API Key
Google CSE ID | [Google Cloud Console](https://console.cloud.google.com/)
[Programmable Search](https://programmablesearchengine.google.com/) | 159 | | **media-tools** | Unsplash Access Key
Google Gemini API Key | [Unsplash Developers](https://unsplash.com/developers)
[Google AI Studio](https://aistudio.google.com/apikey) | 160 | | **presentation-creator** | None | - | 161 | | **pdf-creator** | None | - | 162 | 163 | --- 164 | 165 | ## 📝 Quick Start Example 166 | 167 | Here's a complete example configuration for Claude Desktop using all published servers: 168 | 169 | **File Location**: 170 | - MacOS: `~/Library/Application Support/Claude/claude_desktop_config.json` 171 | - Windows: `%APPDATA%/Claude/claude_desktop_config.json` 172 | 173 | ```json 174 | { 175 | "mcpServers": { 176 | "information-retrieval": { 177 | "command": "npx", 178 | "args": ["-y", "information-retrieval-mcp-server"], 179 | "env": { 180 | "GOOGLE_API_KEY": "your-google-api-key", 181 | "GOOGLE_CSE_ID": "your-search-engine-id" 182 | } 183 | }, 184 | "media-tools": { 185 | "command": "npx", 186 | "args": ["-y", "media-tools-mcp-server"], 187 | "env": { 188 | "UNSPLASH_ACCESS_KEY": "your-unsplash-key", 189 | "GEMINI_API_KEY": "your-gemini-key" 190 | } 191 | }, 192 | "presentation-creator": { 193 | "command": "npx", 194 | "args": ["-y", "presentation-creator-mcp-server"] 195 | } 196 | } 197 | } 198 | ``` 199 | 200 | After adding the configuration, restart your MCP client (e.g., Claude Desktop) to load the servers. 201 | 202 | --- 203 | 204 | ## 🚀 Benefits of Using npx 205 | 206 | 1. **No Installation**: Servers run directly without global installation 207 | 2. **Always Latest**: Automatically uses the latest version 208 | 3. **No Build Required**: No need to clone, build, or maintain local copies 209 | 4. **Easy Updates**: Just restart your MCP client to get updates 210 | 5. **Simple Setup**: Single line configuration per server 211 | 212 | --- 213 | 214 | ## 📚 Additional Resources 215 | 216 | - [Model Context Protocol Documentation](https://modelcontextprotocol.io/) 217 | - [GitHub Repository](https://github.com/Godzilla675/agentic-ai-tool-suite) 218 | - Individual package README files in each server directory 219 | 220 | --- 221 | 222 | ## 🆘 Support 223 | 224 | For issues or questions: 225 | 1. Check the individual server README files 226 | 2. Visit the GitHub repository 227 | 3. Review the MCP documentation 228 | 229 | --- 230 | 231 | **Last Updated**: October 28, 2025 232 | -------------------------------------------------------------------------------- /presentation-creator-server/presentation_creator_server.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | import json 4 | import logging 5 | import tempfile 6 | import shutil 7 | from pathlib import Path 8 | from mcp.server.fastmcp import FastMCP 9 | from pptx import Presentation 10 | from pptx.util import Inches, Pt 11 | from playwright.async_api import async_playwright 12 | from dotenv import load_dotenv 13 | from typing import List, Dict, Any # Import typing helpers 14 | 15 | # Configure logging 16 | logging.basicConfig(level=logging.INFO, stream=sys.stderr, format='%(asctime)s - %(levelname)s - %(message)s') 17 | 18 | # Load environment variables (though none are strictly needed for this server) 19 | load_dotenv() 20 | 21 | # --- Server Setup --- 22 | mcp = FastMCP( 23 | "presentation-creator-server", 24 | version="0.1.0", 25 | title="Presentation Creator Server", 26 | description="Assembles slide content into a PowerPoint presentation.", 27 | ) 28 | 29 | # --- Constants --- 30 | # Define standard slide dimensions (16:9 aspect ratio in inches) 31 | PPTX_WIDTH = Inches(10) 32 | PPTX_HEIGHT = Inches(5.625) 33 | 34 | # --- Tool Implementation: Assemble Presentation --- 35 | @mcp.tool() 36 | async def assemble_presentation(slides_html: List[str], filename: str = "presentation") -> str: # Changed input name and type 37 | """ 38 | Assembles a PowerPoint presentation from a list of HTML strings. 39 | Saves each HTML string to a file, screenshots it, and adds the image to a PPTX file. 40 | 41 | Args: 42 | slides_html: A list where each item is a string containing the full HTML code for one slide. 43 | filename: The desired base name for the output PPTX file (without extension). 44 | 45 | Returns: 46 | The absolute path to the generated .pptx file or an error message. 47 | """ 48 | logging.info(f"Received request to assemble presentation: {filename}.pptx with {len(slides_html)} slides.") 49 | temp_dir = None 50 | try: 51 | if not isinstance(slides_html, list): 52 | return "Error: Input slides_html must be a list." 53 | if not all(isinstance(item, str) for item in slides_html): 54 | return "Error: All items in slides_html must be strings." 55 | 56 | if not slides_html: 57 | return "Error: No slide HTML data provided." 58 | 59 | # Create a temporary directory for HTML files and screenshots 60 | temp_dir = tempfile.mkdtemp(prefix="mcp_ppt_") 61 | logging.info(f"Created temporary directory: {temp_dir}") 62 | image_paths = [] 63 | 64 | # Launch Playwright 65 | async with async_playwright() as p: 66 | browser = await p.chromium.launch() 67 | page = await browser.new_page() 68 | await page.set_viewport_size({"width": 800, "height": 450}) 69 | 70 | # Process each slide 71 | for i, html_content in enumerate(slides_html): # Iterate through provided HTML strings 72 | slide_num = i + 1 73 | html_path = os.path.join(temp_dir, f"slide_{slide_num}.html") 74 | img_path = os.path.join(temp_dir, f"slide_{slide_num}.png") 75 | 76 | # Write the provided HTML content to file 77 | with open(html_path, "w", encoding="utf-8") as f: 78 | f.write(html_content) 79 | 80 | await page.goto(f"file://{html_path}") 81 | await page.screenshot(path=img_path) 82 | image_paths.append(img_path) 83 | logging.info(f"Generated screenshot for slide {slide_num}: {img_path}") 84 | 85 | await browser.close() 86 | 87 | # Create PowerPoint presentation 88 | prs = Presentation() 89 | prs.slide_width = PPTX_WIDTH 90 | prs.slide_height = PPTX_HEIGHT 91 | blank_slide_layout = prs.slide_layouts[6] 92 | 93 | for img_path in image_paths: 94 | slide = prs.slides.add_slide(blank_slide_layout) 95 | left = top = Inches(0) 96 | pic = slide.shapes.add_picture(img_path, left, top, width=prs.slide_width, height=prs.slide_height) 97 | 98 | # Save presentation to Downloads folder 99 | downloads_path = Path.home() / "Downloads" 100 | downloads_path.mkdir(parents=True, exist_ok=True) 101 | output_filename = f"{filename}.pptx" 102 | output_path = downloads_path / output_filename 103 | prs.save(output_path) 104 | final_path = str(output_path.resolve()) 105 | logging.info(f"Presentation saved to: {final_path}") 106 | 107 | return f"Presentation successfully created and saved to: {final_path}" 108 | 109 | except Exception as e: 110 | logging.exception("An error occurred during presentation assembly.") 111 | return f"Error assembling presentation: {e}" 112 | finally: 113 | if temp_dir and os.path.exists(temp_dir): 114 | try: 115 | shutil.rmtree(temp_dir) 116 | logging.info(f"Cleaned up temporary directory: {temp_dir}") 117 | except Exception as e: 118 | logging.error(f"Error cleaning up temporary directory {temp_dir}: {e}") 119 | 120 | 121 | # --- PDF Creation Tool --- 122 | @mcp.tool() 123 | async def create_pdf_from_html(html_content: str, filename: str = "document") -> str: 124 | """ 125 | Generates a PDF document from a string containing HTML code. 126 | 127 | Args: 128 | html_content: A string containing the full HTML code for the document. 129 | filename: The desired base name for the output PDF file (without extension). 130 | 131 | Returns: 132 | The absolute path to the generated .pdf file or an error message. 133 | """ 134 | logging.info(f"Received request to create PDF: {filename}.pdf") 135 | temp_dir = None 136 | html_path = None 137 | try: 138 | if not isinstance(html_content, str) or not html_content.strip(): 139 | return "Error: html_content must be a non-empty string." 140 | 141 | # Create a temporary directory and file for the HTML 142 | temp_dir = tempfile.mkdtemp(prefix="mcp_pdf_") 143 | html_path = os.path.join(temp_dir, "content.html") 144 | with open(html_path, "w", encoding="utf-8") as f: 145 | f.write(html_content) 146 | logging.info(f"Saved HTML to temporary file: {html_path}") 147 | 148 | # Launch Playwright and generate PDF 149 | async with async_playwright() as p: 150 | browser = await p.chromium.launch() 151 | page = await browser.new_page() 152 | 153 | await page.goto(f"file://{html_path}") 154 | 155 | # Generate PDF 156 | downloads_path = Path.home() / "Downloads" 157 | downloads_path.mkdir(parents=True, exist_ok=True) 158 | output_filename = f"{filename}.pdf" 159 | output_path = downloads_path / output_filename 160 | pdf_options = { 161 | "path": str(output_path), 162 | "format": "A4", # Standard paper size 163 | "printBackground": True, # Include background colors/images 164 | "margin": { # Optional margins 165 | "top": "20mm", 166 | "bottom": "20mm", 167 | "left": "20mm", 168 | "right": "20mm" 169 | } 170 | } 171 | await page.pdf(**pdf_options) 172 | await browser.close() 173 | 174 | final_path = str(output_path.resolve()) 175 | logging.info(f"PDF saved to: {final_path}") 176 | return f"PDF successfully created and saved to: {final_path}" 177 | 178 | except Exception as e: 179 | logging.exception("An error occurred during PDF creation.") 180 | return f"Error creating PDF: {e}" 181 | finally: 182 | # Clean up temporary directory/file 183 | if temp_dir and os.path.exists(temp_dir): 184 | try: 185 | shutil.rmtree(temp_dir) 186 | logging.info(f"Cleaned up temporary directory: {temp_dir}") 187 | except Exception as e: 188 | logging.error(f"Error cleaning up temporary directory {temp_dir}: {e}") 189 | 190 | 191 | # --- Server Execution --- 192 | if __name__ == "__main__": 193 | logging.info("Starting Presentation Creator Server...") 194 | mcp.run(transport='stdio') 195 | logging.info("Presentation Creator Server stopped.") 196 | -------------------------------------------------------------------------------- /presentation-creator-server/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /** 4 | * Presentation Creator MCP Server 5 | * Provides tools for creating PowerPoint presentations and PDFs from HTML 6 | */ 7 | 8 | import { Server } from "@modelcontextprotocol/sdk/server/index.js"; 9 | import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; 10 | import { 11 | CallToolRequestSchema, 12 | ErrorCode, 13 | ListToolsRequestSchema, 14 | McpError, 15 | } from "@modelcontextprotocol/sdk/types.js"; 16 | import { z } from "zod"; 17 | import { chromium, Browser, Page } from "playwright"; 18 | import pptxgen from "pptxgenjs"; 19 | const PptxGenJS = pptxgen.default || pptxgen; 20 | import * as fs from "fs"; 21 | import * as path from "path"; 22 | import * as os from "os"; 23 | 24 | /** 25 | * Create an MCP server with presentation and PDF creation tools 26 | */ 27 | const server = new Server( 28 | { 29 | name: "presentation-creator-server", 30 | version: "0.1.1", 31 | }, 32 | { 33 | capabilities: { 34 | resources: {}, 35 | tools: {}, 36 | }, 37 | } 38 | ); 39 | 40 | // --- Helper Functions --- 41 | 42 | async function createTempFile(content: string, extension: string): Promise { 43 | const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "mcp-presentation-")); 44 | const filePath = path.join(tempDir, `content${extension}`); 45 | fs.writeFileSync(filePath, content, "utf-8"); 46 | return filePath; 47 | } 48 | 49 | function cleanupTemp(filePath: string) { 50 | try { 51 | const dir = path.dirname(filePath); 52 | fs.rmSync(dir, { recursive: true, force: true }); 53 | } catch (error) { 54 | console.error("Error cleaning up temp files:", error); 55 | } 56 | } 57 | 58 | // --- Tool Implementation --- 59 | 60 | async function handleAssemblePresentation({ slides_html, filename }: { slides_html: string[]; filename: string }) { 61 | const tempFiles: string[] = []; 62 | let browser: Browser | null = null; 63 | 64 | try { 65 | if (!slides_html || slides_html.length === 0) { 66 | throw new Error("No slide HTML data provided"); 67 | } 68 | 69 | // Create PowerPoint presentation 70 | const pptx = new PptxGenJS(); 71 | pptx.layout = "LAYOUT_16x9"; 72 | 73 | // Launch browser for screenshots 74 | browser = await chromium.launch(); 75 | const page: Page = await browser.newPage(); 76 | await page.setViewportSize({ width: 1920, height: 1080 }); 77 | 78 | // Process each slide 79 | for (let i = 0; i < slides_html.length; i++) { 80 | const htmlContent = slides_html[i]; 81 | 82 | // Create temp HTML file 83 | const htmlPath = await createTempFile(htmlContent, ".html"); 84 | tempFiles.push(htmlPath); 85 | 86 | // Navigate and screenshot 87 | await page.goto(`file://${htmlPath}`, { waitUntil: "domcontentloaded" }); 88 | 89 | const screenshotPath = htmlPath.replace(".html", ".png"); 90 | await page.screenshot({ path: screenshotPath, fullPage: false }); 91 | tempFiles.push(screenshotPath); 92 | 93 | // Add slide with image 94 | const slide = pptx.addSlide(); 95 | slide.addImage({ 96 | path: screenshotPath, 97 | x: 0, 98 | y: 0, 99 | w: "100%", 100 | h: "100%", 101 | }); 102 | 103 | console.error(`Processed slide ${i + 1}/${slides_html.length}`); 104 | } 105 | 106 | await browser.close(); 107 | browser = null; 108 | 109 | // Save presentation to Downloads folder 110 | const downloadsPath = path.join(os.homedir(), "Downloads"); 111 | if (!fs.existsSync(downloadsPath)) { 112 | fs.mkdirSync(downloadsPath, { recursive: true }); 113 | } 114 | 115 | const outputPath = path.join(downloadsPath, `${filename}.pptx`); 116 | await pptx.writeFile({ fileName: outputPath }); 117 | 118 | // Cleanup temp files 119 | tempFiles.forEach(cleanupTemp); 120 | 121 | return { 122 | content: [{ 123 | type: "text", 124 | text: `Presentation successfully created and saved to: ${outputPath}` 125 | }] 126 | }; 127 | 128 | } catch (error: any) { 129 | if (browser) await browser.close(); 130 | tempFiles.forEach(cleanupTemp); 131 | 132 | console.error("Error assembling presentation:", error); 133 | return { 134 | isError: true, 135 | content: [{ 136 | type: "text", 137 | text: `Error assembling presentation: ${error.message}` 138 | }] 139 | }; 140 | } 141 | } 142 | 143 | async function handleCreatePdfFromHtml({ html_content, filename }: { html_content: string; filename: string }) { 144 | let htmlPath: string | null = null; 145 | let browser: Browser | null = null; 146 | 147 | try { 148 | if (!html_content || html_content.trim() === "") { 149 | throw new Error("html_content must be a non-empty string"); 150 | } 151 | 152 | // Create temp HTML file 153 | htmlPath = await createTempFile(html_content, ".html"); 154 | 155 | // Launch browser 156 | browser = await chromium.launch(); 157 | const page: Page = await browser.newPage(); 158 | 159 | await page.goto(`file://${htmlPath}`, { waitUntil: "domcontentloaded" }); 160 | 161 | // Save PDF to Downloads folder 162 | const downloadsPath = path.join(os.homedir(), "Downloads"); 163 | if (!fs.existsSync(downloadsPath)) { 164 | fs.mkdirSync(downloadsPath, { recursive: true }); 165 | } 166 | 167 | const outputPath = path.join(downloadsPath, `${filename}.pdf`); 168 | await page.pdf({ 169 | path: outputPath, 170 | format: "A4", 171 | printBackground: true, 172 | margin: { 173 | top: "20mm", 174 | bottom: "20mm", 175 | left: "20mm", 176 | right: "20mm", 177 | }, 178 | }); 179 | 180 | await browser.close(); 181 | browser = null; 182 | 183 | // Cleanup 184 | if (htmlPath) cleanupTemp(htmlPath); 185 | 186 | return { 187 | content: [{ 188 | type: "text", 189 | text: `PDF successfully created and saved to: ${outputPath}` 190 | }] 191 | }; 192 | 193 | } catch (error: any) { 194 | if (browser) await browser.close(); 195 | if (htmlPath) cleanupTemp(htmlPath); 196 | 197 | console.error("Error creating PDF:", error); 198 | return { 199 | isError: true, 200 | content: [{ 201 | type: "text", 202 | text: `Error creating PDF: ${error.message}` 203 | }] 204 | }; 205 | } 206 | } 207 | 208 | // --- Tool Schemas --- 209 | 210 | const assemblePresentationArgsSchema = z.object({ 211 | slides_html: z.array(z.string()).min(1).describe("A list where each item is a string containing the full HTML code for one slide."), 212 | filename: z.string().optional().default("presentation").describe("The desired base name for the output PPTX file (without extension)."), 213 | }); 214 | 215 | const createPdfFromHtmlArgsSchema = z.object({ 216 | html_content: z.string().min(1).describe("A string containing the full HTML code for the document."), 217 | filename: z.string().optional().default("document").describe("The desired base name for the output PDF file (without extension)."), 218 | }); 219 | 220 | // --- Tool Registration --- 221 | 222 | server.setRequestHandler(ListToolsRequestSchema, async () => { 223 | return { 224 | tools: [ 225 | { 226 | name: "assemble_presentation", 227 | description: "Assembles a PowerPoint presentation from a list of HTML strings. Each HTML string represents one slide.", 228 | inputSchema: { 229 | type: "object", 230 | properties: { 231 | slides_html: { 232 | type: "array", 233 | items: { type: "string" }, 234 | description: "A list where each item is a string containing the full HTML code for one slide." 235 | }, 236 | filename: { 237 | type: "string", 238 | description: "The desired base name for the output PPTX file (without extension).", 239 | default: "presentation" 240 | } 241 | }, 242 | required: ["slides_html"] 243 | } 244 | }, 245 | { 246 | name: "create_pdf_from_html", 247 | description: "Generates a PDF document from a string containing HTML code.", 248 | inputSchema: { 249 | type: "object", 250 | properties: { 251 | html_content: { 252 | type: "string", 253 | description: "A string containing the full HTML code for the document." 254 | }, 255 | filename: { 256 | type: "string", 257 | description: "The desired base name for the output PDF file (without extension).", 258 | default: "document" 259 | } 260 | }, 261 | required: ["html_content"] 262 | } 263 | } 264 | ] 265 | }; 266 | }); 267 | 268 | // --- Tool Handler --- 269 | 270 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 271 | const toolName = request.params.name; 272 | const args = request.params.arguments; 273 | 274 | try { 275 | if (toolName === "assemble_presentation") { 276 | const validatedArgs = assemblePresentationArgsSchema.parse(args); 277 | return await handleAssemblePresentation(validatedArgs); 278 | } else if (toolName === "create_pdf_from_html") { 279 | const validatedArgs = createPdfFromHtmlArgsSchema.parse(args); 280 | return await handleCreatePdfFromHtml(validatedArgs); 281 | } else { 282 | throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`); 283 | } 284 | } catch (error: any) { 285 | console.error(`Error calling tool ${toolName}:`, error); 286 | if (error instanceof z.ZodError) { 287 | throw new McpError( 288 | ErrorCode.InvalidParams, 289 | `Invalid arguments for tool ${toolName}: ${error.errors.map((e) => e.message).join(", ")}` 290 | ); 291 | } 292 | if (error instanceof McpError) { 293 | throw error; 294 | } 295 | throw new McpError(ErrorCode.InternalError, `Error executing tool ${toolName}: ${error.message}`); 296 | } 297 | }); 298 | 299 | // --- Server Execution --- 300 | 301 | async function main() { 302 | const transport = new StdioServerTransport(); 303 | await server.connect(transport); 304 | console.error("Presentation Creator MCP Server running on stdio"); 305 | } 306 | 307 | main().catch((error) => { 308 | console.error("Server error:", error); 309 | process.exit(1); 310 | }); 311 | -------------------------------------------------------------------------------- /.github/copilot-instructions.md: -------------------------------------------------------------------------------- 1 | # Agentic AI Tool Suite - AI Coding Agent Instructions 2 | 3 | ## Project Overview 4 | 5 | This is a **monorepo of Model Context Protocol (MCP) servers** providing media handling, information retrieval, and document creation capabilities. Each server is a separate, independently deployable process that communicates via stdio transport. 6 | 7 | ### Architecture Pattern: Multi-Language MCP Server Suite 8 | 9 | - **TypeScript Servers** (`information-retrieval-server`, `media-tools-server`, `presentation-creator-server`): Use `@modelcontextprotocol/sdk`, Zod validation, stdio transport 10 | - **Python Servers** (`pdf-creator-server`, `presentation-creator-server`): Use `fastmcp` library, async/await patterns 11 | - **Dual Implementation**: `presentation-creator-server` exists in both TypeScript (wrapper) and Python (implementation) - Python version contains the actual logic 12 | 13 | ## Critical Developer Workflows 14 | 15 | ### Building TypeScript Servers 16 | 17 | **Standard build process** (applies to all TS servers): 18 | ```bash 19 | cd 20 | npm install 21 | npm run build # Compiles TS → JS, bundles with esbuild, sets executable permissions 22 | ``` 23 | 24 | The `build` script in `package.json` performs three steps: 25 | 1. `tsc` - TypeScript compilation to `build/` directory 26 | 2. `esbuild` - Bundles into single file with external packages 27 | 3. `chmod 755` - Makes `build/index.js` executable for shebang execution 28 | 29 | **Development workflow**: 30 | ```bash 31 | npm run watch # Auto-rebuild on changes 32 | npm run inspector # Debug with MCP Inspector (opens browser UI) 33 | ``` 34 | 35 | ### Python Server Setup 36 | 37 | **Virtual environment required**: 38 | ```bash 39 | cd 40 | python -m venv .venv 41 | .\.venv\Scripts\activate # Windows PowerShell 42 | pip install -r requirements.txt 43 | playwright install chromium # Required for PDF/presentation generation 44 | ``` 45 | 46 | **Important**: MCP client configs must point to the venv's Python executable, not system Python: 47 | ```json 48 | { 49 | "command": "C:/path/to/.venv/Scripts/python.exe", 50 | "args": ["C:/path/to/server_script.py"] 51 | } 52 | ``` 53 | 54 | ### Publishing Workflow 55 | 56 | **TypeScript servers** are published to npm and can be run via `npx`: 57 | - Published packages: `information-retrieval-mcp-server`, `media-tools-mcp-server`, `presentation-creator-mcp-server` 58 | - Users can run with: `npx -y ` (no installation needed) 59 | - The `prepare` script in package.json auto-builds before publishing 60 | 61 | **Python servers** are packaged but not yet published to PyPI (see `PUBLISHED_PACKAGES.md`) 62 | 63 | ## Project-Specific Conventions 64 | 65 | ### Environment Variables Pattern 66 | 67 | All servers follow this pattern: 68 | 1. Check for required API keys at startup (log warnings, don't exit) 69 | 2. Validate keys when tools are called (return user-friendly error messages) 70 | 3. Support fallback env var names (e.g., `GEMINI_API_KEY` OR `GOOGLE_API_KEY`) 71 | 72 | Example from `information-retrieval-server/src/index.ts`: 73 | ```typescript 74 | const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY; 75 | if (!GOOGLE_API_KEY) { 76 | console.error("WARN: GOOGLE_API_KEY not set. Tools will fail."); 77 | } 78 | ``` 79 | 80 | ### Tool Implementation Pattern 81 | 82 | **TypeScript servers** use this structure: 83 | ```typescript 84 | // 1. Define Zod schema for validation 85 | const toolArgsSchema = z.object({ 86 | param: z.string().describe('Description for LLM'), 87 | }); 88 | 89 | // 2. Implement handler function 90 | async function handleTool({ param }: { param: string }) { 91 | try { 92 | // Tool logic here 93 | return { content: [{ type: 'text', text: 'Result' }] }; 94 | } catch (error: any) { 95 | return { isError: true, content: [{ type: 'text', text: error.message }] }; 96 | } 97 | } 98 | 99 | // 3. Register in ListToolsRequestSchema handler 100 | server.setRequestHandler(ListToolsRequestSchema, async () => ({ 101 | tools: [{ name: 'tool_name', description: '...', inputSchema: {...} }] 102 | })); 103 | 104 | // 4. Route in CallToolRequestSchema handler 105 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 106 | const validatedArgs = toolArgsSchema.parse(request.params.arguments); 107 | return await handleTool(validatedArgs); 108 | }); 109 | ``` 110 | 111 | **Python servers** use FastMCP decorators: 112 | ```python 113 | @mcp.tool() 114 | async def tool_name(param: str, optional_param: str = "default") -> str: 115 | """Docstring becomes tool description for LLM.""" 116 | try: 117 | # Tool logic 118 | return "Success message" 119 | except Exception as e: 120 | return f"Error: {e}" 121 | ``` 122 | 123 | ### Output File Conventions 124 | 125 | All servers save output files to `~/Downloads` folder: 126 | - PDFs: `~/Downloads/.pdf` 127 | - Presentations: `~/Downloads/.pptx` 128 | - Downloaded images: User-specified path (validated for image extensions) 129 | 130 | ### Temporary File Handling 131 | 132 | Python servers use this pattern: 133 | ```python 134 | temp_dir = tempfile.mkdtemp(prefix="mcp__") 135 | try: 136 | # Use temp_dir for intermediate files 137 | pass 138 | finally: 139 | if temp_dir and os.path.exists(temp_dir): 140 | shutil.rmtree(temp_dir) 141 | ``` 142 | 143 | ### Error Handling Philosophy 144 | 145 | - **User-facing errors**: Return helpful messages explaining what went wrong and how to fix it 146 | - **API errors**: Parse and format API error responses (code, message) 147 | - **Never exit the server process** on API errors - return error content to the client 148 | - **Log to stderr**: Use `console.error()` (TS) or `logging` (Python) for diagnostics 149 | 150 | ## Integration Points 151 | 152 | ### External APIs Used 153 | 154 | 1. **Google Custom Search API** (`information-retrieval-server`): 155 | - Requires: `GOOGLE_API_KEY`, `GOOGLE_CSE_ID` 156 | - Rate limits: Handle in error messages 157 | - Endpoint: `https://www.googleapis.com/customsearch/v1` 158 | 159 | 2. **Unsplash API** (`media-tools-server`): 160 | - Requires: `UNSPLASH_ACCESS_KEY` 161 | - Header: `Authorization: Client-ID ` 162 | - Returns: Image URLs, photographer credits 163 | 164 | 3. **YouTube Data API v3** (`media-tools-server`): 165 | - Requires: `YOUTUBE_API_KEY` 166 | - Used for video search only (not transcripts) 167 | 168 | 4. **Google Gemini API** (`media-tools-server`): 169 | - Requires: `GEMINI_API_KEY` 170 | - Model: `gemini-2.5-flash` for vision and text 171 | - Important: Doesn't generate images directly, creates descriptions 172 | 173 | 5. **Playwright** (Multiple servers): 174 | - Used for: Web crawling, PDF generation, screenshot capture 175 | - Browser: Chromium (must be installed: `playwright install chromium`) 176 | - Headless mode by default 177 | 178 | ### Cross-Server Communication 179 | 180 | **None** - servers are completely independent. Each MCP client connects to multiple servers separately. 181 | 182 | ### Package Dependencies Pattern 183 | 184 | TypeScript servers share common dependencies: 185 | - `@modelcontextprotocol/sdk`: ^0.6.0 (listed in both dependencies and devDependencies for development) 186 | - `zod`: Input validation 187 | - `axios`: HTTP requests 188 | - `playwright`: Headless browser automation 189 | 190 | Python servers use: 191 | - `fastmcp`: MCP framework 192 | - `playwright`: Browser automation 193 | - `python-dotenv`: Environment variables 194 | - `python-pptx` OR `pptxgenjs`: Presentation creation 195 | 196 | ## Key Files & Their Roles 197 | 198 | - `example_mcp_settings.json`: Template config for all servers (with placeholder paths/keys) 199 | - `npx_mcp_settings_with_keys.json`: Production config using npx (no local paths needed) 200 | - `PUBLISHED_PACKAGES.md`: Installation guide for published npm packages 201 | - `README.md`: Main documentation with both npx (recommended) and build-from-source instructions 202 | - `build/index.js`: Compiled, bundled, executable output for TS servers (gitignored) 203 | 204 | ## Common Patterns to Follow 205 | 206 | ### When Adding a New Tool 207 | 208 | 1. Add Zod schema (TS) or type hints (Python) 209 | 2. Implement handler with try-catch error handling 210 | 3. Register in tool list with clear description 211 | 4. Add to CallToolRequestSchema router (TS) 212 | 5. Test with `npm run inspector` or MCP client 213 | 6. Document in server's README.md 214 | 215 | ### When Publishing Updates 216 | 217 | 1. Increment version in `package.json` (TS) or `setup.py` (Python) 218 | 2. Run `npm run build` to ensure clean build 219 | 3. Test with `npx -y @latest` before publishing 220 | 4. Publish: `npm publish` (requires npm authentication) 221 | 5. Update `PUBLISHED_PACKAGES.md` with new version number 222 | 223 | ### MCP Client Configuration 224 | 225 | Users configure servers in `claude_desktop_config.json` or `cline_mcp_settings.json`. Two approaches: 226 | 227 | **Approach 1: npx (recommended for published packages)**: 228 | ```json 229 | { 230 | "command": "npx", 231 | "args": ["-y", "package-name"], 232 | "env": { "API_KEY": "value" } 233 | } 234 | ``` 235 | 236 | **Approach 2: Local paths (for development)**: 237 | ```json 238 | { 239 | "command": "node", 240 | "args": ["C:/absolute/path/to/build/index.js"], 241 | "env": { "API_KEY": "value" } 242 | } 243 | ``` 244 | 245 | ## Debugging Notes 246 | 247 | - **stdio transport**: All server communication via stdin/stdout, errors to stderr 248 | - **MCP Inspector**: Essential tool for debugging - shows requests/responses in browser UI 249 | - **PowerShell timeout bug**: Reuse terminal sessions when running commands to avoid initialization delays (see `commands.instructions.md`) 250 | - **Playwright browsers**: Must be explicitly installed after npm/pip install 251 | - **API key issues**: Check environment variables are set in MCP client config, not shell environment 252 | 253 | ## Testing Strategy 254 | 255 | Currently no automated tests. Manual testing workflow: 256 | 1. Build server 257 | 2. Run with MCP Inspector: `npm run inspector` 258 | 3. Test each tool with various inputs 259 | 4. Verify error handling with invalid inputs/missing API keys 260 | 5. Test in actual MCP client (Claude Desktop/Cline) 261 | 262 | ## When Troubleshooting 263 | 264 | 1. **Server won't start**: Check if build succeeded, verify shebang line in `build/index.js` 265 | 2. **API errors**: Verify API keys are set in client config, check API quotas/billing 266 | 3. **Playwright errors**: Ensure browsers installed (`playwright install chromium`) 267 | 4. **Import errors (Python)**: Verify virtual environment is activated and requirements installed 268 | 5. **npx caching issues**: Clear npx cache if old version runs: `Remove-Item -Path "$env:LOCALAPPDATA\npm-cache\_npx" -Recurse -Force` 269 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![MseeP.ai Security Assessment Badge](https://mseep.net/pr/godzilla675-agentic-ai-tool-suite-badge.png)](https://mseep.ai/app/godzilla675-agentic-ai-tool-suite) 2 | 3 | # Unified MCP Suite 4 | 5 | This repository contains a collection of Model Context Protocol (MCP) servers, packaged together for convenience. Each server provides distinct functionalities related to media handling, information retrieval, and document creation. 6 | 7 | **📦 [View Published Packages](./PUBLISHED_PACKAGES.md)** - Easy installation guide for all npm packages! 8 | 9 | **Important:** These servers are designed to run as separate processes. You need to set up and configure each server individually within your MCP client (e.g., Cline or the Claude Desktop App). 10 | 11 | ## Included Servers 12 | 13 | * **Media Tools Server (`media-tools-server`)**: Provides tools for searching images (Unsplash) and videos (YouTube), downloading images, and understanding image/video content (Google Gemini, YouTube Transcripts). (Node.js/TypeScript) 14 | * **Information Retrieval Server (`information-retrieval-server`)**: Provides tools for performing web searches (Google Custom Search) and crawling web pages. (Node.js/TypeScript) 15 | * **PDF Creator Server (`pdf-creator-server`)**: Provides a tool to generate PDF documents from HTML content using Playwright and Pillow. (Python) 16 | * **Presentation Creator Server (`presentation-creator-server`)**: Provides tools to assemble PowerPoint presentations from HTML slide content and generate PDFs from HTML. (Python) 17 | 18 | ## Quick Start (Recommended) 19 | 20 | The easiest way to use these MCP servers is via npm packages. No need to clone or build! 21 | 22 | ### Published Packages 23 | 24 | All TypeScript/Node.js servers are now available on npm: 25 | - **information-retrieval-mcp-server**: Web search and crawling 26 | - **media-tools-mcp-server**: Image/video search and media understanding 27 | - **presentation-creator-mcp-server**: Create presentations and PDFs from HTML 28 | 29 | ### Installation Options 30 | 31 | #### Option 1: Using npx (Easiest - No Installation Required) 32 | 33 | Add to your MCP client config (e.g., `claude_desktop_config.json`): 34 | 35 | **Location of config file:** 36 | - **MacOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` 37 | - **Windows**: `%APPDATA%/Claude/claude_desktop_config.json` 38 | 39 | ```json 40 | { 41 | "mcpServers": { 42 | "information-retrieval": { 43 | "command": "npx", 44 | "args": ["-y", "information-retrieval-mcp-server"], 45 | "env": { 46 | "GOOGLE_API_KEY": "your-google-api-key", 47 | "GOOGLE_CSE_ID": "your-custom-search-engine-id" 48 | } 49 | }, 50 | "media-tools": { 51 | "command": "npx", 52 | "args": ["-y", "media-tools-mcp-server"], 53 | "env": { 54 | "UNSPLASH_ACCESS_KEY": "your-unsplash-key", 55 | "GEMINI_API_KEY": "your-gemini-key" 56 | } 57 | }, 58 | "presentation-creator": { 59 | "command": "npx", 60 | "args": ["-y", "presentation-creator-mcp-server"] 61 | } 62 | } 63 | } 64 | ``` 65 | 66 | **API Keys Required:** 67 | - **Information Retrieval Server**: 68 | - Google Custom Search API key ([Get it here](https://console.cloud.google.com/)) 69 | - Custom Search Engine ID ([Create one here](https://programmablesearchengine.google.com/)) 70 | - **Media Tools Server**: 71 | - Unsplash API key ([Get it here](https://unsplash.com/developers)) 72 | - Google Gemini API key ([Get it here](https://aistudio.google.com/apikey)) 73 | - **Presentation Creator Server**: No API keys required 74 | 75 | #### Option 2: Global npm Installation 76 | 77 | ```bash 78 | npm install -g information-retrieval-mcp-server 79 | npm install -g media-tools-mcp-server 80 | npm install -g presentation-creator-mcp-server 81 | ``` 82 | 83 | Then configure with just the command name: 84 | 85 | ```json 86 | { 87 | "mcpServers": { 88 | "information-retrieval": { 89 | "command": "information-retrieval-mcp-server", 90 | "env": { /* ... */ } 91 | } 92 | } 93 | } 94 | ``` 95 | 96 | ## Advanced Setup (Build from Source) 97 | 98 | If you prefer to build from source or need to modify the servers: 99 | 100 | ### 1. Clone the Repository 101 | 102 | ```bash 103 | git clone # Replace with the actual URL 104 | cd unified-mcp-suite 105 | ``` 106 | 107 | ### 2. Media Tools Server (`media-tools-server`) 108 | 109 | **(Node.js/TypeScript)** 110 | 111 | **a. Navigate to Directory:** 112 | 113 | ```bash 114 | cd media-tools-server 115 | ``` 116 | 117 | **b. Install Dependencies:** 118 | 119 | ```bash 120 | npm install 121 | ``` 122 | 123 | **c. Build the Server:** 124 | 125 | ```bash 126 | npm run build 127 | ``` 128 | (This compiles the TypeScript code into JavaScript in the `build` directory.) 129 | 130 | **d. Obtain API Keys:** 131 | 132 | * **Unsplash API Key:** Required for image search. Create an account and register an application at [https://unsplash.com/developers](https://unsplash.com/developers). 133 | * **Google API Key:** Required for video search/understanding and image understanding. 134 | * Enable the "YouTube Data API v3" and "Vertex AI API" (for Gemini) in your Google Cloud Console project: [https://console.cloud.google.com/](https://console.cloud.google.com/) 135 | * Create an API key under "APIs & Services" -> "Credentials". Restrict the key if necessary. 136 | 137 | **e. Configure MCP Client:** 138 | 139 | Add the following configuration to your MCP client's settings file (e.g., `cline_mcp_settings.json` or `claude_desktop_config.json`). Replace placeholders with your actual API keys and the correct absolute path to the built server file. 140 | 141 | ```json 142 | { 143 | "mcpServers": { 144 | // ... other servers 145 | "media-tools": { 146 | "command": "node", 147 | "args": ["C:/path/to/unified-mcp-suite/media-tools-server/build/index.js"], // <-- UPDATE THIS PATH 148 | "env": { 149 | "UNSPLASH_ACCESS_KEY": "YOUR_UNSPLASH_API_KEY", // <-- ADD YOUR KEY 150 | "GOOGLE_API_KEY": "YOUR_GOOGLE_API_KEY" // <-- ADD YOUR KEY 151 | }, 152 | "disabled": false, // Set to false to enable 153 | "autoApprove": [] 154 | } 155 | // ... other servers 156 | } 157 | } 158 | ``` 159 | 160 | **f. Navigate Back:** 161 | 162 | ```bash 163 | cd .. 164 | ``` 165 | 166 | ### 3. Information Retrieval Server (`information-retrieval-server`) 167 | 168 | **(Node.js/TypeScript)** 169 | 170 | **a. Navigate to Directory:** 171 | 172 | ```bash 173 | cd information-retrieval-server 174 | ``` 175 | 176 | **b. Install Dependencies:** 177 | 178 | ```bash 179 | npm install 180 | ``` 181 | 182 | **c. Build the Server:** 183 | 184 | ```bash 185 | npm run build 186 | ``` 187 | 188 | **d. Obtain API Keys:** 189 | 190 | * **Google Custom Search API:** 191 | * Enable the "Custom Search API" in your Google Cloud Console project: [https://console.cloud.google.com/](https://console.cloud.google.com/) 192 | * Create an API key under "APIs & Services" -> "Credentials". 193 | * Create a Custom Search Engine and get its ID: [https://programmablesearchengine.google.com/](https://programmablesearchengine.google.com/) 194 | 195 | **e. Configure MCP Client:** 196 | 197 | Add the following configuration to your MCP client's settings file. Replace placeholders with your actual API key, Search Engine ID, and the correct absolute path. 198 | 199 | ```json 200 | { 201 | "mcpServers": { 202 | // ... other servers 203 | "information-retrieval": { 204 | "command": "node", 205 | "args": ["C:/path/to/unified-mcp-suite/information-retrieval-server/build/index.js"], // <-- UPDATE THIS PATH 206 | "env": { 207 | "GOOGLE_API_KEY": "YOUR_GOOGLE_API_KEY", // <-- ADD YOUR KEY 208 | "GOOGLE_CSE_ID": "YOUR_CUSTOM_SEARCH_ENGINE_ID" // <-- ADD YOUR ID 209 | }, 210 | "disabled": false, // Set to false to enable 211 | "autoApprove": [] 212 | } 213 | // ... other servers 214 | } 215 | } 216 | ``` 217 | 218 | **f. Navigate Back:** 219 | 220 | ```bash 221 | cd .. 222 | ``` 223 | 224 | ### 4. PDF Creator Server (`pdf-creator-server`) 225 | 226 | **(Python)** 227 | 228 | **a. Navigate to Directory:** 229 | 230 | ```bash 231 | cd pdf-creator-server 232 | ``` 233 | 234 | **b. Create and Activate Virtual Environment:** 235 | 236 | ```bash 237 | # Create environment 238 | python -m venv .venv 239 | 240 | # Activate environment 241 | # Windows (Command Prompt/PowerShell) 242 | .\.venv\Scripts\activate 243 | # macOS/Linux (bash/zsh) 244 | # source .venv/bin/activate 245 | ``` 246 | 247 | **c. Install Dependencies:** 248 | 249 | ```bash 250 | pip install -r requirements.txt 251 | ``` 252 | 253 | **d. Install Playwright Browsers:** (Required for PDF generation) 254 | 255 | ```bash 256 | playwright install 257 | ``` 258 | 259 | **e. Configure MCP Client:** 260 | 261 | Add the following configuration to your MCP client's settings file. Replace the placeholder with the correct absolute path to the Python executable *within the virtual environment* and the server script. 262 | 263 | ```json 264 | { 265 | "mcpServers": { 266 | // ... other servers 267 | "pdf-creator": { 268 | // UPDATE python path to point to the .venv executable 269 | "command": "C:/path/to/unified-mcp-suite/pdf-creator-server/.venv/Scripts/python.exe", // Windows example 270 | // "command": "/path/to/unified-mcp-suite/pdf-creator-server/.venv/bin/python", // macOS/Linux example 271 | "args": ["C:/path/to/unified-mcp-suite/pdf-creator-server/pdf_creator_server.py"], // <-- UPDATE THIS PATH 272 | "env": {}, // No specific environment variables needed by default 273 | "disabled": false, // Set to false to enable 274 | "autoApprove": [] 275 | } 276 | // ... other servers 277 | } 278 | } 279 | ``` 280 | 281 | **f. Deactivate Virtual Environment (Optional):** 282 | 283 | ```bash 284 | deactivate 285 | ``` 286 | 287 | **g. Navigate Back:** 288 | 289 | ```bash 290 | cd .. 291 | ``` 292 | 293 | ### 5. Presentation Creator Server (`presentation-creator-server`) 294 | 295 | **(Python)** 296 | 297 | **a. Navigate to Directory:** 298 | 299 | ```bash 300 | cd presentation-creator-server 301 | ``` 302 | 303 | **b. Create and Activate Virtual Environment:** 304 | 305 | ```bash 306 | # Create environment 307 | python -m venv .venv 308 | 309 | # Activate environment 310 | # Windows (Command Prompt/PowerShell) 311 | .\.venv\Scripts\activate 312 | # macOS/Linux (bash/zsh) 313 | # source .venv/bin/activate 314 | ``` 315 | 316 | **c. Install Dependencies:** 317 | 318 | ```bash 319 | pip install -r requirements.txt 320 | ``` 321 | 322 | **d. Install Playwright Browsers:** (Required for screenshotting HTML slides) 323 | 324 | ```bash 325 | playwright install 326 | ``` 327 | 328 | **e. Configure MCP Client:** 329 | 330 | Add the following configuration to your MCP client's settings file. Replace the placeholder with the correct absolute path to the Python executable *within the virtual environment* and the server script. 331 | 332 | ```json 333 | { 334 | "mcpServers": { 335 | // ... other servers 336 | "presentation-creator": { 337 | // UPDATE python path to point to the .venv executable 338 | "command": "C:/path/to/unified-mcp-suite/presentation-creator-server/.venv/Scripts/python.exe", // Windows example 339 | // "command": "/path/to/unified-mcp-suite/presentation-creator-server/.venv/bin/python", // macOS/Linux example 340 | "args": ["C:/path/to/unified-mcp-suite/presentation-creator-server/presentation_creator_server.py"], // <-- UPDATE THIS PATH 341 | "env": {}, // No specific environment variables needed by default 342 | "disabled": false, // Set to false to enable 343 | "autoApprove": [] 344 | } 345 | // ... other servers 346 | } 347 | } 348 | ``` 349 | 350 | **f. Deactivate Virtual Environment (Optional):** 351 | 352 | ```bash 353 | deactivate 354 | ``` 355 | 356 | **g. Navigate Back:** 357 | 358 | ```bash 359 | cd .. 360 | ``` 361 | 362 | ## Running the Servers 363 | 364 | Once configured in your MCP client, the servers should start automatically when the client launches. You can then use the tools provided by each server through your MCP client interface. 365 | 366 | ## Example Configuration File 367 | 368 | An example configuration file, `example_cline_mcp_settings.json`, is included in the root of this repository. You can use this as a template for configuring the servers in your MCP client (like Cline). 369 | 370 | **To use the example:** 371 | 372 | 1. Locate your MCP client's actual settings file (e.g., `c:\Users\YourUser\AppData\Roaming\Code\User\globalStorage\saoudrizwan.claude-dev\settings\cline_mcp_settings.json` for Cline in VS Code on Windows). 373 | 2. Copy the server configurations from `example_cline_mcp_settings.json` into your actual settings file, merging them with any existing server configurations you might have. 374 | 3. **Crucially, update all placeholder paths** (e.g., `C:/absolute/path/to/...`) to reflect the actual absolute path where you cloned the `unified-mcp-suite` repository on your system. 375 | 4. **Replace all placeholder API keys** (e.g., `YOUR_GOOGLE_API_KEY_HERE`) with your own keys obtained during the setup steps. 376 | 5. Ensure the `command` path for the Python servers correctly points to the `python.exe` (Windows) or `python` (macOS/Linux) executable *inside* the respective `.venv` directory you created. 377 | -------------------------------------------------------------------------------- /information-retrieval-server/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js'; 3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; 4 | import { 5 | CallToolRequestSchema, 6 | ErrorCode, 7 | ListToolsRequestSchema, 8 | McpError, 9 | } from '@modelcontextprotocol/sdk/types.js'; 10 | import { z } from 'zod'; 11 | import axios from 'axios'; 12 | import * as cheerio from 'cheerio'; 13 | import { chromium, Browser, Page } from 'playwright'; // Added Playwright import 14 | 15 | // --- API Configuration --- 16 | const GOOGLE_API_KEY = process.env.GOOGLE_API_KEY; 17 | const GOOGLE_CSE_ID = process.env.GOOGLE_CSE_ID; 18 | 19 | if (!GOOGLE_API_KEY || !GOOGLE_CSE_ID) { 20 | console.error("FATAL: GOOGLE_API_KEY or GOOGLE_CSE_ID environment variables are not set."); 21 | // In a real server, you might want to exit or prevent startup 22 | // process.exit(1); 23 | } 24 | 25 | // --- Server Setup --- 26 | const server = new Server( 27 | { // ServerInfo 28 | name: 'information-retrieval-server', 29 | version: '0.1.0', 30 | }, 31 | { // Options 32 | capabilities: { 33 | resources: {}, 34 | tools: {}, // Enable tools capability 35 | }, 36 | } 37 | ); 38 | 39 | // --- Helper Functions --- 40 | 41 | // Function to perform a single Google Custom Search (Web or Image) 42 | async function performGoogleSearch(query: string, searchType: 'web' | 'image' = 'web', count: number = 10) { 43 | if (!GOOGLE_API_KEY || !GOOGLE_CSE_ID) { 44 | throw new Error('Google API Key or CSE ID is not configured.'); 45 | } 46 | const response = await axios.get('https://www.googleapis.com/customsearch/v1', { 47 | params: { 48 | key: GOOGLE_API_KEY, 49 | cx: GOOGLE_CSE_ID, 50 | q: query, 51 | searchType: searchType === 'image' ? 'image' : undefined, // only include if image search 52 | num: count, // Number of results to return (1-10) 53 | }, 54 | }); 55 | return response.data; 56 | } 57 | 58 | // Function to crawl a webpage and extract text 59 | async function crawlWebpage(url: string): Promise { 60 | try { 61 | const { data } = await axios.get(url, { 62 | headers: { 63 | // Mimic a browser user agent 64 | 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36' 65 | } 66 | }); 67 | const $ = cheerio.load(data); 68 | 69 | // Remove script and style elements 70 | $('script, style, noscript, iframe, header, footer, nav, aside').remove(); 71 | 72 | // Get text content, trying to prioritize main content areas if possible 73 | let bodyText = $('body').text(); // Fallback to full body text 74 | 75 | // Attempt to find common main content selectors 76 | const mainContentSelectors = ['main', 'article', '[role="main"]', '.main-content', '#main-content', '.post-content', '#content']; 77 | for (const selector of mainContentSelectors) { 78 | if ($(selector).length) { 79 | bodyText = $(selector).text(); 80 | break; // Use the first one found 81 | } 82 | } 83 | 84 | // Basic cleanup: replace multiple whitespace chars with a single space 85 | return bodyText.replace(/\s\s+/g, ' ').trim(); 86 | } catch (error: any) { 87 | console.error(`Error crawling ${url}:`, error.message); 88 | throw new Error(`Failed to crawl ${url}. Status: ${error.response?.status || 'N/A'}`); 89 | } 90 | } 91 | 92 | 93 | // --- Tool Logic Implementation --- 94 | 95 | // 1. Web Search Logic 96 | async function handleWebSearch({ query, count }: { query: string; count: number }) { 97 | try { 98 | const data = await performGoogleSearch(query, 'web', count); 99 | const items = data.items || []; 100 | if (items.length === 0) { 101 | return { content: [{ type: 'text', text: `No web results found for "${query}"` }] }; 102 | } 103 | const formattedResults = items.map((item: any, index: number) => 104 | `${index + 1}. Title: ${item.title}\n Link: ${item.link}\n Snippet: ${item.snippet}` 105 | ).join('\n\n'); 106 | return { content: [{ type: 'text', text: `Web search results for "${query}":\n\n${formattedResults}` }] }; 107 | } catch (error: any) { 108 | console.error('Google Web Search Error:', error.response?.data?.error || error.message); 109 | const apiError = error.response?.data?.error; 110 | const errorMessage = apiError ? `${apiError.message} (Code: ${apiError.code})` : error.message; 111 | return { isError: true, content: [{ type: 'text', text: `Error performing web search: ${errorMessage}` }] }; 112 | } 113 | } 114 | 115 | // 2. Batch Web Search Logic 116 | async function handleBatchWebSearch({ queries }: { queries: string[] }) { 117 | if (queries.length === 0) { 118 | return { isError: true, content: [{ type: 'text', text: 'No queries provided for batch search.' }] }; 119 | } 120 | // Limit batch size for safety/cost 121 | const MAX_BATCH_SIZE = 5; 122 | if (queries.length > MAX_BATCH_SIZE) { 123 | return { isError: true, content: [{ type: 'text', text: `Batch size too large. Maximum allowed is ${MAX_BATCH_SIZE}.` }] }; 124 | } 125 | 126 | try { 127 | const results = await Promise.all(queries.map(query => performGoogleSearch(query, 'web', 3))); // Fetch top 3 for each query 128 | let combinedResults = ""; 129 | results.forEach((data, i) => { 130 | const query = queries[i]; 131 | const items = data.items || []; 132 | combinedResults += `Results for "${query}":\n`; 133 | if (items.length === 0) { 134 | combinedResults += " No results found.\n\n"; 135 | } else { 136 | items.forEach((item: any, index: number) => { 137 | combinedResults += ` ${index + 1}. ${item.title} (${item.link})\n`; 138 | }); 139 | combinedResults += "\n"; 140 | } 141 | }); 142 | return { content: [{ type: 'text', text: combinedResults.trim() }] }; 143 | } catch (error: any) { 144 | console.error('Google Batch Web Search Error:', error.response?.data?.error || error.message); 145 | const apiError = error.response?.data?.error; 146 | const errorMessage = apiError ? `${apiError.message} (Code: ${apiError.code})` : error.message; 147 | return { isError: true, content: [{ type: 'text', text: `Error performing batch web search: ${errorMessage}` }] }; 148 | } 149 | } 150 | 151 | // 3. Google Image Search Logic 152 | async function handleGoogleImageSearch({ query, count }: { query: string; count: number }) { 153 | try { 154 | const data = await performGoogleSearch(query, 'image', count); 155 | const items = data.items || []; 156 | if (items.length === 0) { 157 | return { content: [{ type: 'text', text: `No image results found for "${query}"` }] }; 158 | } 159 | const formattedResults = items.map((item: any, index: number) => 160 | `${index + 1}. Title: ${item.title}\n Image URL: ${item.link}\n Source: ${item.displayLink}` 161 | ).join('\n\n'); 162 | return { content: [{ type: 'text', text: `Image search results for "${query}":\n\n${formattedResults}` }] }; 163 | } catch (error: any) { 164 | console.error('Google Image Search Error:', error.response?.data?.error || error.message); 165 | const apiError = error.response?.data?.error; 166 | const errorMessage = apiError ? `${apiError.message} (Code: ${apiError.code})` : error.message; 167 | return { isError: true, content: [{ type: 'text', text: `Error performing image search: ${errorMessage}` }] }; 168 | } 169 | } 170 | 171 | // 4. Web Crawl Logic 172 | async function handleWebCrawl({ url }: { url: string }) { 173 | try { 174 | const textContent = await crawlWebpage(url); 175 | // Limit output size 176 | const maxLength = 30000; 177 | const truncatedContent = textContent.length > maxLength 178 | ? textContent.substring(0, maxLength) + "\n... (content truncated)" 179 | : textContent; 180 | return { content: [{ type: 'text', text: `Content crawled from ${url}:\n\n${truncatedContent}` }] }; 181 | } catch (error: any) { 182 | return { isError: true, content: [{ type: 'text', text: error.message }] }; 183 | } 184 | } 185 | 186 | // 5. Advanced Web Crawl Logic (using Playwright) 187 | async function handleAdvancedWebCrawl({ url }: { url: string }): Promise { 188 | let browser: Browser | null = null; 189 | try { 190 | browser = await chromium.launch(); 191 | const page: Page = await browser.newPage(); 192 | // Changed waitUntil from 'networkidle' to 'domcontentloaded' to potentially avoid timeout 193 | await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 30000 }); 194 | 195 | // Attempt to extract main content using common selectors, falling back to body 196 | const mainContentSelectors = ['main', 'article', '[role="main"]', '.main-content', '#main-content', '.post-content', '#content', 'body']; 197 | let textContent = ''; 198 | 199 | for (const selector of mainContentSelectors) { 200 | const elementText = await page.locator(selector).first().textContent({ timeout: 5000 }); // Use first match 201 | if (elementText && elementText.trim().length > 100) { // Basic check for meaningful content 202 | textContent = elementText; 203 | break; 204 | } 205 | } 206 | 207 | if (!textContent) { 208 | // Fallback if no main selector worked well, get all visible text 209 | textContent = await page.locator('body').textContent({ timeout: 5000 }) ?? ''; 210 | } 211 | 212 | await browser.close(); 213 | 214 | // Basic cleanup 215 | const cleanedText = textContent.replace(/\s\s+/g, ' ').trim(); 216 | 217 | // Limit output size 218 | const maxLength = 40000; // Slightly increased limit for potentially richer content 219 | const truncatedContent = cleanedText.length > maxLength 220 | ? cleanedText.substring(0, maxLength) + "\n... (content truncated)" 221 | : cleanedText; 222 | 223 | return { content: [{ type: 'text', text: `Content crawled from ${url} using advanced crawler:\n\n${truncatedContent}` }] }; 224 | 225 | } catch (error: any) { 226 | console.error(`Error during advanced crawl of ${url}:`, error.message); 227 | if (browser) { 228 | await browser.close(); 229 | } 230 | return { isError: true, content: [{ type: 'text', text: `Error during advanced crawl: ${error.message}` }] }; 231 | } 232 | } 233 | 234 | 235 | // --- Tool Registration --- 236 | 237 | // Define Tool Schemas using Zod for validation later 238 | const webSearchArgsSchema = z.object({ 239 | query: z.string().describe('The search query.'), 240 | count: z.number().int().min(1).max(10).optional().default(5).describe('Number of results (1-10, default 5).'), 241 | }); 242 | 243 | const batchWebSearchArgsSchema = z.object({ 244 | queries: z.array(z.string()).min(1).max(5).describe('A list of search queries (max 5).'), 245 | }); 246 | 247 | const googleImageSearchArgsSchema = z.object({ 248 | query: z.string().describe('The image search query.'), 249 | count: z.number().int().min(1).max(10).optional().default(5).describe('Number of image results (1-10, default 5).'), 250 | }); 251 | 252 | const webCrawlArgsSchema = z.object({ 253 | url: z.string().url().describe('The URL of the webpage to crawl.'), 254 | }); 255 | 256 | const advancedWebCrawlArgsSchema = z.object({ 257 | url: z.string().url().describe('The URL of the webpage to crawl using a headless browser.'), 258 | }); 259 | 260 | 261 | // List Tools Handler 262 | server.setRequestHandler(ListToolsRequestSchema, async () => { 263 | return { 264 | tools: [ 265 | { 266 | name: 'web_search', 267 | description: 'Performs a web search using Google Custom Search API.', 268 | inputSchema: { 269 | type: 'object', 270 | properties: { 271 | query: { type: 'string', description: 'The search query.' }, 272 | count: { type: 'number', description: 'Number of results (1-10, default 5).', default: 5 }, 273 | }, 274 | required: ['query'], 275 | }, 276 | }, 277 | { 278 | name: 'batch_web_search', 279 | description: 'Performs multiple web searches simultaneously (max 5 queries).', 280 | inputSchema: { 281 | type: 'object', 282 | properties: { 283 | queries: { type: 'array', items: { type: 'string' }, description: 'A list of search queries (max 5).' }, 284 | }, 285 | required: ['queries'], 286 | }, 287 | }, 288 | { 289 | name: 'google_image_search', 290 | description: 'Performs an image search using Google Custom Search API.', 291 | inputSchema: { 292 | type: 'object', 293 | properties: { 294 | query: { type: 'string', description: 'The image search query.' }, 295 | count: { type: 'number', description: 'Number of image results (1-10, default 5).', default: 5 }, 296 | }, 297 | required: ['query'], 298 | }, 299 | }, 300 | { 301 | name: 'web_crawl', 302 | description: 'Fetches and extracts the main text content from a given webpage URL.', 303 | inputSchema: { 304 | type: 'object', 305 | properties: { 306 | url: { type: 'string', format: 'uri', description: 'The URL of the webpage to crawl.' }, 307 | }, 308 | required: ['url'], 309 | }, 310 | }, 311 | { 312 | name: 'advanced_web_crawl', 313 | description: 'Fetches and extracts text content from a URL using a headless browser (more robust, but slower). Use if the standard web_crawl tool gets blocked or fails.', 314 | inputSchema: { 315 | type: 'object', 316 | properties: { 317 | url: { type: 'string', format: 'uri', description: 'The URL of the webpage to crawl.' }, 318 | }, 319 | required: ['url'], 320 | }, 321 | }, 322 | ], 323 | }; 324 | }); 325 | 326 | // Call Tool Handler 327 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 328 | const toolName = request.params.name; 329 | const args = request.params.arguments; 330 | 331 | try { 332 | if (toolName === 'web_search') { 333 | const validatedArgs = webSearchArgsSchema.parse(args); 334 | return await handleWebSearch(validatedArgs); 335 | } else if (toolName === 'batch_web_search') { 336 | const validatedArgs = batchWebSearchArgsSchema.parse(args); 337 | return await handleBatchWebSearch(validatedArgs); 338 | } else if (toolName === 'google_image_search') { 339 | const validatedArgs = googleImageSearchArgsSchema.parse(args); 340 | return await handleGoogleImageSearch(validatedArgs); 341 | } else if (toolName === 'web_crawl') { 342 | const validatedArgs = webCrawlArgsSchema.parse(args); 343 | return await handleWebCrawl(validatedArgs); 344 | } else if (toolName === 'advanced_web_crawl') { 345 | const validatedArgs = advancedWebCrawlArgsSchema.parse(args); 346 | return await handleAdvancedWebCrawl(validatedArgs); 347 | } else { 348 | throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`); 349 | } 350 | } catch (error: any) { 351 | console.error(`Error calling tool ${toolName}:`, error); 352 | if (error instanceof z.ZodError) { 353 | throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: ${error.errors.map(e => e.message).join(', ')}`); 354 | } 355 | if (error instanceof McpError) { 356 | throw error; 357 | } 358 | throw new McpError(ErrorCode.InternalError, `Error executing tool ${toolName}: ${error.message}`); 359 | } 360 | }); 361 | 362 | 363 | // --- Server Execution --- 364 | async function main() { 365 | const transport = new StdioServerTransport(); 366 | await server.connect(transport); 367 | console.error('Information Retrieval MCP Server running on stdio'); 368 | } 369 | 370 | main().catch((error) => { 371 | console.error('Fatal error in main():', error); 372 | process.exit(1); 373 | }); 374 | -------------------------------------------------------------------------------- /media-tools-server/src/index.ts: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | import { Server } from '@modelcontextprotocol/sdk/server/index.js'; 3 | import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'; 4 | import { 5 | CallToolRequestSchema, 6 | ErrorCode, 7 | ListToolsRequestSchema, 8 | McpError, 9 | } from '@modelcontextprotocol/sdk/types.js'; 10 | import { z } from 'zod'; 11 | import axios from 'axios'; 12 | import * as fs from 'fs'; 13 | import * as path from 'path'; 14 | import * as os from 'os'; // Import os module for home directory 15 | import { YoutubeTranscript } from 'youtube-transcript'; 16 | import { GoogleGenerativeAI, HarmCategory, HarmBlockThreshold, GenerateContentRequest } from '@google/generative-ai'; // Removed ResponseModality import 17 | 18 | // --- API Configuration --- 19 | const UNSPLASH_ACCESS_KEY = process.env.UNSPLASH_ACCESS_KEY || 'xtiRQvUeNUVQLvUBGs3L_4Nnau0DbfXvVvZoUZcMLzA'; 20 | const YOUTUBE_API_KEY = process.env.YOUTUBE_API_KEY; 21 | const GEMINI_API_KEY = process.env.GEMINI_API_KEY || process.env.GOOGLE_API_KEY; // Support both GEMINI_API_KEY and GOOGLE_API_KEY 22 | 23 | if (!YOUTUBE_API_KEY) { 24 | console.error("WARN: YOUTUBE_API_KEY environment variable is not set. Video search will fail."); 25 | } 26 | // Re-enable Google API Key check and GenAI client setup 27 | if (!GEMINI_API_KEY) { 28 | console.error("WARN: GEMINI_API_KEY environment variable is not set. Image generation/understanding will fail."); 29 | } 30 | 31 | // --- Google AI Client Setup --- 32 | let genAI: GoogleGenerativeAI | null = null; 33 | if (GEMINI_API_KEY) { 34 | genAI = new GoogleGenerativeAI(GEMINI_API_KEY); 35 | } else { 36 | console.error("GoogleGenerativeAI client could not be initialized due to missing API key."); 37 | } 38 | 39 | // --- Server Setup --- 40 | const server = new Server( 41 | { // ServerInfo 42 | name: 'media-tools-server', 43 | version: '0.1.2', // Incremented version 44 | }, 45 | { // Options 46 | capabilities: { 47 | resources: {}, 48 | tools: {}, 49 | }, 50 | } 51 | ); 52 | 53 | // --- Helper Functions --- 54 | async function downloadImage(url: string, filepath: string): Promise { 55 | const dirname = path.dirname(filepath); 56 | if (!fs.existsSync(dirname)) { 57 | fs.mkdirSync(dirname, { recursive: true }); 58 | } 59 | const writer = fs.createWriteStream(filepath); 60 | const response = await axios({ 61 | url, 62 | method: 'GET', 63 | responseType: 'stream', 64 | }); 65 | response.data.pipe(writer); 66 | return new Promise((resolve, reject) => { 67 | writer.on('finish', resolve); 68 | writer.on('error', reject); 69 | }); 70 | } 71 | 72 | // --- Tool Logic Implementation --- 73 | 74 | // 1. Image Search Logic 75 | async function handleImageSearch({ query, count }: { query: string; count: number }) { 76 | if (!UNSPLASH_ACCESS_KEY) { 77 | return { isError: true, content: [{ type: 'text', text: 'Unsplash API key is not configured.' }] }; 78 | } 79 | try { 80 | const response = await axios.get('https://api.unsplash.com/search/photos', { 81 | params: { 82 | query: query, 83 | per_page: count, 84 | }, 85 | headers: { 86 | Authorization: `Client-ID ${UNSPLASH_ACCESS_KEY}`, 87 | 'Accept-Version': 'v1', 88 | }, 89 | }); 90 | 91 | const images = response.data.results.map((img: any) => ({ 92 | id: img.id, 93 | description: img.description || img.alt_description || 'No description', 94 | url_regular: img.urls.regular, // Link to regular size image 95 | url_download: img.links.download_location, // Special link for triggering download count on Unsplash 96 | photographer_name: img.user.name, 97 | photographer_url: img.user.links.html, 98 | })); 99 | 100 | if (images.length === 0) { 101 | return { 102 | content: [{ type: 'text', text: `No images found for query: "${query}"` }], 103 | }; 104 | } 105 | 106 | const formattedResults = images.map((img: any, index: number) => 107 | `${index + 1}. Description: ${img.description}\n Regular URL: ${img.url_regular}\n Photographer: ${img.photographer_name} (${img.photographer_url})` 108 | ).join('\n\n'); 109 | 110 | return { 111 | content: [ 112 | { 113 | type: 'text', 114 | text: `Found ${images.length} images for "${query}":\n\n${formattedResults}\n\nUse the 'download_image' tool with a regular URL to save an image.`, 115 | }, 116 | ], 117 | }; 118 | } catch (error: any) { 119 | console.error('Unsplash API Error:', error.response?.data || error.message); 120 | return { 121 | isError: true, 122 | content: [ 123 | { 124 | type: 'text', 125 | text: `Error searching images: ${error.response?.data?.errors?.[0] || error.message}`, 126 | }, 127 | ], 128 | }; 129 | } 130 | } 131 | 132 | // 2. Download Image Logic 133 | async function handleDownloadImage({ imageUrl, filePath }: { imageUrl: string; filePath: string }) { 134 | try { 135 | if (!filePath.match(/\.(jpg|jpeg|png|gif)$/i)) { 136 | throw new Error('Invalid file path. Please include a valid image extension (.jpg, .png, .gif).'); 137 | } 138 | await downloadImage(imageUrl, filePath); 139 | return { 140 | content: [ { type: 'text', text: `Image successfully downloaded to: ${filePath}` } ], 141 | }; 142 | } catch (error: any) { 143 | console.error('Download Error:', error.message); 144 | return { isError: true, content: [ { type: 'text', text: `Error downloading image: ${error.message}` } ] }; 145 | } 146 | } 147 | 148 | // 3. Video Search Logic 149 | async function handleVideoSearch({ query, count }: { query: string; count: number }) { 150 | if (!YOUTUBE_API_KEY) { 151 | return { isError: true, content: [{ type: 'text', text: 'YouTube API key is not configured.' }] }; 152 | } 153 | try { 154 | const response = await axios.get('https://www.googleapis.com/youtube/v3/search', { 155 | params: { part: 'snippet', q: query, type: 'video', maxResults: count, key: YOUTUBE_API_KEY }, 156 | }); 157 | const videos = response.data.items.map((item: any) => ({ 158 | id: item.id.videoId, 159 | title: item.snippet.title, 160 | description: item.snippet.description, 161 | channelTitle: item.snippet.channelTitle, 162 | url: `https://www.youtube.com/watch?v=${item.id.videoId}`, 163 | })); 164 | if (videos.length === 0) { 165 | return { content: [{ type: 'text', text: `No videos found for query: "${query}"` }] }; 166 | } 167 | const formattedResults = videos.map((video: any, index: number) => 168 | `${index + 1}. Title: ${video.title}\n Channel: ${video.channelTitle}\n URL: ${video.url}\n Description: ${video.description}` 169 | ).join('\n\n'); 170 | return { 171 | content: [ { type: 'text', text: `Found ${videos.length} videos for "${query}":\n\n${formattedResults}\n\nUse the 'video_understanding' tool with a video ID (from the URL) to get its transcript.` } ], 172 | }; 173 | } catch (error: any) { 174 | console.error('YouTube API Error:', error.response?.data?.error || error.message); 175 | const apiError = error.response?.data?.error; 176 | const errorMessage = apiError ? `${apiError.message} (Code: ${apiError.code})` : error.message; 177 | return { isError: true, content: [ { type: 'text', text: `Error searching videos: ${errorMessage}` } ] }; 178 | } 179 | } 180 | 181 | // 4. Video Understanding Logic (Transcript Extraction) 182 | async function handleVideoUnderstanding({ video_id }: { video_id: string }) { 183 | try { 184 | const transcript = await YoutubeTranscript.fetchTranscript(video_id); 185 | if (!transcript || transcript.length === 0) { 186 | return { content: [{ type: 'text', text: `No transcript found or available for video ID: ${video_id}` }] }; 187 | } 188 | const formattedTranscript = transcript.map(entry => `[${(entry.offset / 1000).toFixed(2)}s] ${entry.text}`).join('\n'); 189 | const maxLength = 50000; 190 | const truncatedTranscript = formattedTranscript.length > maxLength ? formattedTranscript.substring(0, maxLength) + "\n... (transcript truncated)" : formattedTranscript; 191 | return { content: [ { type: 'text', text: `Transcript for video ID ${video_id}:\n\n${truncatedTranscript}` } ] }; 192 | } catch (error: any) { 193 | console.error('Transcript Error:', error.message); 194 | let errorMessage = error.message; 195 | if (error.message?.includes('disabled transcript') || error.message?.includes('No transcript found')) { 196 | errorMessage = `Could not retrieve transcript for video ID ${video_id}. Transcripts might be disabled or unavailable for this video.`; 197 | } else if (error.message?.includes('Invalid video ID')) { 198 | errorMessage = `Invalid YouTube video ID provided: ${video_id}`; 199 | } 200 | return { isError: true, content: [ { type: 'text', text: `Error getting transcript: ${errorMessage}` } ] }; 201 | } 202 | } 203 | 204 | // 5. Image Understanding Logic 205 | async function handleImageUnderstanding({ imageUrl, imagePath, prompt }: { imageUrl?: string; imagePath?: string; prompt?: string }) { 206 | if (!genAI) { 207 | return { isError: true, content: [{ type: 'text', text: 'Google AI SDK not initialized. Check API key.' }] }; 208 | } 209 | if (!imageUrl && !imagePath) { 210 | return { isError: true, content: [{ type: 'text', text: 'Either imageUrl or imagePath must be provided.' }] }; 211 | } 212 | if (imageUrl && imagePath) { 213 | return { isError: true, content: [{ type: 'text', text: 'Provide either imageUrl or imagePath, not both.' }] }; 214 | } 215 | 216 | const userPrompt = prompt || "Describe this image in detail."; // Default prompt 217 | let imagePart: any = null; 218 | let mimeType: string | undefined = undefined; 219 | 220 | try { 221 | if (imagePath) { 222 | if (!fs.existsSync(imagePath)) { throw new Error(`File not found: ${imagePath}`); } 223 | const fileBuffer = fs.readFileSync(imagePath); 224 | const mime = await import('mime-types'); // Dynamic import for mime-types 225 | mimeType = mime.lookup(imagePath) || 'application/octet-stream'; 226 | imagePart = { inlineData: { data: fileBuffer.toString('base64'), mimeType: mimeType } }; 227 | } else if (imageUrl) { 228 | const response = await axios.get(imageUrl, { responseType: 'arraybuffer' }); 229 | const buffer = Buffer.from(response.data, 'binary'); 230 | mimeType = response.headers['content-type']?.split(';')[0] || 'application/octet-stream'; 231 | imagePart = { inlineData: { data: buffer.toString('base64'), mimeType: mimeType } }; 232 | } 233 | 234 | if (!imagePart) { throw new Error("Could not prepare image data."); } 235 | 236 | // Use gemini-2.5-flash for image understanding (supports vision) 237 | const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" }); 238 | 239 | const contents = [ { role: "user", parts: [ {text: userPrompt}, imagePart ] } ]; 240 | 241 | const result = await model.generateContent({ contents }); 242 | const response = result.response; 243 | const description = response.text(); 244 | 245 | return { content: [{ type: 'text', text: description }] }; 246 | 247 | } catch (error: any) { 248 | console.error('Gemini Vision API Error:', error.message); 249 | let detailMessage = error.message; 250 | if (error.cause && typeof error.cause === 'object' && 'message' in error.cause) { 251 | detailMessage = error.cause.message; 252 | } 253 | return { isError: true, content: [{ type: 'text', text: `Error understanding image: ${detailMessage}` }] }; 254 | } 255 | } 256 | 257 | // 6. Image Generation Logic 258 | async function handleImageGeneration({ prompt, filePath }: { prompt: string; filePath?: string }) { 259 | if (!genAI) { 260 | return { isError: true, content: [{ type: 'text', text: 'Google AI SDK not initialized. Check API key.' }] }; 261 | } 262 | 263 | try { 264 | // Use gemini-2.5-flash for generating detailed image descriptions 265 | // Gemini doesn't directly generate image files like DALL-E, but provides detailed descriptions 266 | const model = genAI.getGenerativeModel({ model: "gemini-2.5-flash" }); 267 | 268 | // Request a detailed description suitable for image generation 269 | const enhancedPrompt = `Create a highly detailed visual description for generating an image of: "${prompt}". 270 | Include specific details about: 271 | - Composition and framing 272 | - Lighting and atmosphere 273 | - Colors and textures 274 | - Subject details and positioning 275 | - Background elements 276 | - Mood and style 277 | 278 | Provide the description in a way that would help an artist or image generation AI create the image.`; 279 | 280 | const result = await model.generateContent({ 281 | contents: [{ 282 | role: 'user', 283 | parts: [{ text: enhancedPrompt }] 284 | }], 285 | generationConfig: { 286 | temperature: 0.9, 287 | topP: 0.95, 288 | } 289 | }); 290 | 291 | const description = result.response.text(); 292 | 293 | let responseMessage = `Image Generation Request: "${prompt}"\n\n`; 294 | responseMessage += `Detailed Description for Image Generation:\n${description}\n\n`; 295 | responseMessage += `USAGE NOTES:\n`; 296 | responseMessage += `- Gemini does not directly generate images like DALL-E or Midjourney\n`; 297 | responseMessage += `- Use the detailed description above with dedicated image generation services:\n`; 298 | responseMessage += ` • DALL-E (OpenAI)\n`; 299 | responseMessage += ` • Midjourney\n`; 300 | responseMessage += ` • Stable Diffusion\n`; 301 | responseMessage += ` • Adobe Firefly\n`; 302 | responseMessage += `- The description is optimized to help these services create your desired image\n`; 303 | 304 | if (filePath) { 305 | // Save the description to a text file 306 | try { 307 | const dirname = path.dirname(filePath); 308 | if (!fs.existsSync(dirname)) { 309 | fs.mkdirSync(dirname, { recursive: true }); 310 | } 311 | const textFilePath = filePath.replace(/\.[^/.]+$/, '.txt'); 312 | fs.writeFileSync(textFilePath, description); 313 | responseMessage += `\n✓ Description saved to: ${textFilePath}`; 314 | } catch (saveError: any) { 315 | responseMessage += `\n⚠ Warning: Could not save description file: ${saveError.message}`; 316 | } 317 | } 318 | 319 | return { content: [{ type: 'text', text: responseMessage }] }; 320 | 321 | } catch (error: any) { 322 | console.error('Image Generation Error:', error.message); 323 | return { 324 | isError: true, 325 | content: [{ 326 | type: 'text', 327 | text: `Error generating image description: ${error.message}\n\nNote: Gemini provides detailed descriptions for image generation. For actual image files, use dedicated services like DALL-E, Midjourney, or Stable Diffusion.` 328 | }] 329 | }; 330 | } 331 | } 332 | 333 | 334 | // --- Tool Registration --- 335 | 336 | // Define Tool Schemas using Zod for validation later 337 | const imageSearchArgsSchema = z.object({ 338 | query: z.string().describe('The search query for images.'), 339 | count: z.number().int().positive().optional().default(5).describe('Number of images to return (default 5).'), 340 | }); 341 | 342 | const downloadImageArgsSchema = z.object({ 343 | imageUrl: z.string().url().describe('The URL of the image to download.'), 344 | filePath: z.string().describe('The local path (including filename and extension) where the image should be saved. e.g., C:/Users/Ahmed/Desktop/my_image.jpg'), 345 | }); 346 | 347 | const videoSearchArgsSchema = z.object({ 348 | query: z.string().describe('The search query for videos.'), 349 | count: z.number().int().positive().optional().default(5).describe('Number of videos to return (default 5).'), 350 | }); 351 | 352 | const videoUnderstandingArgsSchema = z.object({ 353 | video_id: z.string().describe('The ID of the YouTube video (from the URL).'), 354 | }); 355 | 356 | const imageGenerationArgsSchema = z.object({ 357 | prompt: z.string().describe('Description of the image to generate.'), 358 | filePath: z.string().optional().describe('Optional local file path (including filename and extension) where the image representation should be saved. e.g., C:/Users/Ahmed/Desktop/generated_image.png'), 359 | }); 360 | 361 | const imageUnderstandingArgsSchema = z.object({ 362 | imageUrl: z.string().url().optional().describe('URL of the image to understand.'), 363 | imagePath: z.string().optional().describe('Local file path of the image to understand.'), 364 | prompt: z.string().optional().describe('Optional prompt to guide the understanding (e.g., "What objects are in this image?"). Defaults to "Describe this image in detail."'), 365 | }).refine(data => data.imageUrl || data.imagePath, { 366 | message: "Either imageUrl or imagePath must be provided.", 367 | }).refine(data => !(data.imageUrl && data.imagePath), { 368 | message: "Provide either imageUrl or imagePath, not both.", 369 | }); 370 | 371 | 372 | // List Tools Handler 373 | server.setRequestHandler(ListToolsRequestSchema, async () => { 374 | return { 375 | tools: [ 376 | { 377 | name: 'image_search', 378 | description: 'Search for images using Unsplash API.', 379 | inputSchema: { 380 | type: 'object', 381 | properties: { 382 | query: { type: 'string', description: 'The search query for images.' }, 383 | count: { type: 'number', description: 'Number of images to return (default 5).', default: 5 }, 384 | }, 385 | required: ['query'], 386 | } 387 | }, 388 | { 389 | name: 'download_image', 390 | description: 'Downloads an image from a given URL to a specified file path.', 391 | inputSchema: { 392 | type: 'object', 393 | properties: { 394 | imageUrl: { type: 'string', format: 'uri', description: 'The URL of the image to download.' }, 395 | filePath: { type: 'string', description: 'The **full** local path (including filename and extension) where the image should be saved. e.g., C:/Users/YourUsername/Desktop/my_image.jpg' }, 396 | }, 397 | required: ['imageUrl', 'filePath'], 398 | } 399 | }, 400 | { 401 | name: 'video_search', 402 | description: 'Search for YouTube videos.', 403 | inputSchema: { 404 | type: 'object', 405 | properties: { 406 | query: { type: 'string', description: 'The search query for videos.' }, 407 | count: { type: 'number', description: 'Number of videos to return (default 5).', default: 5 }, 408 | }, 409 | required: ['query'], 410 | } 411 | }, 412 | { 413 | name: 'video_understanding', 414 | description: 'Extracts the transcript with timestamps from a YouTube video.', 415 | inputSchema: { 416 | type: 'object', 417 | properties: { 418 | video_id: { type: 'string', description: 'The ID of the YouTube video (from the URL).' }, 419 | }, 420 | required: ['video_id'], 421 | } 422 | }, 423 | { 424 | name: 'image_understanding', 425 | description: 'Analyzes an image from a URL or local path using Google Gemini and returns a description.', 426 | inputSchema: { 427 | type: 'object', 428 | properties: { 429 | imageUrl: { type: 'string', format: 'uri', description: 'URL of the image to understand.' }, 430 | imagePath: { type: 'string', description: 'Local file path of the image to understand.' }, 431 | prompt: { type: 'string', description: 'Optional prompt to guide the understanding.' }, 432 | }, 433 | // Note: Logic requires one of imageUrl or imagePath, handled in code/Zod refine 434 | }, 435 | }, 436 | { 437 | name: 'image_generation', 438 | description: 'Generates an image description and simple representation using Google Gemini. For production-quality images, use the detailed description with dedicated image generation services.', 439 | inputSchema: { 440 | type: 'object', 441 | properties: { 442 | prompt: { type: 'string', description: 'Description of the image to generate.' }, 443 | filePath: { type: 'string', description: 'Optional local file path (including filename and extension) where a simple image representation should be saved.' }, 444 | }, 445 | required: ['prompt'], 446 | }, 447 | }, 448 | ], 449 | }; 450 | }); 451 | 452 | // Call Tool Handler 453 | server.setRequestHandler(CallToolRequestSchema, async (request) => { 454 | const toolName = request.params.name; 455 | const args = request.params.arguments; 456 | 457 | try { 458 | if (toolName === 'image_search') { 459 | const validatedArgs = imageSearchArgsSchema.parse(args); 460 | return await handleImageSearch(validatedArgs); 461 | } else if (toolName === 'download_image') { 462 | const validatedArgs = downloadImageArgsSchema.parse(args); 463 | return await handleDownloadImage(validatedArgs); 464 | } else if (toolName === 'video_search') { 465 | const validatedArgs = videoSearchArgsSchema.parse(args); 466 | return await handleVideoSearch(validatedArgs); 467 | } else if (toolName === 'video_understanding') { 468 | const validatedArgs = videoUnderstandingArgsSchema.parse(args); 469 | return await handleVideoUnderstanding(validatedArgs); 470 | } else if (toolName === 'image_understanding') { 471 | const validatedArgs = imageUnderstandingArgsSchema.parse(args); 472 | return await handleImageUnderstanding(validatedArgs); 473 | } else if (toolName === 'image_generation') { 474 | const validatedArgs = imageGenerationArgsSchema.parse(args); 475 | return await handleImageGeneration(validatedArgs); 476 | } else { 477 | throw new McpError(ErrorCode.MethodNotFound, `Unknown tool: ${toolName}`); 478 | } 479 | } catch (error: any) { 480 | console.error(`Error calling tool ${toolName}:`, error); 481 | if (error instanceof z.ZodError) { 482 | throw new McpError(ErrorCode.InvalidParams, `Invalid arguments for tool ${toolName}: ${error.errors.map(e => e.message).join(', ')}`); 483 | } 484 | if (error instanceof McpError) { 485 | throw error; 486 | } 487 | throw new McpError(ErrorCode.InternalError, `Error executing tool ${toolName}: ${error.message}`); 488 | } 489 | }); 490 | 491 | 492 | // --- Server Execution --- 493 | async function main() { 494 | const transport = new StdioServerTransport(); 495 | await server.connect(transport); 496 | console.error('Media Tools MCP Server running on stdio'); 497 | } 498 | 499 | main().catch((error) => { 500 | console.error('Fatal error in main():', error); 501 | process.exit(1); 502 | }); 503 | -------------------------------------------------------------------------------- /presentation-creator-server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "presentation-creator-mcp-server", 3 | "version": "0.1.2", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "presentation-creator-mcp-server", 9 | "version": "0.1.2", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@modelcontextprotocol/sdk": "0.6.0", 13 | "playwright": "^1.51.1", 14 | "pptxgenjs": "^3.12.0", 15 | "zod": "^3.22.4" 16 | }, 17 | "bin": { 18 | "presentation-creator-server": "build/index.js" 19 | }, 20 | "devDependencies": { 21 | "@types/node": "^20.11.24", 22 | "esbuild": "^0.25.11", 23 | "typescript": "^5.3.3" 24 | } 25 | }, 26 | "node_modules/@esbuild/aix-ppc64": { 27 | "version": "0.25.11", 28 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", 29 | "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", 30 | "cpu": [ 31 | "ppc64" 32 | ], 33 | "dev": true, 34 | "license": "MIT", 35 | "optional": true, 36 | "os": [ 37 | "aix" 38 | ], 39 | "engines": { 40 | "node": ">=18" 41 | } 42 | }, 43 | "node_modules/@esbuild/android-arm": { 44 | "version": "0.25.11", 45 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", 46 | "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", 47 | "cpu": [ 48 | "arm" 49 | ], 50 | "dev": true, 51 | "license": "MIT", 52 | "optional": true, 53 | "os": [ 54 | "android" 55 | ], 56 | "engines": { 57 | "node": ">=18" 58 | } 59 | }, 60 | "node_modules/@esbuild/android-arm64": { 61 | "version": "0.25.11", 62 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", 63 | "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", 64 | "cpu": [ 65 | "arm64" 66 | ], 67 | "dev": true, 68 | "license": "MIT", 69 | "optional": true, 70 | "os": [ 71 | "android" 72 | ], 73 | "engines": { 74 | "node": ">=18" 75 | } 76 | }, 77 | "node_modules/@esbuild/android-x64": { 78 | "version": "0.25.11", 79 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", 80 | "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", 81 | "cpu": [ 82 | "x64" 83 | ], 84 | "dev": true, 85 | "license": "MIT", 86 | "optional": true, 87 | "os": [ 88 | "android" 89 | ], 90 | "engines": { 91 | "node": ">=18" 92 | } 93 | }, 94 | "node_modules/@esbuild/darwin-arm64": { 95 | "version": "0.25.11", 96 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", 97 | "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", 98 | "cpu": [ 99 | "arm64" 100 | ], 101 | "dev": true, 102 | "license": "MIT", 103 | "optional": true, 104 | "os": [ 105 | "darwin" 106 | ], 107 | "engines": { 108 | "node": ">=18" 109 | } 110 | }, 111 | "node_modules/@esbuild/darwin-x64": { 112 | "version": "0.25.11", 113 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", 114 | "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", 115 | "cpu": [ 116 | "x64" 117 | ], 118 | "dev": true, 119 | "license": "MIT", 120 | "optional": true, 121 | "os": [ 122 | "darwin" 123 | ], 124 | "engines": { 125 | "node": ">=18" 126 | } 127 | }, 128 | "node_modules/@esbuild/freebsd-arm64": { 129 | "version": "0.25.11", 130 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", 131 | "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", 132 | "cpu": [ 133 | "arm64" 134 | ], 135 | "dev": true, 136 | "license": "MIT", 137 | "optional": true, 138 | "os": [ 139 | "freebsd" 140 | ], 141 | "engines": { 142 | "node": ">=18" 143 | } 144 | }, 145 | "node_modules/@esbuild/freebsd-x64": { 146 | "version": "0.25.11", 147 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", 148 | "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", 149 | "cpu": [ 150 | "x64" 151 | ], 152 | "dev": true, 153 | "license": "MIT", 154 | "optional": true, 155 | "os": [ 156 | "freebsd" 157 | ], 158 | "engines": { 159 | "node": ">=18" 160 | } 161 | }, 162 | "node_modules/@esbuild/linux-arm": { 163 | "version": "0.25.11", 164 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", 165 | "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", 166 | "cpu": [ 167 | "arm" 168 | ], 169 | "dev": true, 170 | "license": "MIT", 171 | "optional": true, 172 | "os": [ 173 | "linux" 174 | ], 175 | "engines": { 176 | "node": ">=18" 177 | } 178 | }, 179 | "node_modules/@esbuild/linux-arm64": { 180 | "version": "0.25.11", 181 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", 182 | "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", 183 | "cpu": [ 184 | "arm64" 185 | ], 186 | "dev": true, 187 | "license": "MIT", 188 | "optional": true, 189 | "os": [ 190 | "linux" 191 | ], 192 | "engines": { 193 | "node": ">=18" 194 | } 195 | }, 196 | "node_modules/@esbuild/linux-ia32": { 197 | "version": "0.25.11", 198 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", 199 | "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", 200 | "cpu": [ 201 | "ia32" 202 | ], 203 | "dev": true, 204 | "license": "MIT", 205 | "optional": true, 206 | "os": [ 207 | "linux" 208 | ], 209 | "engines": { 210 | "node": ">=18" 211 | } 212 | }, 213 | "node_modules/@esbuild/linux-loong64": { 214 | "version": "0.25.11", 215 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", 216 | "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", 217 | "cpu": [ 218 | "loong64" 219 | ], 220 | "dev": true, 221 | "license": "MIT", 222 | "optional": true, 223 | "os": [ 224 | "linux" 225 | ], 226 | "engines": { 227 | "node": ">=18" 228 | } 229 | }, 230 | "node_modules/@esbuild/linux-mips64el": { 231 | "version": "0.25.11", 232 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", 233 | "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", 234 | "cpu": [ 235 | "mips64el" 236 | ], 237 | "dev": true, 238 | "license": "MIT", 239 | "optional": true, 240 | "os": [ 241 | "linux" 242 | ], 243 | "engines": { 244 | "node": ">=18" 245 | } 246 | }, 247 | "node_modules/@esbuild/linux-ppc64": { 248 | "version": "0.25.11", 249 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", 250 | "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", 251 | "cpu": [ 252 | "ppc64" 253 | ], 254 | "dev": true, 255 | "license": "MIT", 256 | "optional": true, 257 | "os": [ 258 | "linux" 259 | ], 260 | "engines": { 261 | "node": ">=18" 262 | } 263 | }, 264 | "node_modules/@esbuild/linux-riscv64": { 265 | "version": "0.25.11", 266 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", 267 | "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", 268 | "cpu": [ 269 | "riscv64" 270 | ], 271 | "dev": true, 272 | "license": "MIT", 273 | "optional": true, 274 | "os": [ 275 | "linux" 276 | ], 277 | "engines": { 278 | "node": ">=18" 279 | } 280 | }, 281 | "node_modules/@esbuild/linux-s390x": { 282 | "version": "0.25.11", 283 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", 284 | "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", 285 | "cpu": [ 286 | "s390x" 287 | ], 288 | "dev": true, 289 | "license": "MIT", 290 | "optional": true, 291 | "os": [ 292 | "linux" 293 | ], 294 | "engines": { 295 | "node": ">=18" 296 | } 297 | }, 298 | "node_modules/@esbuild/linux-x64": { 299 | "version": "0.25.11", 300 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", 301 | "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", 302 | "cpu": [ 303 | "x64" 304 | ], 305 | "dev": true, 306 | "license": "MIT", 307 | "optional": true, 308 | "os": [ 309 | "linux" 310 | ], 311 | "engines": { 312 | "node": ">=18" 313 | } 314 | }, 315 | "node_modules/@esbuild/netbsd-arm64": { 316 | "version": "0.25.11", 317 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", 318 | "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", 319 | "cpu": [ 320 | "arm64" 321 | ], 322 | "dev": true, 323 | "license": "MIT", 324 | "optional": true, 325 | "os": [ 326 | "netbsd" 327 | ], 328 | "engines": { 329 | "node": ">=18" 330 | } 331 | }, 332 | "node_modules/@esbuild/netbsd-x64": { 333 | "version": "0.25.11", 334 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", 335 | "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", 336 | "cpu": [ 337 | "x64" 338 | ], 339 | "dev": true, 340 | "license": "MIT", 341 | "optional": true, 342 | "os": [ 343 | "netbsd" 344 | ], 345 | "engines": { 346 | "node": ">=18" 347 | } 348 | }, 349 | "node_modules/@esbuild/openbsd-arm64": { 350 | "version": "0.25.11", 351 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", 352 | "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", 353 | "cpu": [ 354 | "arm64" 355 | ], 356 | "dev": true, 357 | "license": "MIT", 358 | "optional": true, 359 | "os": [ 360 | "openbsd" 361 | ], 362 | "engines": { 363 | "node": ">=18" 364 | } 365 | }, 366 | "node_modules/@esbuild/openbsd-x64": { 367 | "version": "0.25.11", 368 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", 369 | "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", 370 | "cpu": [ 371 | "x64" 372 | ], 373 | "dev": true, 374 | "license": "MIT", 375 | "optional": true, 376 | "os": [ 377 | "openbsd" 378 | ], 379 | "engines": { 380 | "node": ">=18" 381 | } 382 | }, 383 | "node_modules/@esbuild/openharmony-arm64": { 384 | "version": "0.25.11", 385 | "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", 386 | "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", 387 | "cpu": [ 388 | "arm64" 389 | ], 390 | "dev": true, 391 | "license": "MIT", 392 | "optional": true, 393 | "os": [ 394 | "openharmony" 395 | ], 396 | "engines": { 397 | "node": ">=18" 398 | } 399 | }, 400 | "node_modules/@esbuild/sunos-x64": { 401 | "version": "0.25.11", 402 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", 403 | "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", 404 | "cpu": [ 405 | "x64" 406 | ], 407 | "dev": true, 408 | "license": "MIT", 409 | "optional": true, 410 | "os": [ 411 | "sunos" 412 | ], 413 | "engines": { 414 | "node": ">=18" 415 | } 416 | }, 417 | "node_modules/@esbuild/win32-arm64": { 418 | "version": "0.25.11", 419 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", 420 | "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", 421 | "cpu": [ 422 | "arm64" 423 | ], 424 | "dev": true, 425 | "license": "MIT", 426 | "optional": true, 427 | "os": [ 428 | "win32" 429 | ], 430 | "engines": { 431 | "node": ">=18" 432 | } 433 | }, 434 | "node_modules/@esbuild/win32-ia32": { 435 | "version": "0.25.11", 436 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", 437 | "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", 438 | "cpu": [ 439 | "ia32" 440 | ], 441 | "dev": true, 442 | "license": "MIT", 443 | "optional": true, 444 | "os": [ 445 | "win32" 446 | ], 447 | "engines": { 448 | "node": ">=18" 449 | } 450 | }, 451 | "node_modules/@esbuild/win32-x64": { 452 | "version": "0.25.11", 453 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", 454 | "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", 455 | "cpu": [ 456 | "x64" 457 | ], 458 | "dev": true, 459 | "license": "MIT", 460 | "optional": true, 461 | "os": [ 462 | "win32" 463 | ], 464 | "engines": { 465 | "node": ">=18" 466 | } 467 | }, 468 | "node_modules/@modelcontextprotocol/sdk": { 469 | "version": "0.6.0", 470 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz", 471 | "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==", 472 | "license": "MIT", 473 | "dependencies": { 474 | "content-type": "^1.0.5", 475 | "raw-body": "^3.0.0", 476 | "zod": "^3.23.8" 477 | } 478 | }, 479 | "node_modules/@types/node": { 480 | "version": "20.19.23", 481 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.23.tgz", 482 | "integrity": "sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==", 483 | "dev": true, 484 | "license": "MIT", 485 | "dependencies": { 486 | "undici-types": "~6.21.0" 487 | } 488 | }, 489 | "node_modules/bytes": { 490 | "version": "3.1.2", 491 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 492 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 493 | "license": "MIT", 494 | "engines": { 495 | "node": ">= 0.8" 496 | } 497 | }, 498 | "node_modules/content-type": { 499 | "version": "1.0.5", 500 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 501 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 502 | "license": "MIT", 503 | "engines": { 504 | "node": ">= 0.6" 505 | } 506 | }, 507 | "node_modules/core-util-is": { 508 | "version": "1.0.3", 509 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", 510 | "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", 511 | "license": "MIT" 512 | }, 513 | "node_modules/depd": { 514 | "version": "2.0.0", 515 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 516 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 517 | "license": "MIT", 518 | "engines": { 519 | "node": ">= 0.8" 520 | } 521 | }, 522 | "node_modules/esbuild": { 523 | "version": "0.25.11", 524 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", 525 | "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", 526 | "dev": true, 527 | "hasInstallScript": true, 528 | "license": "MIT", 529 | "bin": { 530 | "esbuild": "bin/esbuild" 531 | }, 532 | "engines": { 533 | "node": ">=18" 534 | }, 535 | "optionalDependencies": { 536 | "@esbuild/aix-ppc64": "0.25.11", 537 | "@esbuild/android-arm": "0.25.11", 538 | "@esbuild/android-arm64": "0.25.11", 539 | "@esbuild/android-x64": "0.25.11", 540 | "@esbuild/darwin-arm64": "0.25.11", 541 | "@esbuild/darwin-x64": "0.25.11", 542 | "@esbuild/freebsd-arm64": "0.25.11", 543 | "@esbuild/freebsd-x64": "0.25.11", 544 | "@esbuild/linux-arm": "0.25.11", 545 | "@esbuild/linux-arm64": "0.25.11", 546 | "@esbuild/linux-ia32": "0.25.11", 547 | "@esbuild/linux-loong64": "0.25.11", 548 | "@esbuild/linux-mips64el": "0.25.11", 549 | "@esbuild/linux-ppc64": "0.25.11", 550 | "@esbuild/linux-riscv64": "0.25.11", 551 | "@esbuild/linux-s390x": "0.25.11", 552 | "@esbuild/linux-x64": "0.25.11", 553 | "@esbuild/netbsd-arm64": "0.25.11", 554 | "@esbuild/netbsd-x64": "0.25.11", 555 | "@esbuild/openbsd-arm64": "0.25.11", 556 | "@esbuild/openbsd-x64": "0.25.11", 557 | "@esbuild/openharmony-arm64": "0.25.11", 558 | "@esbuild/sunos-x64": "0.25.11", 559 | "@esbuild/win32-arm64": "0.25.11", 560 | "@esbuild/win32-ia32": "0.25.11", 561 | "@esbuild/win32-x64": "0.25.11" 562 | } 563 | }, 564 | "node_modules/fsevents": { 565 | "version": "2.3.2", 566 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 567 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 568 | "hasInstallScript": true, 569 | "license": "MIT", 570 | "optional": true, 571 | "os": [ 572 | "darwin" 573 | ], 574 | "engines": { 575 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 576 | } 577 | }, 578 | "node_modules/http-errors": { 579 | "version": "2.0.0", 580 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 581 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 582 | "license": "MIT", 583 | "dependencies": { 584 | "depd": "2.0.0", 585 | "inherits": "2.0.4", 586 | "setprototypeof": "1.2.0", 587 | "statuses": "2.0.1", 588 | "toidentifier": "1.0.1" 589 | }, 590 | "engines": { 591 | "node": ">= 0.8" 592 | } 593 | }, 594 | "node_modules/https": { 595 | "version": "1.0.0", 596 | "resolved": "https://registry.npmjs.org/https/-/https-1.0.0.tgz", 597 | "integrity": "sha512-4EC57ddXrkaF0x83Oj8sM6SLQHAWXw90Skqu2M4AEWENZ3F02dFJE/GARA8igO79tcgYqGrD7ae4f5L3um2lgg==", 598 | "license": "ISC" 599 | }, 600 | "node_modules/iconv-lite": { 601 | "version": "0.7.0", 602 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", 603 | "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", 604 | "license": "MIT", 605 | "dependencies": { 606 | "safer-buffer": ">= 2.1.2 < 3.0.0" 607 | }, 608 | "engines": { 609 | "node": ">=0.10.0" 610 | }, 611 | "funding": { 612 | "type": "opencollective", 613 | "url": "https://opencollective.com/express" 614 | } 615 | }, 616 | "node_modules/image-size": { 617 | "version": "1.2.1", 618 | "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz", 619 | "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==", 620 | "license": "MIT", 621 | "dependencies": { 622 | "queue": "6.0.2" 623 | }, 624 | "bin": { 625 | "image-size": "bin/image-size.js" 626 | }, 627 | "engines": { 628 | "node": ">=16.x" 629 | } 630 | }, 631 | "node_modules/immediate": { 632 | "version": "3.0.6", 633 | "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", 634 | "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", 635 | "license": "MIT" 636 | }, 637 | "node_modules/inherits": { 638 | "version": "2.0.4", 639 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 640 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 641 | "license": "ISC" 642 | }, 643 | "node_modules/isarray": { 644 | "version": "1.0.0", 645 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 646 | "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", 647 | "license": "MIT" 648 | }, 649 | "node_modules/jszip": { 650 | "version": "3.10.1", 651 | "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", 652 | "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", 653 | "license": "(MIT OR GPL-3.0-or-later)", 654 | "dependencies": { 655 | "lie": "~3.3.0", 656 | "pako": "~1.0.2", 657 | "readable-stream": "~2.3.6", 658 | "setimmediate": "^1.0.5" 659 | } 660 | }, 661 | "node_modules/lie": { 662 | "version": "3.3.0", 663 | "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", 664 | "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", 665 | "license": "MIT", 666 | "dependencies": { 667 | "immediate": "~3.0.5" 668 | } 669 | }, 670 | "node_modules/pako": { 671 | "version": "1.0.11", 672 | "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", 673 | "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", 674 | "license": "(MIT AND Zlib)" 675 | }, 676 | "node_modules/playwright": { 677 | "version": "1.56.1", 678 | "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.56.1.tgz", 679 | "integrity": "sha512-aFi5B0WovBHTEvpM3DzXTUaeN6eN0qWnTkKx4NQaH4Wvcmc153PdaY2UBdSYKaGYw+UyWXSVyxDUg5DoPEttjw==", 680 | "license": "Apache-2.0", 681 | "dependencies": { 682 | "playwright-core": "1.56.1" 683 | }, 684 | "bin": { 685 | "playwright": "cli.js" 686 | }, 687 | "engines": { 688 | "node": ">=18" 689 | }, 690 | "optionalDependencies": { 691 | "fsevents": "2.3.2" 692 | } 693 | }, 694 | "node_modules/playwright-core": { 695 | "version": "1.56.1", 696 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.56.1.tgz", 697 | "integrity": "sha512-hutraynyn31F+Bifme+Ps9Vq59hKuUCz7H1kDOcBs+2oGguKkWTU50bBWrtz34OUWmIwpBTWDxaRPXrIXkgvmQ==", 698 | "license": "Apache-2.0", 699 | "bin": { 700 | "playwright-core": "cli.js" 701 | }, 702 | "engines": { 703 | "node": ">=18" 704 | } 705 | }, 706 | "node_modules/pptxgenjs": { 707 | "version": "3.12.0", 708 | "resolved": "https://registry.npmjs.org/pptxgenjs/-/pptxgenjs-3.12.0.tgz", 709 | "integrity": "sha512-ZozkYKWb1MoPR4ucw3/aFYlHkVIJxo9czikEclcUVnS4Iw/M+r+TEwdlB3fyAWO9JY1USxJDt0Y0/r15IR/RUA==", 710 | "license": "MIT", 711 | "dependencies": { 712 | "@types/node": "^18.7.3", 713 | "https": "^1.0.0", 714 | "image-size": "^1.0.0", 715 | "jszip": "^3.7.1" 716 | } 717 | }, 718 | "node_modules/pptxgenjs/node_modules/@types/node": { 719 | "version": "18.19.130", 720 | "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", 721 | "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", 722 | "license": "MIT", 723 | "dependencies": { 724 | "undici-types": "~5.26.4" 725 | } 726 | }, 727 | "node_modules/pptxgenjs/node_modules/undici-types": { 728 | "version": "5.26.5", 729 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", 730 | "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", 731 | "license": "MIT" 732 | }, 733 | "node_modules/process-nextick-args": { 734 | "version": "2.0.1", 735 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 736 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", 737 | "license": "MIT" 738 | }, 739 | "node_modules/queue": { 740 | "version": "6.0.2", 741 | "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", 742 | "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", 743 | "license": "MIT", 744 | "dependencies": { 745 | "inherits": "~2.0.3" 746 | } 747 | }, 748 | "node_modules/raw-body": { 749 | "version": "3.0.1", 750 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.1.tgz", 751 | "integrity": "sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==", 752 | "license": "MIT", 753 | "dependencies": { 754 | "bytes": "3.1.2", 755 | "http-errors": "2.0.0", 756 | "iconv-lite": "0.7.0", 757 | "unpipe": "1.0.0" 758 | }, 759 | "engines": { 760 | "node": ">= 0.10" 761 | } 762 | }, 763 | "node_modules/readable-stream": { 764 | "version": "2.3.8", 765 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", 766 | "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", 767 | "license": "MIT", 768 | "dependencies": { 769 | "core-util-is": "~1.0.0", 770 | "inherits": "~2.0.3", 771 | "isarray": "~1.0.0", 772 | "process-nextick-args": "~2.0.0", 773 | "safe-buffer": "~5.1.1", 774 | "string_decoder": "~1.1.1", 775 | "util-deprecate": "~1.0.1" 776 | } 777 | }, 778 | "node_modules/safe-buffer": { 779 | "version": "5.1.2", 780 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 781 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", 782 | "license": "MIT" 783 | }, 784 | "node_modules/safer-buffer": { 785 | "version": "2.1.2", 786 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 787 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 788 | "license": "MIT" 789 | }, 790 | "node_modules/setimmediate": { 791 | "version": "1.0.5", 792 | "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", 793 | "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", 794 | "license": "MIT" 795 | }, 796 | "node_modules/setprototypeof": { 797 | "version": "1.2.0", 798 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 799 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 800 | "license": "ISC" 801 | }, 802 | "node_modules/statuses": { 803 | "version": "2.0.1", 804 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 805 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 806 | "license": "MIT", 807 | "engines": { 808 | "node": ">= 0.8" 809 | } 810 | }, 811 | "node_modules/string_decoder": { 812 | "version": "1.1.1", 813 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 814 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 815 | "license": "MIT", 816 | "dependencies": { 817 | "safe-buffer": "~5.1.0" 818 | } 819 | }, 820 | "node_modules/toidentifier": { 821 | "version": "1.0.1", 822 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 823 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 824 | "license": "MIT", 825 | "engines": { 826 | "node": ">=0.6" 827 | } 828 | }, 829 | "node_modules/typescript": { 830 | "version": "5.9.3", 831 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", 832 | "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", 833 | "dev": true, 834 | "license": "Apache-2.0", 835 | "bin": { 836 | "tsc": "bin/tsc", 837 | "tsserver": "bin/tsserver" 838 | }, 839 | "engines": { 840 | "node": ">=14.17" 841 | } 842 | }, 843 | "node_modules/undici-types": { 844 | "version": "6.21.0", 845 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", 846 | "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", 847 | "dev": true, 848 | "license": "MIT" 849 | }, 850 | "node_modules/unpipe": { 851 | "version": "1.0.0", 852 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 853 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 854 | "license": "MIT", 855 | "engines": { 856 | "node": ">= 0.8" 857 | } 858 | }, 859 | "node_modules/util-deprecate": { 860 | "version": "1.0.2", 861 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 862 | "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", 863 | "license": "MIT" 864 | }, 865 | "node_modules/zod": { 866 | "version": "3.25.76", 867 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", 868 | "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", 869 | "license": "MIT", 870 | "funding": { 871 | "url": "https://github.com/sponsors/colinhacks" 872 | } 873 | } 874 | } 875 | } 876 | -------------------------------------------------------------------------------- /media-tools-server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "media-tools-mcp-server", 3 | "version": "0.1.3", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "media-tools-mcp-server", 9 | "version": "0.1.3", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@google/generative-ai": "^0.24.0", 13 | "@modelcontextprotocol/sdk": "0.6.0", 14 | "@types/mime-types": "^2.1.4", 15 | "axios": "^1.8.4", 16 | "mime-types": "^3.0.1", 17 | "youtube-transcript": "^1.2.1", 18 | "zod": "^3.22.4" 19 | }, 20 | "bin": { 21 | "media-tools-server": "build/index.js" 22 | }, 23 | "devDependencies": { 24 | "@types/node": "^20.11.24", 25 | "esbuild": "^0.25.11", 26 | "typescript": "^5.3.3" 27 | } 28 | }, 29 | "node_modules/@esbuild/aix-ppc64": { 30 | "version": "0.25.11", 31 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", 32 | "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", 33 | "cpu": [ 34 | "ppc64" 35 | ], 36 | "dev": true, 37 | "license": "MIT", 38 | "optional": true, 39 | "os": [ 40 | "aix" 41 | ], 42 | "engines": { 43 | "node": ">=18" 44 | } 45 | }, 46 | "node_modules/@esbuild/android-arm": { 47 | "version": "0.25.11", 48 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", 49 | "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", 50 | "cpu": [ 51 | "arm" 52 | ], 53 | "dev": true, 54 | "license": "MIT", 55 | "optional": true, 56 | "os": [ 57 | "android" 58 | ], 59 | "engines": { 60 | "node": ">=18" 61 | } 62 | }, 63 | "node_modules/@esbuild/android-arm64": { 64 | "version": "0.25.11", 65 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", 66 | "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", 67 | "cpu": [ 68 | "arm64" 69 | ], 70 | "dev": true, 71 | "license": "MIT", 72 | "optional": true, 73 | "os": [ 74 | "android" 75 | ], 76 | "engines": { 77 | "node": ">=18" 78 | } 79 | }, 80 | "node_modules/@esbuild/android-x64": { 81 | "version": "0.25.11", 82 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", 83 | "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", 84 | "cpu": [ 85 | "x64" 86 | ], 87 | "dev": true, 88 | "license": "MIT", 89 | "optional": true, 90 | "os": [ 91 | "android" 92 | ], 93 | "engines": { 94 | "node": ">=18" 95 | } 96 | }, 97 | "node_modules/@esbuild/darwin-arm64": { 98 | "version": "0.25.11", 99 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", 100 | "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", 101 | "cpu": [ 102 | "arm64" 103 | ], 104 | "dev": true, 105 | "license": "MIT", 106 | "optional": true, 107 | "os": [ 108 | "darwin" 109 | ], 110 | "engines": { 111 | "node": ">=18" 112 | } 113 | }, 114 | "node_modules/@esbuild/darwin-x64": { 115 | "version": "0.25.11", 116 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", 117 | "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", 118 | "cpu": [ 119 | "x64" 120 | ], 121 | "dev": true, 122 | "license": "MIT", 123 | "optional": true, 124 | "os": [ 125 | "darwin" 126 | ], 127 | "engines": { 128 | "node": ">=18" 129 | } 130 | }, 131 | "node_modules/@esbuild/freebsd-arm64": { 132 | "version": "0.25.11", 133 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", 134 | "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", 135 | "cpu": [ 136 | "arm64" 137 | ], 138 | "dev": true, 139 | "license": "MIT", 140 | "optional": true, 141 | "os": [ 142 | "freebsd" 143 | ], 144 | "engines": { 145 | "node": ">=18" 146 | } 147 | }, 148 | "node_modules/@esbuild/freebsd-x64": { 149 | "version": "0.25.11", 150 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", 151 | "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", 152 | "cpu": [ 153 | "x64" 154 | ], 155 | "dev": true, 156 | "license": "MIT", 157 | "optional": true, 158 | "os": [ 159 | "freebsd" 160 | ], 161 | "engines": { 162 | "node": ">=18" 163 | } 164 | }, 165 | "node_modules/@esbuild/linux-arm": { 166 | "version": "0.25.11", 167 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", 168 | "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", 169 | "cpu": [ 170 | "arm" 171 | ], 172 | "dev": true, 173 | "license": "MIT", 174 | "optional": true, 175 | "os": [ 176 | "linux" 177 | ], 178 | "engines": { 179 | "node": ">=18" 180 | } 181 | }, 182 | "node_modules/@esbuild/linux-arm64": { 183 | "version": "0.25.11", 184 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", 185 | "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", 186 | "cpu": [ 187 | "arm64" 188 | ], 189 | "dev": true, 190 | "license": "MIT", 191 | "optional": true, 192 | "os": [ 193 | "linux" 194 | ], 195 | "engines": { 196 | "node": ">=18" 197 | } 198 | }, 199 | "node_modules/@esbuild/linux-ia32": { 200 | "version": "0.25.11", 201 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", 202 | "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", 203 | "cpu": [ 204 | "ia32" 205 | ], 206 | "dev": true, 207 | "license": "MIT", 208 | "optional": true, 209 | "os": [ 210 | "linux" 211 | ], 212 | "engines": { 213 | "node": ">=18" 214 | } 215 | }, 216 | "node_modules/@esbuild/linux-loong64": { 217 | "version": "0.25.11", 218 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", 219 | "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", 220 | "cpu": [ 221 | "loong64" 222 | ], 223 | "dev": true, 224 | "license": "MIT", 225 | "optional": true, 226 | "os": [ 227 | "linux" 228 | ], 229 | "engines": { 230 | "node": ">=18" 231 | } 232 | }, 233 | "node_modules/@esbuild/linux-mips64el": { 234 | "version": "0.25.11", 235 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", 236 | "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", 237 | "cpu": [ 238 | "mips64el" 239 | ], 240 | "dev": true, 241 | "license": "MIT", 242 | "optional": true, 243 | "os": [ 244 | "linux" 245 | ], 246 | "engines": { 247 | "node": ">=18" 248 | } 249 | }, 250 | "node_modules/@esbuild/linux-ppc64": { 251 | "version": "0.25.11", 252 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", 253 | "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", 254 | "cpu": [ 255 | "ppc64" 256 | ], 257 | "dev": true, 258 | "license": "MIT", 259 | "optional": true, 260 | "os": [ 261 | "linux" 262 | ], 263 | "engines": { 264 | "node": ">=18" 265 | } 266 | }, 267 | "node_modules/@esbuild/linux-riscv64": { 268 | "version": "0.25.11", 269 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", 270 | "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", 271 | "cpu": [ 272 | "riscv64" 273 | ], 274 | "dev": true, 275 | "license": "MIT", 276 | "optional": true, 277 | "os": [ 278 | "linux" 279 | ], 280 | "engines": { 281 | "node": ">=18" 282 | } 283 | }, 284 | "node_modules/@esbuild/linux-s390x": { 285 | "version": "0.25.11", 286 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", 287 | "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", 288 | "cpu": [ 289 | "s390x" 290 | ], 291 | "dev": true, 292 | "license": "MIT", 293 | "optional": true, 294 | "os": [ 295 | "linux" 296 | ], 297 | "engines": { 298 | "node": ">=18" 299 | } 300 | }, 301 | "node_modules/@esbuild/linux-x64": { 302 | "version": "0.25.11", 303 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", 304 | "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", 305 | "cpu": [ 306 | "x64" 307 | ], 308 | "dev": true, 309 | "license": "MIT", 310 | "optional": true, 311 | "os": [ 312 | "linux" 313 | ], 314 | "engines": { 315 | "node": ">=18" 316 | } 317 | }, 318 | "node_modules/@esbuild/netbsd-arm64": { 319 | "version": "0.25.11", 320 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", 321 | "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", 322 | "cpu": [ 323 | "arm64" 324 | ], 325 | "dev": true, 326 | "license": "MIT", 327 | "optional": true, 328 | "os": [ 329 | "netbsd" 330 | ], 331 | "engines": { 332 | "node": ">=18" 333 | } 334 | }, 335 | "node_modules/@esbuild/netbsd-x64": { 336 | "version": "0.25.11", 337 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", 338 | "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", 339 | "cpu": [ 340 | "x64" 341 | ], 342 | "dev": true, 343 | "license": "MIT", 344 | "optional": true, 345 | "os": [ 346 | "netbsd" 347 | ], 348 | "engines": { 349 | "node": ">=18" 350 | } 351 | }, 352 | "node_modules/@esbuild/openbsd-arm64": { 353 | "version": "0.25.11", 354 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", 355 | "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", 356 | "cpu": [ 357 | "arm64" 358 | ], 359 | "dev": true, 360 | "license": "MIT", 361 | "optional": true, 362 | "os": [ 363 | "openbsd" 364 | ], 365 | "engines": { 366 | "node": ">=18" 367 | } 368 | }, 369 | "node_modules/@esbuild/openbsd-x64": { 370 | "version": "0.25.11", 371 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", 372 | "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", 373 | "cpu": [ 374 | "x64" 375 | ], 376 | "dev": true, 377 | "license": "MIT", 378 | "optional": true, 379 | "os": [ 380 | "openbsd" 381 | ], 382 | "engines": { 383 | "node": ">=18" 384 | } 385 | }, 386 | "node_modules/@esbuild/openharmony-arm64": { 387 | "version": "0.25.11", 388 | "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", 389 | "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", 390 | "cpu": [ 391 | "arm64" 392 | ], 393 | "dev": true, 394 | "license": "MIT", 395 | "optional": true, 396 | "os": [ 397 | "openharmony" 398 | ], 399 | "engines": { 400 | "node": ">=18" 401 | } 402 | }, 403 | "node_modules/@esbuild/sunos-x64": { 404 | "version": "0.25.11", 405 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", 406 | "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", 407 | "cpu": [ 408 | "x64" 409 | ], 410 | "dev": true, 411 | "license": "MIT", 412 | "optional": true, 413 | "os": [ 414 | "sunos" 415 | ], 416 | "engines": { 417 | "node": ">=18" 418 | } 419 | }, 420 | "node_modules/@esbuild/win32-arm64": { 421 | "version": "0.25.11", 422 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", 423 | "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", 424 | "cpu": [ 425 | "arm64" 426 | ], 427 | "dev": true, 428 | "license": "MIT", 429 | "optional": true, 430 | "os": [ 431 | "win32" 432 | ], 433 | "engines": { 434 | "node": ">=18" 435 | } 436 | }, 437 | "node_modules/@esbuild/win32-ia32": { 438 | "version": "0.25.11", 439 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", 440 | "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", 441 | "cpu": [ 442 | "ia32" 443 | ], 444 | "dev": true, 445 | "license": "MIT", 446 | "optional": true, 447 | "os": [ 448 | "win32" 449 | ], 450 | "engines": { 451 | "node": ">=18" 452 | } 453 | }, 454 | "node_modules/@esbuild/win32-x64": { 455 | "version": "0.25.11", 456 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", 457 | "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", 458 | "cpu": [ 459 | "x64" 460 | ], 461 | "dev": true, 462 | "license": "MIT", 463 | "optional": true, 464 | "os": [ 465 | "win32" 466 | ], 467 | "engines": { 468 | "node": ">=18" 469 | } 470 | }, 471 | "node_modules/@google/generative-ai": { 472 | "version": "0.24.0", 473 | "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.0.tgz", 474 | "integrity": "sha512-fnEITCGEB7NdX0BhoYZ/cq/7WPZ1QS5IzJJfC3Tg/OwkvBetMiVJciyaan297OvE4B9Jg1xvo0zIazX/9sGu1Q==", 475 | "license": "Apache-2.0", 476 | "engines": { 477 | "node": ">=18.0.0" 478 | } 479 | }, 480 | "node_modules/@modelcontextprotocol/sdk": { 481 | "version": "0.6.0", 482 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz", 483 | "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==", 484 | "license": "MIT", 485 | "dependencies": { 486 | "content-type": "^1.0.5", 487 | "raw-body": "^3.0.0", 488 | "zod": "^3.23.8" 489 | } 490 | }, 491 | "node_modules/@types/mime-types": { 492 | "version": "2.1.4", 493 | "resolved": "https://registry.npmjs.org/@types/mime-types/-/mime-types-2.1.4.tgz", 494 | "integrity": "sha512-lfU4b34HOri+kAY5UheuFMWPDOI+OPceBSHZKp69gEyTL/mmJ4cnU6Y/rlme3UL3GyOn6Y42hyIEw0/q8sWx5w==", 495 | "license": "MIT" 496 | }, 497 | "node_modules/@types/node": { 498 | "version": "20.17.30", 499 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz", 500 | "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", 501 | "dev": true, 502 | "license": "MIT", 503 | "dependencies": { 504 | "undici-types": "~6.19.2" 505 | } 506 | }, 507 | "node_modules/asynckit": { 508 | "version": "0.4.0", 509 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 510 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 511 | "license": "MIT" 512 | }, 513 | "node_modules/axios": { 514 | "version": "1.8.4", 515 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", 516 | "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", 517 | "license": "MIT", 518 | "dependencies": { 519 | "follow-redirects": "^1.15.6", 520 | "form-data": "^4.0.0", 521 | "proxy-from-env": "^1.1.0" 522 | } 523 | }, 524 | "node_modules/bytes": { 525 | "version": "3.1.2", 526 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 527 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 528 | "license": "MIT", 529 | "engines": { 530 | "node": ">= 0.8" 531 | } 532 | }, 533 | "node_modules/call-bind-apply-helpers": { 534 | "version": "1.0.2", 535 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 536 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 537 | "license": "MIT", 538 | "dependencies": { 539 | "es-errors": "^1.3.0", 540 | "function-bind": "^1.1.2" 541 | }, 542 | "engines": { 543 | "node": ">= 0.4" 544 | } 545 | }, 546 | "node_modules/combined-stream": { 547 | "version": "1.0.8", 548 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 549 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 550 | "license": "MIT", 551 | "dependencies": { 552 | "delayed-stream": "~1.0.0" 553 | }, 554 | "engines": { 555 | "node": ">= 0.8" 556 | } 557 | }, 558 | "node_modules/content-type": { 559 | "version": "1.0.5", 560 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 561 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 562 | "license": "MIT", 563 | "engines": { 564 | "node": ">= 0.6" 565 | } 566 | }, 567 | "node_modules/delayed-stream": { 568 | "version": "1.0.0", 569 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 570 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 571 | "license": "MIT", 572 | "engines": { 573 | "node": ">=0.4.0" 574 | } 575 | }, 576 | "node_modules/depd": { 577 | "version": "2.0.0", 578 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 579 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 580 | "license": "MIT", 581 | "engines": { 582 | "node": ">= 0.8" 583 | } 584 | }, 585 | "node_modules/dunder-proto": { 586 | "version": "1.0.1", 587 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 588 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 589 | "license": "MIT", 590 | "dependencies": { 591 | "call-bind-apply-helpers": "^1.0.1", 592 | "es-errors": "^1.3.0", 593 | "gopd": "^1.2.0" 594 | }, 595 | "engines": { 596 | "node": ">= 0.4" 597 | } 598 | }, 599 | "node_modules/es-define-property": { 600 | "version": "1.0.1", 601 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 602 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 603 | "license": "MIT", 604 | "engines": { 605 | "node": ">= 0.4" 606 | } 607 | }, 608 | "node_modules/es-errors": { 609 | "version": "1.3.0", 610 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 611 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 612 | "license": "MIT", 613 | "engines": { 614 | "node": ">= 0.4" 615 | } 616 | }, 617 | "node_modules/es-object-atoms": { 618 | "version": "1.1.1", 619 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 620 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 621 | "license": "MIT", 622 | "dependencies": { 623 | "es-errors": "^1.3.0" 624 | }, 625 | "engines": { 626 | "node": ">= 0.4" 627 | } 628 | }, 629 | "node_modules/es-set-tostringtag": { 630 | "version": "2.1.0", 631 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", 632 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", 633 | "license": "MIT", 634 | "dependencies": { 635 | "es-errors": "^1.3.0", 636 | "get-intrinsic": "^1.2.6", 637 | "has-tostringtag": "^1.0.2", 638 | "hasown": "^2.0.2" 639 | }, 640 | "engines": { 641 | "node": ">= 0.4" 642 | } 643 | }, 644 | "node_modules/esbuild": { 645 | "version": "0.25.11", 646 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", 647 | "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", 648 | "dev": true, 649 | "hasInstallScript": true, 650 | "license": "MIT", 651 | "bin": { 652 | "esbuild": "bin/esbuild" 653 | }, 654 | "engines": { 655 | "node": ">=18" 656 | }, 657 | "optionalDependencies": { 658 | "@esbuild/aix-ppc64": "0.25.11", 659 | "@esbuild/android-arm": "0.25.11", 660 | "@esbuild/android-arm64": "0.25.11", 661 | "@esbuild/android-x64": "0.25.11", 662 | "@esbuild/darwin-arm64": "0.25.11", 663 | "@esbuild/darwin-x64": "0.25.11", 664 | "@esbuild/freebsd-arm64": "0.25.11", 665 | "@esbuild/freebsd-x64": "0.25.11", 666 | "@esbuild/linux-arm": "0.25.11", 667 | "@esbuild/linux-arm64": "0.25.11", 668 | "@esbuild/linux-ia32": "0.25.11", 669 | "@esbuild/linux-loong64": "0.25.11", 670 | "@esbuild/linux-mips64el": "0.25.11", 671 | "@esbuild/linux-ppc64": "0.25.11", 672 | "@esbuild/linux-riscv64": "0.25.11", 673 | "@esbuild/linux-s390x": "0.25.11", 674 | "@esbuild/linux-x64": "0.25.11", 675 | "@esbuild/netbsd-arm64": "0.25.11", 676 | "@esbuild/netbsd-x64": "0.25.11", 677 | "@esbuild/openbsd-arm64": "0.25.11", 678 | "@esbuild/openbsd-x64": "0.25.11", 679 | "@esbuild/openharmony-arm64": "0.25.11", 680 | "@esbuild/sunos-x64": "0.25.11", 681 | "@esbuild/win32-arm64": "0.25.11", 682 | "@esbuild/win32-ia32": "0.25.11", 683 | "@esbuild/win32-x64": "0.25.11" 684 | } 685 | }, 686 | "node_modules/follow-redirects": { 687 | "version": "1.15.9", 688 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", 689 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", 690 | "funding": [ 691 | { 692 | "type": "individual", 693 | "url": "https://github.com/sponsors/RubenVerborgh" 694 | } 695 | ], 696 | "license": "MIT", 697 | "engines": { 698 | "node": ">=4.0" 699 | }, 700 | "peerDependenciesMeta": { 701 | "debug": { 702 | "optional": true 703 | } 704 | } 705 | }, 706 | "node_modules/form-data": { 707 | "version": "4.0.2", 708 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", 709 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", 710 | "license": "MIT", 711 | "dependencies": { 712 | "asynckit": "^0.4.0", 713 | "combined-stream": "^1.0.8", 714 | "es-set-tostringtag": "^2.1.0", 715 | "mime-types": "^2.1.12" 716 | }, 717 | "engines": { 718 | "node": ">= 6" 719 | } 720 | }, 721 | "node_modules/form-data/node_modules/mime-db": { 722 | "version": "1.52.0", 723 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 724 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 725 | "license": "MIT", 726 | "engines": { 727 | "node": ">= 0.6" 728 | } 729 | }, 730 | "node_modules/form-data/node_modules/mime-types": { 731 | "version": "2.1.35", 732 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 733 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 734 | "license": "MIT", 735 | "dependencies": { 736 | "mime-db": "1.52.0" 737 | }, 738 | "engines": { 739 | "node": ">= 0.6" 740 | } 741 | }, 742 | "node_modules/function-bind": { 743 | "version": "1.1.2", 744 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 745 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 746 | "license": "MIT", 747 | "funding": { 748 | "url": "https://github.com/sponsors/ljharb" 749 | } 750 | }, 751 | "node_modules/get-intrinsic": { 752 | "version": "1.3.0", 753 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 754 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 755 | "license": "MIT", 756 | "dependencies": { 757 | "call-bind-apply-helpers": "^1.0.2", 758 | "es-define-property": "^1.0.1", 759 | "es-errors": "^1.3.0", 760 | "es-object-atoms": "^1.1.1", 761 | "function-bind": "^1.1.2", 762 | "get-proto": "^1.0.1", 763 | "gopd": "^1.2.0", 764 | "has-symbols": "^1.1.0", 765 | "hasown": "^2.0.2", 766 | "math-intrinsics": "^1.1.0" 767 | }, 768 | "engines": { 769 | "node": ">= 0.4" 770 | }, 771 | "funding": { 772 | "url": "https://github.com/sponsors/ljharb" 773 | } 774 | }, 775 | "node_modules/get-proto": { 776 | "version": "1.0.1", 777 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 778 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 779 | "license": "MIT", 780 | "dependencies": { 781 | "dunder-proto": "^1.0.1", 782 | "es-object-atoms": "^1.0.0" 783 | }, 784 | "engines": { 785 | "node": ">= 0.4" 786 | } 787 | }, 788 | "node_modules/gopd": { 789 | "version": "1.2.0", 790 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 791 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 792 | "license": "MIT", 793 | "engines": { 794 | "node": ">= 0.4" 795 | }, 796 | "funding": { 797 | "url": "https://github.com/sponsors/ljharb" 798 | } 799 | }, 800 | "node_modules/has-symbols": { 801 | "version": "1.1.0", 802 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 803 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 804 | "license": "MIT", 805 | "engines": { 806 | "node": ">= 0.4" 807 | }, 808 | "funding": { 809 | "url": "https://github.com/sponsors/ljharb" 810 | } 811 | }, 812 | "node_modules/has-tostringtag": { 813 | "version": "1.0.2", 814 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 815 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 816 | "license": "MIT", 817 | "dependencies": { 818 | "has-symbols": "^1.0.3" 819 | }, 820 | "engines": { 821 | "node": ">= 0.4" 822 | }, 823 | "funding": { 824 | "url": "https://github.com/sponsors/ljharb" 825 | } 826 | }, 827 | "node_modules/hasown": { 828 | "version": "2.0.2", 829 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 830 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 831 | "license": "MIT", 832 | "dependencies": { 833 | "function-bind": "^1.1.2" 834 | }, 835 | "engines": { 836 | "node": ">= 0.4" 837 | } 838 | }, 839 | "node_modules/http-errors": { 840 | "version": "2.0.0", 841 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 842 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 843 | "license": "MIT", 844 | "dependencies": { 845 | "depd": "2.0.0", 846 | "inherits": "2.0.4", 847 | "setprototypeof": "1.2.0", 848 | "statuses": "2.0.1", 849 | "toidentifier": "1.0.1" 850 | }, 851 | "engines": { 852 | "node": ">= 0.8" 853 | } 854 | }, 855 | "node_modules/iconv-lite": { 856 | "version": "0.6.3", 857 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 858 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 859 | "license": "MIT", 860 | "dependencies": { 861 | "safer-buffer": ">= 2.1.2 < 3.0.0" 862 | }, 863 | "engines": { 864 | "node": ">=0.10.0" 865 | } 866 | }, 867 | "node_modules/inherits": { 868 | "version": "2.0.4", 869 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 870 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 871 | "license": "ISC" 872 | }, 873 | "node_modules/math-intrinsics": { 874 | "version": "1.1.0", 875 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 876 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 877 | "license": "MIT", 878 | "engines": { 879 | "node": ">= 0.4" 880 | } 881 | }, 882 | "node_modules/mime-db": { 883 | "version": "1.54.0", 884 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", 885 | "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", 886 | "license": "MIT", 887 | "engines": { 888 | "node": ">= 0.6" 889 | } 890 | }, 891 | "node_modules/mime-types": { 892 | "version": "3.0.1", 893 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", 894 | "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", 895 | "license": "MIT", 896 | "dependencies": { 897 | "mime-db": "^1.54.0" 898 | }, 899 | "engines": { 900 | "node": ">= 0.6" 901 | } 902 | }, 903 | "node_modules/proxy-from-env": { 904 | "version": "1.1.0", 905 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 906 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 907 | "license": "MIT" 908 | }, 909 | "node_modules/raw-body": { 910 | "version": "3.0.0", 911 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 912 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 913 | "license": "MIT", 914 | "dependencies": { 915 | "bytes": "3.1.2", 916 | "http-errors": "2.0.0", 917 | "iconv-lite": "0.6.3", 918 | "unpipe": "1.0.0" 919 | }, 920 | "engines": { 921 | "node": ">= 0.8" 922 | } 923 | }, 924 | "node_modules/safer-buffer": { 925 | "version": "2.1.2", 926 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 927 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 928 | "license": "MIT" 929 | }, 930 | "node_modules/setprototypeof": { 931 | "version": "1.2.0", 932 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 933 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 934 | "license": "ISC" 935 | }, 936 | "node_modules/statuses": { 937 | "version": "2.0.1", 938 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 939 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 940 | "license": "MIT", 941 | "engines": { 942 | "node": ">= 0.8" 943 | } 944 | }, 945 | "node_modules/toidentifier": { 946 | "version": "1.0.1", 947 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 948 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 949 | "license": "MIT", 950 | "engines": { 951 | "node": ">=0.6" 952 | } 953 | }, 954 | "node_modules/typescript": { 955 | "version": "5.8.2", 956 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.2.tgz", 957 | "integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==", 958 | "dev": true, 959 | "license": "Apache-2.0", 960 | "bin": { 961 | "tsc": "bin/tsc", 962 | "tsserver": "bin/tsserver" 963 | }, 964 | "engines": { 965 | "node": ">=14.17" 966 | } 967 | }, 968 | "node_modules/undici-types": { 969 | "version": "6.19.8", 970 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 971 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 972 | "dev": true, 973 | "license": "MIT" 974 | }, 975 | "node_modules/unpipe": { 976 | "version": "1.0.0", 977 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 978 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 979 | "license": "MIT", 980 | "engines": { 981 | "node": ">= 0.8" 982 | } 983 | }, 984 | "node_modules/youtube-transcript": { 985 | "version": "1.2.1", 986 | "resolved": "https://registry.npmjs.org/youtube-transcript/-/youtube-transcript-1.2.1.tgz", 987 | "integrity": "sha512-TvEGkBaajKw+B6y91ziLuBLsa5cawgowou+Bk0ciGpjELDfAzSzTGXaZmeSSkUeknCPpEr/WGApOHDwV7V+Y9Q==", 988 | "license": "MIT", 989 | "engines": { 990 | "node": ">=18.0.0" 991 | } 992 | }, 993 | "node_modules/zod": { 994 | "version": "3.24.2", 995 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 996 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 997 | "license": "MIT", 998 | "funding": { 999 | "url": "https://github.com/sponsors/colinhacks" 1000 | } 1001 | } 1002 | } 1003 | } 1004 | -------------------------------------------------------------------------------- /information-retrieval-server/package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "information-retrieval-mcp-server", 3 | "version": "0.1.1", 4 | "lockfileVersion": 3, 5 | "requires": true, 6 | "packages": { 7 | "": { 8 | "name": "information-retrieval-mcp-server", 9 | "version": "0.1.1", 10 | "license": "MIT", 11 | "dependencies": { 12 | "@modelcontextprotocol/sdk": "0.6.0", 13 | "@types/cheerio": "^0.22.35", 14 | "axios": "^1.8.4", 15 | "cheerio": "^1.0.0", 16 | "playwright": "^1.51.1", 17 | "zod": "^3.22.4" 18 | }, 19 | "bin": { 20 | "information-retrieval-server": "build/index.js" 21 | }, 22 | "devDependencies": { 23 | "@types/node": "^20.11.24", 24 | "esbuild": "^0.25.11", 25 | "typescript": "^5.3.3" 26 | } 27 | }, 28 | "node_modules/@esbuild/aix-ppc64": { 29 | "version": "0.25.11", 30 | "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.11.tgz", 31 | "integrity": "sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==", 32 | "cpu": [ 33 | "ppc64" 34 | ], 35 | "dev": true, 36 | "license": "MIT", 37 | "optional": true, 38 | "os": [ 39 | "aix" 40 | ], 41 | "engines": { 42 | "node": ">=18" 43 | } 44 | }, 45 | "node_modules/@esbuild/android-arm": { 46 | "version": "0.25.11", 47 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.11.tgz", 48 | "integrity": "sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==", 49 | "cpu": [ 50 | "arm" 51 | ], 52 | "dev": true, 53 | "license": "MIT", 54 | "optional": true, 55 | "os": [ 56 | "android" 57 | ], 58 | "engines": { 59 | "node": ">=18" 60 | } 61 | }, 62 | "node_modules/@esbuild/android-arm64": { 63 | "version": "0.25.11", 64 | "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.11.tgz", 65 | "integrity": "sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==", 66 | "cpu": [ 67 | "arm64" 68 | ], 69 | "dev": true, 70 | "license": "MIT", 71 | "optional": true, 72 | "os": [ 73 | "android" 74 | ], 75 | "engines": { 76 | "node": ">=18" 77 | } 78 | }, 79 | "node_modules/@esbuild/android-x64": { 80 | "version": "0.25.11", 81 | "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.11.tgz", 82 | "integrity": "sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==", 83 | "cpu": [ 84 | "x64" 85 | ], 86 | "dev": true, 87 | "license": "MIT", 88 | "optional": true, 89 | "os": [ 90 | "android" 91 | ], 92 | "engines": { 93 | "node": ">=18" 94 | } 95 | }, 96 | "node_modules/@esbuild/darwin-arm64": { 97 | "version": "0.25.11", 98 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.11.tgz", 99 | "integrity": "sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==", 100 | "cpu": [ 101 | "arm64" 102 | ], 103 | "dev": true, 104 | "license": "MIT", 105 | "optional": true, 106 | "os": [ 107 | "darwin" 108 | ], 109 | "engines": { 110 | "node": ">=18" 111 | } 112 | }, 113 | "node_modules/@esbuild/darwin-x64": { 114 | "version": "0.25.11", 115 | "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.11.tgz", 116 | "integrity": "sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==", 117 | "cpu": [ 118 | "x64" 119 | ], 120 | "dev": true, 121 | "license": "MIT", 122 | "optional": true, 123 | "os": [ 124 | "darwin" 125 | ], 126 | "engines": { 127 | "node": ">=18" 128 | } 129 | }, 130 | "node_modules/@esbuild/freebsd-arm64": { 131 | "version": "0.25.11", 132 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.11.tgz", 133 | "integrity": "sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==", 134 | "cpu": [ 135 | "arm64" 136 | ], 137 | "dev": true, 138 | "license": "MIT", 139 | "optional": true, 140 | "os": [ 141 | "freebsd" 142 | ], 143 | "engines": { 144 | "node": ">=18" 145 | } 146 | }, 147 | "node_modules/@esbuild/freebsd-x64": { 148 | "version": "0.25.11", 149 | "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.11.tgz", 150 | "integrity": "sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==", 151 | "cpu": [ 152 | "x64" 153 | ], 154 | "dev": true, 155 | "license": "MIT", 156 | "optional": true, 157 | "os": [ 158 | "freebsd" 159 | ], 160 | "engines": { 161 | "node": ">=18" 162 | } 163 | }, 164 | "node_modules/@esbuild/linux-arm": { 165 | "version": "0.25.11", 166 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.11.tgz", 167 | "integrity": "sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==", 168 | "cpu": [ 169 | "arm" 170 | ], 171 | "dev": true, 172 | "license": "MIT", 173 | "optional": true, 174 | "os": [ 175 | "linux" 176 | ], 177 | "engines": { 178 | "node": ">=18" 179 | } 180 | }, 181 | "node_modules/@esbuild/linux-arm64": { 182 | "version": "0.25.11", 183 | "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.11.tgz", 184 | "integrity": "sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==", 185 | "cpu": [ 186 | "arm64" 187 | ], 188 | "dev": true, 189 | "license": "MIT", 190 | "optional": true, 191 | "os": [ 192 | "linux" 193 | ], 194 | "engines": { 195 | "node": ">=18" 196 | } 197 | }, 198 | "node_modules/@esbuild/linux-ia32": { 199 | "version": "0.25.11", 200 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.11.tgz", 201 | "integrity": "sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==", 202 | "cpu": [ 203 | "ia32" 204 | ], 205 | "dev": true, 206 | "license": "MIT", 207 | "optional": true, 208 | "os": [ 209 | "linux" 210 | ], 211 | "engines": { 212 | "node": ">=18" 213 | } 214 | }, 215 | "node_modules/@esbuild/linux-loong64": { 216 | "version": "0.25.11", 217 | "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.11.tgz", 218 | "integrity": "sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==", 219 | "cpu": [ 220 | "loong64" 221 | ], 222 | "dev": true, 223 | "license": "MIT", 224 | "optional": true, 225 | "os": [ 226 | "linux" 227 | ], 228 | "engines": { 229 | "node": ">=18" 230 | } 231 | }, 232 | "node_modules/@esbuild/linux-mips64el": { 233 | "version": "0.25.11", 234 | "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.11.tgz", 235 | "integrity": "sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==", 236 | "cpu": [ 237 | "mips64el" 238 | ], 239 | "dev": true, 240 | "license": "MIT", 241 | "optional": true, 242 | "os": [ 243 | "linux" 244 | ], 245 | "engines": { 246 | "node": ">=18" 247 | } 248 | }, 249 | "node_modules/@esbuild/linux-ppc64": { 250 | "version": "0.25.11", 251 | "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.11.tgz", 252 | "integrity": "sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==", 253 | "cpu": [ 254 | "ppc64" 255 | ], 256 | "dev": true, 257 | "license": "MIT", 258 | "optional": true, 259 | "os": [ 260 | "linux" 261 | ], 262 | "engines": { 263 | "node": ">=18" 264 | } 265 | }, 266 | "node_modules/@esbuild/linux-riscv64": { 267 | "version": "0.25.11", 268 | "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.11.tgz", 269 | "integrity": "sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==", 270 | "cpu": [ 271 | "riscv64" 272 | ], 273 | "dev": true, 274 | "license": "MIT", 275 | "optional": true, 276 | "os": [ 277 | "linux" 278 | ], 279 | "engines": { 280 | "node": ">=18" 281 | } 282 | }, 283 | "node_modules/@esbuild/linux-s390x": { 284 | "version": "0.25.11", 285 | "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.11.tgz", 286 | "integrity": "sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==", 287 | "cpu": [ 288 | "s390x" 289 | ], 290 | "dev": true, 291 | "license": "MIT", 292 | "optional": true, 293 | "os": [ 294 | "linux" 295 | ], 296 | "engines": { 297 | "node": ">=18" 298 | } 299 | }, 300 | "node_modules/@esbuild/linux-x64": { 301 | "version": "0.25.11", 302 | "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.11.tgz", 303 | "integrity": "sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==", 304 | "cpu": [ 305 | "x64" 306 | ], 307 | "dev": true, 308 | "license": "MIT", 309 | "optional": true, 310 | "os": [ 311 | "linux" 312 | ], 313 | "engines": { 314 | "node": ">=18" 315 | } 316 | }, 317 | "node_modules/@esbuild/netbsd-arm64": { 318 | "version": "0.25.11", 319 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.11.tgz", 320 | "integrity": "sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==", 321 | "cpu": [ 322 | "arm64" 323 | ], 324 | "dev": true, 325 | "license": "MIT", 326 | "optional": true, 327 | "os": [ 328 | "netbsd" 329 | ], 330 | "engines": { 331 | "node": ">=18" 332 | } 333 | }, 334 | "node_modules/@esbuild/netbsd-x64": { 335 | "version": "0.25.11", 336 | "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.11.tgz", 337 | "integrity": "sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==", 338 | "cpu": [ 339 | "x64" 340 | ], 341 | "dev": true, 342 | "license": "MIT", 343 | "optional": true, 344 | "os": [ 345 | "netbsd" 346 | ], 347 | "engines": { 348 | "node": ">=18" 349 | } 350 | }, 351 | "node_modules/@esbuild/openbsd-arm64": { 352 | "version": "0.25.11", 353 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.11.tgz", 354 | "integrity": "sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==", 355 | "cpu": [ 356 | "arm64" 357 | ], 358 | "dev": true, 359 | "license": "MIT", 360 | "optional": true, 361 | "os": [ 362 | "openbsd" 363 | ], 364 | "engines": { 365 | "node": ">=18" 366 | } 367 | }, 368 | "node_modules/@esbuild/openbsd-x64": { 369 | "version": "0.25.11", 370 | "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.11.tgz", 371 | "integrity": "sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==", 372 | "cpu": [ 373 | "x64" 374 | ], 375 | "dev": true, 376 | "license": "MIT", 377 | "optional": true, 378 | "os": [ 379 | "openbsd" 380 | ], 381 | "engines": { 382 | "node": ">=18" 383 | } 384 | }, 385 | "node_modules/@esbuild/openharmony-arm64": { 386 | "version": "0.25.11", 387 | "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.11.tgz", 388 | "integrity": "sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==", 389 | "cpu": [ 390 | "arm64" 391 | ], 392 | "dev": true, 393 | "license": "MIT", 394 | "optional": true, 395 | "os": [ 396 | "openharmony" 397 | ], 398 | "engines": { 399 | "node": ">=18" 400 | } 401 | }, 402 | "node_modules/@esbuild/sunos-x64": { 403 | "version": "0.25.11", 404 | "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.11.tgz", 405 | "integrity": "sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==", 406 | "cpu": [ 407 | "x64" 408 | ], 409 | "dev": true, 410 | "license": "MIT", 411 | "optional": true, 412 | "os": [ 413 | "sunos" 414 | ], 415 | "engines": { 416 | "node": ">=18" 417 | } 418 | }, 419 | "node_modules/@esbuild/win32-arm64": { 420 | "version": "0.25.11", 421 | "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.11.tgz", 422 | "integrity": "sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==", 423 | "cpu": [ 424 | "arm64" 425 | ], 426 | "dev": true, 427 | "license": "MIT", 428 | "optional": true, 429 | "os": [ 430 | "win32" 431 | ], 432 | "engines": { 433 | "node": ">=18" 434 | } 435 | }, 436 | "node_modules/@esbuild/win32-ia32": { 437 | "version": "0.25.11", 438 | "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.11.tgz", 439 | "integrity": "sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==", 440 | "cpu": [ 441 | "ia32" 442 | ], 443 | "dev": true, 444 | "license": "MIT", 445 | "optional": true, 446 | "os": [ 447 | "win32" 448 | ], 449 | "engines": { 450 | "node": ">=18" 451 | } 452 | }, 453 | "node_modules/@esbuild/win32-x64": { 454 | "version": "0.25.11", 455 | "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.11.tgz", 456 | "integrity": "sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==", 457 | "cpu": [ 458 | "x64" 459 | ], 460 | "dev": true, 461 | "license": "MIT", 462 | "optional": true, 463 | "os": [ 464 | "win32" 465 | ], 466 | "engines": { 467 | "node": ">=18" 468 | } 469 | }, 470 | "node_modules/@modelcontextprotocol/sdk": { 471 | "version": "0.6.0", 472 | "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-0.6.0.tgz", 473 | "integrity": "sha512-9rsDudGhDtMbvxohPoMMyAUOmEzQsOK+XFchh6gZGqo8sx9sBuZQs+CUttXqa8RZXKDaJRCN2tUtgGof7jRkkw==", 474 | "license": "MIT", 475 | "dependencies": { 476 | "content-type": "^1.0.5", 477 | "raw-body": "^3.0.0", 478 | "zod": "^3.23.8" 479 | } 480 | }, 481 | "node_modules/@types/cheerio": { 482 | "version": "0.22.35", 483 | "resolved": "https://registry.npmjs.org/@types/cheerio/-/cheerio-0.22.35.tgz", 484 | "integrity": "sha512-yD57BchKRvTV+JD53UZ6PD8KWY5g5rvvMLRnZR3EQBCZXiDT/HR+pKpMzFGlWNhFrXlo7VPZXtKvIEwZkAWOIA==", 485 | "license": "MIT", 486 | "dependencies": { 487 | "@types/node": "*" 488 | } 489 | }, 490 | "node_modules/@types/node": { 491 | "version": "20.17.30", 492 | "resolved": "https://registry.npmjs.org/@types/node/-/node-20.17.30.tgz", 493 | "integrity": "sha512-7zf4YyHA+jvBNfVrk2Gtvs6x7E8V+YDW05bNfG2XkWDJfYRXrTiP/DsB2zSYTaHX0bGIujTBQdMVAhb+j7mwpg==", 494 | "license": "MIT", 495 | "dependencies": { 496 | "undici-types": "~6.19.2" 497 | } 498 | }, 499 | "node_modules/asynckit": { 500 | "version": "0.4.0", 501 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 502 | "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", 503 | "license": "MIT" 504 | }, 505 | "node_modules/axios": { 506 | "version": "1.8.4", 507 | "resolved": "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz", 508 | "integrity": "sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw==", 509 | "license": "MIT", 510 | "dependencies": { 511 | "follow-redirects": "^1.15.6", 512 | "form-data": "^4.0.0", 513 | "proxy-from-env": "^1.1.0" 514 | } 515 | }, 516 | "node_modules/boolbase": { 517 | "version": "1.0.0", 518 | "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", 519 | "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", 520 | "license": "ISC" 521 | }, 522 | "node_modules/bytes": { 523 | "version": "3.1.2", 524 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", 525 | "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", 526 | "license": "MIT", 527 | "engines": { 528 | "node": ">= 0.8" 529 | } 530 | }, 531 | "node_modules/call-bind-apply-helpers": { 532 | "version": "1.0.2", 533 | "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", 534 | "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", 535 | "license": "MIT", 536 | "dependencies": { 537 | "es-errors": "^1.3.0", 538 | "function-bind": "^1.1.2" 539 | }, 540 | "engines": { 541 | "node": ">= 0.4" 542 | } 543 | }, 544 | "node_modules/cheerio": { 545 | "version": "1.0.0", 546 | "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", 547 | "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", 548 | "license": "MIT", 549 | "dependencies": { 550 | "cheerio-select": "^2.1.0", 551 | "dom-serializer": "^2.0.0", 552 | "domhandler": "^5.0.3", 553 | "domutils": "^3.1.0", 554 | "encoding-sniffer": "^0.2.0", 555 | "htmlparser2": "^9.1.0", 556 | "parse5": "^7.1.2", 557 | "parse5-htmlparser2-tree-adapter": "^7.0.0", 558 | "parse5-parser-stream": "^7.1.2", 559 | "undici": "^6.19.5", 560 | "whatwg-mimetype": "^4.0.0" 561 | }, 562 | "engines": { 563 | "node": ">=18.17" 564 | }, 565 | "funding": { 566 | "url": "https://github.com/cheeriojs/cheerio?sponsor=1" 567 | } 568 | }, 569 | "node_modules/cheerio-select": { 570 | "version": "2.1.0", 571 | "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", 572 | "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", 573 | "license": "BSD-2-Clause", 574 | "dependencies": { 575 | "boolbase": "^1.0.0", 576 | "css-select": "^5.1.0", 577 | "css-what": "^6.1.0", 578 | "domelementtype": "^2.3.0", 579 | "domhandler": "^5.0.3", 580 | "domutils": "^3.0.1" 581 | }, 582 | "funding": { 583 | "url": "https://github.com/sponsors/fb55" 584 | } 585 | }, 586 | "node_modules/combined-stream": { 587 | "version": "1.0.8", 588 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", 589 | "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", 590 | "license": "MIT", 591 | "dependencies": { 592 | "delayed-stream": "~1.0.0" 593 | }, 594 | "engines": { 595 | "node": ">= 0.8" 596 | } 597 | }, 598 | "node_modules/content-type": { 599 | "version": "1.0.5", 600 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", 601 | "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", 602 | "license": "MIT", 603 | "engines": { 604 | "node": ">= 0.6" 605 | } 606 | }, 607 | "node_modules/css-select": { 608 | "version": "5.1.0", 609 | "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", 610 | "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", 611 | "license": "BSD-2-Clause", 612 | "dependencies": { 613 | "boolbase": "^1.0.0", 614 | "css-what": "^6.1.0", 615 | "domhandler": "^5.0.2", 616 | "domutils": "^3.0.1", 617 | "nth-check": "^2.0.1" 618 | }, 619 | "funding": { 620 | "url": "https://github.com/sponsors/fb55" 621 | } 622 | }, 623 | "node_modules/css-what": { 624 | "version": "6.1.0", 625 | "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", 626 | "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", 627 | "license": "BSD-2-Clause", 628 | "engines": { 629 | "node": ">= 6" 630 | }, 631 | "funding": { 632 | "url": "https://github.com/sponsors/fb55" 633 | } 634 | }, 635 | "node_modules/delayed-stream": { 636 | "version": "1.0.0", 637 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 638 | "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", 639 | "license": "MIT", 640 | "engines": { 641 | "node": ">=0.4.0" 642 | } 643 | }, 644 | "node_modules/depd": { 645 | "version": "2.0.0", 646 | "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", 647 | "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", 648 | "license": "MIT", 649 | "engines": { 650 | "node": ">= 0.8" 651 | } 652 | }, 653 | "node_modules/dom-serializer": { 654 | "version": "2.0.0", 655 | "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", 656 | "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", 657 | "license": "MIT", 658 | "dependencies": { 659 | "domelementtype": "^2.3.0", 660 | "domhandler": "^5.0.2", 661 | "entities": "^4.2.0" 662 | }, 663 | "funding": { 664 | "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" 665 | } 666 | }, 667 | "node_modules/domelementtype": { 668 | "version": "2.3.0", 669 | "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", 670 | "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", 671 | "funding": [ 672 | { 673 | "type": "github", 674 | "url": "https://github.com/sponsors/fb55" 675 | } 676 | ], 677 | "license": "BSD-2-Clause" 678 | }, 679 | "node_modules/domhandler": { 680 | "version": "5.0.3", 681 | "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", 682 | "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", 683 | "license": "BSD-2-Clause", 684 | "dependencies": { 685 | "domelementtype": "^2.3.0" 686 | }, 687 | "engines": { 688 | "node": ">= 4" 689 | }, 690 | "funding": { 691 | "url": "https://github.com/fb55/domhandler?sponsor=1" 692 | } 693 | }, 694 | "node_modules/domutils": { 695 | "version": "3.2.2", 696 | "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", 697 | "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", 698 | "license": "BSD-2-Clause", 699 | "dependencies": { 700 | "dom-serializer": "^2.0.0", 701 | "domelementtype": "^2.3.0", 702 | "domhandler": "^5.0.3" 703 | }, 704 | "funding": { 705 | "url": "https://github.com/fb55/domutils?sponsor=1" 706 | } 707 | }, 708 | "node_modules/dunder-proto": { 709 | "version": "1.0.1", 710 | "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", 711 | "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", 712 | "license": "MIT", 713 | "dependencies": { 714 | "call-bind-apply-helpers": "^1.0.1", 715 | "es-errors": "^1.3.0", 716 | "gopd": "^1.2.0" 717 | }, 718 | "engines": { 719 | "node": ">= 0.4" 720 | } 721 | }, 722 | "node_modules/encoding-sniffer": { 723 | "version": "0.2.0", 724 | "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", 725 | "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", 726 | "license": "MIT", 727 | "dependencies": { 728 | "iconv-lite": "^0.6.3", 729 | "whatwg-encoding": "^3.1.1" 730 | }, 731 | "funding": { 732 | "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" 733 | } 734 | }, 735 | "node_modules/entities": { 736 | "version": "4.5.0", 737 | "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", 738 | "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", 739 | "license": "BSD-2-Clause", 740 | "engines": { 741 | "node": ">=0.12" 742 | }, 743 | "funding": { 744 | "url": "https://github.com/fb55/entities?sponsor=1" 745 | } 746 | }, 747 | "node_modules/es-define-property": { 748 | "version": "1.0.1", 749 | "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", 750 | "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", 751 | "license": "MIT", 752 | "engines": { 753 | "node": ">= 0.4" 754 | } 755 | }, 756 | "node_modules/es-errors": { 757 | "version": "1.3.0", 758 | "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", 759 | "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", 760 | "license": "MIT", 761 | "engines": { 762 | "node": ">= 0.4" 763 | } 764 | }, 765 | "node_modules/es-object-atoms": { 766 | "version": "1.1.1", 767 | "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", 768 | "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", 769 | "license": "MIT", 770 | "dependencies": { 771 | "es-errors": "^1.3.0" 772 | }, 773 | "engines": { 774 | "node": ">= 0.4" 775 | } 776 | }, 777 | "node_modules/es-set-tostringtag": { 778 | "version": "2.1.0", 779 | "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", 780 | "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", 781 | "license": "MIT", 782 | "dependencies": { 783 | "es-errors": "^1.3.0", 784 | "get-intrinsic": "^1.2.6", 785 | "has-tostringtag": "^1.0.2", 786 | "hasown": "^2.0.2" 787 | }, 788 | "engines": { 789 | "node": ">= 0.4" 790 | } 791 | }, 792 | "node_modules/esbuild": { 793 | "version": "0.25.11", 794 | "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.11.tgz", 795 | "integrity": "sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==", 796 | "dev": true, 797 | "hasInstallScript": true, 798 | "license": "MIT", 799 | "bin": { 800 | "esbuild": "bin/esbuild" 801 | }, 802 | "engines": { 803 | "node": ">=18" 804 | }, 805 | "optionalDependencies": { 806 | "@esbuild/aix-ppc64": "0.25.11", 807 | "@esbuild/android-arm": "0.25.11", 808 | "@esbuild/android-arm64": "0.25.11", 809 | "@esbuild/android-x64": "0.25.11", 810 | "@esbuild/darwin-arm64": "0.25.11", 811 | "@esbuild/darwin-x64": "0.25.11", 812 | "@esbuild/freebsd-arm64": "0.25.11", 813 | "@esbuild/freebsd-x64": "0.25.11", 814 | "@esbuild/linux-arm": "0.25.11", 815 | "@esbuild/linux-arm64": "0.25.11", 816 | "@esbuild/linux-ia32": "0.25.11", 817 | "@esbuild/linux-loong64": "0.25.11", 818 | "@esbuild/linux-mips64el": "0.25.11", 819 | "@esbuild/linux-ppc64": "0.25.11", 820 | "@esbuild/linux-riscv64": "0.25.11", 821 | "@esbuild/linux-s390x": "0.25.11", 822 | "@esbuild/linux-x64": "0.25.11", 823 | "@esbuild/netbsd-arm64": "0.25.11", 824 | "@esbuild/netbsd-x64": "0.25.11", 825 | "@esbuild/openbsd-arm64": "0.25.11", 826 | "@esbuild/openbsd-x64": "0.25.11", 827 | "@esbuild/openharmony-arm64": "0.25.11", 828 | "@esbuild/sunos-x64": "0.25.11", 829 | "@esbuild/win32-arm64": "0.25.11", 830 | "@esbuild/win32-ia32": "0.25.11", 831 | "@esbuild/win32-x64": "0.25.11" 832 | } 833 | }, 834 | "node_modules/follow-redirects": { 835 | "version": "1.15.9", 836 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", 837 | "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", 838 | "funding": [ 839 | { 840 | "type": "individual", 841 | "url": "https://github.com/sponsors/RubenVerborgh" 842 | } 843 | ], 844 | "license": "MIT", 845 | "engines": { 846 | "node": ">=4.0" 847 | }, 848 | "peerDependenciesMeta": { 849 | "debug": { 850 | "optional": true 851 | } 852 | } 853 | }, 854 | "node_modules/form-data": { 855 | "version": "4.0.2", 856 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", 857 | "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", 858 | "license": "MIT", 859 | "dependencies": { 860 | "asynckit": "^0.4.0", 861 | "combined-stream": "^1.0.8", 862 | "es-set-tostringtag": "^2.1.0", 863 | "mime-types": "^2.1.12" 864 | }, 865 | "engines": { 866 | "node": ">= 6" 867 | } 868 | }, 869 | "node_modules/fsevents": { 870 | "version": "2.3.2", 871 | "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", 872 | "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", 873 | "hasInstallScript": true, 874 | "license": "MIT", 875 | "optional": true, 876 | "os": [ 877 | "darwin" 878 | ], 879 | "engines": { 880 | "node": "^8.16.0 || ^10.6.0 || >=11.0.0" 881 | } 882 | }, 883 | "node_modules/function-bind": { 884 | "version": "1.1.2", 885 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", 886 | "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", 887 | "license": "MIT", 888 | "funding": { 889 | "url": "https://github.com/sponsors/ljharb" 890 | } 891 | }, 892 | "node_modules/get-intrinsic": { 893 | "version": "1.3.0", 894 | "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", 895 | "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", 896 | "license": "MIT", 897 | "dependencies": { 898 | "call-bind-apply-helpers": "^1.0.2", 899 | "es-define-property": "^1.0.1", 900 | "es-errors": "^1.3.0", 901 | "es-object-atoms": "^1.1.1", 902 | "function-bind": "^1.1.2", 903 | "get-proto": "^1.0.1", 904 | "gopd": "^1.2.0", 905 | "has-symbols": "^1.1.0", 906 | "hasown": "^2.0.2", 907 | "math-intrinsics": "^1.1.0" 908 | }, 909 | "engines": { 910 | "node": ">= 0.4" 911 | }, 912 | "funding": { 913 | "url": "https://github.com/sponsors/ljharb" 914 | } 915 | }, 916 | "node_modules/get-proto": { 917 | "version": "1.0.1", 918 | "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", 919 | "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", 920 | "license": "MIT", 921 | "dependencies": { 922 | "dunder-proto": "^1.0.1", 923 | "es-object-atoms": "^1.0.0" 924 | }, 925 | "engines": { 926 | "node": ">= 0.4" 927 | } 928 | }, 929 | "node_modules/gopd": { 930 | "version": "1.2.0", 931 | "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", 932 | "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", 933 | "license": "MIT", 934 | "engines": { 935 | "node": ">= 0.4" 936 | }, 937 | "funding": { 938 | "url": "https://github.com/sponsors/ljharb" 939 | } 940 | }, 941 | "node_modules/has-symbols": { 942 | "version": "1.1.0", 943 | "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", 944 | "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", 945 | "license": "MIT", 946 | "engines": { 947 | "node": ">= 0.4" 948 | }, 949 | "funding": { 950 | "url": "https://github.com/sponsors/ljharb" 951 | } 952 | }, 953 | "node_modules/has-tostringtag": { 954 | "version": "1.0.2", 955 | "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", 956 | "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", 957 | "license": "MIT", 958 | "dependencies": { 959 | "has-symbols": "^1.0.3" 960 | }, 961 | "engines": { 962 | "node": ">= 0.4" 963 | }, 964 | "funding": { 965 | "url": "https://github.com/sponsors/ljharb" 966 | } 967 | }, 968 | "node_modules/hasown": { 969 | "version": "2.0.2", 970 | "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", 971 | "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", 972 | "license": "MIT", 973 | "dependencies": { 974 | "function-bind": "^1.1.2" 975 | }, 976 | "engines": { 977 | "node": ">= 0.4" 978 | } 979 | }, 980 | "node_modules/htmlparser2": { 981 | "version": "9.1.0", 982 | "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", 983 | "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", 984 | "funding": [ 985 | "https://github.com/fb55/htmlparser2?sponsor=1", 986 | { 987 | "type": "github", 988 | "url": "https://github.com/sponsors/fb55" 989 | } 990 | ], 991 | "license": "MIT", 992 | "dependencies": { 993 | "domelementtype": "^2.3.0", 994 | "domhandler": "^5.0.3", 995 | "domutils": "^3.1.0", 996 | "entities": "^4.5.0" 997 | } 998 | }, 999 | "node_modules/http-errors": { 1000 | "version": "2.0.0", 1001 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", 1002 | "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", 1003 | "license": "MIT", 1004 | "dependencies": { 1005 | "depd": "2.0.0", 1006 | "inherits": "2.0.4", 1007 | "setprototypeof": "1.2.0", 1008 | "statuses": "2.0.1", 1009 | "toidentifier": "1.0.1" 1010 | }, 1011 | "engines": { 1012 | "node": ">= 0.8" 1013 | } 1014 | }, 1015 | "node_modules/iconv-lite": { 1016 | "version": "0.6.3", 1017 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", 1018 | "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", 1019 | "license": "MIT", 1020 | "dependencies": { 1021 | "safer-buffer": ">= 2.1.2 < 3.0.0" 1022 | }, 1023 | "engines": { 1024 | "node": ">=0.10.0" 1025 | } 1026 | }, 1027 | "node_modules/inherits": { 1028 | "version": "2.0.4", 1029 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 1030 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", 1031 | "license": "ISC" 1032 | }, 1033 | "node_modules/math-intrinsics": { 1034 | "version": "1.1.0", 1035 | "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", 1036 | "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", 1037 | "license": "MIT", 1038 | "engines": { 1039 | "node": ">= 0.4" 1040 | } 1041 | }, 1042 | "node_modules/mime-db": { 1043 | "version": "1.52.0", 1044 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", 1045 | "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", 1046 | "license": "MIT", 1047 | "engines": { 1048 | "node": ">= 0.6" 1049 | } 1050 | }, 1051 | "node_modules/mime-types": { 1052 | "version": "2.1.35", 1053 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", 1054 | "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", 1055 | "license": "MIT", 1056 | "dependencies": { 1057 | "mime-db": "1.52.0" 1058 | }, 1059 | "engines": { 1060 | "node": ">= 0.6" 1061 | } 1062 | }, 1063 | "node_modules/nth-check": { 1064 | "version": "2.1.1", 1065 | "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", 1066 | "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", 1067 | "license": "BSD-2-Clause", 1068 | "dependencies": { 1069 | "boolbase": "^1.0.0" 1070 | }, 1071 | "funding": { 1072 | "url": "https://github.com/fb55/nth-check?sponsor=1" 1073 | } 1074 | }, 1075 | "node_modules/parse5": { 1076 | "version": "7.2.1", 1077 | "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", 1078 | "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", 1079 | "license": "MIT", 1080 | "dependencies": { 1081 | "entities": "^4.5.0" 1082 | }, 1083 | "funding": { 1084 | "url": "https://github.com/inikulin/parse5?sponsor=1" 1085 | } 1086 | }, 1087 | "node_modules/parse5-htmlparser2-tree-adapter": { 1088 | "version": "7.1.0", 1089 | "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", 1090 | "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", 1091 | "license": "MIT", 1092 | "dependencies": { 1093 | "domhandler": "^5.0.3", 1094 | "parse5": "^7.0.0" 1095 | }, 1096 | "funding": { 1097 | "url": "https://github.com/inikulin/parse5?sponsor=1" 1098 | } 1099 | }, 1100 | "node_modules/parse5-parser-stream": { 1101 | "version": "7.1.2", 1102 | "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", 1103 | "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", 1104 | "license": "MIT", 1105 | "dependencies": { 1106 | "parse5": "^7.0.0" 1107 | }, 1108 | "funding": { 1109 | "url": "https://github.com/inikulin/parse5?sponsor=1" 1110 | } 1111 | }, 1112 | "node_modules/playwright": { 1113 | "version": "1.51.1", 1114 | "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.51.1.tgz", 1115 | "integrity": "sha512-kkx+MB2KQRkyxjYPc3a0wLZZoDczmppyGJIvQ43l+aZihkaVvmu/21kiyaHeHjiFxjxNNFnUncKmcGIyOojsaw==", 1116 | "license": "Apache-2.0", 1117 | "dependencies": { 1118 | "playwright-core": "1.51.1" 1119 | }, 1120 | "bin": { 1121 | "playwright": "cli.js" 1122 | }, 1123 | "engines": { 1124 | "node": ">=18" 1125 | }, 1126 | "optionalDependencies": { 1127 | "fsevents": "2.3.2" 1128 | } 1129 | }, 1130 | "node_modules/playwright-core": { 1131 | "version": "1.51.1", 1132 | "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.51.1.tgz", 1133 | "integrity": "sha512-/crRMj8+j/Nq5s8QcvegseuyeZPxpQCZb6HNk3Sos3BlZyAknRjoyJPFWkpNn8v0+P3WiwqFF8P+zQo4eqiNuw==", 1134 | "license": "Apache-2.0", 1135 | "bin": { 1136 | "playwright-core": "cli.js" 1137 | }, 1138 | "engines": { 1139 | "node": ">=18" 1140 | } 1141 | }, 1142 | "node_modules/proxy-from-env": { 1143 | "version": "1.1.0", 1144 | "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", 1145 | "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", 1146 | "license": "MIT" 1147 | }, 1148 | "node_modules/raw-body": { 1149 | "version": "3.0.0", 1150 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz", 1151 | "integrity": "sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==", 1152 | "license": "MIT", 1153 | "dependencies": { 1154 | "bytes": "3.1.2", 1155 | "http-errors": "2.0.0", 1156 | "iconv-lite": "0.6.3", 1157 | "unpipe": "1.0.0" 1158 | }, 1159 | "engines": { 1160 | "node": ">= 0.8" 1161 | } 1162 | }, 1163 | "node_modules/safer-buffer": { 1164 | "version": "2.1.2", 1165 | "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", 1166 | "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", 1167 | "license": "MIT" 1168 | }, 1169 | "node_modules/setprototypeof": { 1170 | "version": "1.2.0", 1171 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", 1172 | "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", 1173 | "license": "ISC" 1174 | }, 1175 | "node_modules/statuses": { 1176 | "version": "2.0.1", 1177 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", 1178 | "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", 1179 | "license": "MIT", 1180 | "engines": { 1181 | "node": ">= 0.8" 1182 | } 1183 | }, 1184 | "node_modules/toidentifier": { 1185 | "version": "1.0.1", 1186 | "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", 1187 | "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", 1188 | "license": "MIT", 1189 | "engines": { 1190 | "node": ">=0.6" 1191 | } 1192 | }, 1193 | "node_modules/typescript": { 1194 | "version": "5.8.3", 1195 | "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", 1196 | "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", 1197 | "dev": true, 1198 | "license": "Apache-2.0", 1199 | "bin": { 1200 | "tsc": "bin/tsc", 1201 | "tsserver": "bin/tsserver" 1202 | }, 1203 | "engines": { 1204 | "node": ">=14.17" 1205 | } 1206 | }, 1207 | "node_modules/undici": { 1208 | "version": "6.21.2", 1209 | "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz", 1210 | "integrity": "sha512-uROZWze0R0itiAKVPsYhFov9LxrPMHLMEQFszeI2gCN6bnIIZ8twzBCJcN2LJrBBLfrP0t1FW0g+JmKVl8Vk1g==", 1211 | "license": "MIT", 1212 | "engines": { 1213 | "node": ">=18.17" 1214 | } 1215 | }, 1216 | "node_modules/undici-types": { 1217 | "version": "6.19.8", 1218 | "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", 1219 | "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", 1220 | "license": "MIT" 1221 | }, 1222 | "node_modules/unpipe": { 1223 | "version": "1.0.0", 1224 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", 1225 | "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", 1226 | "license": "MIT", 1227 | "engines": { 1228 | "node": ">= 0.8" 1229 | } 1230 | }, 1231 | "node_modules/whatwg-encoding": { 1232 | "version": "3.1.1", 1233 | "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", 1234 | "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", 1235 | "license": "MIT", 1236 | "dependencies": { 1237 | "iconv-lite": "0.6.3" 1238 | }, 1239 | "engines": { 1240 | "node": ">=18" 1241 | } 1242 | }, 1243 | "node_modules/whatwg-mimetype": { 1244 | "version": "4.0.0", 1245 | "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", 1246 | "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", 1247 | "license": "MIT", 1248 | "engines": { 1249 | "node": ">=18" 1250 | } 1251 | }, 1252 | "node_modules/zod": { 1253 | "version": "3.24.2", 1254 | "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz", 1255 | "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==", 1256 | "license": "MIT", 1257 | "funding": { 1258 | "url": "https://github.com/sponsors/colinhacks" 1259 | } 1260 | } 1261 | } 1262 | } 1263 | --------------------------------------------------------------------------------