mcp-internet-archive 3.3.2 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/bin.js +2 -160
- package/dist/bin.js.map +1 -1
- package/dist/server.d.ts +8 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +181 -0
- package/dist/server.js.map +1 -0
- package/package.json +3 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
## [3.4.0](https://github.com/Mearman/mcp-wayback-machine/compare/v3.3.2...v3.4.0) (2026-05-10)
|
|
2
|
+
|
|
3
|
+
### Features
|
|
4
|
+
|
|
5
|
+
* add integration and E2E test suites, extract server factory for DI ([69030a5](https://github.com/Mearman/mcp-wayback-machine/commit/69030a5047a87e814a6c6abff2ed8fed1690b3df))
|
|
6
|
+
|
|
1
7
|
## [3.3.2](https://github.com/Mearman/mcp-wayback-machine/compare/v3.3.1...v3.3.2) (2026-05-09)
|
|
2
8
|
|
|
3
9
|
### Documentation
|
package/dist/bin.js
CHANGED
|
@@ -1,166 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
-
import {
|
|
5
|
-
import { SaveUrl, saveUrl } from "./tools/save.js";
|
|
6
|
-
import { SearchArchives, searchArchives } from "./tools/search.js";
|
|
7
|
-
import { CheckArchiveStatus, checkArchiveStatus } from "./tools/status.js";
|
|
8
|
-
import { ListScreenshots, listScreenshots } from "./tools/screenshots.js";
|
|
9
|
-
import { ClearCache, clearCache } from "./tools/cache.js";
|
|
10
|
-
import { CompareSnapshots, compareSnapshots } from "./tools/compare.js";
|
|
3
|
+
import { createServer } from "./server.js";
|
|
11
4
|
import { context } from "./contexts.js";
|
|
12
|
-
import pkg from "../package.json" with { type: "json" };
|
|
13
|
-
const VERSION = pkg.version;
|
|
14
|
-
const server = new McpServer({
|
|
15
|
-
name: "mcp-wayback-machine",
|
|
16
|
-
version: VERSION,
|
|
17
|
-
}, {
|
|
18
|
-
capabilities: {
|
|
19
|
-
tools: {},
|
|
20
|
-
},
|
|
21
|
-
instructions: "Interact with the Internet Archive's Wayback Machine to save, retrieve, search, and check the archival status of URLs. " +
|
|
22
|
-
"Supports screenshot retrieval, full CDX search with filtering/pagination, " +
|
|
23
|
-
"and optional authentication for higher SPN2 rate limits.",
|
|
24
|
-
});
|
|
25
|
-
server.registerTool("save_url", {
|
|
26
|
-
description: "Save a URL to the Wayback Machine for archival using the SPN2 API. " +
|
|
27
|
-
"Supports capturing screenshots, outlinks, and conditional archiving. " +
|
|
28
|
-
"Set WAYBACK_ACCESS_KEY and WAYBACK_SECRET_KEY env vars for higher SPN2 rate limits.",
|
|
29
|
-
inputSchema: SaveUrl,
|
|
30
|
-
}, async (args) => {
|
|
31
|
-
const result = await saveUrl(args, context);
|
|
32
|
-
let text = result.message;
|
|
33
|
-
if (result.archivedUrl !== undefined) {
|
|
34
|
-
text += `\n\nArchived URL: ${result.archivedUrl}`;
|
|
35
|
-
}
|
|
36
|
-
if (result.timestamp !== undefined) {
|
|
37
|
-
text += `\nTimestamp: ${result.timestamp}`;
|
|
38
|
-
}
|
|
39
|
-
if (result.jobId !== undefined) {
|
|
40
|
-
text += `\nJob ID: ${result.jobId}`;
|
|
41
|
-
}
|
|
42
|
-
return { content: [{ type: "text", text }] };
|
|
43
|
-
});
|
|
44
|
-
server.registerTool("get_archived_url", {
|
|
45
|
-
description: "Retrieve an archived version of a URL from the Wayback Machine. " +
|
|
46
|
-
"Returns the snapshot content. Supports URL modifiers: " +
|
|
47
|
-
"id_ (raw content), im_ (screenshot image), js_ (JavaScript), cs_ (CSS).",
|
|
48
|
-
inputSchema: GetArchivedUrl,
|
|
49
|
-
}, async (args) => {
|
|
50
|
-
const result = await getArchivedUrl(args, context);
|
|
51
|
-
let text = result.message;
|
|
52
|
-
if (result.archivedUrl !== undefined) {
|
|
53
|
-
text += `\n\nArchived URL: ${result.archivedUrl}`;
|
|
54
|
-
}
|
|
55
|
-
if (result.timestamp !== undefined) {
|
|
56
|
-
text += `\nTimestamp: ${result.timestamp}`;
|
|
57
|
-
}
|
|
58
|
-
if (result.available !== undefined) {
|
|
59
|
-
text += `\nAvailable: ${result.available ? "Yes" : "No"}`;
|
|
60
|
-
}
|
|
61
|
-
if (result.content !== undefined) {
|
|
62
|
-
text += `\n\nContent-Type: ${result.contentType ?? "unknown"}`;
|
|
63
|
-
text += `\n\n${result.content}`;
|
|
64
|
-
}
|
|
65
|
-
return { content: [{ type: "text", text }] };
|
|
66
|
-
});
|
|
67
|
-
server.registerTool("search_archives", {
|
|
68
|
-
description: "Search the Wayback Machine CDX API for archived versions of a URL. " +
|
|
69
|
-
"Supports match types (exact/prefix/host/domain), date range filtering, " +
|
|
70
|
-
"collapsing duplicates, field filtering, pagination, and duplicate counting.",
|
|
71
|
-
inputSchema: SearchArchives,
|
|
72
|
-
}, async (args) => {
|
|
73
|
-
const result = await searchArchives(args, context);
|
|
74
|
-
let text = result.message;
|
|
75
|
-
if (result.results !== undefined && result.results.length > 0) {
|
|
76
|
-
text += "\n\nResults:";
|
|
77
|
-
for (const archive of result.results) {
|
|
78
|
-
text += `\n\n- Date: ${archive.date}`;
|
|
79
|
-
text += `\n URL: ${archive.archivedUrl}`;
|
|
80
|
-
text += `\n Status: ${archive.statusCode}`;
|
|
81
|
-
text += `\n Type: ${archive.mimeType}`;
|
|
82
|
-
if (archive.duplicateCount !== undefined) {
|
|
83
|
-
text += `\n Duplicates: ${String(archive.duplicateCount)}`;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
return { content: [{ type: "text", text }] };
|
|
88
|
-
});
|
|
89
|
-
server.registerTool("check_archive_status", {
|
|
90
|
-
description: "Check if a URL has been archived by the Wayback Machine and get capture " +
|
|
91
|
-
"statistics including yearly breakdowns.",
|
|
92
|
-
inputSchema: CheckArchiveStatus,
|
|
93
|
-
}, async (args) => {
|
|
94
|
-
const result = await checkArchiveStatus(args, context);
|
|
95
|
-
let text = result.message;
|
|
96
|
-
if (result.isArchived) {
|
|
97
|
-
if (result.firstCapture !== undefined) {
|
|
98
|
-
text += `\n\nFirst captured: ${result.firstCapture}`;
|
|
99
|
-
}
|
|
100
|
-
if (result.lastCapture !== undefined) {
|
|
101
|
-
text += `\nLast captured: ${result.lastCapture}`;
|
|
102
|
-
}
|
|
103
|
-
if (result.totalCaptures !== undefined) {
|
|
104
|
-
text += `\nTotal captures: ${String(result.totalCaptures)}`;
|
|
105
|
-
}
|
|
106
|
-
if (result.yearlyCaptures !== undefined &&
|
|
107
|
-
Object.keys(result.yearlyCaptures).length > 0) {
|
|
108
|
-
text += "\n\nCaptures by year:";
|
|
109
|
-
for (const [year, count] of Object.entries(result.yearlyCaptures)) {
|
|
110
|
-
text += `\n ${year}: ${String(count)}`;
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
return { content: [{ type: "text", text }] };
|
|
115
|
-
});
|
|
116
|
-
server.registerTool("list_screenshots", {
|
|
117
|
-
description: "List available screenshots for a URL from the Wayback Machine. " +
|
|
118
|
-
"Screenshots are generated when captures are made with capture_screenshot=1.",
|
|
119
|
-
inputSchema: ListScreenshots,
|
|
120
|
-
}, async (args) => {
|
|
121
|
-
const result = await listScreenshots(args, context);
|
|
122
|
-
let text = result.message;
|
|
123
|
-
if (result.screenshots !== undefined && result.screenshots.length > 0) {
|
|
124
|
-
text += "\n\nScreenshots:";
|
|
125
|
-
for (const screenshot of result.screenshots) {
|
|
126
|
-
text += `\n\n- Date: ${screenshot.date}`;
|
|
127
|
-
text += `\n Screenshot: ${screenshot.screenshotUrl}`;
|
|
128
|
-
text += `\n Original: ${screenshot.originalUrl}`;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return { content: [{ type: "text", text }] };
|
|
132
|
-
});
|
|
133
|
-
server.registerTool("clear_cache", {
|
|
134
|
-
description: "Clear all cached Wayback Machine API responses. " +
|
|
135
|
-
"Use when fresh data is needed or after saving a URL.",
|
|
136
|
-
inputSchema: ClearCache,
|
|
137
|
-
}, async () => {
|
|
138
|
-
const result = await clearCache();
|
|
139
|
-
return { content: [{ type: "text", text: result.message }] };
|
|
140
|
-
});
|
|
141
|
-
server.registerTool("compare_snapshots", {
|
|
142
|
-
description: "Compare two archived snapshots of a URL. " +
|
|
143
|
-
"Fetches the raw content of both snapshots and provides a visual diff URL. " +
|
|
144
|
-
"If no timestamps specified, compares the oldest and newest available snapshots.",
|
|
145
|
-
inputSchema: CompareSnapshots,
|
|
146
|
-
}, async (args) => {
|
|
147
|
-
const result = await compareSnapshots(args, context);
|
|
148
|
-
let text = result.message;
|
|
149
|
-
if (result.snapshotA !== undefined && result.snapshotB !== undefined) {
|
|
150
|
-
text += `\n\nSnapshot A: ${result.snapshotA.date} (${result.snapshotA.timestamp})`;
|
|
151
|
-
text += `\nSnapshot B: ${result.snapshotB.date} (${result.snapshotB.timestamp})`;
|
|
152
|
-
}
|
|
153
|
-
if (result.changesUrl !== undefined) {
|
|
154
|
-
text += `\n\nVisual diff: ${result.changesUrl}`;
|
|
155
|
-
}
|
|
156
|
-
if (result.contentA !== undefined) {
|
|
157
|
-
text += `\n\n--- Snapshot A Content ---\n${result.contentA}`;
|
|
158
|
-
}
|
|
159
|
-
if (result.contentB !== undefined) {
|
|
160
|
-
text += `\n\n--- Snapshot B Content ---\n${result.contentB}`;
|
|
161
|
-
}
|
|
162
|
-
return { content: [{ type: "text", text }] };
|
|
163
|
-
});
|
|
164
5
|
async function main() {
|
|
165
6
|
const isCliMode = process.stdin.isTTY || process.argv.length > 2;
|
|
166
7
|
if (isCliMode && process.argv.length > 2) {
|
|
@@ -169,6 +10,7 @@ async function main() {
|
|
|
169
10
|
await program.parseAsync(process.argv);
|
|
170
11
|
}
|
|
171
12
|
else {
|
|
13
|
+
const server = createServer(context);
|
|
172
14
|
const transport = new StdioServerTransport();
|
|
173
15
|
await server.connect(transport);
|
|
174
16
|
console.error("MCP Wayback Machine server running on stdio");
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAExC,KAAK,UAAU,IAAI;IACf,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;IAEjE,IAAI,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,SAAS,EAAE,CAAC;QAC5B,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,CAAC;SAAM,CAAC;QACJ,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;AACL,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;IAC5B,OAAO,CAAC,KAAK,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;IACrC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server factory — creates a configured McpServer with all tools registered.
|
|
3
|
+
* Accepts a ToolContext so the HTTP boundary can be injected for testing.
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import type { ToolContext } from "./tools/context.ts";
|
|
7
|
+
export declare function createServer(ctx: ToolContext): McpServer;
|
|
8
|
+
//# sourceMappingURL=server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AASpE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAkBtD,wBAAgB,YAAY,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,CA6NxD"}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP server factory — creates a configured McpServer with all tools registered.
|
|
3
|
+
* Accepts a ToolContext so the HTTP boundary can be injected for testing.
|
|
4
|
+
*/
|
|
5
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
|
+
import { GetArchivedUrl, getArchivedUrl } from "./tools/retrieve.js";
|
|
7
|
+
import { SaveUrl, saveUrl } from "./tools/save.js";
|
|
8
|
+
import { SearchArchives, searchArchives } from "./tools/search.js";
|
|
9
|
+
import { CheckArchiveStatus, checkArchiveStatus } from "./tools/status.js";
|
|
10
|
+
import { ListScreenshots, listScreenshots } from "./tools/screenshots.js";
|
|
11
|
+
import { ClearCache, clearCache } from "./tools/cache.js";
|
|
12
|
+
import { CompareSnapshots, compareSnapshots } from "./tools/compare.js";
|
|
13
|
+
import pkg from "../package.json" with { type: "json" };
|
|
14
|
+
const VERSION = pkg.version;
|
|
15
|
+
/**
|
|
16
|
+
* Build an MCP tool result from a tool's { success, message, ... } output.
|
|
17
|
+
* Sets isError: true when success is false so MCP clients can distinguish
|
|
18
|
+
* errors from normal responses.
|
|
19
|
+
*/
|
|
20
|
+
function toolResult(success, text) {
|
|
21
|
+
return {
|
|
22
|
+
content: [{ type: "text", text }],
|
|
23
|
+
...(success ? {} : { isError: true }),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
export function createServer(ctx) {
|
|
27
|
+
const server = new McpServer({
|
|
28
|
+
name: "mcp-wayback-machine",
|
|
29
|
+
version: VERSION,
|
|
30
|
+
}, {
|
|
31
|
+
capabilities: {
|
|
32
|
+
tools: {},
|
|
33
|
+
},
|
|
34
|
+
instructions: "Interact with the Internet Archive's Wayback Machine to save, retrieve, search, and check the archival status of URLs. " +
|
|
35
|
+
"Supports screenshot retrieval, full CDX search with filtering/pagination, " +
|
|
36
|
+
"and optional authentication for higher SPN2 rate limits.",
|
|
37
|
+
});
|
|
38
|
+
server.registerTool("save_url", {
|
|
39
|
+
description: "Save a URL to the Wayback Machine for archival using the SPN2 API. " +
|
|
40
|
+
"Supports capturing screenshots, outlinks, and conditional archiving. " +
|
|
41
|
+
"Set WAYBACK_ACCESS_KEY and WAYBACK_SECRET_KEY env vars for higher SPN2 rate limits.",
|
|
42
|
+
inputSchema: SaveUrl,
|
|
43
|
+
}, async (args) => {
|
|
44
|
+
const result = await saveUrl(args, ctx);
|
|
45
|
+
let text = result.message;
|
|
46
|
+
if (result.archivedUrl !== undefined) {
|
|
47
|
+
text += `\n\nArchived URL: ${result.archivedUrl}`;
|
|
48
|
+
}
|
|
49
|
+
if (result.timestamp !== undefined) {
|
|
50
|
+
text += `\nTimestamp: ${result.timestamp}`;
|
|
51
|
+
}
|
|
52
|
+
if (result.jobId !== undefined) {
|
|
53
|
+
text += `\nJob ID: ${result.jobId}`;
|
|
54
|
+
}
|
|
55
|
+
return toolResult(result.success, text);
|
|
56
|
+
});
|
|
57
|
+
server.registerTool("get_archived_url", {
|
|
58
|
+
description: "Retrieve an archived version of a URL from the Wayback Machine. " +
|
|
59
|
+
"Returns the snapshot content. Supports URL modifiers: " +
|
|
60
|
+
"id_ (raw content), im_ (screenshot image), js_ (JavaScript), cs_ (CSS).",
|
|
61
|
+
inputSchema: GetArchivedUrl,
|
|
62
|
+
}, async (args) => {
|
|
63
|
+
const result = await getArchivedUrl(args, ctx);
|
|
64
|
+
let text = result.message;
|
|
65
|
+
if (result.archivedUrl !== undefined) {
|
|
66
|
+
text += `\n\nArchived URL: ${result.archivedUrl}`;
|
|
67
|
+
}
|
|
68
|
+
if (result.timestamp !== undefined) {
|
|
69
|
+
text += `\nTimestamp: ${result.timestamp}`;
|
|
70
|
+
}
|
|
71
|
+
if (result.available !== undefined) {
|
|
72
|
+
text += `\nAvailable: ${result.available ? "Yes" : "No"}`;
|
|
73
|
+
}
|
|
74
|
+
if (result.content !== undefined) {
|
|
75
|
+
text += `\n\nContent-Type: ${result.contentType ?? "unknown"}`;
|
|
76
|
+
text += `\n\n${result.content}`;
|
|
77
|
+
}
|
|
78
|
+
return toolResult(result.success, text);
|
|
79
|
+
});
|
|
80
|
+
server.registerTool("search_archives", {
|
|
81
|
+
description: "Search the Wayback Machine CDX API for archived versions of a URL. " +
|
|
82
|
+
"Supports match types (exact/prefix/host/domain), date range filtering, " +
|
|
83
|
+
"collapsing duplicates, field filtering, pagination, and duplicate counting.",
|
|
84
|
+
inputSchema: SearchArchives,
|
|
85
|
+
}, async (args) => {
|
|
86
|
+
const result = await searchArchives(args, ctx);
|
|
87
|
+
let text = result.message;
|
|
88
|
+
if (result.results !== undefined && result.results.length > 0) {
|
|
89
|
+
text += "\n\nResults:";
|
|
90
|
+
for (const archive of result.results) {
|
|
91
|
+
text += `\n\n- Date: ${archive.date}`;
|
|
92
|
+
text += `\n URL: ${archive.archivedUrl}`;
|
|
93
|
+
text += `\n Status: ${archive.statusCode}`;
|
|
94
|
+
text += `\n Type: ${archive.mimeType}`;
|
|
95
|
+
if (archive.duplicateCount !== undefined) {
|
|
96
|
+
text += `\n Duplicates: ${String(archive.duplicateCount)}`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return toolResult(result.success, text);
|
|
101
|
+
});
|
|
102
|
+
server.registerTool("check_archive_status", {
|
|
103
|
+
description: "Check if a URL has been archived by the Wayback Machine and get capture " +
|
|
104
|
+
"statistics including yearly breakdowns.",
|
|
105
|
+
inputSchema: CheckArchiveStatus,
|
|
106
|
+
}, async (args) => {
|
|
107
|
+
const result = await checkArchiveStatus(args, ctx);
|
|
108
|
+
let text = result.message;
|
|
109
|
+
if (result.isArchived) {
|
|
110
|
+
if (result.firstCapture !== undefined) {
|
|
111
|
+
text += `\n\nFirst captured: ${result.firstCapture}`;
|
|
112
|
+
}
|
|
113
|
+
if (result.lastCapture !== undefined) {
|
|
114
|
+
text += `\nLast captured: ${result.lastCapture}`;
|
|
115
|
+
}
|
|
116
|
+
if (result.totalCaptures !== undefined) {
|
|
117
|
+
text += `\nTotal captures: ${String(result.totalCaptures)}`;
|
|
118
|
+
}
|
|
119
|
+
if (result.yearlyCaptures !== undefined &&
|
|
120
|
+
Object.keys(result.yearlyCaptures).length > 0) {
|
|
121
|
+
text += "\n\nCaptures by year:";
|
|
122
|
+
for (const [year, count] of Object.entries(result.yearlyCaptures)) {
|
|
123
|
+
text += `\n ${year}: ${String(count)}`;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return toolResult(result.success, text);
|
|
128
|
+
});
|
|
129
|
+
server.registerTool("list_screenshots", {
|
|
130
|
+
description: "List available screenshots for a URL from the Wayback Machine. " +
|
|
131
|
+
"Screenshots are generated when captures are made with capture_screenshot=1.",
|
|
132
|
+
inputSchema: ListScreenshots,
|
|
133
|
+
}, async (args) => {
|
|
134
|
+
const result = await listScreenshots(args, ctx);
|
|
135
|
+
let text = result.message;
|
|
136
|
+
if (result.screenshots !== undefined &&
|
|
137
|
+
result.screenshots.length > 0) {
|
|
138
|
+
text += "\n\nScreenshots:";
|
|
139
|
+
for (const screenshot of result.screenshots) {
|
|
140
|
+
text += `\n\n- Date: ${screenshot.date}`;
|
|
141
|
+
text += `\n Screenshot: ${screenshot.screenshotUrl}`;
|
|
142
|
+
text += `\n Original: ${screenshot.originalUrl}`;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return toolResult(result.success, text);
|
|
146
|
+
});
|
|
147
|
+
server.registerTool("clear_cache", {
|
|
148
|
+
description: "Clear all cached Wayback Machine API responses. " +
|
|
149
|
+
"Use when fresh data is needed or after saving a URL.",
|
|
150
|
+
inputSchema: ClearCache,
|
|
151
|
+
}, async () => {
|
|
152
|
+
const result = await clearCache();
|
|
153
|
+
return toolResult(result.success, result.message);
|
|
154
|
+
});
|
|
155
|
+
server.registerTool("compare_snapshots", {
|
|
156
|
+
description: "Compare two archived snapshots of a URL. " +
|
|
157
|
+
"Fetches the raw content of both snapshots and provides a visual diff URL. " +
|
|
158
|
+
"If no timestamps specified, compares the oldest and newest available snapshots.",
|
|
159
|
+
inputSchema: CompareSnapshots,
|
|
160
|
+
}, async (args) => {
|
|
161
|
+
const result = await compareSnapshots(args, ctx);
|
|
162
|
+
let text = result.message;
|
|
163
|
+
if (result.snapshotA !== undefined &&
|
|
164
|
+
result.snapshotB !== undefined) {
|
|
165
|
+
text += `\n\nSnapshot A: ${result.snapshotA.date} (${result.snapshotA.timestamp})`;
|
|
166
|
+
text += `\nSnapshot B: ${result.snapshotB.date} (${result.snapshotB.timestamp})`;
|
|
167
|
+
}
|
|
168
|
+
if (result.changesUrl !== undefined) {
|
|
169
|
+
text += `\n\nVisual diff: ${result.changesUrl}`;
|
|
170
|
+
}
|
|
171
|
+
if (result.contentA !== undefined) {
|
|
172
|
+
text += `\n\n--- Snapshot A Content ---\n${result.contentA}`;
|
|
173
|
+
}
|
|
174
|
+
if (result.contentB !== undefined) {
|
|
175
|
+
text += `\n\n--- Snapshot B Content ---\n${result.contentB}`;
|
|
176
|
+
}
|
|
177
|
+
return toolResult(result.success, text);
|
|
178
|
+
});
|
|
179
|
+
return server;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEpE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC3E,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGxE,OAAO,GAAG,MAAM,iBAAiB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAExD,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC;AAE5B;;;;GAIG;AACH,SAAS,UAAU,CAAC,OAAgB,EAAE,IAAY;IAC9C,OAAO;QACH,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC;QAC1C,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAa,EAAE,CAAC;KACjD,CAAC;AACN,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAgB;IACzC,MAAM,MAAM,GAAG,IAAI,SAAS,CACxB;QACI,IAAI,EAAE,qBAAqB;QAC3B,OAAO,EAAE,OAAO;KACnB,EACD;QACI,YAAY,EAAE;YACV,KAAK,EAAE,EAAE;SACZ;QACD,YAAY,EACR,yHAAyH;YACzH,4EAA4E;YAC5E,0DAA0D;KACjE,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,UAAU,EACV;QACI,WAAW,EACP,qEAAqE;YACrE,uEAAuE;YACvE,qFAAqF;QACzF,WAAW,EAAE,OAAO;KACvB,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAExC,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,IAAI,qBAAqB,MAAM,CAAC,WAAW,EAAE,CAAC;QACtD,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,IAAI,gBAAgB,MAAM,CAAC,SAAS,EAAE,CAAC;QAC/C,CAAC;QACD,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,IAAI,IAAI,aAAa,MAAM,CAAC,KAAK,EAAE,CAAC;QACxC,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,kBAAkB,EAClB;QACI,WAAW,EACP,kEAAkE;YAClE,wDAAwD;YACxD,yEAAyE;QAC7E,WAAW,EAAE,cAAc;KAC9B,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAE/C,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,IAAI,qBAAqB,MAAM,CAAC,WAAW,EAAE,CAAC;QACtD,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,IAAI,gBAAgB,MAAM,CAAC,SAAS,EAAE,CAAC;QAC/C,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,IAAI,gBAAgB,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9D,CAAC;QACD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAC/B,IAAI,IAAI,qBAAqB,MAAM,CAAC,WAAW,IAAI,SAAS,EAAE,CAAC;YAC/D,IAAI,IAAI,OAAO,MAAM,CAAC,OAAO,EAAE,CAAC;QACpC,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,iBAAiB,EACjB;QACI,WAAW,EACP,qEAAqE;YACrE,yEAAyE;YACzE,6EAA6E;QACjF,WAAW,EAAE,cAAc;KAC9B,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAE/C,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5D,IAAI,IAAI,cAAc,CAAC;YACvB,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnC,IAAI,IAAI,eAAe,OAAO,CAAC,IAAI,EAAE,CAAC;gBACtC,IAAI,IAAI,YAAY,OAAO,CAAC,WAAW,EAAE,CAAC;gBAC1C,IAAI,IAAI,eAAe,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC5C,IAAI,IAAI,aAAa,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACxC,IAAI,OAAO,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;oBACvC,IAAI,IAAI,mBAAmB,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;gBAChE,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,sBAAsB,EACtB;QACI,WAAW,EACP,0EAA0E;YAC1E,yCAAyC;QAC7C,WAAW,EAAE,kBAAkB;KAClC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEnD,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpB,IAAI,MAAM,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;gBACpC,IAAI,IAAI,uBAAuB,MAAM,CAAC,YAAY,EAAE,CAAC;YACzD,CAAC;YACD,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;gBACnC,IAAI,IAAI,oBAAoB,MAAM,CAAC,WAAW,EAAE,CAAC;YACrD,CAAC;YACD,IAAI,MAAM,CAAC,aAAa,KAAK,SAAS,EAAE,CAAC;gBACrC,IAAI,IAAI,qBAAqB,MAAM,CAAC,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC;YAChE,CAAC;YACD,IACI,MAAM,CAAC,cAAc,KAAK,SAAS;gBACnC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC,EAC/C,CAAC;gBACC,IAAI,IAAI,uBAAuB,CAAC;gBAChC,KAAK,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CACtC,MAAM,CAAC,cAAc,CACxB,EAAE,CAAC;oBACA,IAAI,IAAI,OAAO,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC5C,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,kBAAkB,EAClB;QACI,WAAW,EACP,iEAAiE;YACjE,6EAA6E;QACjF,WAAW,EAAE,eAAe;KAC/B,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,MAAM,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEhD,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IACI,MAAM,CAAC,WAAW,KAAK,SAAS;YAChC,MAAM,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,EAC/B,CAAC;YACC,IAAI,IAAI,kBAAkB,CAAC;YAC3B,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,WAAW,EAAE,CAAC;gBAC1C,IAAI,IAAI,eAAe,UAAU,CAAC,IAAI,EAAE,CAAC;gBACzC,IAAI,IAAI,mBAAmB,UAAU,CAAC,aAAa,EAAE,CAAC;gBACtD,IAAI,IAAI,iBAAiB,UAAU,CAAC,WAAW,EAAE,CAAC;YACtD,CAAC;QACL,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,aAAa,EACb;QACI,WAAW,EACP,kDAAkD;YAClD,sDAAsD;QAC1D,WAAW,EAAE,UAAU;KAC1B,EACD,KAAK,IAAI,EAAE;QACP,MAAM,MAAM,GAAG,MAAM,UAAU,EAAE,CAAC;QAClC,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,CAAC;IACtD,CAAC,CACJ,CAAC;IAEF,MAAM,CAAC,YAAY,CACf,mBAAmB,EACnB;QACI,WAAW,EACP,2CAA2C;YAC3C,4EAA4E;YAC5E,iFAAiF;QACrF,WAAW,EAAE,gBAAgB;KAChC,EACD,KAAK,EAAE,IAAI,EAAE,EAAE;QACX,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QAEjD,IAAI,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC;QAC1B,IACI,MAAM,CAAC,SAAS,KAAK,SAAS;YAC9B,MAAM,CAAC,SAAS,KAAK,SAAS,EAChC,CAAC;YACC,IAAI,IAAI,mBAAmB,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC;YACnF,IAAI,IAAI,iBAAiB,MAAM,CAAC,SAAS,CAAC,IAAI,KAAK,MAAM,CAAC,SAAS,CAAC,SAAS,GAAG,CAAC;QACrF,CAAC;QACD,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;YAClC,IAAI,IAAI,oBAAoB,MAAM,CAAC,UAAU,EAAE,CAAC;QACpD,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,IAAI,mCAAmC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACjE,CAAC;QACD,IAAI,MAAM,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;YAChC,IAAI,IAAI,mCAAmC,MAAM,CAAC,QAAQ,EAAE,CAAC;QACjE,CAAC;QAED,OAAO,UAAU,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IAC5C,CAAC,CACJ,CAAC;IAEF,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-internet-archive",
|
|
3
3
|
"mcpName": "io.github.Mearman/mcp-wayback-machine",
|
|
4
|
-
"version": "3.
|
|
4
|
+
"version": "3.4.0",
|
|
5
5
|
"description": "MCP server and CLI tool for interacting with the Wayback Machine without API keys",
|
|
6
6
|
"main": "./dist/bin.js",
|
|
7
7
|
"type": "module",
|
|
@@ -81,12 +81,14 @@
|
|
|
81
81
|
"_lint:fix": "eslint --cache --fix",
|
|
82
82
|
"_test": "node --test 'tests/**/*.unit.test.ts' 'tests/**/*.integration.test.ts'",
|
|
83
83
|
"_test:coverage": "node --test --experimental-test-coverage --test-coverage-lines=80 --test-coverage-branches=80 --test-coverage-functions=80 --test-coverage-include='src/**/*.ts' 'tests/**/*.unit.test.ts' 'tests/**/*.integration.test.ts'",
|
|
84
|
+
"_test:e2e": "node --test 'tests/e2e.test.ts'",
|
|
84
85
|
"_build": "tsc -p tsconfig.build.json && chmod +x dist/bin.js",
|
|
85
86
|
"typecheck": "turbo run _typecheck",
|
|
86
87
|
"lint": "turbo run _lint",
|
|
87
88
|
"lint:fix": "turbo run _lint:fix",
|
|
88
89
|
"test": "turbo run _test",
|
|
89
90
|
"test:coverage": "turbo run _test:coverage",
|
|
91
|
+
"test:e2e": "WAYBACK_LIVE_TESTS=1 turbo run _test:e2e",
|
|
90
92
|
"check": "turbo run _check",
|
|
91
93
|
"validate": "turbo run _validate",
|
|
92
94
|
"release": "semantic-release",
|