agent-ready-mcp 0.5.4 → 0.6.1
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/mcp-server.mjs +83 -4
- package/package.json +1 -1
package/dist/mcp-server.mjs
CHANGED
|
@@ -23093,6 +23093,55 @@ async function call(config2, opts) {
|
|
|
23093
23093
|
}
|
|
23094
23094
|
return payload;
|
|
23095
23095
|
}
|
|
23096
|
+
async function postAnonScan(config2, url2) {
|
|
23097
|
+
const path = "/api/scan";
|
|
23098
|
+
let res;
|
|
23099
|
+
try {
|
|
23100
|
+
res = await fetch(`${config2.baseUrl}${path}`, {
|
|
23101
|
+
method: "POST",
|
|
23102
|
+
headers: {
|
|
23103
|
+
"Content-Type": "application/json",
|
|
23104
|
+
Accept: "application/json",
|
|
23105
|
+
// Funnel attribution: /api/scan is shared with the web app, so without
|
|
23106
|
+
// this header keyless npm-MCP scans are recorded as source=`web`. The
|
|
23107
|
+
// server tags them `mcp-npm` (distinct from `mcp`, the hosted keyed
|
|
23108
|
+
// endpoint). Read only on /api/scan; ignored elsewhere.
|
|
23109
|
+
"X-Agent-Ready-Client": "mcp-npm"
|
|
23110
|
+
},
|
|
23111
|
+
body: JSON.stringify({ url: url2 }),
|
|
23112
|
+
signal: AbortSignal.timeout(config2.scanTimeoutMs)
|
|
23113
|
+
});
|
|
23114
|
+
} catch (err) {
|
|
23115
|
+
if (err instanceof Error && err.name === "TimeoutError") {
|
|
23116
|
+
throw new ApiError(
|
|
23117
|
+
"timeout",
|
|
23118
|
+
`Request to ${path} timed out after ${config2.scanTimeoutMs}ms.`
|
|
23119
|
+
);
|
|
23120
|
+
}
|
|
23121
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
23122
|
+
throw new ApiError("network_error", `Network error calling ${path}: ${message}`);
|
|
23123
|
+
}
|
|
23124
|
+
const text = await res.text();
|
|
23125
|
+
let payload = null;
|
|
23126
|
+
if (text.length > 0) {
|
|
23127
|
+
try {
|
|
23128
|
+
payload = JSON.parse(text);
|
|
23129
|
+
} catch {
|
|
23130
|
+
}
|
|
23131
|
+
}
|
|
23132
|
+
if (!res.ok) {
|
|
23133
|
+
const body = payload && typeof payload === "object" ? payload : null;
|
|
23134
|
+
let message = typeof body?.error === "string" && body.error ? body.error : text || `HTTP ${res.status} from ${path}`;
|
|
23135
|
+
if (res.status === 429) {
|
|
23136
|
+
if (typeof body?.resetAt === "string") {
|
|
23137
|
+
message += ` Quota resets ${body.resetAt.slice(0, 10)}.`;
|
|
23138
|
+
}
|
|
23139
|
+
throw new ApiError("quota_exhausted", message, res.status);
|
|
23140
|
+
}
|
|
23141
|
+
throw new ApiError(`http_${res.status}`, message, res.status);
|
|
23142
|
+
}
|
|
23143
|
+
return payload;
|
|
23144
|
+
}
|
|
23096
23145
|
async function postScan(config2, body) {
|
|
23097
23146
|
return call(config2, {
|
|
23098
23147
|
method: "POST",
|
|
@@ -31531,7 +31580,31 @@ var POLL_INTERVAL_MS = 2e3;
|
|
|
31531
31580
|
async function sleep(ms) {
|
|
31532
31581
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
31533
31582
|
}
|
|
31583
|
+
var ANON_TIER_NOTE = "Scanned on the anonymous free tier (3 scans per 30 days per IP, 25-page depth). A Pro API key (AGENT_READY_API_KEY) unlocks 50 scans/month, 250-page depth, scan history via get_scan, and weekly monitoring \u2014 https://agent-ready.dev/pricing";
|
|
31534
31584
|
async function scanSite(config2, input) {
|
|
31585
|
+
if (!config2.apiKey) {
|
|
31586
|
+
let res;
|
|
31587
|
+
try {
|
|
31588
|
+
res = await postAnonScan(config2, input.url);
|
|
31589
|
+
} catch (err) {
|
|
31590
|
+
if (err instanceof ApiError) {
|
|
31591
|
+
const hint = err.status === 429 ? " Set a Pro API key (AGENT_READY_API_KEY, from https://agent-ready.dev/dashboard/api-keys) to remove the anonymous cap." : "";
|
|
31592
|
+
throw new ToolError(err.code, err.message + hint);
|
|
31593
|
+
}
|
|
31594
|
+
throw err;
|
|
31595
|
+
}
|
|
31596
|
+
if (!res || typeof res !== "object" || !res.scan) {
|
|
31597
|
+
throw new ToolError(
|
|
31598
|
+
"invalid_response",
|
|
31599
|
+
"Anonymous scan returned no scan payload from /api/scan."
|
|
31600
|
+
);
|
|
31601
|
+
}
|
|
31602
|
+
const payload = { ...res.scan, message: ANON_TIER_NOTE };
|
|
31603
|
+
return {
|
|
31604
|
+
content: [{ type: "text", text: JSON.stringify(payload) }],
|
|
31605
|
+
structuredContent: payload
|
|
31606
|
+
};
|
|
31607
|
+
}
|
|
31535
31608
|
let placeholder;
|
|
31536
31609
|
try {
|
|
31537
31610
|
placeholder = await postScan(config2, {
|
|
@@ -31605,6 +31678,12 @@ async function getScanById(config2, input) {
|
|
|
31605
31678
|
if (err.status === 404) {
|
|
31606
31679
|
throw new ToolError("not_found", `Scan ${input.id} not found.`);
|
|
31607
31680
|
}
|
|
31681
|
+
if (err.code === "missing_api_key") {
|
|
31682
|
+
throw new ToolError(
|
|
31683
|
+
"missing_api_key",
|
|
31684
|
+
"get_scan needs a Pro API key (scan history is account-scoped). scan_site works without one on the anonymous tier and returns its result inline. Keys: https://agent-ready.dev/dashboard/api-keys"
|
|
31685
|
+
);
|
|
31686
|
+
}
|
|
31608
31687
|
throw new ToolError(err.code, err.message);
|
|
31609
31688
|
}
|
|
31610
31689
|
throw err;
|
|
@@ -31754,7 +31833,7 @@ var validateStructuredDataInputShape = {
|
|
|
31754
31833
|
// src/server.ts
|
|
31755
31834
|
var SERVER_INFO = {
|
|
31756
31835
|
name: "agent-ready",
|
|
31757
|
-
version: "0.
|
|
31836
|
+
version: "0.6.1"
|
|
31758
31837
|
};
|
|
31759
31838
|
function createMcpServer(config2) {
|
|
31760
31839
|
const server = new McpServer(SERVER_INFO);
|
|
@@ -31768,7 +31847,7 @@ function createMcpServer(config2) {
|
|
|
31768
31847
|
"scan_site",
|
|
31769
31848
|
{
|
|
31770
31849
|
title: "Scan a site for AI agent readability",
|
|
31771
|
-
description: "Runs the agent-ready.dev scanner against a URL and returns structured results: Vercel score, llmstxt.org score, and per-check findings with remediation hints.
|
|
31850
|
+
description: "Runs the agent-ready.dev scanner against a URL and returns structured results: Vercel score, llmstxt.org score, and per-check findings with remediation hints. Works without an API key on the anonymous free tier (3 scans/30 days per IP, 25-page depth, synchronous). With a Pro AGENT_READY_API_KEY it scans deeper (up to 250 pages) and may take up to ~60s; if the local poll deadline elapses, the tool returns the scan id and asks you to poll with get_scan.",
|
|
31772
31851
|
inputSchema: scanSiteInputShape,
|
|
31773
31852
|
outputSchema: scanOutputShape,
|
|
31774
31853
|
annotations: READ_ONLY_OPEN_WORLD
|
|
@@ -31785,7 +31864,7 @@ function createMcpServer(config2) {
|
|
|
31785
31864
|
"get_scan",
|
|
31786
31865
|
{
|
|
31787
31866
|
title: "Get a previous scan by id",
|
|
31788
|
-
description: "Fetches a completed or in-progress scan by its id.
|
|
31867
|
+
description: "Fetches a completed or in-progress scan by its id. Requires a Pro API key \u2014 scan history is account-scoped. (Anonymous scan_site calls return their result inline, so keyless use never needs this tool.)",
|
|
31789
31868
|
inputSchema: getScanInputShape,
|
|
31790
31869
|
outputSchema: scanOutputShape,
|
|
31791
31870
|
annotations: READ_ONLY_OPEN_WORLD
|
|
@@ -31853,7 +31932,7 @@ async function main() {
|
|
|
31853
31932
|
const config2 = createConfig();
|
|
31854
31933
|
if (!config2.apiKey) {
|
|
31855
31934
|
process.stderr.write(
|
|
31856
|
-
"agent-ready-mcp started without AGENT_READY_API_KEY \u2014
|
|
31935
|
+
"agent-ready-mcp started without AGENT_READY_API_KEY \u2014 scan_site runs on the anonymous free tier (3 scans per 30 days per IP, 25-page depth); get_scan needs a Pro key. Issue one at https://agent-ready.dev/dashboard/api-keys for deeper scans, history, and monitoring.\n"
|
|
31857
31936
|
);
|
|
31858
31937
|
}
|
|
31859
31938
|
const server = createMcpServer(config2);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-ready-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"mcpName": "io.github.mlava/agent-ready-mcp",
|
|
5
5
|
"description": "MCP server for Agent Ready — scan any URL for AI-readability against the Vercel Agent Readability Spec, the llmstxt.org standard, and agent-protocol manifests (MCP server cards, A2A, agents.json, agent-permissions.json, UCP, x402, NLWeb). 69 checks with per-check fix guidance.",
|
|
6
6
|
"license": "MIT",
|