wiki-formant 0.11.0 → 0.13.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/README.md CHANGED
@@ -120,10 +120,48 @@ What it gets right:
120
120
  - **Malformed JSON is `-32700` with a `400`**, never a 500.
121
121
  - **`GET` is an explicit 405 with CORS headers.** A framework's automatic 405 carries none, so a browser client cannot even read the refusal.
122
122
  - **The preflight allow-list includes `Accept` and `Mcp-Protocol-Version`.** One missing entry fails the preflight rather than the POST, which presents as "the server is down".
123
- - **Batches are capped** (default 20) with a teaching error, because the rate limiter charges one token per HTTP request before the body is parsed.
123
+ - **Batches are capped** (default 20) with a teaching error, because the rate limiter charges one token per HTTP request before the body is parsed. Under 2025-06-18 they are refused outright, because the revision removed them.
124
+ - **The protocol version is negotiated, not asserted.** `initialize` echoes what the client asked for when it is one of `2025-06-18`, `2025-03-26` or `2024-11-05`, and offers the newest otherwise; every response carries the negotiated version back in `MCP-Protocol-Version`. Answering a constant is legal and still costs the caller structured output, tool titles and `_meta` without ever saying so.
125
+ - **`Access-Control-Expose-Headers` is set.** Allow-Headers governs what a browser may send, Expose-Headers what it may read — without the second a browser client cannot see `Retry-After` on a 429, and a rate limit presents as a hang.
126
+ - **The rate limit is declared, not wired.** Put `rateLimit: {capacity, refillPerSec}` on the config and `mcpResponse` enforces it before parsing the body, refuses with a JSON-RPC envelope, and states `RateLimit-Limit`/`-Remaining`/`-Reset` on every answer. Four routes had each transcribed that by hand through three differently-named local helpers, which is how a headroom header gets added to one surface and forgotten on the next.
127
+ - **`mcpRateLimited(retryAfterSec)` is a JSON-RPC envelope.** A 429 whose body is `{"error": "..."}` is a string where the client's parser expects `{code, message}`, on the one response an agent meets exactly when it is working hard.
128
+
129
+ ### Structured output, `_meta`, and the envelope gate
130
+
131
+ **Every object a handler returns comes back as `structuredContent` beside the text block**, so a client reads the answer rather than scraping prose for it. This used to be gated on declaring an `outputSchema`, and the result was that across four live servers and thirty-two tools — every one of them answering in JSON — not a single response ever carried it. `outputSchema` remains the stronger contract, because a client validates against it; it is no longer the price of admission. A handler returning a string is left alone.
132
+
133
+ `inputSchema.requireOneOf` names a set of which at least one must be present. `required` cannot express "query or popular", so the one tool needing it checked in its handler and the caller learned at execution time — the single class of argument mistake this module was otherwise catching before dispatch.
134
+
135
+ A handler's second argument is its context:
136
+
137
+ ```ts
138
+ handler: async (args, ctx) => {
139
+ ctx.meta; // params._meta, as it arrived
140
+ ctx.setMeta('x402/payment-response', receipt); // rides back on result._meta
141
+ return { hits: 2 };
142
+ }
143
+ ```
144
+
145
+ `config.gate` is envelope-level middleware: it may withhold entries before dispatch and merge its own responses back afterwards. A payment gate has to sit there rather than in a handler, because the demand *replaces* the call and the receipt rides on the envelope.
146
+
147
+ ## Conformance
148
+
149
+ `wiki-formant/conformance` is the half of an MCP conformance run that is not about any one server's tools: a JSON-RPC client that backs off on a 429, the transport assertions (CORS preflight, `GET`→405, a notification answering 202 with no body, `-32700`, the batch cap, honest `capabilities`, version negotiation), version coherence across every descriptor a surface publishes, A2A card parity, conditional-GET and `robots` checks, and a pass/fail table with an exit code.
150
+
151
+ ```ts
152
+ const t = createTester({ base: 'https://example.com', clientName: 'my-mcp-test' });
153
+ await transportChecks(t, 'my-mcp-test');
154
+ await annotationChecks(t, { writes: ['create_page'] });
155
+ await payloadBudget(t, [{ name: 'search', args: { query: 'x' } }]);
156
+ process.exit(t.summary());
157
+ ```
158
+
159
+ What stays in your repo is fixtures: which tools you expect, what a good answer from each looks like, and which text surfaces you publish. `payloadBudget` weighs every listed call **and** every read-only tool that takes no required arguments, because the one tool nobody thought to list is the one that answers with 3.3 MB; pass a per-call `maxBytes` for a bulk-export tool that is deliberately large. It also asserts that a JSON answer arrived with `structuredContent`.
124
160
 
