UNPKG

mcp-wayback-machine

Version:

MCP server and CLI tool for interacting with the Wayback Machine without API keys

206 lines 7.91 kB
import { Command } from "commander"; import { getArchivedUrl } from "./tools/retrieve.js"; import { saveUrl } from "./tools/save.js"; import { searchArchives } from "./tools/search.js"; import { checkArchiveStatus } from "./tools/status.js"; import { listScreenshots } from "./tools/screenshots.js"; import { compareSnapshots } from "./tools/compare.js"; import { context } from "./contexts.js"; export function createCLI() { const program = new Command(); program .name("wayback") .description("CLI tool for interacting with the Wayback Machine") .version("1.0.0"); // Save URL command program .command("save <url>") .description("Save a URL to the Wayback Machine") .action(async (url) => { try { console.log("Saving URL to Wayback Machine..."); const result = await saveUrl({ url }, context); if (result.success) { console.log("URL saved successfully!"); console.log("Archive URL:", result.archivedUrl); if (result.timestamp) { console.log("Timestamp:", result.timestamp); } if (result.jobId) { console.log("Job ID:", result.jobId); } } else { console.error(result.message); } } catch (error) { console.error("Error saving URL"); console.error(error); } }); // Get archived URL command program .command("get <url>") .description("Get the archived version of a URL") .option("-t, --timestamp <timestamp>", 'Specific timestamp (YYYYMMDDHHMMSS) or "latest"') .action(async (url, options) => { try { console.log("Retrieving archived URL..."); const result = await getArchivedUrl({ url, timestamp: options.timestamp }, context); if (result.success && result.available) { console.log("Archive found!"); console.log("Archived URL:", result.archivedUrl); console.log("Timestamp:", result.timestamp); if (result.content) { console.log("\nContent:"); console.log(result.content); } } else { console.log(result.message); } } catch (error) { console.error("Error retrieving archive"); console.error(error); } }); // Search archives command program .command("search <url>") .description("Search for all archived versions of a URL") .option("-f, --from <date>", "Start date (YYYY-MM-DD)") .option("-t, --to <date>", "End date (YYYY-MM-DD)") .option("-l, --limit <number>", "Maximum number of results", "10") .action(async (url, options) => { try { console.log("Searching archives..."); const result = await searchArchives({ url, from: options.from, to: options.to, limit: Number.parseInt(options.limit, 10), }, context); if (result.success && result.results && result.results.length > 0) { console.log(`Found ${String(result.totalResults)} archives`); console.log("\nArchive snapshots:"); for (const snapshot of result.results) { console.log("─".repeat(60)); console.log("Date:", snapshot.date); console.log("URL:", snapshot.archivedUrl); console.log("Status:", snapshot.statusCode); console.log("Type:", snapshot.mimeType); } } else { console.log(result.message); } } catch (error) { console.error("Error searching archives"); console.error(error); } }); // Check status command program .command("status <url>") .description("Check the archive status of a URL") .action(async (url) => { try { console.log("Checking archive status..."); const result = await checkArchiveStatus({ url }, context); if (result.success) { if (result.isArchived) { console.log("URL is archived!"); console.log("Total captures:", result.totalCaptures); console.log("First capture:", result.firstCapture); console.log("Last capture:", result.lastCapture); if (result.yearlyCaptures) { console.log("\nYearly captures:"); for (const [year, count] of Object.entries(result.yearlyCaptures)) { console.log(`${year}:`, count); } } } else { console.log("URL has not been archived"); } } else { console.error(result.message); } } catch (error) { console.error("Error checking status"); console.error(error); } }); // List screenshots command program .command("screenshots <url>") .description("List available screenshots for a URL") .option("-l, --limit <number>", "Maximum number of results", "10") .action(async (url, options) => { try { console.log("Searching for screenshots..."); const result = await listScreenshots({ url, limit: Number.parseInt(options.limit, 10), }, context); if (result.success && result.screenshots && result.screenshots.length > 0) { console.log(`Found ${String(result.totalScreenshots)} screenshot(s)`); for (const s of result.screenshots) { console.log("─".repeat(60)); console.log("Date:", s.date); console.log("Screenshot:", s.screenshotUrl); } } else { console.log(result.message); } } catch (error) { console.error("Error listing screenshots"); console.error(error); } }); // Compare snapshots command program .command("compare <url>") .description("Compare two archived snapshots of a URL") .option("-a, --timestamp-a <timestamp>", "First timestamp (YYYYMMDDhhmmss)") .option("-b, --timestamp-b <timestamp>", "Second timestamp (YYYYMMDDhhmmss)") .action(async (url, options) => { try { console.log("Comparing snapshots..."); const result = await compareSnapshots({ url, timestampA: options.timestampA, timestampB: options.timestampB, }, context); if (result.success) { if (result.snapshotA && result.snapshotB) { console.log(`Snapshot A: ${result.snapshotA.date} (${result.snapshotA.timestamp})`); console.log(`Snapshot B: ${result.snapshotB.date} (${result.snapshotB.timestamp})`); } if (result.changesUrl) { console.log(`\nVisual diff: ${result.changesUrl}`); } } else { console.error(result.message); } } catch (error) { console.error("Error comparing snapshots"); console.error(error); } }); return program; } //# sourceMappingURL=cli.js.map