@forkpoint/agent-lighthouse-mcp 0.2.4 → 0.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/dist/index.js +1 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -2
- package/dist/index.mjs.map +1 -1
- package/dist/server.js +39 -2
- package/dist/server.js.map +1 -1
- package/dist/server.mjs +39 -2
- package/dist/server.mjs.map +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -26,8 +26,7 @@ module.exports = __toCommonJS(src_exports);
|
|
|
26
26
|
var import_agent_lighthouse_core = require("@forkpoint/agent-lighthouse-core");
|
|
27
27
|
var import_agent_lighthouse_report = require("@forkpoint/agent-lighthouse-report");
|
|
28
28
|
async function auditWebsite(url) {
|
|
29
|
-
const report = await (0, import_agent_lighthouse_core.runScan)(url
|
|
30
|
-
});
|
|
29
|
+
const report = await (0, import_agent_lighthouse_core.runScan)(url);
|
|
31
30
|
const view = (0, import_agent_lighthouse_report.buildReportView)(report);
|
|
32
31
|
return {
|
|
33
32
|
url: report.url,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\n\n/**\n * Programmatic helper functions powering the Agent Lighthouse MCP server and custom agent tools.\n */\nexport async function auditWebsite(url: string) {\n const report = await runScan(url
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\n\n/**\n * Programmatic helper functions powering the Agent Lighthouse MCP server and custom agent tools.\n */\nexport async function auditWebsite(url: string) {\n const report = await runScan(url);\n const view = buildReportView(report);\n \n return {\n url: report.url,\n overallScore: view.overallScore,\n scoreTier: view.scoreTier,\n durationMs: view.durationMs,\n categories: view.groups.flatMap(g => g.categories.map(c => ({\n name: c.name,\n score: c.score,\n pass: c.counts.pass,\n warn: c.counts.warn,\n fail: c.counts.fail,\n }))),\n topFails: report.topFails.map(f => ({\n id: f.id,\n title: f.title,\n priority: f.priority,\n impact: f.impact,\n fix: f.fix,\n })),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mCAAwB;AACxB,qCAAgC;AAKhC,eAAsB,aAAa,KAAa;AAC9C,QAAM,SAAS,UAAM,sCAAQ,GAAG;AAChC,QAAM,WAAO,gDAAgB,MAAM;AAEnC,SAAO;AAAA,IACL,KAAK,OAAO;AAAA,IACZ,cAAc,KAAK;AAAA,IACnB,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,YAAY,KAAK,OAAO,QAAQ,OAAK,EAAE,WAAW,IAAI,QAAM;AAAA,MAC1D,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,MACT,MAAM,EAAE,OAAO;AAAA,MACf,MAAM,EAAE,OAAO;AAAA,MACf,MAAM,EAAE,OAAO;AAAA,IACjB,EAAE,CAAC;AAAA,IACH,UAAU,OAAO,SAAS,IAAI,QAAM;AAAA,MAClC,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,UAAU,EAAE;AAAA,MACZ,QAAQ,EAAE;AAAA,MACV,KAAK,EAAE;AAAA,IACT,EAAE;AAAA,EACJ;AACF;","names":[]}
|
package/dist/index.mjs
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
import { runScan } from "@forkpoint/agent-lighthouse-core";
|
|
3
3
|
import { buildReportView } from "@forkpoint/agent-lighthouse-report";
|
|
4
4
|
async function auditWebsite(url) {
|
|
5
|
-
const report = await runScan(url
|
|
6
|
-
});
|
|
5
|
+
const report = await runScan(url);
|
|
7
6
|
const view = buildReportView(report);
|
|
8
7
|
return {
|
|
9
8
|
url: report.url,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\n\n/**\n * Programmatic helper functions powering the Agent Lighthouse MCP server and custom agent tools.\n */\nexport async function auditWebsite(url: string) {\n const report = await runScan(url
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\n\n/**\n * Programmatic helper functions powering the Agent Lighthouse MCP server and custom agent tools.\n */\nexport async function auditWebsite(url: string) {\n const report = await runScan(url);\n const view = buildReportView(report);\n \n return {\n url: report.url,\n overallScore: view.overallScore,\n scoreTier: view.scoreTier,\n durationMs: view.durationMs,\n categories: view.groups.flatMap(g => g.categories.map(c => ({\n name: c.name,\n score: c.score,\n pass: c.counts.pass,\n warn: c.counts.warn,\n fail: c.counts.fail,\n }))),\n topFails: report.topFails.map(f => ({\n id: f.id,\n title: f.title,\n priority: f.priority,\n impact: f.impact,\n fix: f.fix,\n })),\n };\n}\n"],"mappings":";AAAA,SAAS,eAAe;AACxB,SAAS,uBAAuB;AAKhC,eAAsB,aAAa,KAAa;AAC9C,QAAM,SAAS,MAAM,QAAQ,GAAG;AAChC,QAAM,OAAO,gBAAgB,MAAM;AAEnC,SAAO;AAAA,IACL,KAAK,OAAO;AAAA,IACZ,cAAc,KAAK;AAAA,IACnB,WAAW,KAAK;AAAA,IAChB,YAAY,KAAK;AAAA,IACjB,YAAY,KAAK,OAAO,QAAQ,OAAK,EAAE,WAAW,IAAI,QAAM;AAAA,MAC1D,MAAM,EAAE;AAAA,MACR,OAAO,EAAE;AAAA,MACT,MAAM,EAAE,OAAO;AAAA,MACf,MAAM,EAAE,OAAO;AAAA,MACf,MAAM,EAAE,OAAO;AAAA,IACjB,EAAE,CAAC;AAAA,IACH,UAAU,OAAO,SAAS,IAAI,QAAM;AAAA,MAClC,IAAI,EAAE;AAAA,MACN,OAAO,EAAE;AAAA,MACT,UAAU,EAAE;AAAA,MACZ,QAAQ,EAAE;AAAA,MACV,KAAK,EAAE;AAAA,IACT,EAAE;AAAA,EACJ;AACF;","names":[]}
|
package/dist/server.js
CHANGED
|
@@ -6,7 +6,37 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
6
6
|
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
7
7
|
var import_agent_lighthouse_core = require("@forkpoint/agent-lighthouse-core");
|
|
8
8
|
var import_agent_lighthouse_report = require("@forkpoint/agent-lighthouse-report");
|
|
9
|
-
|
|
9
|
+
|
|
10
|
+
// src/progress.ts
|
|
11
|
+
function createProgressNotifier(progressToken, notify, options = {}) {
|
|
12
|
+
if (progressToken === void 0) return void 0;
|
|
13
|
+
const minInterval = options.minIntervalMs ?? 1e3;
|
|
14
|
+
const now = options.now ?? (() => Date.now());
|
|
15
|
+
let lastSent = Number.NEGATIVE_INFINITY;
|
|
16
|
+
const send = (fraction, force) => {
|
|
17
|
+
const t = now();
|
|
18
|
+
if (!force && t - lastSent < minInterval) return;
|
|
19
|
+
lastSent = t;
|
|
20
|
+
notify({ progressToken, progress: fraction, total: 1 });
|
|
21
|
+
};
|
|
22
|
+
return (event) => {
|
|
23
|
+
switch (event.type) {
|
|
24
|
+
case "unit:done":
|
|
25
|
+
case "phase:start":
|
|
26
|
+
case "phase:done":
|
|
27
|
+
send(event.fraction, false);
|
|
28
|
+
break;
|
|
29
|
+
case "scan:done":
|
|
30
|
+
send(event.fraction, true);
|
|
31
|
+
break;
|
|
32
|
+
default:
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// src/server.ts
|
|
39
|
+
var MCP_SERVER_VERSION = true ? "0.4.0" : "unknown";
|
|
10
40
|
var server = new import_server.Server(
|
|
11
41
|
{
|
|
12
42
|
name: "agent-lighthouse-mcp",
|
|
@@ -44,7 +74,14 @@ server.setRequestHandler(import_types.CallToolRequestSchema, async (request) =>
|
|
|
44
74
|
if (!url) {
|
|
45
75
|
throw new Error("Missing target URL");
|
|
46
76
|
}
|
|
47
|
-
const
|
|
77
|
+
const onEvent = createProgressNotifier(
|
|
78
|
+
request.params._meta?.progressToken,
|
|
79
|
+
(params) => {
|
|
80
|
+
void server.notification({ method: "notifications/progress", params }).catch(() => {
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
const report = await (0, import_agent_lighthouse_core.runScan)(url, { onEvent });
|
|
48
85
|
const view = (0, import_agent_lighthouse_report.buildReportView)(report);
|
|
49
86
|
const summary = {
|
|
50
87
|
url: report.url,
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\n\ndeclare const __PACKAGE_VERSION__: string;\n\nconst MCP_SERVER_VERSION = typeof __PACKAGE_VERSION__ === 'string' ? __PACKAGE_VERSION__ : 'unknown';\n\nconst server = new Server(\n {\n name: 'agent-lighthouse-mcp',\n version: MCP_SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// Register Available Tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'audit_website',\n description:\n 'Audit a website or storefront for Agentic Readiness (WebMCP, OpenAPI, JSON-LD, robots.txt, and answer engines). Returns overall score, category breakdown, and actionable fix recommendations.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The target website or storefront URL to audit (e.g. https://example.com)',\n },\n },\n required: ['url'],\n },\n },\n ],\n };\n});\n\n// Handle Tool Execution\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (request.params.name === 'audit_website') {\n const url = String(request.params.arguments?.url);\n if (!url) {\n throw new Error('Missing target URL');\n }\n\n const report = await runScan(url);\n const view = buildReportView(report);\n\n const summary = {\n url: report.url,\n overallScore: view.overallScore,\n scoreTier: view.scoreTier,\n durationSeconds: (view.durationMs / 1000).toFixed(1),\n vitals: view.vitals,\n categories: view.groups.flatMap((g) =>\n g.categories.map((c) => ({\n name: c.name,\n score: c.score,\n passCount: c.counts.pass,\n warnCount: c.counts.warn,\n failCount: c.counts.fail,\n }))\n ),\n topOpportunities: report.topFails.slice(0, 10).map((f) => ({\n id: f.id,\n title: f.title,\n priority: f.priority,\n impact: f.impact,\n fix: f.fix,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(summary, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown tool: ${request.params.name}`);\n});\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error('Fatal MCP server error:', err);\n process.exit(1);\n});\n"],"mappings":";;;AAAA,oBAAuB;AACvB,mBAAqC;AACrC,mBAGO;AACP,mCAAwB;AACxB,qCAAgC;
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/progress.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\nimport { createProgressNotifier } from './progress';\n\ndeclare const __PACKAGE_VERSION__: string;\n\nconst MCP_SERVER_VERSION = typeof __PACKAGE_VERSION__ === 'string' ? __PACKAGE_VERSION__ : 'unknown';\n\nconst server = new Server(\n {\n name: 'agent-lighthouse-mcp',\n version: MCP_SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// Register Available Tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'audit_website',\n description:\n 'Audit a website or storefront for Agentic Readiness (WebMCP, OpenAPI, JSON-LD, robots.txt, and answer engines). Returns overall score, category breakdown, and actionable fix recommendations.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The target website or storefront URL to audit (e.g. https://example.com)',\n },\n },\n required: ['url'],\n },\n },\n ],\n };\n});\n\n// Handle Tool Execution\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (request.params.name === 'audit_website') {\n const url = String(request.params.arguments?.url);\n if (!url) {\n throw new Error('Missing target URL');\n }\n\n // Forward scan progress as notifications/progress when the client\n // supplied a progressToken; otherwise scan silently as before.\n const onEvent = createProgressNotifier(\n request.params._meta?.progressToken,\n (params) => {\n // Fire-and-forget, but swallow rejections (e.g. client disconnected\n // mid-scan) so they never surface as unhandled.\n void server.notification({ method: 'notifications/progress', params }).catch(() => {});\n },\n );\n\n const report = await runScan(url, { onEvent });\n const view = buildReportView(report);\n\n const summary = {\n url: report.url,\n overallScore: view.overallScore,\n scoreTier: view.scoreTier,\n durationSeconds: (view.durationMs / 1000).toFixed(1),\n vitals: view.vitals,\n categories: view.groups.flatMap((g) =>\n g.categories.map((c) => ({\n name: c.name,\n score: c.score,\n passCount: c.counts.pass,\n warnCount: c.counts.warn,\n failCount: c.counts.fail,\n }))\n ),\n topOpportunities: report.topFails.slice(0, 10).map((f) => ({\n id: f.id,\n title: f.title,\n priority: f.priority,\n impact: f.impact,\n fix: f.fix,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(summary, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown tool: ${request.params.name}`);\n});\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error('Fatal MCP server error:', err);\n process.exit(1);\n});\n","import type { ScanEvent } from '@forkpoint/agent-lighthouse-core';\n\nexport interface ProgressNotification {\n progressToken: string | number;\n progress: number;\n total: number;\n}\n\nexport interface ProgressNotifierOptions {\n /** Minimum milliseconds between notifications. Default 1000 (~1/sec). */\n minIntervalMs?: number;\n now?: () => number;\n}\n\n/**\n * Builds a runScan `onEvent` handler that forwards scan progress as MCP\n * `notifications/progress` params, throttled to ~1/sec. The final 1.0 is\n * always sent. Returns undefined when the request carried no progressToken,\n * so callers can pass the result straight into `runScan(url, { onEvent })`.\n */\nexport function createProgressNotifier(\n progressToken: string | number | undefined,\n notify: (notification: ProgressNotification) => void,\n options: ProgressNotifierOptions = {},\n): ((event: ScanEvent) => void) | undefined {\n if (progressToken === undefined) return undefined;\n const minInterval = options.minIntervalMs ?? 1000;\n const now = options.now ?? (() => Date.now());\n let lastSent = Number.NEGATIVE_INFINITY;\n\n const send = (fraction: number, force: boolean) => {\n const t = now();\n if (!force && t - lastSent < minInterval) return;\n lastSent = t;\n notify({ progressToken, progress: fraction, total: 1 });\n };\n\n return (event) => {\n switch (event.type) {\n case 'unit:done':\n case 'phase:start':\n case 'phase:done':\n send(event.fraction, false);\n break;\n case 'scan:done':\n send(event.fraction, true);\n break;\n default:\n break;\n }\n };\n}\n"],"mappings":"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","names":[]}
|
package/dist/server.mjs
CHANGED
|
@@ -7,7 +7,37 @@ import {
|
|
|
7
7
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
8
8
|
import { runScan } from "@forkpoint/agent-lighthouse-core";
|
|
9
9
|
import { buildReportView } from "@forkpoint/agent-lighthouse-report";
|
|
10
|
-
|
|
10
|
+
|
|
11
|
+
// src/progress.ts
|
|
12
|
+
function createProgressNotifier(progressToken, notify, options = {}) {
|
|
13
|
+
if (progressToken === void 0) return void 0;
|
|
14
|
+
const minInterval = options.minIntervalMs ?? 1e3;
|
|
15
|
+
const now = options.now ?? (() => Date.now());
|
|
16
|
+
let lastSent = Number.NEGATIVE_INFINITY;
|
|
17
|
+
const send = (fraction, force) => {
|
|
18
|
+
const t = now();
|
|
19
|
+
if (!force && t - lastSent < minInterval) return;
|
|
20
|
+
lastSent = t;
|
|
21
|
+
notify({ progressToken, progress: fraction, total: 1 });
|
|
22
|
+
};
|
|
23
|
+
return (event) => {
|
|
24
|
+
switch (event.type) {
|
|
25
|
+
case "unit:done":
|
|
26
|
+
case "phase:start":
|
|
27
|
+
case "phase:done":
|
|
28
|
+
send(event.fraction, false);
|
|
29
|
+
break;
|
|
30
|
+
case "scan:done":
|
|
31
|
+
send(event.fraction, true);
|
|
32
|
+
break;
|
|
33
|
+
default:
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// src/server.ts
|
|
40
|
+
var MCP_SERVER_VERSION = true ? "0.4.0" : "unknown";
|
|
11
41
|
var server = new Server(
|
|
12
42
|
{
|
|
13
43
|
name: "agent-lighthouse-mcp",
|
|
@@ -45,7 +75,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
45
75
|
if (!url) {
|
|
46
76
|
throw new Error("Missing target URL");
|
|
47
77
|
}
|
|
48
|
-
const
|
|
78
|
+
const onEvent = createProgressNotifier(
|
|
79
|
+
request.params._meta?.progressToken,
|
|
80
|
+
(params) => {
|
|
81
|
+
void server.notification({ method: "notifications/progress", params }).catch(() => {
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
const report = await runScan(url, { onEvent });
|
|
49
86
|
const view = buildReportView(report);
|
|
50
87
|
const summary = {
|
|
51
88
|
url: report.url,
|
package/dist/server.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/server.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\n\ndeclare const __PACKAGE_VERSION__: string;\n\nconst MCP_SERVER_VERSION = typeof __PACKAGE_VERSION__ === 'string' ? __PACKAGE_VERSION__ : 'unknown';\n\nconst server = new Server(\n {\n name: 'agent-lighthouse-mcp',\n version: MCP_SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// Register Available Tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'audit_website',\n description:\n 'Audit a website or storefront for Agentic Readiness (WebMCP, OpenAPI, JSON-LD, robots.txt, and answer engines). Returns overall score, category breakdown, and actionable fix recommendations.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The target website or storefront URL to audit (e.g. https://example.com)',\n },\n },\n required: ['url'],\n },\n },\n ],\n };\n});\n\n// Handle Tool Execution\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (request.params.name === 'audit_website') {\n const url = String(request.params.arguments?.url);\n if (!url) {\n throw new Error('Missing target URL');\n }\n\n const report = await runScan(url);\n const view = buildReportView(report);\n\n const summary = {\n url: report.url,\n overallScore: view.overallScore,\n scoreTier: view.scoreTier,\n durationSeconds: (view.durationMs / 1000).toFixed(1),\n vitals: view.vitals,\n categories: view.groups.flatMap((g) =>\n g.categories.map((c) => ({\n name: c.name,\n score: c.score,\n passCount: c.counts.pass,\n warnCount: c.counts.warn,\n failCount: c.counts.fail,\n }))\n ),\n topOpportunities: report.topFails.slice(0, 10).map((f) => ({\n id: f.id,\n title: f.title,\n priority: f.priority,\n impact: f.impact,\n fix: f.fix,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(summary, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown tool: ${request.params.name}`);\n});\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error('Fatal MCP server error:', err);\n process.exit(1);\n});\n"],"mappings":";AAAA,SAAS,cAAc;AACvB,SAAS,4BAA4B;AACrC;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,uBAAuB;
|
|
1
|
+
{"version":3,"sources":["../src/server.ts","../src/progress.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from '@modelcontextprotocol/sdk/types.js';\nimport { runScan } from '@forkpoint/agent-lighthouse-core';\nimport { buildReportView } from '@forkpoint/agent-lighthouse-report';\nimport { createProgressNotifier } from './progress';\n\ndeclare const __PACKAGE_VERSION__: string;\n\nconst MCP_SERVER_VERSION = typeof __PACKAGE_VERSION__ === 'string' ? __PACKAGE_VERSION__ : 'unknown';\n\nconst server = new Server(\n {\n name: 'agent-lighthouse-mcp',\n version: MCP_SERVER_VERSION,\n },\n {\n capabilities: {\n tools: {},\n },\n }\n);\n\n// Register Available Tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: 'audit_website',\n description:\n 'Audit a website or storefront for Agentic Readiness (WebMCP, OpenAPI, JSON-LD, robots.txt, and answer engines). Returns overall score, category breakdown, and actionable fix recommendations.',\n inputSchema: {\n type: 'object',\n properties: {\n url: {\n type: 'string',\n description: 'The target website or storefront URL to audit (e.g. https://example.com)',\n },\n },\n required: ['url'],\n },\n },\n ],\n };\n});\n\n// Handle Tool Execution\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n if (request.params.name === 'audit_website') {\n const url = String(request.params.arguments?.url);\n if (!url) {\n throw new Error('Missing target URL');\n }\n\n // Forward scan progress as notifications/progress when the client\n // supplied a progressToken; otherwise scan silently as before.\n const onEvent = createProgressNotifier(\n request.params._meta?.progressToken,\n (params) => {\n // Fire-and-forget, but swallow rejections (e.g. client disconnected\n // mid-scan) so they never surface as unhandled.\n void server.notification({ method: 'notifications/progress', params }).catch(() => {});\n },\n );\n\n const report = await runScan(url, { onEvent });\n const view = buildReportView(report);\n\n const summary = {\n url: report.url,\n overallScore: view.overallScore,\n scoreTier: view.scoreTier,\n durationSeconds: (view.durationMs / 1000).toFixed(1),\n vitals: view.vitals,\n categories: view.groups.flatMap((g) =>\n g.categories.map((c) => ({\n name: c.name,\n score: c.score,\n passCount: c.counts.pass,\n warnCount: c.counts.warn,\n failCount: c.counts.fail,\n }))\n ),\n topOpportunities: report.topFails.slice(0, 10).map((f) => ({\n id: f.id,\n title: f.title,\n priority: f.priority,\n impact: f.impact,\n fix: f.fix,\n })),\n };\n\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(summary, null, 2),\n },\n ],\n };\n }\n\n throw new Error(`Unknown tool: ${request.params.name}`);\n});\n\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n\nmain().catch((err) => {\n console.error('Fatal MCP server error:', err);\n process.exit(1);\n});\n","import type { ScanEvent } from '@forkpoint/agent-lighthouse-core';\n\nexport interface ProgressNotification {\n progressToken: string | number;\n progress: number;\n total: number;\n}\n\nexport interface ProgressNotifierOptions {\n /** Minimum milliseconds between notifications. Default 1000 (~1/sec). */\n minIntervalMs?: number;\n now?: () => number;\n}\n\n/**\n * Builds a runScan `onEvent` handler that forwards scan progress as MCP\n * `notifications/progress` params, throttled to ~1/sec. The final 1.0 is\n * always sent. Returns undefined when the request carried no progressToken,\n * so callers can pass the result straight into `runScan(url, { onEvent })`.\n */\nexport function createProgressNotifier(\n progressToken: string | number | undefined,\n notify: (notification: ProgressNotification) => void,\n options: ProgressNotifierOptions = {},\n): ((event: ScanEvent) => void) | undefined {\n if (progressToken === undefined) return undefined;\n const minInterval = options.minIntervalMs ?? 1000;\n const now = options.now ?? (() => Date.now());\n let lastSent = Number.NEGATIVE_INFINITY;\n\n const send = (fraction: number, force: boolean) => {\n const t = now();\n if (!force && t - lastSent < minInterval) return;\n lastSent = t;\n notify({ progressToken, progress: fraction, total: 1 });\n };\n\n return (event) => {\n switch (event.type) {\n case 'unit:done':\n case 'phase:start':\n case 'phase:done':\n send(event.fraction, false);\n break;\n case 'scan:done':\n send(event.fraction, true);\n break;\n default:\n break;\n }\n };\n}\n"],"mappings":"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","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forkpoint/agent-lighthouse-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Model Context Protocol (MCP) server that lets Claude, Cursor, and agentic IDEs audit website AI-agent readiness with Agent Lighthouse",
|
|
5
5
|
"author": "ForkPoint",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -47,8 +47,8 @@
|
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
49
|
"@modelcontextprotocol/sdk": "^1.5.0",
|
|
50
|
-
"@forkpoint/agent-lighthouse-core": "0.
|
|
51
|
-
"@forkpoint/agent-lighthouse-report": "0.
|
|
50
|
+
"@forkpoint/agent-lighthouse-core": "0.4.0",
|
|
51
|
+
"@forkpoint/agent-lighthouse-report": "0.4.0"
|
|
52
52
|
},
|
|
53
53
|
"devDependencies": {
|
|
54
54
|
"@types/node": "^22.10.5",
|