125
161
  ## Markdown twins
126
162
 
163
+ Pass an `etag` and answer `notModified` before rendering: a twin is the single most recrawled URL a page has, so a twin with no validator is a full render on every pass, forever — the same arithmetic that justifies the corpus ETag, applied per page.
164
+
127
165
  `htmlToMarkdown` preserves the structure an agent cites by — headings, lists, tables, code, emphasis — rather than flattening to prose. Tables convert first so the generic rules cannot eat their markup, ordered lists number per list, pipes inside cells are escaped, and a headerless table gets a synthesised header because GFM has no other form.
128
166
 
129
167
  ```ts
@@ -135,7 +173,7 @@ return new Response(
135
173
  license: { spdx: 'CC-BY-4.0', url: 'https://creativecommons.org/licenses/by/4.0/' } },
136
174
  blocksToMarkdown(page.content), // your block types, your function
137
175
  ),
138
- { headers: markdownHeaders(lastModified) },
176
+ { headers: markdownHeaders(lastModified, { etag }) },
139
177
  );
140
178
  ```
141
179
 
@@ -387,7 +425,7 @@ they name a gap in the corpus in the reader's own words.
387
425
  | `injectHeadingIds`, `headingsFrom`, `slugifyHeading` | `wiki-formant/headings` |
388
426
  | `mcpResponse`, `mcpGet`, `mcpOptions`, `handleMcp`, `withMcpCors`, `McpToolError`, `MCP_CORS`, `MCP_PROTOCOL_VERSION` | `wiki-formant/mcp` |
389
427
  | `htmlToMarkdown`, `inlineToMarkdown`, `tableToMarkdown`, `frontmatter`, `markdownDocument`, `decodeEntities` | `wiki-formant/markdown` |
390
- | `corpusEtag`, `notModified`, `textHeaders`, `markdownHeaders`, `cleanSnippet`, `pageLine` | `wiki-formant/http` |
428
+ | `corpusEtag`, `notModified`, `textHeaders`, `markdownHeaders`, `descriptorHeaders`, `descriptorResponse`, `cleanSnippet`, `pageLine` | `wiki-formant/http` |
391
429
  | `parsePagination`, `paginatedResponse`, `toOffset` | `wiki-formant/pagination` |
392
430
  | `mapBlockTree`, `mapBlockTreeAsync`, `someBlock`, `renderBlockTree` | `wiki-formant/blocks` |
393
431
  | `parseVersion`, `formatVersion`, `incrementVersion`, `bump`, `compareVersions` | `wiki-formant/versioning` |
@@ -3,19 +3,35 @@ export interface Rpc {
3
3
  content?: Array<{
4
4
  text?: string;
5
5
  }>;
6
+ structuredContent?: unknown;
6
7
  isError?: boolean;
7
8
  tools?: Array<{
8
9
  name: string;
10
+ title?: string;
11
+ description?: string;
12
+ inputSchema?: {
13
+ required?: string[];
14
+ requireOneOf?: string[];
15
+ };
16
+ annotations?: Record<string, unknown>;
9
17
  }>;
10
18
  resources?: Array<{
11
19
  uri: string;
12
20
  }>;
21
+ prompts?: Array<{
22
+ name: string;
23
+ description?: string;
24
+ }>;
25
+ resourceTemplates?: Array<{
26
+ uriTemplate?: string;
27
+ }>;
13
28
  contents?: Array<{
14
29
  text?: string;
15
30
  }>;
16
31
  serverInfo?: {
17
32
  version?: string;
18
33
  };
34
+ protocolVersion?: string;
19
35
  capabilities?: Record<string, unknown>;
20
36
  instructions?: string;
21
37
  };
@@ -75,6 +91,8 @@ export declare function transportChecks(t: Tester, clientName: string,
75
91
  * business, so it is a parameter rather than one surface's set hardcoded here.
76
92
  */
77
93
  expectedCapabilities?: readonly string[]): Promise<Rpc>;
94
+ /** The newest protocol revision `wiki-formant/mcp` speaks. */
95
+ export declare const CURRENT_PROTOCOL = "2025-06-18";
78
96
  /**
79
97
  * One service, many descriptors — server.json, the two agent-card paths, the
80
98
  * OpenAPI document, the MCP server card, and `initialize` — should never
@@ -92,8 +110,55 @@ export declare function versionCoherence(t: Tester, expected: string, sources: R
92
110
  */
93
111
  export declare function agentCardParity(t: Tester): Promise<void>;
