gc-waybackurls-mcp
Version:
Model Context Protocol (MCP) server for interacting with waybackurls for historical URL discovery
116 lines (115 loc) • 4.23 kB
JavaScript
;
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);
});