UNPKG

gc-waybackurls-mcp

Version:

Model Context Protocol (MCP) server for interacting with waybackurls for historical URL discovery

116 lines (115 loc) 4.23 kB
#!/usr/bin/env node "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const mcp_js_1 = require("@modelcontextprotocol/sdk/server/mcp.js"); const stdio_js_1 = require("@modelcontextprotocol/sdk/server/stdio.js"); const zod_1 = require("zod"); const child_process_1 = require("child_process"); // Get waybackurls path from environment variable const waybackurlsPath = process.env.WAYBACKURLS_PATH; if (!waybackurlsPath) { console.error("WAYBACKURLS_PATH environment variable not set"); process.exit(1); } // Utility function to handle string or array input function parseArgs(args) { if (Array.isArray(args)) { return args; } // Handle string input - need to parse respecting quotes const result = []; let current = ''; let inQuote = false; let quoteChar = ''; for (let i = 0; i < args.length; i++) { const char = args[i]; if ((char === '"' || char === "'") && (i === 0 || args[i - 1] !== '\\')) { if (!inQuote) { inQuote = true; quoteChar = char; } else if (char === quoteChar) { inQuote = false; quoteChar = ''; } else { current += char; } } else if (char === ' ' && !inQuote) { if (current) { result.push(current); current = ''; } } else { current += char; } } if (current) { result.push(current); } return result; } // Create server instance const server = new mcp_js_1.McpServer({ name: "waybackurls", version: "1.1.2", }); server.tool("do-waybackurls", "Execute Waybackurls, a tool that fetches known URLs from the Wayback Machine archive for a given domain. This helps in discovering historical endpoints, forgotten API paths, and potentially vulnerable URLs that might not be directly accessible or linked from the current version of the website.", { target: zod_1.z.string().url().describe("Target domain to retrieve historical URLs from the Wayback Machine (e.g., example.com)"), noSub: zod_1.z.boolean().nullable().describe("When set to true, only retrieves URLs from the exact domain specified, excluding all subdomains"), waybackurls_args: zod_1.z.union([ zod_1.z.string().describe("Waybackurls arguments as a string (e.g. '--with-bodies')"), zod_1.z.array(zod_1.z.string()).describe("Waybackurls arguments as an array (e.g. ['--with-bodies'])") ]).optional().describe("Additional waybackurls arguments") }, async ({ target, noSub, waybackurls_args }) => { let args = [target]; if (noSub) { args.push('--no-subs'); } // Add additional arguments if provided if (waybackurls_args) { const parsedArgs = parseArgs(waybackurls_args); args = [...args, ...parsedArgs]; } const waybackurls = (0, child_process_1.spawn)(waybackurlsPath, args); let output = ''; // Handle stdout waybackurls.stdout.on('data', (data) => { output += data.toString(); }); // Handle stderr waybackurls.stderr.on('data', (data) => { output += data.toString(); }); // Handle process completion return new Promise((resolve, reject) => { waybackurls.on('close', (code) => { if (code === 0) { resolve({ content: [{ type: "text", text: `${output}\n waybackurls completed successfully` }] }); } else { reject(new Error(`waybackurls exited with code ${code}`)); } }); waybackurls.on('error', (error) => { reject(new Error(`Failed to start waybackurls: ${error.message}`)); }); }); }); // Start the server async function main() { const transport = new stdio_js_1.StdioServerTransport(); await server.connect(transport); console.error("waybackurls MCP Server running on stdio"); } main().catch((error) => { console.error("Fatal error in main():", error); process.exit(1); });