94
112
  /**
95
- * A corpus export that costs a full render should answer a conditional GET with
96
- * a 304. Checks each path serves an ETag and honours it on the way back.
113
+ * Any surface an agent recrawls should answer a conditional GET with a 304.
114
+ *
115
+ * Point this at every such surface, not only the corpus exports. Aimed solely
116
+ * at the `llms.*` family — the paths that already had validators — it reported
117
+ * green across three origins whose markdown twins, agent cards and OpenAPI
118
+ * documents carried no ETag at all. A check that only looks where it knows it
119
+ * will pass is a check that measures nothing.
97
120
  */
98
121
  export declare function conditionalGetChecks(t: Tester, paths: readonly string[]): Promise<void>;
122
+ /**
123
+ * A JSON descriptor is revalidatable — an agent card, an OpenAPI document, a
124
+ * registry manifest, a server card.
125
+ *
126
+ * Separate from `conditionalGetChecks` because the contract genuinely differs:
127
+ * a descriptor is built from code, not from rows, so it has no honest
128
+ * `Last-Modified` to offer. A stamp taken at cold start would move without the
129
+ * document moving, which is worse than none. The body-derived ETag is the whole
130
+ * validator, and it is enough.
131
+ */
132
+ export declare function descriptorChecks(t: Tester, paths: readonly string[]): Promise<void>;
133
+ /**
134
+ * Every tool carries behavioural hints, and the ones that write say so.
135
+ *
136
+ * Without them a client that auto-approves read-only calls has no way to tell a
137
+ * lookup from one that signs a transaction — and two of the three servers here
138
+ * shipped write tools with no annotations at all.
139
+ */
140
+ export declare function annotationChecks(t: Tester, opts?: {
141
+ writes?: readonly string[];
142
+ }): Promise<void>;
143
+ /**
144
+ * The orientation calls stay inside a context window.
145
+ *
146
+ * A tool that passes a metadata column straight through is one stored blob away
147
+ * from returning 350 KB — around 90k tokens — from the first call an agent
148
+ * makes. Nothing in a pass/fail table notices that unless something weighs the
149
+ * answer, so this weighs it.
150
+ */
151
+ export declare function payloadBudget(t: Tester, calls: ReadonlyArray<{
152
+ name: string;
153
+ args?: Record<string, unknown>;
154
+ maxBytes?: number;
155
+ }>, maxBytes?: number): Promise<void>;
156
+ /**
157
+ * The default `User-agent: *` group may reach everything the descriptors
158
+ * advertise.
159
+ *
160
+ * An origin whose card names an MCP endpoint its own robots.txt disallows to
161
+ * every unnamed crawler is telling two different stories to the same caller.
162
+ */
163
+ export declare function robotsChecks(t: Tester, paths: readonly string[]): Promise<void>;
99
164
  //# sourceMappingURL=conformance.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conformance.d.ts","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
@@ -82,11 +82,38 @@ expectedCapabilities = ['tools']) {
82
82
  clientInfo: { name: clientName, version: '1' },
83
83
  });
84
84
  t.check('initialize', !!init.result?.serverInfo && !!init.result?.instructions, JSON.stringify(init.result?.serverInfo ?? init.error));
85
+ // The version a server answers is the version its clients get. Asking for one
86
+ // and never looking at the reply is how three servers sat pinned to
87
+ // 2025-03-26 — forfeiting structured output, tool titles and `_meta` — while
88
+ // every suite reported green.
89
+ const echoed = await t.rpc('initialize', {
90
+ protocolVersion: CURRENT_PROTOCOL,
91
+ capabilities: {},
92
+ clientInfo: { name: clientName, version: '1' },
93
+ });
94
+ t.check('protocol negotiated', echoed.result?.protocolVersion === CURRENT_PROTOCOL, `asked ${CURRENT_PROTOCOL}, got ${echoed.result?.protocolVersion}`);
95
+ t.check('downgrades gracefully', (init.result?.protocolVersion ?? '').length > 0, `asked 2024-11-05, got ${init.result?.protocolVersion}`);
85
96
  console.log(`\n=== transport ===`);
86
97
  const opt = await fetch(t.endpoint, { method: 'OPTIONS' });
87
98
  t.check('OPTIONS preflight', opt.status === 204 &&
88
99
  opt.headers.get('access-control-allow-origin') === '*' &&
89
100
  (opt.headers.get('access-control-allow-headers') ?? '').includes('Mcp-Protocol-Version'), `${opt.status} ACAO=${opt.headers.get('access-control-allow-origin')}`);
