├── package.json ├── test ├── .test.env.template ├── test-update-page.js └── test-get-page.js ├── Dockerfile ├── .gitignore ├── smithery.yaml ├── README.md ├── src ├── auth.js ├── wp-api.js └── index.js └── yarn.lock /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "elementor-mcp", 3 | "version": "1.0.1", 4 | "main": "src/index.js", 5 | "license": "MIT", 6 | "bin": { 7 | "elementor-mcp": "./src/index.js" 8 | }, 9 | "dependencies": { 10 | "@modelcontextprotocol/sdk": "^1.10.1", 11 | "axios": "^1.8.4", 12 | "axios-cookiejar-support": "^6.0.0", 13 | "dotenv": "^16.5.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /test/.test.env.template: -------------------------------------------------------------------------------- 1 | # --- WordPress Site Configuration --- 2 | WP_URL=https://url.of.target.website 3 | 4 | # --- Get Page Script Env --- 5 | TARGET_SLUG=url_slug_here 6 | 7 | # --- Update Page Script Env --- 8 | # Target ID number 9 | TARGET_ID=16 10 | TARGET_FILE=path/to/your/file.ext 11 | 12 | # --- Authentication with Application Password (Must includes space) --- 13 | WP_APP_USER=wordpress_username 14 | WP_APP_PASSWORD=Appl icat ion_ Pass word -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Generated by https://smithery.ai. See: https://smithery.ai/docs/config#dockerfile 2 | FROM node:lts-alpine 3 | 4 | # Create app directory 5 | WORKDIR /app 6 | 7 | # Install dependencies 8 | COPY package.json package-lock.json ./ 9 | RUN npm install --production 10 | 11 | # Copy source code 12 | COPY src ./src 13 | 14 | # Expose standard IO for MCP 15 | # No ports required; uses stdio 16 | 17 | # Default command 18 | CMD ["node", "src/index.js"] 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # General 2 | .DS_Store 3 | .AppleDouble 4 | .LSOverride 5 | 6 | # Icon must end with two \r 7 | Icon 8 | 9 | 10 | # Thumbnails 11 | ._* 12 | 13 | # Files that might appear in the root of a volume 14 | .DocumentRevisions-V100 15 | .fseventsd 16 | .Spotlight-V100 17 | .TemporaryItems 18 | .Trashes 19 | .VolumeIcon.icns 20 | .com.apple.timemachine.donotpresent 21 | 22 | # Directories potentially created on remote AFP share 23 | .AppleDB 24 | .AppleDesktop 25 | Network Trash Folder 26 | Temporary Items 27 | .apdisk 28 | 29 | node_modules 30 | .env 31 | *.log 32 | .*.env 33 | -------------------------------------------------------------------------------- /test/test-update-page.js: -------------------------------------------------------------------------------- 1 | // Test script to get a specific page by slug 2 | // import 'dotenv/config'; // Don't use this if calling config() manually 3 | const dotenv = require("dotenv"); // Import the dotenv object 4 | const path = require("path"); // Import path using require 5 | // No need for fileURLToPath in CommonJS 6 | const { initializeApiClient } = require("../src/auth"); // Use require, no .js 7 | const { updatePage } = require("../src/wp-api"); // Use require, no .js 8 | const fs = require("fs"); 9 | 10 | dotenv.config({ path: path.resolve(__dirname, ".test.env") }); 11 | 12 | const TARGET_PAGE_ID = process.env.TARGET_ID; 13 | const ELEMENTOR_DATA = JSON.parse( 14 | fs.readFileSync(path.resolve(__dirname, `${TARGET_FILE}`), "utf8") 15 | ).meta._elementor_data; 16 | 17 | async function runTest() { 18 | await initializeApiClient(); 19 | const updatedPage = await updatePage(TARGET_PAGE_ID, { 20 | elementor_data: ELEMENTOR_DATA, 21 | }); 22 | console.log(updatedPage); 23 | } 24 | 25 | runTest(); 26 | -------------------------------------------------------------------------------- /smithery.yaml: -------------------------------------------------------------------------------- 1 | # Smithery configuration file: https://smithery.ai/docs/config#smitheryyaml 2 | 3 | startCommand: 4 | type: stdio 5 | configSchema: 6 | # JSON Schema defining the configuration options for the MCP. 7 | type: object 8 | required: 9 | - wpUrl 10 | - wpAppUser 11 | - wpAppPassword 12 | properties: 13 | wpUrl: 14 | type: string 15 | description: The URL of the target WordPress website. 16 | wpAppUser: 17 | type: string 18 | description: The WordPress application username. 19 | wpAppPassword: 20 | type: string 21 | description: The WordPress application password. 22 | commandFunction: 23 | # A JS function that produces the CLI command based on the given config to start the MCP on stdio. 24 | |- 25 | (config) => ({ command: 'node', args: ['src/index.js'], env: { WP_URL: config.wpUrl, WP_APP_USER: config.wpAppUser, WP_APP_PASSWORD: config.wpAppPassword } }) 26 | exampleConfig: 27 | wpUrl: https://example.com 28 | wpAppUser: admin 29 | wpAppPassword: AppPass_1234 30 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![MseeP.ai Security Assessment Badge](https://mseep.net/pr/aguaitech-elementor-mcp-badge.png)](https://mseep.ai/app/aguaitech-elementor-mcp) 2 | 3 | # Elementor MCP Server 4 | 5 | [![smithery badge](https://smithery.ai/badge/@aguaitech/Elementor-MCP)](https://smithery.ai/server/@aguaitech/Elementor-MCP) 6 | 7 | > We recommand you to use [this template project](https://github.com/aguaitech/Elementor_Project_Workflow) to manage your Elementor project. 8 | 9 | This is a simple MCP server for Elementor. It is used to perform CRUD operations on the Elementor data for a given page. 10 | 11 | ## Installation 12 | 13 | ### Installing via Smithery 14 | 15 | To install Elementor MCP Server for Claude Desktop automatically via [Smithery](https://smithery.ai/server/@aguaitech/Elementor-MCP): 16 | 17 | ```bash 18 | npx -y @smithery/cli install @aguaitech/Elementor-MCP --client claude 19 | ``` 20 | 21 | Or configure the MCP server in your `mcp.json` file. Note that the environment variables are required. 22 | * WP_URL: The URL of the target website. 23 | * WP_APP_USER: The username of the target website. Note: it's the username to log in to the target website, not the application name. 24 | * WP_APP_PASSWORD: The application password of the target website, keep the space. You can create one in the target website's WordPress dashboard, see [Generating Manually Section in this page](https://make.wordpress.org/core/2020/11/05/application-passwords-integration-guide/). 25 | 26 | ### MacOS / Linux 27 | 28 | ```json 29 | { 30 | "mcpServers": { 31 | "Elementor MCP": { 32 | "command": "npx", 33 | "args": ["-y", "elementor-mcp"], 34 | "env": { 35 | "WP_URL": "https://url.of.target.website", 36 | "WP_APP_USER": "wordpress_username", 37 | "WP_APP_PASSWORD": "Appl icat ion_ Pass word" 38 | } 39 | } 40 | } 41 | } 42 | ``` 43 | 44 | ### Windows 45 | 46 | ```json 47 | { 48 | "mcpServers": { 49 | "Elementor MCP": { 50 | "command": "cmd", 51 | "args": ["/c", "npx", "-y", "elementor-mcp"], 52 | "env": { 53 | "WP_URL": "https://url.of.target.website", 54 | "WP_APP_USER": "wordpress_username", 55 | "WP_APP_PASSWORD": "Appl icat ion_ Pass word" 56 | } 57 | } 58 | } 59 | } 60 | ``` 61 | 62 | ## License 63 | 64 | This project is licensed under the MIT License 65 | -------------------------------------------------------------------------------- /src/auth.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); // Use CommonJS configuration call 2 | const axios = require('axios'); // Use CommonJS require 3 | 4 | let axiosInstance = null; // Singleton instance 5 | 6 | async function initializeApiClient() { 7 | // No need to call loadESMDependencies 8 | 9 | if (axiosInstance) { 10 | // Already initialized 11 | return; 12 | } 13 | 14 | const baseURL = process.env.WP_URL; 15 | if (!baseURL) { 16 | throw new Error('WP_URL environment variable is not set.'); 17 | } 18 | const cleanBaseURL = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL; 19 | 20 | const appUser = process.env.WP_APP_USER; 21 | const appPassword = process.env.WP_APP_PASSWORD; 22 | 23 | // --- Strategy 1: Application Password (Basic Auth) --- 24 | if (appUser && appPassword) { 25 | const token = Buffer.from(`${appUser}:${appPassword}`, 'utf8').toString('base64'); 26 | axiosInstance = axios.create({ 27 | baseURL: cleanBaseURL, 28 | headers: { 29 | 'Authorization': `Basic ${token}` 30 | } 31 | }); 32 | } 33 | // --- Strategy 3: No Authentication --- 34 | else { 35 | console.error('No application password credentials found (WP_APP_USER, WP_APP_PASSWORD). API requests might fail.'); 36 | axiosInstance = axios.create({ 37 | baseURL: cleanBaseURL 38 | }); 39 | } 40 | 41 | if (axiosInstance) { 42 | axiosInstance.interceptors.response.use( 43 | response => response, 44 | error => { 45 | console.error("Axios Error:", error.response?.status, error.response?.data || error.message); 46 | let errorMessage = 'WordPress API request failed'; 47 | if (error.response?.headers?.['content-type']?.includes('text/html') && typeof error.response?.data === 'string') { 48 | if (error.response.data.includes('incorrect_password')) { 49 | errorMessage = 'WordPress API Error: Incorrect password.'; 50 | } else if (error.response.data.includes('invalid_username')) { 51 | errorMessage = 'WordPress API Error: Invalid username.'; 52 | } else if (error.response.data.includes('nonce') || error.response.data.includes('security check')) { 53 | errorMessage = 'WordPress API Error: Nonce or security check failed.'; 54 | } 55 | } else if (error.response?.data?.message) { 56 | errorMessage = `WordPress API Error: ${error.response.data.message}`; 57 | } 58 | return Promise.reject(error.response?.data || new Error(errorMessage)); 59 | } 60 | ); 61 | } else { 62 | throw new Error("Failed to initialize API client."); 63 | } 64 | } 65 | 66 | function getApiClient() { 67 | if (!axiosInstance) { 68 | throw new Error('API client has not been initialized. Call initializeApiClient() first.'); 69 | } 70 | return axiosInstance; 71 | } 72 | 73 | // Export using CommonJS syntax 74 | module.exports = { initializeApiClient, getApiClient }; -------------------------------------------------------------------------------- /test/test-get-page.js: -------------------------------------------------------------------------------- 1 | // Test script to get a specific page by slug 2 | // import 'dotenv/config'; // Don't use this if calling config() manually 3 | const dotenv = require('dotenv'); // Import the dotenv object 4 | const path = require('path'); // Import path using require 5 | // No need for fileURLToPath in CommonJS 6 | const { initializeApiClient } = require('../src/auth'); // Use require, no .js 7 | const { getPage, getPageIdBySlug } = require('../src/wp-api'); // Use require, no .js 8 | 9 | // Standard CommonJS __dirname works directly 10 | dotenv.config({ path: path.resolve(__dirname, '.test.env') }); 11 | 12 | const TARGET_SLUG = process.env.TARGET_SLUG; 13 | 14 | async function runTest() { 15 | if (!TARGET_SLUG) { 16 | console.error("Error: TARGET_SLUG not set in .test.env file."); 17 | process.exit(1); 18 | } 19 | try { 20 | console.log("Initializing API client..."); 21 | await initializeApiClient(); // Authenticate using .env credentials 22 | // No need for client directly here if only using wp-api functions 23 | console.log("API client initialized."); 24 | 25 | // 1. Find the page ID by slug using the shared function 26 | console.log(`Searching for page ID with slug: ${TARGET_SLUG}...`); 27 | let pageId = null; 28 | try { 29 | pageId = await getPageIdBySlug(TARGET_SLUG); 30 | // Log is already handled inside getPageIdBySlug 31 | } catch (error) { 32 | // Error logging is already handled inside getPageIdBySlug 33 | console.error(`Test script cannot continue: Failed to get Page ID for slug '${TARGET_SLUG}'.`); 34 | return; // Exit on error 35 | } 36 | 37 | // 2. Get the full page data using the found ID 38 | console.log(`\nFetching full page data for ID: ${pageId}...`); 39 | const pageData = await getPage(pageId); // Use our existing function 40 | 41 | console.log(`\n--- Page Data for ID ${pageId} ---`); 42 | console.log(`Title: ${pageData.title?.rendered}`); 43 | console.log(`Status: ${pageData.status}`); 44 | console.log(`Link: ${pageData.link}`); 45 | 46 | // Attempt to parse and display Elementor data 47 | if (pageData.meta && pageData.meta._elementor_data) { 48 | console.log("\n--- Elementor Data (Parsed) ---"); 49 | try { 50 | const elementorJson = JSON.parse(pageData.meta._elementor_data); 51 | // Pretty print the JSON structure 52 | console.log(JSON.stringify(elementorJson, null, 2)); 53 | } catch (e) { 54 | console.error("Could not parse Elementor JSON string:", e.message); 55 | console.log("Raw Elementor Data String:", pageData.meta._elementor_data); 56 | } 57 | } else { 58 | console.log("\nNo Elementor data found in page meta."); 59 | } 60 | 61 | // Optionally log the entire page object for debugging 62 | // console.log("\n--- Full Page Object ---"); 63 | // console.log(JSON.stringify(pageData, null, 2)); 64 | 65 | } catch (error) { 66 | console.error("\nTest script failed:", error.message || error); 67 | if (error.response) { // Log Axios error details if available 68 | console.error("Response Status:", error.response.status); 69 | console.error("Response Data:", error.response.data); 70 | } 71 | process.exit(1); 72 | } 73 | } 74 | 75 | runTest(); -------------------------------------------------------------------------------- /src/wp-api.js: -------------------------------------------------------------------------------- 1 | const { getApiClient } = require('./auth.js'); // Use CommonJS require 2 | 3 | // --- CREATE --- 4 | async function createPage(pageData) { 5 | const client = getApiClient(); 6 | // Ensure Elementor data is properly nested under meta 7 | const payload = { 8 | title: pageData.title, 9 | status: pageData.status || 'draft', // Default to draft 10 | content: pageData.content || '', // Optional standard content 11 | meta: { 12 | _elementor_data: pageData.elementor_data // MUST be a JSON string 13 | } 14 | // Add other WP fields as needed (e.g., template, author, etc.) 15 | }; 16 | 17 | // Validate elementor_data is a string 18 | if (typeof payload.meta._elementor_data !== 'string') { 19 | throw new Error('elementor_data must be provided as a JSON string.'); 20 | } 21 | try { 22 | JSON.parse(payload.meta._elementor_data); // Basic validation it's parsable JSON 23 | } catch (e) { 24 | throw new Error('elementor_data is not valid JSON string.'); 25 | } 26 | 27 | 28 | const response = await client.post('/wp-json/wp/v2/pages', payload); 29 | return response.data; // Return the created page object 30 | } 31 | 32 | // --- READ --- 33 | async function getPage(pageId) { 34 | const client = getApiClient(); 35 | // Use context=edit to potentially get more fields like meta 36 | const response = await client.get(`/wp-json/wp/v2/pages/${pageId}?context=edit`); 37 | return response.data; 38 | } 39 | 40 | // --- UPDATE --- 41 | async function updatePage(pageId, pageData) { 42 | const client = getApiClient(); 43 | 44 | const payload = {}; 45 | if (pageData.title) payload.title = pageData.title; 46 | if (pageData.status) payload.status = pageData.status; 47 | if (pageData.content) payload.content = pageData.content; // Use !== undefined to allow setting empty content 48 | 49 | if (pageData.elementor_data) { 50 | if (typeof pageData.elementor_data !== 'string') { 51 | throw new Error('elementor_data must be provided as a JSON string.'); 52 | } 53 | try { 54 | JSON.parse(pageData.elementor_data); // Basic validation 55 | } catch (e) { 56 | throw new Error('elementor_data is not valid JSON string.'); 57 | } 58 | payload.meta = { _elementor_data: pageData.elementor_data }; 59 | } 60 | 61 | if (Object.keys(payload).length === 0) { 62 | throw new Error("No update data provided."); 63 | } 64 | 65 | // WP uses POST for updates via ID route 66 | const response = await client.post(`/wp-json/wp/v2/pages/${pageId}`, payload); 67 | return response.data; 68 | } 69 | 70 | // --- DELETE --- 71 | async function deletePage(pageId, force = true) { 72 | const client = getApiClient(); 73 | const response = await client.delete(`/wp-json/wp/v2/pages/${pageId}?force=${force}`); 74 | // WP delete usually returns the object before deletion or a specific structure 75 | return response.data; 76 | } 77 | 78 | // --- NEW FUNCTION: Get Page ID by Slug --- 79 | async function getPageIdBySlug(slug) { 80 | const client = getApiClient(); 81 | let pageId = null; 82 | 83 | try { 84 | const response = await client.get(`/wp-json/wp/v2/pages`, { 85 | params: { 86 | slug: slug, 87 | _fields: 'id', // Only need the ID 88 | } 89 | }); 90 | 91 | if (response.data && response.data.length > 0) { 92 | pageId = response.data[0].id; 93 | return pageId; // Return the ID directly 94 | } else { 95 | // Throw an error if not found, to be caught by the caller 96 | throw new Error(`Page with slug '${slug}' not found.`); 97 | } 98 | } catch (error) { 99 | // Re-throw the error for the caller to handle 100 | throw error; // Propagate the error (could be Axios error or the 'not found' error) 101 | } 102 | } 103 | 104 | // --- Export using CommonJS --- 105 | module.exports = { 106 | createPage, 107 | getPage, 108 | updatePage, 109 | deletePage, 110 | getPageIdBySlug 111 | }; -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | const { McpServer } = require("@modelcontextprotocol/sdk/server/mcp.js"); 4 | const { 5 | StdioServerTransport, 6 | } = require("@modelcontextprotocol/sdk/server/stdio.js"); 7 | const { z } = require("zod"); 8 | const { initializeApiClient } = require("./auth"); 9 | const { 10 | createPage, 11 | getPage, 12 | updatePage, 13 | deletePage, 14 | getPageIdBySlug, 15 | } = require("./wp-api"); 16 | const fs = require("fs"); 17 | 18 | // Wrap server start in an async function to allow await for initialization 19 | async function main() { 20 | try { 21 | // --- Initialize Server --- 22 | const server = new McpServer({ 23 | name: "WordPressElementorMCP", 24 | version: "1.0.0", 25 | description: 26 | "Provides tools to interact with WordPress pages and Elementor data.", // Optional description 27 | }); 28 | 29 | // Initialize the API client (handles authentication) 30 | await initializeApiClient(); 31 | 32 | // --- Define Tools --- 33 | 34 | server.tool( 35 | "create_page", 36 | "Creates a new page in WordPress with Elementor data, it will return the created page ID.", 37 | { 38 | // Input Schema: Use plain object with Zod types 39 | title: z.string().describe("The title for the new page (required)."), 40 | status: z 41 | .enum(["publish", "future", "draft", "pending", "private"]) 42 | .optional() 43 | .describe( 44 | "The status for the page (e.g., 'publish', 'draft'). Defaults to 'draft' on create." 45 | ), 46 | content: z 47 | .string() 48 | .optional() 49 | .describe("The standard WordPress content for the page (optional)."), 50 | elementor_data: z 51 | .string() 52 | .describe( 53 | "The Elementor page data as a JSON string (required for create)." 54 | ), 55 | }, 56 | async (input) => { 57 | // Handler function 58 | const newPage = await createPage(input); 59 | // Return the result object directly 60 | return { 61 | content: [ 62 | { 63 | type: "text", 64 | text: `${newPage.id}`, 65 | }, 66 | ], 67 | }; 68 | // Errors thrown here will be handled by McpServer 69 | } 70 | ); 71 | 72 | server.tool( 73 | "get_page", 74 | "Retrieves a specific page from WordPress by its ID, including meta fields like _elementor_data.", 75 | { 76 | // Input Schema 77 | pageId: z 78 | .number() 79 | .int() 80 | .positive() 81 | .describe("The ID of the page to retrieve."), 82 | }, 83 | async (input) => { 84 | // Handler 85 | const pageData = await getPage(input.pageId); 86 | return { 87 | content: [ 88 | { 89 | type: "text", 90 | text: JSON.stringify(pageData), 91 | }, 92 | ], 93 | }; 94 | } 95 | ); 96 | 97 | server.tool( 98 | "download_page_to_file", 99 | "Downloads a specific page from WordPress by its ID, including meta fields like _elementor_data, and saves it to a file.", 100 | { 101 | pageId: z 102 | .number() 103 | .int() 104 | .positive() 105 | .describe("The ID of the page to download."), 106 | filePath: z 107 | .string() 108 | .describe( 109 | "The path to save the file to, have to be the absolute path." 110 | ), 111 | onlyElementorData: z 112 | .boolean() 113 | .optional() 114 | .default(false) 115 | .describe( 116 | "Whether to only save the _elementor_data field to the file, defaults to false." 117 | ), 118 | }, 119 | async (input) => { 120 | const pageData = await getPage(input.pageId); 121 | if (input.onlyElementorData) { 122 | fs.writeFileSync( 123 | input.filePath, 124 | JSON.stringify(pageData.meta._elementor_data, null, 0) 125 | ); 126 | } else { 127 | fs.writeFileSync(input.filePath, JSON.stringify(pageData, null, 0)); 128 | } 129 | return { 130 | content: [{ type: "text", text: "true" }], 131 | }; 132 | } 133 | ); 134 | 135 | server.tool( 136 | "update_page", 137 | "Updates an existing page in WordPress with Elementor data, it will return a boolean value to indicate if the update was successful.", 138 | { 139 | // Input Schema: Use plain object with Zod types 140 | pageId: z 141 | .number() 142 | .int() 143 | .positive() 144 | .describe("The ID of the page to update."), 145 | title: z.string().optional().describe("The title for the page."), 146 | status: z 147 | .enum(["publish", "future", "draft", "pending", "private"]) 148 | .optional() 149 | .describe("The status for the page (e.g., 'publish', 'draft')."), 150 | content: z 151 | .string() 152 | .optional() 153 | .describe("The standard WordPress content for the page (optional)."), 154 | elementor_data: z 155 | .string() 156 | .optional() 157 | .describe( 158 | "The Elementor page data as a JSON string. Optional for update." 159 | ), 160 | }, 161 | async (input) => { 162 | // Handler 163 | const { pageId, ...updateData } = input; 164 | // Basic validation, although schema handles optionality 165 | if (Object.keys(updateData).length === 0) { 166 | throw new Error( 167 | "No update data provided (title, status, content, or elementor_data)." 168 | ); 169 | } 170 | await updatePage(pageId, updateData); 171 | return { 172 | content: [ 173 | { 174 | type: "text", 175 | text: "true", 176 | }, 177 | ], 178 | }; 179 | } 180 | ); 181 | 182 | server.tool( 183 | "update_page_from_file", 184 | "Updates an existing page in WordPress with Elementor data from a file, it will return a boolean value to indicate if the update was successful.", 185 | { 186 | pageId: z 187 | .number() 188 | .int() 189 | .positive() 190 | .describe("The ID of the page to update."), 191 | title: z.string().optional().describe("The title for the page."), 192 | status: z 193 | .enum(["publish", "future", "draft", "pending", "private"]) 194 | .optional() 195 | .describe("The status for the page (e.g., 'publish', 'draft')."), 196 | contentFilePath: z 197 | .string() 198 | .optional() 199 | .describe( 200 | "The absolute path to the file to update the WordPress content from, optional." 201 | ), 202 | elementorFilePath: z 203 | .string() 204 | .describe("The absolute path to the file to update the Elementor data from."), 205 | }, 206 | async (input) => { 207 | const pageData = JSON.parse( 208 | fs.readFileSync(input.elementorFilePath, "utf8") 209 | ); 210 | let contentData = null; 211 | if (input.contentFilePath) { 212 | contentData = fs.readFileSync(input.contentFilePath, "utf8"); 213 | } 214 | await updatePage(input.pageId, { 215 | title: input.title, 216 | status: input.status, 217 | content: contentData, 218 | elementor_data: JSON.stringify(pageData, null, 0), 219 | }); 220 | return { 221 | content: [{ type: "text", text: "true" }], 222 | }; 223 | } 224 | ); 225 | 226 | server.tool( 227 | "delete_page", 228 | "Deletes a specific page from WordPress, it will return a boolean value to indicate if the deletion was successful.", 229 | { 230 | // Input Schema: Use plain object with Zod types 231 | pageId: z 232 | .number() 233 | .int() 234 | .positive() 235 | .describe("The ID of the page to delete."), 236 | force: z 237 | .boolean() 238 | .optional() 239 | .default(false) 240 | .describe( 241 | "Whether to bypass the trash and force deletion. Defaults to false." 242 | ), 243 | }, 244 | async (input) => { 245 | // Handler 246 | await deletePage(input.pageId, input.force); 247 | return { 248 | content: [ 249 | { 250 | type: "text", 251 | text: "true", 252 | }, 253 | ], 254 | }; 255 | } 256 | ); 257 | 258 | server.tool( 259 | "get_page_id_by_slug", 260 | "Retrieves the ID of a specific WordPress page by its slug.", 261 | { 262 | // Input Schema 263 | slug: z 264 | .string() 265 | .describe("The slug (URL-friendly name) of the page to find."), 266 | }, 267 | async (input) => { 268 | // Handler 269 | const pageId = await getPageIdBySlug(input.slug); 270 | return { 271 | content: [ 272 | { 273 | type: "text", 274 | text: `${pageId}`, 275 | }, 276 | ], 277 | }; 278 | } 279 | ); 280 | 281 | // --- Connect Server to Transport --- 282 | const transport = new StdioServerTransport(); 283 | await server.connect(transport); 284 | } catch (error) { 285 | process.exit(1); // Exit if initialization fails 286 | } 287 | } 288 | 289 | // Execute the main function 290 | main(); 291 | -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@modelcontextprotocol/sdk@^1.10.1": 6 | version "1.10.1" 7 | resolved "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.10.1.tgz" 8 | integrity sha512-xNYdFdkJqEfIaTVP1gPKoEvluACHZsHZegIoICX8DM1o6Qf3G5u2BQJHmgd0n4YgRPqqK/u1ujQvrgAxxSJT9w== 9 | dependencies: 10 | content-type "^1.0.5" 11 | cors "^2.8.5" 12 | cross-spawn "^7.0.3" 13 | eventsource "^3.0.2" 14 | express "^5.0.1" 15 | express-rate-limit "^7.5.0" 16 | pkce-challenge "^5.0.0" 17 | raw-body "^3.0.0" 18 | zod "^3.23.8" 19 | zod-to-json-schema "^3.24.1" 20 | 21 | accepts@^2.0.0: 22 | version "2.0.0" 23 | resolved "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz" 24 | integrity sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng== 25 | dependencies: 26 | mime-types "^3.0.0" 27 | negotiator "^1.0.0" 28 | 29 | agent-base@^7.1.3: 30 | version "7.1.3" 31 | resolved "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz" 32 | integrity sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw== 33 | 34 | asynckit@^0.4.0: 35 | version "0.4.0" 36 | resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz" 37 | integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== 38 | 39 | axios-cookiejar-support@^6.0.0: 40 | version "6.0.0" 41 | resolved "https://registry.npmjs.org/axios-cookiejar-support/-/axios-cookiejar-support-6.0.0.tgz" 42 | integrity sha512-jZwNWbSEN/Qn1z7yfciyhctzeVi7fCCJEWqdUSX+xNadabfRBfM5RSvwu5yQgV0VE4j6/FsgJB0+WNKbnuHzgQ== 43 | dependencies: 44 | http-cookie-agent "^7.0.1" 45 | 46 | axios@^1.8.4, axios@>=0.20.0: 47 | version "1.8.4" 48 | resolved "https://registry.npmjs.org/axios/-/axios-1.8.4.tgz" 49 | integrity sha512-eBSYY4Y68NNlHbHBMdeDmKNtDgXWhQsJcGqzO3iLUM0GraQFSS9cVgPX5I9b3lbdFKyYoAEGAZF1DwhTaljNAw== 50 | dependencies: 51 | follow-redirects "^1.15.6" 52 | form-data "^4.0.0" 53 | proxy-from-env "^1.1.0" 54 | 55 | body-parser@^2.2.0: 56 | version "2.2.0" 57 | resolved "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz" 58 | integrity sha512-02qvAaxv8tp7fBa/mw1ga98OGm+eCbqzJOKoRt70sLmfEEi+jyBYVTDGfCL/k06/4EMk/z01gCe7HoCH/f2LTg== 59 | dependencies: 60 | bytes "^3.1.2" 61 | content-type "^1.0.5" 62 | debug "^4.4.0" 63 | http-errors "^2.0.0" 64 | iconv-lite "^0.6.3" 65 | on-finished "^2.4.1" 66 | qs "^6.14.0" 67 | raw-body "^3.0.0" 68 | type-is "^2.0.0" 69 | 70 | bytes@^3.1.2, bytes@3.1.2: 71 | version "3.1.2" 72 | resolved "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz" 73 | integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== 74 | 75 | call-bind-apply-helpers@^1.0.1, call-bind-apply-helpers@^1.0.2: 76 | version "1.0.2" 77 | resolved "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz" 78 | integrity sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ== 79 | dependencies: 80 | es-errors "^1.3.0" 81 | function-bind "^1.1.2" 82 | 83 | call-bound@^1.0.2: 84 | version "1.0.4" 85 | resolved "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz" 86 | integrity sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg== 87 | dependencies: 88 | call-bind-apply-helpers "^1.0.2" 89 | get-intrinsic "^1.3.0" 90 | 91 | combined-stream@^1.0.8: 92 | version "1.0.8" 93 | resolved "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz" 94 | integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== 95 | dependencies: 96 | delayed-stream "~1.0.0" 97 | 98 | content-disposition@^1.0.0: 99 | version "1.0.0" 100 | resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz" 101 | integrity sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg== 102 | dependencies: 103 | safe-buffer "5.2.1" 104 | 105 | content-type@^1.0.5: 106 | version "1.0.5" 107 | resolved "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz" 108 | integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== 109 | 110 | cookie-signature@^1.2.1: 111 | version "1.2.2" 112 | resolved "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz" 113 | integrity sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg== 114 | 115 | cookie@^0.7.1: 116 | version "0.7.2" 117 | resolved "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz" 118 | integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== 119 | 120 | cors@^2.8.5: 121 | version "2.8.5" 122 | resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" 123 | integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== 124 | dependencies: 125 | object-assign "^4" 126 | vary "^1" 127 | 128 | cross-spawn@^7.0.3: 129 | version "7.0.6" 130 | resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz" 131 | integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== 132 | dependencies: 133 | path-key "^3.1.0" 134 | shebang-command "^2.0.0" 135 | which "^2.0.1" 136 | 137 | debug@^4.3.5, debug@^4.4.0: 138 | version "4.4.0" 139 | resolved "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz" 140 | integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== 141 | dependencies: 142 | ms "^2.1.3" 143 | 144 | delayed-stream@~1.0.0: 145 | version "1.0.0" 146 | resolved "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz" 147 | integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== 148 | 149 | depd@^2.0.0, depd@2.0.0: 150 | version "2.0.0" 151 | resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" 152 | integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== 153 | 154 | dotenv@^16.5.0: 155 | version "16.5.0" 156 | resolved "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz" 157 | integrity sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg== 158 | 159 | dunder-proto@^1.0.1: 160 | version "1.0.1" 161 | resolved "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz" 162 | integrity sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A== 163 | dependencies: 164 | call-bind-apply-helpers "^1.0.1" 165 | es-errors "^1.3.0" 166 | gopd "^1.2.0" 167 | 168 | ee-first@1.1.1: 169 | version "1.1.1" 170 | resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" 171 | integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== 172 | 173 | encodeurl@^2.0.0: 174 | version "2.0.0" 175 | resolved "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz" 176 | integrity sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg== 177 | 178 | es-define-property@^1.0.1: 179 | version "1.0.1" 180 | resolved "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz" 181 | integrity sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g== 182 | 183 | es-errors@^1.3.0: 184 | version "1.3.0" 185 | resolved "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz" 186 | integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== 187 | 188 | es-object-atoms@^1.0.0, es-object-atoms@^1.1.1: 189 | version "1.1.1" 190 | resolved "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz" 191 | integrity sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA== 192 | dependencies: 193 | es-errors "^1.3.0" 194 | 195 | es-set-tostringtag@^2.1.0: 196 | version "2.1.0" 197 | resolved "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz" 198 | integrity sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA== 199 | dependencies: 200 | es-errors "^1.3.0" 201 | get-intrinsic "^1.2.6" 202 | has-tostringtag "^1.0.2" 203 | hasown "^2.0.2" 204 | 205 | escape-html@^1.0.3: 206 | version "1.0.3" 207 | resolved "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz" 208 | integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== 209 | 210 | etag@^1.8.1: 211 | version "1.8.1" 212 | resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" 213 | integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== 214 | 215 | eventsource-parser@^3.0.1: 216 | version "3.0.1" 217 | resolved "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.1.tgz" 218 | integrity sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA== 219 | 220 | eventsource@^3.0.2: 221 | version "3.0.6" 222 | resolved "https://registry.npmjs.org/eventsource/-/eventsource-3.0.6.tgz" 223 | integrity sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA== 224 | dependencies: 225 | eventsource-parser "^3.0.1" 226 | 227 | express-rate-limit@^7.5.0: 228 | version "7.5.0" 229 | resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.0.tgz" 230 | integrity sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg== 231 | 232 | "express@^4.11 || 5 || ^5.0.0-beta.1", express@^5.0.1: 233 | version "5.1.0" 234 | resolved "https://registry.npmjs.org/express/-/express-5.1.0.tgz" 235 | integrity sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA== 236 | dependencies: 237 | accepts "^2.0.0" 238 | body-parser "^2.2.0" 239 | content-disposition "^1.0.0" 240 | content-type "^1.0.5" 241 | cookie "^0.7.1" 242 | cookie-signature "^1.2.1" 243 | debug "^4.4.0" 244 | encodeurl "^2.0.0" 245 | escape-html "^1.0.3" 246 | etag "^1.8.1" 247 | finalhandler "^2.1.0" 248 | fresh "^2.0.0" 249 | http-errors "^2.0.0" 250 | merge-descriptors "^2.0.0" 251 | mime-types "^3.0.0" 252 | on-finished "^2.4.1" 253 | once "^1.4.0" 254 | parseurl "^1.3.3" 255 | proxy-addr "^2.0.7" 256 | qs "^6.14.0" 257 | range-parser "^1.2.1" 258 | router "^2.2.0" 259 | send "^1.1.0" 260 | serve-static "^2.2.0" 261 | statuses "^2.0.1" 262 | type-is "^2.0.1" 263 | vary "^1.1.2" 264 | 265 | finalhandler@^2.1.0: 266 | version "2.1.0" 267 | resolved "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz" 268 | integrity sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q== 269 | dependencies: 270 | debug "^4.4.0" 271 | encodeurl "^2.0.0" 272 | escape-html "^1.0.3" 273 | on-finished "^2.4.1" 274 | parseurl "^1.3.3" 275 | statuses "^2.0.1" 276 | 277 | follow-redirects@^1.15.6: 278 | version "1.15.9" 279 | resolved "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz" 280 | integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== 281 | 282 | form-data@^4.0.0: 283 | version "4.0.2" 284 | resolved "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz" 285 | integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w== 286 | dependencies: 287 | asynckit "^0.4.0" 288 | combined-stream "^1.0.8" 289 | es-set-tostringtag "^2.1.0" 290 | mime-types "^2.1.12" 291 | 292 | forwarded@0.2.0: 293 | version "0.2.0" 294 | resolved "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz" 295 | integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== 296 | 297 | fresh@^2.0.0: 298 | version "2.0.0" 299 | resolved "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz" 300 | integrity sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A== 301 | 302 | function-bind@^1.1.2: 303 | version "1.1.2" 304 | resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz" 305 | integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== 306 | 307 | get-intrinsic@^1.2.5, get-intrinsic@^1.2.6, get-intrinsic@^1.3.0: 308 | version "1.3.0" 309 | resolved "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz" 310 | integrity sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ== 311 | dependencies: 312 | call-bind-apply-helpers "^1.0.2" 313 | es-define-property "^1.0.1" 314 | es-errors "^1.3.0" 315 | es-object-atoms "^1.1.1" 316 | function-bind "^1.1.2" 317 | get-proto "^1.0.1" 318 | gopd "^1.2.0" 319 | has-symbols "^1.1.0" 320 | hasown "^2.0.2" 321 | math-intrinsics "^1.1.0" 322 | 323 | get-proto@^1.0.1: 324 | version "1.0.1" 325 | resolved "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz" 326 | integrity sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g== 327 | dependencies: 328 | dunder-proto "^1.0.1" 329 | es-object-atoms "^1.0.0" 330 | 331 | gopd@^1.2.0: 332 | version "1.2.0" 333 | resolved "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz" 334 | integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== 335 | 336 | has-symbols@^1.0.3, has-symbols@^1.1.0: 337 | version "1.1.0" 338 | resolved "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz" 339 | integrity sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ== 340 | 341 | has-tostringtag@^1.0.2: 342 | version "1.0.2" 343 | resolved "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz" 344 | integrity sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw== 345 | dependencies: 346 | has-symbols "^1.0.3" 347 | 348 | hasown@^2.0.2: 349 | version "2.0.2" 350 | resolved "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz" 351 | integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== 352 | dependencies: 353 | function-bind "^1.1.2" 354 | 355 | http-cookie-agent@^7.0.1: 356 | version "7.0.1" 357 | resolved "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.1.tgz" 358 | integrity sha512-lZHFZUdPTw64PdksQac5xbUd4NWjUbyDYnvR//2sbLpcC4UqEUW0x/6O+rDntVzJzJ07QvhtL5XZSC+c5EK+IQ== 359 | dependencies: 360 | agent-base "^7.1.3" 361 | 362 | http-errors@^2.0.0, http-errors@2.0.0: 363 | version "2.0.0" 364 | resolved "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz" 365 | integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== 366 | dependencies: 367 | depd "2.0.0" 368 | inherits "2.0.4" 369 | setprototypeof "1.2.0" 370 | statuses "2.0.1" 371 | toidentifier "1.0.1" 372 | 373 | iconv-lite@^0.6.3, iconv-lite@0.6.3: 374 | version "0.6.3" 375 | resolved "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz" 376 | integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== 377 | dependencies: 378 | safer-buffer ">= 2.1.2 < 3.0.0" 379 | 380 | inherits@2.0.4: 381 | version "2.0.4" 382 | resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz" 383 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 384 | 385 | ipaddr.js@1.9.1: 386 | version "1.9.1" 387 | resolved "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz" 388 | integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== 389 | 390 | is-promise@^4.0.0: 391 | version "4.0.0" 392 | resolved "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz" 393 | integrity sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ== 394 | 395 | isexe@^2.0.0: 396 | version "2.0.0" 397 | resolved "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz" 398 | integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== 399 | 400 | math-intrinsics@^1.1.0: 401 | version "1.1.0" 402 | resolved "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz" 403 | integrity sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g== 404 | 405 | media-typer@^1.1.0: 406 | version "1.1.0" 407 | resolved "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz" 408 | integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== 409 | 410 | merge-descriptors@^2.0.0: 411 | version "2.0.0" 412 | resolved "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz" 413 | integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== 414 | 415 | mime-db@^1.54.0: 416 | version "1.54.0" 417 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz" 418 | integrity sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ== 419 | 420 | mime-db@1.52.0: 421 | version "1.52.0" 422 | resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" 423 | integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== 424 | 425 | mime-types@^2.1.12: 426 | version "2.1.35" 427 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz" 428 | integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== 429 | dependencies: 430 | mime-db "1.52.0" 431 | 432 | mime-types@^3.0.0, mime-types@^3.0.1: 433 | version "3.0.1" 434 | resolved "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz" 435 | integrity sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA== 436 | dependencies: 437 | mime-db "^1.54.0" 438 | 439 | ms@^2.1.3: 440 | version "2.1.3" 441 | resolved "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" 442 | integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== 443 | 444 | negotiator@^1.0.0: 445 | version "1.0.0" 446 | resolved "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz" 447 | integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== 448 | 449 | object-assign@^4: 450 | version "4.1.1" 451 | resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" 452 | integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== 453 | 454 | object-inspect@^1.13.3: 455 | version "1.13.4" 456 | resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz" 457 | integrity sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew== 458 | 459 | on-finished@^2.4.1: 460 | version "2.4.1" 461 | resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" 462 | integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== 463 | dependencies: 464 | ee-first "1.1.1" 465 | 466 | once@^1.4.0: 467 | version "1.4.0" 468 | resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz" 469 | integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== 470 | dependencies: 471 | wrappy "1" 472 | 473 | parseurl@^1.3.3: 474 | version "1.3.3" 475 | resolved "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz" 476 | integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== 477 | 478 | path-key@^3.1.0: 479 | version "3.1.1" 480 | resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" 481 | integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== 482 | 483 | path-to-regexp@^8.0.0: 484 | version "8.2.0" 485 | resolved "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz" 486 | integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ== 487 | 488 | pkce-challenge@^5.0.0: 489 | version "5.0.0" 490 | resolved "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz" 491 | integrity sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ== 492 | 493 | proxy-addr@^2.0.7: 494 | version "2.0.7" 495 | resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" 496 | integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== 497 | dependencies: 498 | forwarded "0.2.0" 499 | ipaddr.js "1.9.1" 500 | 501 | proxy-from-env@^1.1.0: 502 | version "1.1.0" 503 | resolved "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz" 504 | integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== 505 | 506 | qs@^6.14.0: 507 | version "6.14.0" 508 | resolved "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz" 509 | integrity sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w== 510 | dependencies: 511 | side-channel "^1.1.0" 512 | 513 | range-parser@^1.2.1: 514 | version "1.2.1" 515 | resolved "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz" 516 | integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== 517 | 518 | raw-body@^3.0.0: 519 | version "3.0.0" 520 | resolved "https://registry.npmjs.org/raw-body/-/raw-body-3.0.0.tgz" 521 | integrity sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g== 522 | dependencies: 523 | bytes "3.1.2" 524 | http-errors "2.0.0" 525 | iconv-lite "0.6.3" 526 | unpipe "1.0.0" 527 | 528 | router@^2.2.0: 529 | version "2.2.0" 530 | resolved "https://registry.npmjs.org/router/-/router-2.2.0.tgz" 531 | integrity sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ== 532 | dependencies: 533 | debug "^4.4.0" 534 | depd "^2.0.0" 535 | is-promise "^4.0.0" 536 | parseurl "^1.3.3" 537 | path-to-regexp "^8.0.0" 538 | 539 | safe-buffer@5.2.1: 540 | version "5.2.1" 541 | resolved "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz" 542 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== 543 | 544 | "safer-buffer@>= 2.1.2 < 3.0.0": 545 | version "2.1.2" 546 | resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" 547 | integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== 548 | 549 | send@^1.1.0, send@^1.2.0: 550 | version "1.2.0" 551 | resolved "https://registry.npmjs.org/send/-/send-1.2.0.tgz" 552 | integrity sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw== 553 | dependencies: 554 | debug "^4.3.5" 555 | encodeurl "^2.0.0" 556 | escape-html "^1.0.3" 557 | etag "^1.8.1" 558 | fresh "^2.0.0" 559 | http-errors "^2.0.0" 560 | mime-types "^3.0.1" 561 | ms "^2.1.3" 562 | on-finished "^2.4.1" 563 | range-parser "^1.2.1" 564 | statuses "^2.0.1" 565 | 566 | serve-static@^2.2.0: 567 | version "2.2.0" 568 | resolved "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz" 569 | integrity sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ== 570 | dependencies: 571 | encodeurl "^2.0.0" 572 | escape-html "^1.0.3" 573 | parseurl "^1.3.3" 574 | send "^1.2.0" 575 | 576 | setprototypeof@1.2.0: 577 | version "1.2.0" 578 | resolved "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz" 579 | integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== 580 | 581 | shebang-command@^2.0.0: 582 | version "2.0.0" 583 | resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" 584 | integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== 585 | dependencies: 586 | shebang-regex "^3.0.0" 587 | 588 | shebang-regex@^3.0.0: 589 | version "3.0.0" 590 | resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" 591 | integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== 592 | 593 | side-channel-list@^1.0.0: 594 | version "1.0.0" 595 | resolved "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz" 596 | integrity sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA== 597 | dependencies: 598 | es-errors "^1.3.0" 599 | object-inspect "^1.13.3" 600 | 601 | side-channel-map@^1.0.1: 602 | version "1.0.1" 603 | resolved "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz" 604 | integrity sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA== 605 | dependencies: 606 | call-bound "^1.0.2" 607 | es-errors "^1.3.0" 608 | get-intrinsic "^1.2.5" 609 | object-inspect "^1.13.3" 610 | 611 | side-channel-weakmap@^1.0.2: 612 | version "1.0.2" 613 | resolved "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz" 614 | integrity sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A== 615 | dependencies: 616 | call-bound "^1.0.2" 617 | es-errors "^1.3.0" 618 | get-intrinsic "^1.2.5" 619 | object-inspect "^1.13.3" 620 | side-channel-map "^1.0.1" 621 | 622 | side-channel@^1.1.0: 623 | version "1.1.0" 624 | resolved "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz" 625 | integrity sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw== 626 | dependencies: 627 | es-errors "^1.3.0" 628 | object-inspect "^1.13.3" 629 | side-channel-list "^1.0.0" 630 | side-channel-map "^1.0.1" 631 | side-channel-weakmap "^1.0.2" 632 | 633 | statuses@^2.0.1, statuses@2.0.1: 634 | version "2.0.1" 635 | resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" 636 | integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== 637 | 638 | tldts-core@^6.1.86: 639 | version "6.1.86" 640 | resolved "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz" 641 | integrity sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA== 642 | 643 | tldts@^6.1.32: 644 | version "6.1.86" 645 | resolved "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz" 646 | integrity sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ== 647 | dependencies: 648 | tldts-core "^6.1.86" 649 | 650 | toidentifier@1.0.1: 651 | version "1.0.1" 652 | resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" 653 | integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== 654 | 655 | "tough-cookie@^4.0.0 || ^5.0.0", tough-cookie@>=4.0.0: 656 | version "5.1.2" 657 | resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz" 658 | integrity sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A== 659 | dependencies: 660 | tldts "^6.1.32" 661 | 662 | type-is@^2.0.0, type-is@^2.0.1: 663 | version "2.0.1" 664 | resolved "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz" 665 | integrity sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw== 666 | dependencies: 667 | content-type "^1.0.5" 668 | media-typer "^1.1.0" 669 | mime-types "^3.0.0" 670 | 671 | unpipe@1.0.0: 672 | version "1.0.0" 673 | resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" 674 | integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== 675 | 676 | vary@^1, vary@^1.1.2: 677 | version "1.1.2" 678 | resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" 679 | integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== 680 | 681 | which@^2.0.1: 682 | version "2.0.2" 683 | resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" 684 | integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== 685 | dependencies: 686 | isexe "^2.0.0" 687 | 688 | wrappy@1: 689 | version "1.0.2" 690 | resolved "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz" 691 | integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== 692 | 693 | zod-to-json-schema@^3.24.1: 694 | version "3.24.5" 695 | resolved "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz" 696 | integrity sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g== 697 | 698 | zod@^3.23.8, zod@^3.24.1: 699 | version "3.24.3" 700 | resolved "https://registry.npmjs.org/zod/-/zod-3.24.3.tgz" 701 | integrity sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg== 702 | --------------------------------------------------------------------------------