ax-audit 4.2.1 → 6.0.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 +19 -0
- package/README.md +39 -4
- package/dist/baseline.js +1 -1
- package/dist/baseline.js.map +1 -1
- package/dist/check-ids.js +1 -1
- package/dist/check-ids.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/constants.d.ts +1 -85
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +0 -135
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/license.d.ts +8 -0
- package/dist/license.d.ts.map +1 -0
- package/dist/license.js +18 -0
- package/dist/license.js.map +1 -0
- package/dist/metadata.d.ts +6 -0
- package/dist/metadata.d.ts.map +1 -0
- package/dist/metadata.js +205 -0
- package/dist/metadata.js.map +1 -0
- package/dist/orchestrator.d.ts +1 -0
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +134 -56
- package/dist/orchestrator.js.map +1 -1
- package/dist/scorer.js +2 -2
- package/dist/scorer.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/dist/types.d.ts.map +1 -1
- package/docs/api.md +14 -3
- package/docs/architecture.md +9 -98
- package/docs/ci.md +19 -0
- package/docs/cli.md +11 -0
- package/docs/faq.md +18 -0
- package/docs/getting-started.md +33 -1
- package/package.json +5 -5
- package/dist/checks/agent-access.d.ts +0 -33
- package/dist/checks/agent-access.d.ts.map +0 -1
- package/dist/checks/agent-access.js +0 -256
- package/dist/checks/agent-access.js.map +0 -1
- package/dist/checks/agent-card.d.ts +0 -37
- package/dist/checks/agent-card.d.ts.map +0 -1
- package/dist/checks/agent-card.js +0 -352
- package/dist/checks/agent-card.js.map +0 -1
- package/dist/checks/agent-operability.d.ts +0 -66
- package/dist/checks/agent-operability.d.ts.map +0 -1
- package/dist/checks/agent-operability.js +0 -383
- package/dist/checks/agent-operability.js.map +0 -1
- package/dist/checks/agent-skills.d.ts +0 -24
- package/dist/checks/agent-skills.d.ts.map +0 -1
- package/dist/checks/agent-skills.js +0 -316
- package/dist/checks/agent-skills.js.map +0 -1
- package/dist/checks/ai-catalog.d.ts +0 -28
- package/dist/checks/ai-catalog.d.ts.map +0 -1
- package/dist/checks/ai-catalog.js +0 -254
- package/dist/checks/ai-catalog.js.map +0 -1
- package/dist/checks/ai-directives.d.ts +0 -57
- package/dist/checks/ai-directives.d.ts.map +0 -1
- package/dist/checks/ai-directives.js +0 -263
- package/dist/checks/ai-directives.js.map +0 -1
- package/dist/checks/api-discovery.d.ts +0 -26
- package/dist/checks/api-discovery.d.ts.map +0 -1
- package/dist/checks/api-discovery.js +0 -432
- package/dist/checks/api-discovery.js.map +0 -1
- package/dist/checks/auth-discovery.d.ts +0 -28
- package/dist/checks/auth-discovery.d.ts.map +0 -1
- package/dist/checks/auth-discovery.js +0 -302
- package/dist/checks/auth-discovery.js.map +0 -1
- package/dist/checks/commerce-discovery.d.ts +0 -40
- package/dist/checks/commerce-discovery.d.ts.map +0 -1
- package/dist/checks/commerce-discovery.js +0 -295
- package/dist/checks/commerce-discovery.js.map +0 -1
- package/dist/checks/content-negotiation.d.ts +0 -4
- package/dist/checks/content-negotiation.d.ts.map +0 -1
- package/dist/checks/content-negotiation.js +0 -253
- package/dist/checks/content-negotiation.js.map +0 -1
- package/dist/checks/crawl-efficiency.d.ts +0 -16
- package/dist/checks/crawl-efficiency.d.ts.map +0 -1
- package/dist/checks/crawl-efficiency.js +0 -186
- package/dist/checks/crawl-efficiency.js.map +0 -1
- package/dist/checks/frontmatter.d.ts +0 -34
- package/dist/checks/frontmatter.d.ts.map +0 -1
- package/dist/checks/frontmatter.js +0 -100
- package/dist/checks/frontmatter.js.map +0 -1
- package/dist/checks/html-rendering.d.ts +0 -21
- package/dist/checks/html-rendering.d.ts.map +0 -1
- package/dist/checks/html-rendering.js +0 -221
- package/dist/checks/html-rendering.js.map +0 -1
- package/dist/checks/html-utils.d.ts +0 -66
- package/dist/checks/html-utils.d.ts.map +0 -1
- package/dist/checks/html-utils.js +0 -139
- package/dist/checks/html-utils.js.map +0 -1
- package/dist/checks/http-headers.d.ts +0 -11
- package/dist/checks/http-headers.d.ts.map +0 -1
- package/dist/checks/http-headers.js +0 -249
- package/dist/checks/http-headers.js.map +0 -1
- package/dist/checks/http-hygiene.d.ts +0 -26
- package/dist/checks/http-hygiene.d.ts.map +0 -1
- package/dist/checks/http-hygiene.js +0 -257
- package/dist/checks/http-hygiene.js.map +0 -1
- package/dist/checks/index.d.ts +0 -3
- package/dist/checks/index.d.ts.map +0 -1
- package/dist/checks/index.js +0 -55
- package/dist/checks/index.js.map +0 -1
- package/dist/checks/llms-txt.d.ts +0 -19
- package/dist/checks/llms-txt.d.ts.map +0 -1
- package/dist/checks/llms-txt.js +0 -281
- package/dist/checks/llms-txt.js.map +0 -1
- package/dist/checks/mcp-discovery.d.ts +0 -30
- package/dist/checks/mcp-discovery.d.ts.map +0 -1
- package/dist/checks/mcp-discovery.js +0 -523
- package/dist/checks/mcp-discovery.js.map +0 -1
- package/dist/checks/meta-tags.d.ts +0 -17
- package/dist/checks/meta-tags.d.ts.map +0 -1
- package/dist/checks/meta-tags.js +0 -188
- package/dist/checks/meta-tags.js.map +0 -1
- package/dist/checks/robots-parser.d.ts +0 -110
- package/dist/checks/robots-parser.d.ts.map +0 -1
- package/dist/checks/robots-parser.js +0 -277
- package/dist/checks/robots-parser.js.map +0 -1
- package/dist/checks/robots-txt.d.ts +0 -6
- package/dist/checks/robots-txt.d.ts.map +0 -1
- package/dist/checks/robots-txt.js +0 -367
- package/dist/checks/robots-txt.js.map +0 -1
- package/dist/checks/rsl.d.ts +0 -4
- package/dist/checks/rsl.d.ts.map +0 -1
- package/dist/checks/rsl.js +0 -242
- package/dist/checks/rsl.js.map +0 -1
- package/dist/checks/security-txt.d.ts +0 -4
- package/dist/checks/security-txt.d.ts.map +0 -1
- package/dist/checks/security-txt.js +0 -81
- package/dist/checks/security-txt.js.map +0 -1
- package/dist/checks/seo-basics.d.ts +0 -13
- package/dist/checks/seo-basics.d.ts.map +0 -1
- package/dist/checks/seo-basics.js +0 -221
- package/dist/checks/seo-basics.js.map +0 -1
- package/dist/checks/sitemap.d.ts +0 -12
- package/dist/checks/sitemap.d.ts.map +0 -1
- package/dist/checks/sitemap.js +0 -240
- package/dist/checks/sitemap.js.map +0 -1
- package/dist/checks/structured-data.d.ts +0 -4
- package/dist/checks/structured-data.d.ts.map +0 -1
- package/dist/checks/structured-data.js +0 -408
- package/dist/checks/structured-data.js.map +0 -1
- package/dist/checks/structured-fields.d.ts +0 -46
- package/dist/checks/structured-fields.d.ts.map +0 -1
- package/dist/checks/structured-fields.js +0 -112
- package/dist/checks/structured-fields.js.map +0 -1
- package/dist/checks/surface.d.ts +0 -59
- package/dist/checks/surface.d.ts.map +0 -1
- package/dist/checks/surface.js +0 -106
- package/dist/checks/surface.js.map +0 -1
- package/dist/checks/tls-https.d.ts +0 -13
- package/dist/checks/tls-https.d.ts.map +0 -1
- package/dist/checks/tls-https.js +0 -163
- package/dist/checks/tls-https.js.map +0 -1
- package/dist/checks/usage-policy.d.ts +0 -53
- package/dist/checks/usage-policy.d.ts.map +0 -1
- package/dist/checks/usage-policy.js +0 -339
- package/dist/checks/usage-policy.js.map +0 -1
- package/dist/checks/utils.d.ts +0 -40
- package/dist/checks/utils.d.ts.map +0 -1
- package/dist/checks/utils.js +0 -74
- package/dist/checks/utils.js.map +0 -1
- package/dist/checks/waf.d.ts +0 -75
- package/dist/checks/waf.d.ts.map +0 -1
- package/dist/checks/waf.js +0 -203
- package/dist/checks/waf.js.map +0 -1
- package/dist/checks/webmcp.d.ts +0 -55
- package/dist/checks/webmcp.d.ts.map +0 -1
- package/dist/checks/webmcp.js +0 -209
- package/dist/checks/webmcp.js.map +0 -1
- package/dist/checks/well-known.d.ts +0 -38
- package/dist/checks/well-known.d.ts.map +0 -1
- package/dist/checks/well-known.js +0 -202
- package/dist/checks/well-known.js.map +0 -1
- package/dist/fetcher.d.ts +0 -15
- package/dist/fetcher.d.ts.map +0 -1
- package/dist/fetcher.js +0 -127
- package/dist/fetcher.js.map +0 -1
- package/dist/guide-urls.d.ts +0 -2
- package/dist/guide-urls.d.ts.map +0 -1
- package/dist/guide-urls.js +0 -5
- package/dist/guide-urls.js.map +0 -1
- package/docs/roadmap.md +0 -367
package/dist/checks/waf.js
DELETED
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
/** Body markers for challenge interstitials that do not set a header. */
|
|
2
|
-
const CHALLENGE_BODY_MARKERS = [
|
|
3
|
-
{ marker: /\/cdn-cgi\/challenge-platform\//i, vendor: 'Cloudflare' },
|
|
4
|
-
{ marker: /<title>\s*Just a moment/i, vendor: 'Cloudflare' },
|
|
5
|
-
{ marker: /Vercel Security Checkpoint/i, vendor: 'Vercel' },
|
|
6
|
-
{ marker: /challenges\.cloudflare\.com\/turnstile/i, vendor: 'Cloudflare Turnstile' },
|
|
7
|
-
{ marker: /www\.google\.com\/recaptcha\//i, vendor: 'reCAPTCHA' },
|
|
8
|
-
{ marker: /\bhcaptcha\.com\/(1\/api\.js|captcha)/i, vendor: 'hCaptcha' },
|
|
9
|
-
{ marker: /_Incapsula_Resource|Incapsula incident ID/i, vendor: 'Imperva' },
|
|
10
|
-
{ marker: /Checking your browser before accessing/i, vendor: 'Cloudflare' },
|
|
11
|
-
{ marker: /Please enable (JS|JavaScript) and disable any ad ?blocker/i, vendor: 'Cloudflare' },
|
|
12
|
-
{ marker: /Request unsuccessful\. Incapsula/i, vendor: 'Imperva' },
|
|
13
|
-
{ marker: /Pardon Our Interruption/i, vendor: 'Imperva' },
|
|
14
|
-
{ marker: /PerimeterX|px-captcha/i, vendor: 'HUMAN (PerimeterX)' },
|
|
15
|
-
{ marker: /Access Denied.*Reference #[0-9a-f.]+/is, vendor: 'Akamai' },
|
|
16
|
-
];
|
|
17
|
-
/** Identify the CDN or edge from response headers, for context in findings. */
|
|
18
|
-
export function detectEdgeVendor(headers) {
|
|
19
|
-
if (headers['cf-ray'] !== undefined || /cloudflare/i.test(headers['server'] ?? ''))
|
|
20
|
-
return 'Cloudflare';
|
|
21
|
-
if (headers['x-vercel-id'] !== undefined || /vercel/i.test(headers['server'] ?? ''))
|
|
22
|
-
return 'Vercel';
|
|
23
|
-
if (headers['x-amzn-waf-action'] !== undefined || headers['x-amz-cf-id'] !== undefined)
|
|
24
|
-
return 'AWS';
|
|
25
|
-
if (headers['x-served-by']?.includes('cache-') || /varnish/i.test(headers['via'] ?? ''))
|
|
26
|
-
return 'Fastly';
|
|
27
|
-
if (headers['x-akamai-transformed'] !== undefined || /akamai/i.test(headers['server'] ?? ''))
|
|
28
|
-
return 'Akamai';
|
|
29
|
-
if (/netlify/i.test(headers['server'] ?? ''))
|
|
30
|
-
return 'Netlify';
|
|
31
|
-
return undefined;
|
|
32
|
-
}
|
|
33
|
-
function withVendor(base, vendor) {
|
|
34
|
-
return vendor === undefined ? base : `${base} (${vendor})`;
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* Classify a fetch result. Pure and total: any response produces a
|
|
38
|
-
* classification, and unknown shapes fall back to status-based buckets.
|
|
39
|
-
*/
|
|
40
|
-
export function classifyResponse(res) {
|
|
41
|
-
const h = res.headers ?? {};
|
|
42
|
-
const edge = detectEdgeVendor(h);
|
|
43
|
-
const body = res.body ?? '';
|
|
44
|
-
if (res.status === 0) {
|
|
45
|
-
return {
|
|
46
|
-
kind: 'network-error',
|
|
47
|
-
label: res.error ? `Network error: ${res.error}` : 'Network error',
|
|
48
|
-
evidence: res.error ? [res.error] : [],
|
|
49
|
-
inconclusive: true,
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
/* ── Challenges: an interstitial, not a policy decision ───────────────── */
|
|
53
|
-
if ((h['cf-mitigated'] ?? '').toLowerCase() === 'challenge') {
|
|
54
|
-
return {
|
|
55
|
-
kind: 'challenge',
|
|
56
|
-
vendor: 'Cloudflare',
|
|
57
|
-
label: 'Cloudflare served a challenge page',
|
|
58
|
-
evidence: ['cf-mitigated: challenge'],
|
|
59
|
-
inconclusive: true,
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
if ((h['x-vercel-mitigated'] ?? '').toLowerCase() === 'challenge' || h['x-vercel-challenge-token'] !== undefined) {
|
|
63
|
-
return {
|
|
64
|
-
kind: 'challenge',
|
|
65
|
-
vendor: 'Vercel',
|
|
66
|
-
label: 'Vercel served a security checkpoint',
|
|
67
|
-
evidence: [
|
|
68
|
-
h['x-vercel-mitigated'] !== undefined ? `x-vercel-mitigated: ${h['x-vercel-mitigated']}` : '',
|
|
69
|
-
h['x-vercel-challenge-token'] !== undefined ? 'x-vercel-challenge-token present' : '',
|
|
70
|
-
].filter(Boolean),
|
|
71
|
-
inconclusive: true,
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
if ((h['x-amzn-waf-action'] ?? '').toLowerCase() === 'challenge') {
|
|
75
|
-
return {
|
|
76
|
-
kind: 'challenge',
|
|
77
|
-
vendor: 'AWS WAF',
|
|
78
|
-
label: `AWS WAF served a challenge (HTTP ${res.status})`,
|
|
79
|
-
evidence: [`x-amzn-waf-action: challenge`, `status ${res.status}`],
|
|
80
|
-
inconclusive: true,
|
|
81
|
-
};
|
|
82
|
-
}
|
|
83
|
-
/* ── Payment and licensing: an offer, not a refusal ───────────────────── */
|
|
84
|
-
if (res.status === 402) {
|
|
85
|
-
const price = h['crawler-price'];
|
|
86
|
-
if (price !== undefined) {
|
|
87
|
-
return {
|
|
88
|
-
kind: 'paywall',
|
|
89
|
-
vendor: 'Cloudflare pay-per-crawl',
|
|
90
|
-
label: `Content is priced for crawlers at ${price}`,
|
|
91
|
-
evidence: [`crawler-price: ${price}`],
|
|
92
|
-
inconclusive: false,
|
|
93
|
-
price,
|
|
94
|
-
};
|
|
95
|
-
}
|
|
96
|
-
if (h['payment-signature'] !== undefined || /"(payTo|maxTimeoutSeconds|x402Version)"/.test(body)) {
|
|
97
|
-
return {
|
|
98
|
-
kind: 'paywall',
|
|
99
|
-
vendor: withVendor('x402', edge),
|
|
100
|
-
label: 'Content is monetised through an x402 payment challenge',
|
|
101
|
-
evidence: [h['payment-signature'] !== undefined ? 'payment-signature header' : 'x402 fields in body'],
|
|
102
|
-
inconclusive: false,
|
|
103
|
-
};
|
|
104
|
-
}
|
|
105
|
-
if (/^License\b/i.test(h['www-authenticate'] ?? '')) {
|
|
106
|
-
return {
|
|
107
|
-
kind: 'license-required',
|
|
108
|
-
vendor: 'RSL Open Licensing Protocol',
|
|
109
|
-
label: 'A licence is required before this content may be used',
|
|
110
|
-
evidence: [`www-authenticate: ${h['www-authenticate']}`],
|
|
111
|
-
inconclusive: false,
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
return {
|
|
115
|
-
kind: 'blocked',
|
|
116
|
-
vendor: edge,
|
|
117
|
-
label: withVendor('Refused with 402 but no payment mechanism advertised', edge),
|
|
118
|
-
evidence: ['status 402 with no crawler-price, x402 fields, or licence challenge'],
|
|
119
|
-
inconclusive: false,
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
if (res.status === 401 && /^License\b/i.test(h['www-authenticate'] ?? '')) {
|
|
123
|
-
return {
|
|
124
|
-
kind: 'license-required',
|
|
125
|
-
vendor: 'RSL Open Licensing Protocol',
|
|
126
|
-
label: 'A licence is required before this content may be used',
|
|
127
|
-
evidence: [`www-authenticate: ${h['www-authenticate']}`],
|
|
128
|
-
inconclusive: false,
|
|
129
|
-
};
|
|
130
|
-
}
|
|
131
|
-
/* ── Signature demands: the site wants a verifiable agent ─────────────── */
|
|
132
|
-
if ((res.status === 401 || res.status === 403) && h['accept-signature'] !== undefined) {
|
|
133
|
-
return {
|
|
134
|
-
kind: 'needs-signature',
|
|
135
|
-
vendor: withVendor('Web Bot Auth', edge),
|
|
136
|
-
label: 'The origin requires a signed request (Web Bot Auth)',
|
|
137
|
-
evidence: [`accept-signature: ${h['accept-signature']}`],
|
|
138
|
-
inconclusive: true,
|
|
139
|
-
};
|
|
140
|
-
}
|
|
141
|
-
if (res.status === 429) {
|
|
142
|
-
return {
|
|
143
|
-
kind: 'rate-limited',
|
|
144
|
-
vendor: edge,
|
|
145
|
-
label: h['retry-after'] !== undefined ? `Rate limited, retry after ${h['retry-after']}` : 'Rate limited',
|
|
146
|
-
evidence: h['retry-after'] !== undefined ? [`retry-after: ${h['retry-after']}`] : ['status 429'],
|
|
147
|
-
inconclusive: true,
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
/* ── Body-marker challenges, on any status ────────────────────────────── */
|
|
151
|
-
const bodyChallenge = CHALLENGE_BODY_MARKERS.find((m) => m.marker.test(body));
|
|
152
|
-
if (bodyChallenge !== undefined) {
|
|
153
|
-
return {
|
|
154
|
-
kind: 'challenge',
|
|
155
|
-
vendor: bodyChallenge.vendor,
|
|
156
|
-
label: `${bodyChallenge.vendor} interstitial served instead of the page`,
|
|
157
|
-
evidence: [`body matched ${bodyChallenge.vendor} challenge markup`, `status ${res.status}`],
|
|
158
|
-
inconclusive: true,
|
|
159
|
-
};
|
|
160
|
-
}
|
|
161
|
-
if (res.status === 401 || res.status === 403) {
|
|
162
|
-
return {
|
|
163
|
-
kind: 'blocked',
|
|
164
|
-
vendor: edge,
|
|
165
|
-
label: withVendor(`Refused with HTTP ${res.status}`, edge),
|
|
166
|
-
evidence: [`status ${res.status}`],
|
|
167
|
-
// An edge that verifies bots by IP range or signature rejects an unsigned
|
|
168
|
-
// probe on principle, so a bare 403 from a known bot-managing CDN cannot
|
|
169
|
-
// prove a policy block.
|
|
170
|
-
inconclusive: edge !== undefined,
|
|
171
|
-
};
|
|
172
|
-
}
|
|
173
|
-
if (res.status === 404 || res.status === 410) {
|
|
174
|
-
return { kind: 'not-found', vendor: edge, label: `HTTP ${res.status}`, evidence: [], inconclusive: false };
|
|
175
|
-
}
|
|
176
|
-
if (res.status >= 500) {
|
|
177
|
-
return {
|
|
178
|
-
kind: 'server-error',
|
|
179
|
-
vendor: edge,
|
|
180
|
-
label: `Server error (HTTP ${res.status})`,
|
|
181
|
-
evidence: [`status ${res.status}`],
|
|
182
|
-
inconclusive: true,
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
if (res.ok) {
|
|
186
|
-
return { kind: 'ok', vendor: edge, label: `HTTP ${res.status}`, evidence: [], inconclusive: false };
|
|
187
|
-
}
|
|
188
|
-
return {
|
|
189
|
-
kind: 'blocked',
|
|
190
|
-
vendor: edge,
|
|
191
|
-
label: `Unexpected HTTP ${res.status}`,
|
|
192
|
-
evidence: [`status ${res.status}`],
|
|
193
|
-
inconclusive: true,
|
|
194
|
-
};
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Standard caveat for classifications an unauthenticated probe cannot settle.
|
|
198
|
-
* Appended to hints so a report never overstates what it observed.
|
|
199
|
-
*/
|
|
200
|
-
export const INCONCLUSIVE_CAVEAT = 'ax-audit sends this user agent from its own network without a Web Bot Auth signature, so an edge that verifies ' +
|
|
201
|
-
'crawlers by IP range or signature will reject the probe while admitting the real crawler. Confirm against your ' +
|
|
202
|
-
'WAF logs before changing any rule.';
|
|
203
|
-
//# sourceMappingURL=waf.js.map
|
package/dist/checks/waf.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"waf.js","sourceRoot":"","sources":["../../src/checks/waf.ts"],"names":[],"mappings":"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"}
|
package/dist/checks/webmcp.d.ts
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { CheckContext, CheckResult, CheckMeta } from '../types.js';
|
|
2
|
-
/**
|
|
3
|
-
* "webmcp" — can a browser agent invoke this page's forms as tools?
|
|
4
|
-
*
|
|
5
|
-
* Today an agent that wants to use a form has to look at pixels, guess which
|
|
6
|
-
* field is which, type into them, and hope. WebMCP lets a page declare a form as
|
|
7
|
-
* a callable tool with named parameters, so the agent calls it instead of
|
|
8
|
-
* driving it. The declarative form is two attributes:
|
|
9
|
-
*
|
|
10
|
-
* ```html
|
|
11
|
-
* <form toolname="searchDocs" tooldescription="Search the documentation">
|
|
12
|
-
* <input name="q" toolparamdescription="The search query">
|
|
13
|
-
* </form>
|
|
14
|
-
* ```
|
|
15
|
-
*
|
|
16
|
-
* Status, verified 2026-09-04: a W3C Web Machine Learning Community Group draft
|
|
17
|
-
* with a Chrome origin trial running from Chrome 149. Not a standard, not
|
|
18
|
-
* shipped by default, not implemented in Firefox or Safari. Adoption is
|
|
19
|
-
* effectively zero.
|
|
20
|
-
*
|
|
21
|
-
* So this check never asks for WebMCP and never scores a site down for lacking
|
|
22
|
-
* it. It reports N/A on a page with no forms and no WebMCP code at all. What it
|
|
23
|
-
* does do, on pages that have adopted it, is catch the mistakes a static
|
|
24
|
-
* analysis can catch with certainty: a `toolname` with no `tooldescription`,
|
|
25
|
-
* which is the exact condition Lighthouse's `webmcp-schema-validity` audit
|
|
26
|
-
* fails, parameters with no description, and use of the `navigator.modelContext`
|
|
27
|
-
* namespace that Chrome deprecated in favour of `document.modelContext`.
|
|
28
|
-
*/
|
|
29
|
-
export declare const meta: CheckMeta;
|
|
30
|
-
export interface FormAnalysis {
|
|
31
|
-
total: number;
|
|
32
|
-
annotated: number;
|
|
33
|
-
/** Forms declaring a name but no description — invalid, and Lighthouse fails them. */
|
|
34
|
-
missingDescription: string[];
|
|
35
|
-
/** Forms declaring a description but no name: nothing for an agent to call. */
|
|
36
|
-
missingName: number;
|
|
37
|
-
/** Tool names that are not usable identifiers. */
|
|
38
|
-
invalidNames: string[];
|
|
39
|
-
/** Annotated forms whose named controls lack `toolparamdescription`. */
|
|
40
|
-
undescribedParams: {
|
|
41
|
-
tool: string;
|
|
42
|
-
missing: number;
|
|
43
|
-
total: number;
|
|
44
|
-
}[];
|
|
45
|
-
autoSubmit: string[];
|
|
46
|
-
}
|
|
47
|
-
/** Analyse declarative WebMCP annotations across every form on the page. */
|
|
48
|
-
export declare function analyseForms(html: string): FormAnalysis;
|
|
49
|
-
/** Detect imperative WebMCP registration in inline scripts. */
|
|
50
|
-
export declare function detectImperative(html: string): {
|
|
51
|
-
registers: boolean;
|
|
52
|
-
deprecatedNamespace: boolean;
|
|
53
|
-
};
|
|
54
|
-
export default function check(ctx: CheckContext): Promise<CheckResult>;
|
|
55
|
-
//# sourceMappingURL=webmcp.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webmcp.d.ts","sourceRoot":"","sources":["../../src/checks/webmcp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAW,MAAM,aAAa,CAAC;AAIjF;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,IAAI,EAAE,SAKlB,CAAC;AAWF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,sFAAsF;IACtF,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,+EAA+E;IAC/E,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,wEAAwE;IACxE,iBAAiB,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACtE,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAWD,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAiDvD;AAED,+DAA+D;AAC/D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,mBAAmB,EAAE,OAAO,CAAA;CAAE,CAMnG;AAED,wBAA8B,KAAK,CAAC,GAAG,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAmH3E"}
|
package/dist/checks/webmcp.js
DELETED
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
import { guideUrl } from '../guide-urls.js';
|
|
2
|
-
import { buildResult, notApplicable } from './utils.js';
|
|
3
|
-
import { getAttribute } from './html-utils.js';
|
|
4
|
-
/**
|
|
5
|
-
* "webmcp" — can a browser agent invoke this page's forms as tools?
|
|
6
|
-
*
|
|
7
|
-
* Today an agent that wants to use a form has to look at pixels, guess which
|
|
8
|
-
* field is which, type into them, and hope. WebMCP lets a page declare a form as
|
|
9
|
-
* a callable tool with named parameters, so the agent calls it instead of
|
|
10
|
-
* driving it. The declarative form is two attributes:
|
|
11
|
-
*
|
|
12
|
-
* ```html
|
|
13
|
-
* <form toolname="searchDocs" tooldescription="Search the documentation">
|
|
14
|
-
* <input name="q" toolparamdescription="The search query">
|
|
15
|
-
* </form>
|
|
16
|
-
* ```
|
|
17
|
-
*
|
|
18
|
-
* Status, verified 2026-09-04: a W3C Web Machine Learning Community Group draft
|
|
19
|
-
* with a Chrome origin trial running from Chrome 149. Not a standard, not
|
|
20
|
-
* shipped by default, not implemented in Firefox or Safari. Adoption is
|
|
21
|
-
* effectively zero.
|
|
22
|
-
*
|
|
23
|
-
* So this check never asks for WebMCP and never scores a site down for lacking
|
|
24
|
-
* it. It reports N/A on a page with no forms and no WebMCP code at all. What it
|
|
25
|
-
* does do, on pages that have adopted it, is catch the mistakes a static
|
|
26
|
-
* analysis can catch with certainty: a `toolname` with no `tooldescription`,
|
|
27
|
-
* which is the exact condition Lighthouse's `webmcp-schema-validity` audit
|
|
28
|
-
* fails, parameters with no description, and use of the `navigator.modelContext`
|
|
29
|
-
* namespace that Chrome deprecated in favour of `document.modelContext`.
|
|
30
|
-
*/
|
|
31
|
-
export const meta = {
|
|
32
|
-
id: 'webmcp',
|
|
33
|
-
name: 'WebMCP',
|
|
34
|
-
description: 'Checks declarative WebMCP tool annotations on forms',
|
|
35
|
-
category: 'protocols',
|
|
36
|
-
};
|
|
37
|
-
/** Tool names are identifiers an agent calls, so they follow identifier rules. */
|
|
38
|
-
const TOOL_NAME_RE = /^[A-Za-z_][A-Za-z0-9_]{0,127}$/;
|
|
39
|
-
/** Form controls that carry a value an agent would need described. */
|
|
40
|
-
const CONTROL_RE = /<(input|select|textarea)\b([^>]*)>/gi;
|
|
41
|
-
/** Input types that carry no user-supplied value worth describing. */
|
|
42
|
-
const VALUELESS_TYPES = new Set(['hidden', 'submit', 'button', 'reset', 'image']);
|
|
43
|
-
/** Split the document into `<form>` blocks, keeping each element's attributes and inner HTML. */
|
|
44
|
-
function forms(html) {
|
|
45
|
-
const out = [];
|
|
46
|
-
for (const m of html.matchAll(/<form\b([^>]*)>([\s\S]*?)<\/form>/gi)) {
|
|
47
|
-
out.push({ attrs: m[1], inner: m[2] });
|
|
48
|
-
}
|
|
49
|
-
return out;
|
|
50
|
-
}
|
|
51
|
-
/** Analyse declarative WebMCP annotations across every form on the page. */
|
|
52
|
-
export function analyseForms(html) {
|
|
53
|
-
const analysis = {
|
|
54
|
-
total: 0,
|
|
55
|
-
annotated: 0,
|
|
56
|
-
missingDescription: [],
|
|
57
|
-
missingName: 0,
|
|
58
|
-
invalidNames: [],
|
|
59
|
-
undescribedParams: [],
|
|
60
|
-
autoSubmit: [],
|
|
61
|
-
};
|
|
62
|
-
for (const form of forms(html)) {
|
|
63
|
-
analysis.total++;
|
|
64
|
-
const toolName = getAttribute(form.attrs, 'toolname');
|
|
65
|
-
const toolDescription = getAttribute(form.attrs, 'tooldescription');
|
|
66
|
-
if (toolName === null && toolDescription === null)
|
|
67
|
-
continue;
|
|
68
|
-
const label = toolName ?? '(unnamed)';
|
|
69
|
-
analysis.annotated++;
|
|
70
|
-
if (toolName === null || toolName.trim() === '') {
|
|
71
|
-
analysis.missingName++;
|
|
72
|
-
}
|
|
73
|
-
if (toolDescription === null || toolDescription.trim() === '') {
|
|
74
|
-
analysis.missingDescription.push(label);
|
|
75
|
-
}
|
|
76
|
-
if (toolName !== null && !TOOL_NAME_RE.test(toolName)) {
|
|
77
|
-
analysis.invalidNames.push(toolName);
|
|
78
|
-
}
|
|
79
|
-
if (/\btoolautosubmit\b/i.test(form.attrs)) {
|
|
80
|
-
analysis.autoSubmit.push(label);
|
|
81
|
-
}
|
|
82
|
-
let total = 0;
|
|
83
|
-
let missing = 0;
|
|
84
|
-
for (const control of form.inner.matchAll(CONTROL_RE)) {
|
|
85
|
-
const attrs = control[2];
|
|
86
|
-
const type = (getAttribute(attrs, 'type') ?? '').toLowerCase();
|
|
87
|
-
if (VALUELESS_TYPES.has(type))
|
|
88
|
-
continue;
|
|
89
|
-
if (getAttribute(attrs, 'name') === null)
|
|
90
|
-
continue;
|
|
91
|
-
total++;
|
|
92
|
-
if (getAttribute(attrs, 'toolparamdescription') === null)
|
|
93
|
-
missing++;
|
|
94
|
-
}
|
|
95
|
-
if (total > 0 && missing > 0) {
|
|
96
|
-
analysis.undescribedParams.push({ tool: label, missing, total });
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
return analysis;
|
|
100
|
-
}
|
|
101
|
-
/** Detect imperative WebMCP registration in inline scripts. */
|
|
102
|
-
export function detectImperative(html) {
|
|
103
|
-
const scripts = [...html.matchAll(/<script\b[^>]*>([\s\S]*?)<\/script>/gi)].map((m) => m[1]).join('\n');
|
|
104
|
-
return {
|
|
105
|
-
registers: /\bmodelContext\s*\.\s*(registerTool|provideContext)\s*\(/.test(scripts),
|
|
106
|
-
deprecatedNamespace: /\bnavigator\s*\.\s*modelContext\b/.test(scripts),
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
export default async function check(ctx) {
|
|
110
|
-
const start = performance.now();
|
|
111
|
-
const findings = [];
|
|
112
|
-
let score = 100;
|
|
113
|
-
const html = ctx.html ?? '';
|
|
114
|
-
const analysis = analyseForms(html);
|
|
115
|
-
const imperative = detectImperative(html);
|
|
116
|
-
if (analysis.total === 0 && !imperative.registers && !imperative.deprecatedNamespace) {
|
|
117
|
-
findings.push({
|
|
118
|
-
status: 'pass',
|
|
119
|
-
message: 'No forms and no WebMCP code — nothing here for an agent to invoke as a tool',
|
|
120
|
-
});
|
|
121
|
-
return notApplicable(meta, findings, start);
|
|
122
|
-
}
|
|
123
|
-
if (imperative.registers) {
|
|
124
|
-
findings.push({
|
|
125
|
-
status: 'pass',
|
|
126
|
-
message: 'Imperative WebMCP registration detected in page scripts',
|
|
127
|
-
detail: 'A static audit cannot enumerate the registered tools or validate their schemas; that needs a browser.',
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
if (imperative.deprecatedNamespace) {
|
|
131
|
-
findings.push({
|
|
132
|
-
status: 'warn',
|
|
133
|
-
message: 'Page uses the deprecated navigator.modelContext namespace',
|
|
134
|
-
hint: 'Chrome moved the API to document.modelContext. Feature-detect both while the origin trial runs: const ctx = document.modelContext ?? navigator.modelContext.',
|
|
135
|
-
learnMoreUrl: guideUrl(meta.id, 'deprecated-namespace'),
|
|
136
|
-
});
|
|
137
|
-
score -= 10;
|
|
138
|
-
}
|
|
139
|
-
if (analysis.annotated === 0) {
|
|
140
|
-
findings.push({
|
|
141
|
-
status: 'warn',
|
|
142
|
-
message: `${analysis.total} form(s) on the page, none declared as agent tools`,
|
|
143
|
-
detail: 'WebMCP is a W3C Community Group draft in a Chrome origin trial. It is not a standard and adoption is minimal, ' +
|
|
144
|
-
'so this is a forward-looking note, not a defect.',
|
|
145
|
-
hint: 'A declared form is called by an agent rather than driven pixel by pixel. Add toolname and tooldescription to ' +
|
|
146
|
-
'the forms worth automating — search, filter, subscribe — and toolparamdescription to each field.',
|
|
147
|
-
learnMoreUrl: guideUrl(meta.id, 'no-annotations'),
|
|
148
|
-
});
|
|
149
|
-
return buildResult(meta, score, findings, start);
|
|
150
|
-
}
|
|
151
|
-
findings.push({
|
|
152
|
-
status: 'pass',
|
|
153
|
-
message: `${analysis.annotated}/${analysis.total} form(s) declared as agent tools`,
|
|
154
|
-
});
|
|
155
|
-
if (analysis.missingDescription.length > 0) {
|
|
156
|
-
findings.push({
|
|
157
|
-
status: 'fail',
|
|
158
|
-
message: `${analysis.missingDescription.length} tool form(s) declare a name but no description`,
|
|
159
|
-
detail: analysis.missingDescription.join(', '),
|
|
160
|
-
hint: 'The description is what an agent reads to decide whether to call the tool; a named tool without one is ' +
|
|
161
|
-
'unusable. Both attributes are required together.',
|
|
162
|
-
learnMoreUrl: guideUrl(meta.id, 'missing-description'),
|
|
163
|
-
});
|
|
164
|
-
score -= 30;
|
|
165
|
-
}
|
|
166
|
-
if (analysis.missingName > 0) {
|
|
167
|
-
findings.push({
|
|
168
|
-
status: 'fail',
|
|
169
|
-
message: `${analysis.missingName} form(s) declare a tool description but no tool name`,
|
|
170
|
-
hint: 'Without a toolname there is nothing for an agent to call. Both attributes are required together.',
|
|
171
|
-
learnMoreUrl: guideUrl(meta.id, 'missing-name'),
|
|
172
|
-
});
|
|
173
|
-
score -= 30;
|
|
174
|
-
}
|
|
175
|
-
if (analysis.invalidNames.length > 0) {
|
|
176
|
-
findings.push({
|
|
177
|
-
status: 'warn',
|
|
178
|
-
message: 'Tool name is not a usable identifier',
|
|
179
|
-
detail: analysis.invalidNames.join(', '),
|
|
180
|
-
hint: 'A tool name is called like a function. Use letters, digits and underscores, starting with a letter: searchDocs, subscribe_newsletter.',
|
|
181
|
-
learnMoreUrl: guideUrl(meta.id, 'invalid-name'),
|
|
182
|
-
});
|
|
183
|
-
score -= 10;
|
|
184
|
-
}
|
|
185
|
-
if (analysis.undescribedParams.length > 0) {
|
|
186
|
-
const totalMissing = analysis.undescribedParams.reduce((acc, p) => acc + p.missing, 0);
|
|
187
|
-
findings.push({
|
|
188
|
-
status: 'warn',
|
|
189
|
-
message: `${totalMissing} tool parameter(s) have no description`,
|
|
190
|
-
detail: analysis.undescribedParams.map((p) => `${p.tool}: ${p.missing}/${p.total} fields undescribed`).join('\n'),
|
|
191
|
-
hint: 'Add toolparamdescription to each named field. Without it an agent has to infer a field’s meaning from its ' +
|
|
192
|
-
'name, which is how a search box gets an email address in it.',
|
|
193
|
-
learnMoreUrl: guideUrl(meta.id, 'undescribed-params'),
|
|
194
|
-
});
|
|
195
|
-
score -= 15;
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
findings.push({ status: 'pass', message: 'Every tool parameter carries a description' });
|
|
199
|
-
}
|
|
200
|
-
if (analysis.autoSubmit.length > 0) {
|
|
201
|
-
findings.push({
|
|
202
|
-
status: 'pass',
|
|
203
|
-
message: `${analysis.autoSubmit.length} tool form(s) declare toolautosubmit`,
|
|
204
|
-
detail: 'The agent submits without a further confirmation step. Appropriate for read-only actions such as search, not for anything that charges, sends or deletes.',
|
|
205
|
-
});
|
|
206
|
-
}
|
|
207
|
-
return buildResult(meta, score, findings, start);
|
|
208
|
-
}
|
|
209
|
-
//# sourceMappingURL=webmcp.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"webmcp.js","sourceRoot":"","sources":["../../src/checks/webmcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standing of every well-known URI and discovery convention ax-audit probes.
|
|
3
|
-
*
|
|
4
|
-
* The agent web is a mix of IETF-registered URIs, vendor conventions that are
|
|
5
|
-
* widely deployed but unregistered, and drafts that may be renamed next month.
|
|
6
|
-
* Reporting them all as equally authoritative would be misleading, so every
|
|
7
|
-
* probe carries its standing and audiences can weigh a miss accordingly:
|
|
8
|
-
*
|
|
9
|
-
* - `registered` — in the IANA Well-Known URI registry (permanent or provisional).
|
|
10
|
-
* - `convention` — no registration, but shipped by multiple independent vendors.
|
|
11
|
-
* - `draft` — an open spec PR, individual I-D, or origin-trial-era proposal.
|
|
12
|
-
* - `legacy` — superseded or abandoned; recognised so we can advise removal.
|
|
13
|
-
*
|
|
14
|
-
* Registry snapshot: https://www.iana.org/assignments/well-known-uris/well-known-uris.xhtml
|
|
15
|
-
* (last verified 2026-09-04, registry last updated 2026-08-19).
|
|
16
|
-
*/
|
|
17
|
-
export type Standing = 'registered' | 'convention' | 'draft' | 'legacy';
|
|
18
|
-
export interface WellKnownEntry {
|
|
19
|
-
/** Path as probed, root-relative. */
|
|
20
|
-
path: string;
|
|
21
|
-
standing: Standing;
|
|
22
|
-
/** Short human label used in findings. */
|
|
23
|
-
label: string;
|
|
24
|
-
/** Authoritative reference for the path. */
|
|
25
|
-
specUrl: string;
|
|
26
|
-
/** Free-text note surfaced in `detail` when the standing is not `registered`. */
|
|
27
|
-
note?: string;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Every path ax-audit knows about, keyed by path. Checks look up their probe
|
|
31
|
-
* targets here so a rename in a draft spec is a one-line change in one file.
|
|
32
|
-
*/
|
|
33
|
-
export declare const WELL_KNOWN: Record<string, WellKnownEntry>;
|
|
34
|
-
/** Look up a path's standing, defaulting to `convention` for unknown paths. */
|
|
35
|
-
export declare function standingOf(path: string): Standing;
|
|
36
|
-
/** Human sentence describing a path's standing, for finding details. */
|
|
37
|
-
export declare function standingNote(path: string): string | undefined;
|
|
38
|
-
//# sourceMappingURL=well-known.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"well-known.d.ts","sourceRoot":"","sources":["../../src/checks/well-known.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,GAAG,OAAO,GAAG,QAAQ,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,QAAQ,CAAC;IACnB,0CAA0C;IAC1C,KAAK,EAAE,MAAM,CAAC;IACd,4CAA4C;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,iFAAiF;IACjF,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAqLrD,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAEjD;AAED,wEAAwE;AACxE,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAY7D"}
|