101
+ // Allow-Headers governs what a browser may send; Expose-Headers what it may
102
+ // read. Without the second, a browser client cannot see `Retry-After` on a
103
+ // 429 and a rate limit reads to it as a hang.
104
+ t.check('CORS exposes response headers', ['Mcp-Protocol-Version', 'Retry-After', 'RateLimit-Remaining'].every(h => (opt.headers.get('access-control-expose-headers') ?? '').includes(h)), `expose=${opt.headers.get('access-control-expose-headers')}`);
105
+ // A budget stated only in the 429 can be discovered only by exceeding it —
106
+ // the one moment an agent is least able to act on it. This suite is the
107
+ // proof: with no header to read, its own client blind-sleeps five seconds on
108
+ // a 429 and hopes.
109
+ const headroom = await fetch(t.endpoint, {
110
+ method: 'POST',
111
+ headers: { 'Content-Type': 'application/json' },
112
+ body: JSON.stringify({ jsonrpc: '2.0', id: 'headroom', method: 'ping' }),
113
+ });
114
+ t.recordCall();
115
+ const remaining = headroom.headers.get('ratelimit-remaining');
116
+ t.check('rate limit states headroom', !!headroom.headers.get('ratelimit-limit') && remaining !== null, `RateLimit-Limit=${headroom.headers.get('ratelimit-limit')} Remaining=${remaining} Reset=${headroom.headers.get('ratelimit-reset')}`);
90
117
  const get = await fetch(t.endpoint);
91
118
  t.check('GET→405', get.status === 405 && get.headers.get('access-control-allow-origin') === '*', `${get.status} Allow=${get.headers.get('allow')} ACAO=${get.headers.get('access-control-allow-origin')}`);
92
119
  // A notification has no id, so it must be acknowledged with no body at all —
@@ -110,8 +137,32 @@ expectedCapabilities = ['tools']) {
110
137
  t.check('batch cap (21)', overJson.error?.code === -32600, `code=${overJson.error?.code}: ${(overJson.error?.message ?? '').slice(0, 80)}`);
111
138
  const caps = init.result?.capabilities ?? {};
112
139
  t.check('capabilities honest', expectedCapabilities.every(k => k in caps), `${JSON.stringify(caps)} expected=[${expectedCapabilities.join(', ')}]`);
140
+ // Declaring `resources` makes a client ask for templates. -32601 to a method
141
+ // the capability implies reads as a broken server, not as "none registered".
142
+ if ('resources' in caps) {
143
+ const templates = await t.rpc('resources/templates/list');
144
+ t.check('resources/templates/list', Array.isArray(templates.result?.resourceTemplates), templates.error ? `-${templates.error.code}` : `${templates.result?.resourceTemplates?.length} templates`);
145
+ }
146
+ const versioned = await fetch(t.endpoint, {
147
+ method: 'POST',
148
+ headers: { 'Content-Type': 'application/json', 'MCP-Protocol-Version': CURRENT_PROTOCOL },
149
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'ping' }),
150
+ });
151
+ t.recordCall();
152
+ t.check('MCP-Protocol-Version echoed', versioned.headers.get('mcp-protocol-version') === CURRENT_PROTOCOL, `sent ${CURRENT_PROTOCOL}, got ${versioned.headers.get('mcp-protocol-version')}`);
153
+ // Batching was removed in 2025-06-18. A server that keeps honouring it under
154
+ // a version that forbids it is telling the client something untrue.
155
+ const batched = await fetch(t.endpoint, {
156
+ method: 'POST',
157
+ headers: { 'Content-Type': 'application/json', 'MCP-Protocol-Version': CURRENT_PROTOCOL },
158
+ body: JSON.stringify([{ jsonrpc: '2.0', id: 1, method: 'ping' }]),
159
+ });
160
+ t.recordCall();
161
+ t.check('batch refused at 2025-06-18', batched.status === 400, `${batched.status}`);
113
162
  return init;
114
163
  }
