├── 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 | [](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 |
--------------------------------------------------------------------------------