164
+ /** The newest protocol revision `wiki-formant/mcp` speaks. */
165
+ export const CURRENT_PROTOCOL = '2025-06-18';
115
166
  /**
116
167
  * One service, many descriptors — server.json, the two agent-card paths, the
117
168
  * OpenAPI document, the MCP server card, and `initialize` — should never
@@ -142,25 +193,183 @@ export async function agentCardParity(t) {
142
193
  fetch(`${t.base}/.well-known/agent.json`).then(r => r.json()),
143
194
  ]);
144
195
  t.check('agent card parity', JSON.stringify(a) === JSON.stringify(b), 'agent.json === agent-card.json');
196
+ // A card missing a required field is a card a spec-current client rejects, and
197
+ // parity alone happily reports two identical unusable ones.
198
+ const required = [
199
+ 'protocolVersion',
200
+ 'name',
201
+ 'description',
202
+ 'url',
203
+ 'preferredTransport',
204
+ 'version',
205
+ 'capabilities',
206
+ 'skills',
207
+ 'defaultInputModes',
208
+ 'defaultOutputModes',
209
+ ];
210
+ const missing = required.filter(k => a[k] === undefined);
211
+ t.check('agent card complete', missing.length === 0, missing.length ? `missing: ${missing.join(', ')}` : `A2A ${a.protocolVersion}`);
212
+ // `url` is where a client sends its first call. Pointed at the homepage it
213
+ // gets HTML back, which is the failure that looks like a broken agent.
214
+ const endpoint = String(a.url ?? '');
215
+ const probe = await fetch(endpoint, {
216
+ method: 'POST',
217
+ headers: { 'Content-Type': 'application/json' },
218
+ body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'ping' }),
219
+ });
220
+ t.recordCall();
221
+ t.check('agent card url is callable', (probe.headers.get('content-type') ?? '').includes('json'), `POST ${endpoint} -> ${probe.status} ${probe.headers.get('content-type')}`);
145
222
  }
146
223
  /**
147
- * A corpus export that costs a full render should answer a conditional GET with
148
- * a 304. Checks each path serves an ETag and honours it on the way back.
224
+ * Any surface an agent recrawls should answer a conditional GET with a 304.
225
+ *
226
+ * Point this at every such surface, not only the corpus exports. Aimed solely
227
+ * at the `llms.*` family — the paths that already had validators — it reported
228
+ * green across three origins whose markdown twins, agent cards and OpenAPI
229
+ * documents carried no ETag at all. A check that only looks where it knows it
230
+ * will pass is a check that measures nothing.
149
231
  */
150
232
  export async function conditionalGetChecks(t, paths) {
151
233
  for (const path of paths) {
152
- const fresh = await fetch(`${t.base}/${path}`);
234
+ const url = path.startsWith('http') ? path : `${t.base}/${path.replace(/^\//, '')}`;
235
+ const label = path.replace(t.base, '');
236
+ const fresh = await fetch(url);
153
237
  const etag = fresh.headers.get('etag');
154
238
  // Both validators, not just the one the 304 is driven by. A crawler that
155
239
  // sends If-Modified-Since rather than If-None-Match — and several do — gets
156
240
  // a full render on every pass from a response that carries no Last-Modified,
157
- // and the ETag check alone would call that surface conformant. acuiq2's
158
- // suite asserted this locally; adopting the shared check should not have
159
- // been a trade.
241
+ // and the ETag check alone would call that surface conformant.
160
242
  const lastModified = fresh.headers.get('last-modified');
161
- const revalidated = etag ? await fetch(`${t.base}/${path}`, { headers: { 'If-None-Match': etag } }) : null;
162
- t.check(`${path} 304`, !!etag && revalidated?.status === 304, `etag=${etag} revalidate=${revalidated?.status}`);
163
- t.check(`${path} last-modified`, !!lastModified, `${fresh.status} ${lastModified}`);
243
+ const revalidated = etag ? await fetch(url, { headers: { 'If-None-Match': etag } }) : null;
244
+ t.check(`${label} 304`, !!etag && revalidated?.status === 304, `etag=${etag} revalidate=${revalidated?.status}`);
245
+ t.check(`${label} last-modified`, !!lastModified, `${fresh.status} ${lastModified}`);
246
+ // A list is what a client that holds two revisions actually sends, and the
247
+ // weak prefix is what a proxy adds in transit. Exact string equality passes
248
+ // the check above and fails both of these.
249
+ if (etag) {
250
+ const listed = await fetch(url, { headers: { 'If-None-Match': `W/"stale-x", ${etag}` } });
251
+ t.check(`${label} 304 (etag list)`, listed.status === 304, `${listed.status}`);
252
+ }
253
+ }
254
+ }
255
+ /**
256
+ * A JSON descriptor is revalidatable — an agent card, an OpenAPI document, a
257
+ * registry manifest, a server card.
258
+ *
259
+ * Separate from `conditionalGetChecks` because the contract genuinely differs:
260
+ * a descriptor is built from code, not from rows, so it has no honest
261
+ * `Last-Modified` to offer. A stamp taken at cold start would move without the
262
+ * document moving, which is worse than none. The body-derived ETag is the whole
263
+ * validator, and it is enough.
264
+ */
265
+ export async function descriptorChecks(t, paths) {
266
+ for (const path of paths) {
267
+ const url = path.startsWith('http') ? path : `${t.base}/${path.replace(/^\//, '')}`;
268
+ const label = path.replace(t.base, '');
269
+ const fresh = await fetch(url);
270
+ const etag = fresh.headers.get('etag');
271
+ const json = (fresh.headers.get('content-type') ?? '').includes('json');
272
+ const revalidated = etag ? await fetch(url, { headers: { 'If-None-Match': etag } }) : null;
273
+ t.check(`${label} revalidates`, !!etag && json && revalidated?.status === 304, `${fresh.status} ${fresh.headers.get('content-type')} etag=${etag} revalidate=${revalidated?.status}`);
274
+ // No max-age at all leaves a caller on heuristic freshness, which for a
275
+ // document with no Last-Modified means it may never refetch at all.
276
+ t.check(`${label} states a freshness`, /max-age=\d+/.test(fresh.headers.get('cache-control') ?? ''), `cache-control: ${fresh.headers.get('cache-control')}`);
277
+ }
278
+ }
279
+ /**
280
+ * Every tool carries behavioural hints, and the ones that write say so.
281
+ *
282
+ * Without them a client that auto-approves read-only calls has no way to tell a
283
+ * lookup from one that signs a transaction — and two of the three servers here
284
+ * shipped write tools with no annotations at all.
285
+ */
286
+ export async function annotationChecks(t, opts = {}) {
287
+ const tools = (await t.rpc('tools/list')).result?.tools ?? [];
288
+ const writes = new Set(opts.writes ?? []);
289
+ const unannotated = tools.filter(x => x.annotations?.readOnlyHint === undefined);
290
+ t.check('tools annotated', unannotated.length === 0, unannotated.length ? `missing readOnlyHint: ${unannotated.map(x => x.name).join(', ')}` : `${tools.length} tools`);
291
+ const mislabelled = tools.filter(x => writes.has(x.name) && x.annotations?.readOnlyHint !== false);
292
+ t.check('writes not marked read-only', mislabelled.length === 0, mislabelled.length ? mislabelled.map(x => x.name).join(', ') : `${writes.size} write tools`);
293
+ const thin = tools.filter(x => (x.description ?? '').length < 120);
294
+ t.check('descriptions carry a usage note', thin.length === 0, thin.length ? thin.map(x => `${x.name}:${(x.description ?? '').length}ch`).join(' ') : `min ${Math.min(...tools.map(x => (x.description ?? '').length))}ch`);
295
+ }
296
+ /**
297
+ * The orientation calls stay inside a context window.
298
+ *
299
+ * A tool that passes a metadata column straight through is one stored blob away
300
+ * from returning 350 KB — around 90k tokens — from the first call an agent
301
+ * makes. Nothing in a pass/fail table notices that unless something weighs the
302
+ * answer, so this weighs it.
303
+ */
304
+ export async function payloadBudget(t, calls, maxBytes = 120_000) {
305
+ // Every read-only tool a caller can invoke with no arguments at all, whether
306
+ // or not the suite thought to name it. This check used to weigh only the
307
+ // listed calls, which is how a tool taking no parameters and answering with
308
+ // 3.3 MB — 27× the budget it was exempt from — passed a suite that measured
309
+ // the four tools beside it. A tool with required arguments still has to be
310
+ // listed: the suite is the only thing that knows a valid pair.
311
+ const listed = new Set(calls.map(c => c.name));
312
+ const bare = ((await t.rpc('tools/list')).result?.tools ?? [])
313
+ .filter(x => x.annotations?.readOnlyHint === true && !listed.has(x.name))
314
+ // `requireOneOf` is a required argument too, just one this cannot pick for
315
+ // the caller — such a tool has to be listed with args like any other.
316
+ .filter(x => !(x.inputSchema?.required ?? []).length && !(x.inputSchema?.requireOneOf ?? []).length)
317
+ .map(x => ({ name: x.name, args: undefined, maxBytes: undefined }));
318
+ for (const { name, args, maxBytes: own } of [...calls, ...bare]) {
319
+ const budget = own ?? maxBytes;
320
+ const answer = await t.call(name, args ?? {});
321
+ const text = answer.result?.content?.[0]?.text ?? '';
322
+ // An empty answer is not a small one. The first draft compared only the
323
+ // length, so a call that failed outright — a cold connection pool timing
324
+ // out, in the run that caught this — reported `PASS 0 chars` and the check
325
+ // measured nothing. A budget that green-lights a call that never returned
326
+ // is the exact failure it exists to catch.
327
+ const answered = text.length > 0 && !answer.error && !answer.result?.isError;
328
+ t.check(`${name} within budget`, answered && text.length <= budget, answered
329
+ ? `${text.length.toLocaleString()} chars (max ${budget.toLocaleString()})`
330
+ : `no answer to weigh: ${answer.error ? `-${answer.error.code} ${answer.error.message}` : answer.result?.isError ? `isError: ${text.slice(0, 80)}` : 'empty result'}`);
331
+ // A JSON answer that arrives only as prose costs every client a parse it
332
+ // should never have had to write. Measured on the answer already in hand,
333
+ // so it is free — and it stays quiet for a tool that genuinely returns
334
+ // prose, which is the only reason a read tool may skip it.
335
+ if (answered && /^\s*\{/.test(text)) {
336
+ t.check(`${name} structured`, answer.result?.structuredContent !== undefined, answer.result?.structuredContent !== undefined
337
+ ? 'structuredContent beside the text'
338
+ : 'JSON answer with no structuredContent — the client has to parse prose');
339
+ }
340
+ }
341
+ }
342
+ /**
343
+ * The default `User-agent: *` group may reach everything the descriptors
344
+ * advertise.
345
+ *
346
+ * An origin whose card names an MCP endpoint its own robots.txt disallows to
347
+ * every unnamed crawler is telling two different stories to the same caller.
348
+ */
349
+ export async function robotsChecks(t, paths) {
350
+ const body = await (await fetch(`${t.base}/robots.txt`)).text();
351
+ const rules = [];
352
+ let inStar = false;
353
+ for (const raw of body.split('\n')) {
354
+ const line = raw.replace(/#.*$/, '').trim();
355
+ const [field, ...rest] = line.split(':');
356
+ if (!field || !rest.length)
357
+ continue;
358
+ const key = field.trim().toLowerCase();
359
+ const value = rest.join(':').trim();
360
+ if (key === 'user-agent')
361
+ inStar = value === '*';
362
+ else if (inStar && (key === 'allow' || key === 'disallow') && value) {
363
+ rules.push({ allow: key === 'allow', path: value });
364
+ }
365
+ }
366
+ for (const path of paths) {
367
+ // Longest match wins, Allow breaking a tie — the rule every major crawler
368
+ // implements.
369
+ const match = rules
370
+ .filter(r => path.startsWith(r.path.replace(/\*$/, '')))
371
+ .sort((a, b) => b.path.length - a.path.length || Number(b.allow) - Number(a.allow))[0];
372
+ t.check(`robots allows ${path}`, !match || match.allow, match ? `${match.allow ? 'Allow' : 'Disallow'}: ${match.path}` : 'no matching rule');
164
373
  }
165
374
  }
166
375
  //# sourceMappingURL=conformance.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"conformance.js","sourceRoot":"","sources":["../src/conformance.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"crawlers.d.ts","sourceRoot":"","sources":["../src/crawlers.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,SAAS;IACxB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAuB3C,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAM/E;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC5B,GAAG,WAAW,EAAE,CAShB"}
1
+ {"version":3,"file":"crawlers.d.ts","sourceRoot":"","sources":["../src/crawlers.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,SAAS;IACxB,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAuB3C,CAAC;AAEF,gFAAgF;AAChF,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAM/E;AAED,8EAA8E;AAC9E,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IACnC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC5B,OAAO,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CAC5B,GAAG,WAAW,EAAE,CAgBhB"}
package/dist/crawlers.js CHANGED
@@ -68,11 +68,18 @@ export function aiCrawlerTokens() {
68
68
  * agent everything, because it stops matching `*` the moment it matches itself.
69
69
  */
70
70
  export function aiCrawlerRules(opts) {
71
+ const aiAllow = [opts.aiAllow].flat();
71
72
  return [
72
- { userAgent: '*', allow: opts.allow, disallow: opts.disallow },
73
+ // `aiAllow` rides on the default group too, not only on the named roster.
74
+ // The agent surface an origin advertises has to be reachable by a caller it
75
+ // has never heard of: two origins here disallowed `/api/` under `*` while
76
+ // their own agent card named `/api/mcp`, so an MCP client that identified
77
+ // honestly as itself was told the endpoint was off limits. The roster is
78
+ // for indexing policy, not for hiding a documented endpoint.
79
+ { userAgent: '*', allow: [...new Set([...[opts.allow].flat(), ...aiAllow])], disallow: opts.disallow },
73
80
  ...aiCrawlerTokens().map(userAgent => ({
74
81
  userAgent,
75
- allow: opts.aiAllow,
82
+ allow: aiAllow,
76
83
  disallow: opts.disallow,
77
84
  })),
78
85
  ];
@@ -1 +1 @@
1
- {"version":3,"file":"crawlers.js","sourceRoot":"","sources":["../src/crawlers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crawlers.js","sourceRoot":"","sources":["../src/crawlers.ts"],"names":[],"mappings":"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"}
package/dist/http.d.ts CHANGED
@@ -1,7 +1,27 @@
1
1
  /** A stable ETag from whatever the corpus revision is (count + newest stamp). */
2
2
  export declare function corpusEtag(parts: Array<string | number | Date | null | undefined>): string;
3
- /** 304 when the client already holds this revision, else `null` to render. */
4
- export declare function notModified(request: Request, etag: string, lastModified: string): Response | null;
3
+ /**
4
+ * 304 when the client already holds this revision, else `null` to render.
5
+ *
6
+ * Both validators are matched the way RFC 9110 defines them rather than by
7
+ * string equality, because equality is wrong in the cases that actually occur:
8
+ * a client sends every tag it holds as a list, a proxy adds or strips the weak
9
+ * prefix, and a crawler reformats the date. Each of those took a full render
10
+ * from a response that was already fresh.
11
+ */
12
+ export declare function notModified(request: Request, etag: string, lastModified?: string | null): Response | null;
13
+ /**
14
+ * A 404 that teaches, for the plain-GET half of an agent surface.
15
+ *
16
+ * The MCP half of every server here answers a wrong identifier by naming the
17
+ * tools that find a right one. The GET half, reached by exactly the agents that
18
+ * guessed a URL, answered the same mistake with `Page not found`, `Not found`,
19
+ * and in one case a 26 KB HTML error page — nothing to retry from. `hints` are
20
+ * merged into the body, so an index URL or a nearest match rides along. A
21
+ * missing page is a hot crawler path, so it is cacheable by default; pass
22
+ * `cacheControl` where the surface has its own edge posture.
23
+ */
24
+ export declare function teachingNotFound(message: string, hints?: Record<string, unknown>, cacheControl?: string): Response;
5
25
  /**
6
26
  * Headers for a plain-text export. `maxAge` is the edge window — a curated
7
27
  * corpus can sit on hours, a projection of live data should pass a short one.
@@ -16,11 +36,42 @@ export declare function textHeaders(etag: string, lastModified: string, maxAge?:
16
36
  * offer, and a twin that stamps the epoch is worse than one that stamps
17
37
  * nothing. `extra` carries whatever the mount needs on top — an `X-Robots-Tag`
18
38
  * where the twin is a second public URL with no canonical of its own.
39
+ *
40
+ * Pass `etag`. The twin is the single most recrawled URL a page has, and a
41
+ * response with no validator is a full render on every pass forever — the same
42
+ * arithmetic that justifies the corpus ETag, applied per page. Three wikis
43
+ * shipped twins with neither validator and only 304'd where a proxy happened to
44
+ * synthesise one; that is why it is spelled out here rather than left optional
45
+ * in spirit.
19
46
  */
20
47
  export declare function markdownHeaders(lastModified?: string | null, opts?: {
21
48
  maxAge?: number;
49
+ etag?: string;
22
50
  extra?: Record<string, string>;
23
51
  }): Record<string, string>;
52
+ /**
53
+ * Headers for a JSON descriptor — an agent card, an OpenAPI document, a
54
+ * registry manifest. These are the documents a client refetches most and the
55
+ * ones that had no validator at all: served as `Cache-Control: public` with no
56
+ * `max-age`, a caller falls back to heuristic freshness and can never
57
+ * revalidate, so a corrected card takes an unbounded time to reach anyone.
58
+ */
59
+ export declare function descriptorHeaders(etag: string, opts?: {
60
+ maxAge?: number;
61
+ extra?: Record<string, string>;
62
+ }): Record<string, string>;
63
+ /**
64
+ * A JSON descriptor served with a validator, answering a conditional GET.
65
+ *
66
+ * The body is its own ETag source, so the tag moves exactly when the document
67
+ * does and never otherwise. Every descriptor route in this workspace was a
68
+ * hand-rolled `NextResponse.json` with a Cache-Control and no validator at all,
69
+ * which is why a corrected agent card took an unbounded time to reach anyone.
70
+ */
71
+ export declare function descriptorResponse(request: Request, body: unknown, opts?: {
72
+ maxAge?: number;
73
+ extra?: Record<string, string>;
74
+ }): Response;
24
75
  /** Strip URLs and collapse whitespace so an excerpt stays one readable line. */
25
76
  export declare function cleanSnippet(text: string, max?: number): string;
26
77
  /** One markdown bullet: linked title, excerpt, and the date an agent diffs on. */