@ashlar-blue/x402-trust 0.3.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/LICENSE +21 -0
- package/README.md +198 -0
- package/dist/attested-directory.d.ts +78 -0
- package/dist/attested-directory.d.ts.map +1 -0
- package/dist/attested-directory.js +163 -0
- package/dist/attested-directory.js.map +1 -0
- package/dist/badges.d.ts +131 -0
- package/dist/badges.d.ts.map +1 -0
- package/dist/badges.js +213 -0
- package/dist/badges.js.map +1 -0
- package/dist/catalog-mcp.d.ts +145 -0
- package/dist/catalog-mcp.d.ts.map +1 -0
- package/dist/catalog-mcp.js +409 -0
- package/dist/catalog-mcp.js.map +1 -0
- package/dist/census-reconcile.d.ts +69 -0
- package/dist/census-reconcile.d.ts.map +1 -0
- package/dist/census-reconcile.js +162 -0
- package/dist/census-reconcile.js.map +1 -0
- package/dist/directory-classify.d.ts +47 -0
- package/dist/directory-classify.d.ts.map +1 -0
- package/dist/directory-classify.js +54 -0
- package/dist/directory-classify.js.map +1 -0
- package/dist/discovery.d.ts +304 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +926 -0
- package/dist/discovery.js.map +1 -0
- package/dist/evidence-ref.d.ts +96 -0
- package/dist/evidence-ref.d.ts.map +1 -0
- package/dist/evidence-ref.js +179 -0
- package/dist/evidence-ref.js.map +1 -0
- package/dist/facilitator-config.d.ts +83 -0
- package/dist/facilitator-config.d.ts.map +1 -0
- package/dist/facilitator-config.js +94 -0
- package/dist/facilitator-config.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest-sig.d.ts +131 -0
- package/dist/manifest-sig.d.ts.map +1 -0
- package/dist/manifest-sig.js +262 -0
- package/dist/manifest-sig.js.map +1 -0
- package/dist/merkle-transcript.d.ts +34 -0
- package/dist/merkle-transcript.d.ts.map +1 -0
- package/dist/merkle-transcript.js +162 -0
- package/dist/merkle-transcript.js.map +1 -0
- package/dist/open-catalog.d.ts +111 -0
- package/dist/open-catalog.d.ts.map +1 -0
- package/dist/open-catalog.js +307 -0
- package/dist/open-catalog.js.map +1 -0
- package/dist/reconcile.d.ts +150 -0
- package/dist/reconcile.d.ts.map +1 -0
- package/dist/reconcile.js +136 -0
- package/dist/reconcile.js.map +1 -0
- package/dist/trust-sdk.d.ts +127 -0
- package/dist/trust-sdk.d.ts.map +1 -0
- package/dist/trust-sdk.js +147 -0
- package/dist/trust-sdk.js.map +1 -0
- package/dist/types.d.ts +213 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +68 -0
- package/dist/types.js.map +1 -0
- package/package.json +52 -0
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
// GENERATED from src/x402/catalog-mcp.ts by scripts/sdk/sync-sdk.ts — do not edit here.
|
|
2
|
+
// The canonical module is the one FlareClaw runs in production; this is a copy so
|
|
3
|
+
// that what we publish and what we run cannot diverge. Edit the canonical file.
|
|
4
|
+
/**
|
|
5
|
+
* The x402 Open Catalog — public MCP server core.
|
|
6
|
+
*
|
|
7
|
+
* Protocol posture (SEP-2575 review, docs/plans/x402/2026-08-14-sep-2575-
|
|
8
|
+
* stateless-mcp-review.md): primary = the RELEASED stateless spec revision
|
|
9
|
+
* 2026-07-28 — every request self-contained, no sessions, POST-only JSON —
|
|
10
|
+
* plus a thin LEGACY SHIM answering `initialize` for the deployed-client
|
|
11
|
+
* majority (≤2025-11-25). The shim is legal statelessly: `Mcp-Session-Id`
|
|
12
|
+
* was always optional pre-2575, and no tool here needs cross-call state.
|
|
13
|
+
*
|
|
14
|
+
* This module is transport-free on purpose: it maps one parsed JSON body +
|
|
15
|
+
* two headers to one {status, body} answer, so the facilitator wires it to
|
|
16
|
+
* Express in a few lines and tests drive it with zero network.
|
|
17
|
+
*
|
|
18
|
+
* Evidence doctrine (#3149, three info-loss instances in one week): the
|
|
19
|
+
* snapshot digest + on-chain anchor ride BOTH the result `_meta`
|
|
20
|
+
* (`app.flareclaw/evidence`, the sanctioned server-metadata slot per
|
|
21
|
+
* #3002) AND the human-readable content, because clients demonstrably
|
|
22
|
+
* drop `_meta` before the caller sees it.
|
|
23
|
+
*
|
|
24
|
+
* Cache doctrine (SEP-2549): catalog reads carry `cacheScope: "public"`
|
|
25
|
+
* with a `ttlMs` derived from the actual refresh cadence — the hint tells
|
|
26
|
+
* the truth about when the underlying anchored snapshot can change.
|
|
27
|
+
*
|
|
28
|
+
* Tool names use underscores (`catalog_search`), not dots: several
|
|
29
|
+
* deployed clients validate names against [a-zA-Z0-9_-] and a
|
|
30
|
+
* distribution wedge must not fail the strictest common validator.
|
|
31
|
+
*/
|
|
32
|
+
import { queryCatalog, catalogStats, catalogSnapshotDigest, loadCatalog, } from './open-catalog.js';
|
|
33
|
+
export const MCP_PROTOCOL_STATELESS = '2026-07-28';
|
|
34
|
+
/** Newest first; `initialize` negotiation answers with the first of these. */
|
|
35
|
+
export const MCP_PROTOCOL_LEGACY = ['2025-11-25', '2025-06-18', '2025-03-26'];
|
|
36
|
+
export const MCP_SUPPORTED_VERSIONS = [MCP_PROTOCOL_STATELESS, ...MCP_PROTOCOL_LEGACY];
|
|
37
|
+
const META_PROTOCOL_KEY = 'io.modelcontextprotocol/protocolVersion';
|
|
38
|
+
const EVIDENCE_META_KEY = 'app.flareclaw/evidence';
|
|
39
|
+
/** JSON-RPC error codes — spec-assigned, not ours to invent. */
|
|
40
|
+
const E_PARSE = -32700;
|
|
41
|
+
const E_INVALID_REQUEST = -32600;
|
|
42
|
+
const E_METHOD_NOT_FOUND = -32601; // HTTP 404 per 2026-07-28
|
|
43
|
+
const E_INVALID_PARAMS = -32602;
|
|
44
|
+
const E_UNSUPPORTED_PROTOCOL = -32022; // HTTP 400, lists `supported`
|
|
45
|
+
const E_MISSING_CLIENT_CAPABILITY = -32021;
|
|
46
|
+
export const CATALOG_MCP_SERVER_INFO = {
|
|
47
|
+
name: 'flareclaw-open-catalog',
|
|
48
|
+
title: 'The x402 Open Catalog',
|
|
49
|
+
version: '0.1.0',
|
|
50
|
+
};
|
|
51
|
+
const INSTRUCTIONS = 'The x402 Open Catalog over MCP: a community-run, provenance-tagged index of x402 '
|
|
52
|
+
+ 'resources — the CDP Bazaar mirrored via its own public API, plus discovery-crawled '
|
|
53
|
+
+ 'records (#2979) carrying independently-checkable attestation status. Nothing here is '
|
|
54
|
+
+ 'an endorsement: every row names its source and how to re-derive it without trusting '
|
|
55
|
+
+ 'this server, and every result carries the served snapshot\'s sha256 digest plus its '
|
|
56
|
+
+ 'on-chain anchor (x402cat/1 self-tx on Flare Coston2) in both _meta and content.';
|
|
57
|
+
function errorAnswer(status, id, code, message, data) {
|
|
58
|
+
return {
|
|
59
|
+
status,
|
|
60
|
+
body: { jsonrpc: '2.0', id, error: { code, message, ...(data !== undefined ? { data } : {}) } },
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function isPlainObject(v) {
|
|
64
|
+
return typeof v === 'object' && v !== null && !Array.isArray(v);
|
|
65
|
+
}
|
|
66
|
+
// ── Evidence + cache hints ───────────────────────────────────────────
|
|
67
|
+
function evidenceBlock(deps) {
|
|
68
|
+
const explorer = deps.explorerBase ?? 'https://coston2-explorer.flare.network';
|
|
69
|
+
const anchor = deps.anchor?.() ?? null;
|
|
70
|
+
return {
|
|
71
|
+
snapshotDigest: catalogSnapshotDigest(deps.statePath),
|
|
72
|
+
// The anchored digest may legitimately LAG the served one between a
|
|
73
|
+
// refresh and its anchor confirmation — both are exposed so the lag
|
|
74
|
+
// is visible, never hidden (honest-manifest doctrine).
|
|
75
|
+
anchor: anchor ? { ...anchor, explorer: `${explorer}/tx/${anchor.tx}` } : null,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
function evidenceSentence(ev) {
|
|
79
|
+
const anchor = ev.anchor;
|
|
80
|
+
const served = ev.snapshotDigest ?? 'none (no snapshot yet)';
|
|
81
|
+
if (!anchor)
|
|
82
|
+
return `Evidence: served snapshot ${served}; no on-chain anchor yet this boot.`;
|
|
83
|
+
const lag = anchor.digest === ev.snapshotDigest ? '' : ' (anchor lags the served snapshot — refresh newer than last anchor)';
|
|
84
|
+
return `Evidence: served snapshot ${served}; anchored on Coston2 by ${anchor.tx} (${anchor.explorer})${lag}.`;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* ttl = time until the serving process's next scheduled refresh, floored
|
|
88
|
+
* at one minute. Derived from the snapshot's own timestamps so the hint
|
|
89
|
+
* cannot claim freshness the process doesn't deliver.
|
|
90
|
+
*/
|
|
91
|
+
function snapshotTtlMs(deps) {
|
|
92
|
+
const s = loadCatalog(deps.statePath);
|
|
93
|
+
const last = Math.max(s.crawledAt ? Date.parse(s.crawledAt) || 0 : 0, s.mirrorFetchedAt ? Date.parse(s.mirrorFetchedAt) || 0 : 0);
|
|
94
|
+
if (!last)
|
|
95
|
+
return 60_000;
|
|
96
|
+
const interval = deps.refreshIntervalMs ?? 12 * 3_600_000;
|
|
97
|
+
const now = deps.now?.() ?? Date.now();
|
|
98
|
+
return Math.max(60_000, last + interval - now);
|
|
99
|
+
}
|
|
100
|
+
/** Every result carries serverInfo (spec SHOULD) + resultType (required). */
|
|
101
|
+
function decorate(result, deps, opts) {
|
|
102
|
+
const meta = { serverInfo: CATALOG_MCP_SERVER_INFO };
|
|
103
|
+
if (opts?.evidence)
|
|
104
|
+
meta[EVIDENCE_META_KEY] = evidenceBlock(deps);
|
|
105
|
+
return {
|
|
106
|
+
...result,
|
|
107
|
+
resultType: 'success',
|
|
108
|
+
...(opts?.ttlMs !== undefined ? { ttlMs: opts.ttlMs, cacheScope: opts.cacheScope ?? 'public' } : {}),
|
|
109
|
+
_meta: { ...(result._meta ?? {}), ...meta },
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
// ── Tools ────────────────────────────────────────────────────────────
|
|
113
|
+
/** Alphabetical and stays that way: deterministic tools/list order is a
|
|
114
|
+
* spec requirement (prompt-cache friendliness), enforced by a test. */
|
|
115
|
+
export const CATALOG_MCP_TOOLS = [
|
|
116
|
+
{
|
|
117
|
+
name: 'catalog_get',
|
|
118
|
+
description: 'Look up Open Catalog entries for one resource URL or domain, across both provenance lanes (bazaar-mirror + discovery). Returns every matching row with its source and re-derivation recipe.',
|
|
119
|
+
inputSchema: {
|
|
120
|
+
type: 'object',
|
|
121
|
+
properties: {
|
|
122
|
+
resource: { type: 'string', description: 'Resource URL (exact or prefix) or a bare domain name' },
|
|
123
|
+
},
|
|
124
|
+
required: ['resource'],
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'catalog_search',
|
|
129
|
+
description: 'Query the Open Catalog: filter by source (bazaar-mirror | discovery), network, or independently-verifiable attestation; paginated. Every row is provenance-tagged — how to re-derive it without trusting this server.',
|
|
130
|
+
inputSchema: {
|
|
131
|
+
type: 'object',
|
|
132
|
+
properties: {
|
|
133
|
+
source: { type: 'string', enum: ['bazaar-mirror', 'discovery'] },
|
|
134
|
+
network: { type: 'string', description: 'e.g. "coston2", "base", "eip155:114"' },
|
|
135
|
+
attested: { type: 'boolean', description: 'true → only entries whose attestation claim is independently checkable' },
|
|
136
|
+
limit: { type: 'number', description: '1–500, default 50' },
|
|
137
|
+
offset: { type: 'number' },
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'catalog_stats',
|
|
143
|
+
description: 'Headline numbers: mirrored vs discovered vs attested counts, networks the Bazaar structurally excludes, the served snapshot\'s sha256 digest and its on-chain anchor.',
|
|
144
|
+
inputSchema: { type: 'object', properties: {} },
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'reconcile',
|
|
148
|
+
description: 'Determinate verdict for one EIP-3009 payment authorization on the Coston2 rail: settled (with the settlement tx + transfers), refused-not-charged (window closed, nonce unconsumed — can never settle), or indeterminate with a machine-readable reason. Every verdict re-derivable from public RPC: authorizationState + AuthorizationUsed logs.',
|
|
149
|
+
inputSchema: {
|
|
150
|
+
type: 'object',
|
|
151
|
+
properties: {
|
|
152
|
+
asset: { type: 'string', description: 'EIP-3009 asset contract address (0x…)' },
|
|
153
|
+
payer: { type: 'string', description: 'The authorizer — the `from` of the authorization (0x…)' },
|
|
154
|
+
nonce: { type: 'string', description: 'The 32-byte authorization nonce (0x + 64 hex)' },
|
|
155
|
+
validBefore: { type: 'number', description: 'The authorization\'s validBefore (unix seconds). Required to prove refused-not-charged: an unconsumed nonce inside its window could still settle.' },
|
|
156
|
+
},
|
|
157
|
+
required: ['asset', 'payer', 'nonce'],
|
|
158
|
+
},
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
name: 'verify_host',
|
|
162
|
+
description: 'Two-observation verdict for a hostname: a LIVE x402 discovery resolution (DNS TXT → /.well-known/x402 → live capability cross-check) compared against this catalog\'s last anchored crawl observation. Discovery is not endorsement; this reports checkability, not trustworthiness.',
|
|
163
|
+
inputSchema: {
|
|
164
|
+
type: 'object',
|
|
165
|
+
properties: {
|
|
166
|
+
domain: { type: 'string', description: 'Bare hostname, e.g. "api.flareclaw.app"' },
|
|
167
|
+
},
|
|
168
|
+
required: ['domain'],
|
|
169
|
+
},
|
|
170
|
+
},
|
|
171
|
+
];
|
|
172
|
+
const HOSTNAME_RE = /^(?=.{4,253}$)[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,62}[a-z0-9])?)+$/i;
|
|
173
|
+
function toolResult(deps, summary, structured, opts) {
|
|
174
|
+
const ev = evidenceBlock(deps);
|
|
175
|
+
// Belt and suspenders (#3149): evidence in content AND _meta.
|
|
176
|
+
const text = `${summary}\n${evidenceSentence(ev)}\n\n${JSON.stringify(structured, null, 2)}`;
|
|
177
|
+
return decorate({
|
|
178
|
+
content: [{ type: 'text', text }],
|
|
179
|
+
structuredContent: { ...structured, evidence: ev },
|
|
180
|
+
isError: false,
|
|
181
|
+
}, deps, { ...opts, evidence: true });
|
|
182
|
+
}
|
|
183
|
+
async function callTool(id, name, args, deps) {
|
|
184
|
+
const ok = (result) => ({ status: 200, body: { jsonrpc: '2.0', id, result } });
|
|
185
|
+
switch (name) {
|
|
186
|
+
case 'catalog_search': {
|
|
187
|
+
const q = {
|
|
188
|
+
...(args.source === 'bazaar-mirror' || args.source === 'discovery' ? { source: args.source } : {}),
|
|
189
|
+
...(typeof args.network === 'string' ? { network: args.network } : {}),
|
|
190
|
+
...(args.attested === true ? { attested: true } : {}),
|
|
191
|
+
...(typeof args.limit === 'number' ? { limit: args.limit } : {}),
|
|
192
|
+
...(typeof args.offset === 'number' ? { offset: args.offset } : {}),
|
|
193
|
+
};
|
|
194
|
+
const r = queryCatalog(q, deps.statePath);
|
|
195
|
+
return ok(toolResult(deps, `${r.pagination.total} matching entries (returning ${r.rows.length} from offset ${r.pagination.offset}).`, r, { ttlMs: snapshotTtlMs(deps) }));
|
|
196
|
+
}
|
|
197
|
+
case 'catalog_get': {
|
|
198
|
+
const needle = typeof args.resource === 'string' ? args.resource.trim().toLowerCase() : '';
|
|
199
|
+
if (!needle)
|
|
200
|
+
return errorAnswer(400, id, E_INVALID_PARAMS, 'catalog_get requires a non-empty "resource" string');
|
|
201
|
+
const s = loadCatalog(deps.statePath);
|
|
202
|
+
const rows = [];
|
|
203
|
+
for (const d of s.discovered) {
|
|
204
|
+
const base = (d.baseUrl ?? `https://${d.domain}`).toLowerCase();
|
|
205
|
+
if (d.domain.toLowerCase() === needle || base === needle || base.startsWith(needle)
|
|
206
|
+
|| d.resources.some(u => u.toLowerCase().startsWith(needle))) {
|
|
207
|
+
rows.push({ source: 'discovery', ...d });
|
|
208
|
+
}
|
|
209
|
+
if (rows.length >= 50)
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
for (const m of s.mirror) {
|
|
213
|
+
const r = m.resource.toLowerCase();
|
|
214
|
+
if (r === needle || r.startsWith(needle) || r.includes(`//${needle}/`) || r.endsWith(`//${needle}`)) {
|
|
215
|
+
rows.push({ source: 'bazaar-mirror', ...m });
|
|
216
|
+
}
|
|
217
|
+
if (rows.length >= 50)
|
|
218
|
+
break;
|
|
219
|
+
}
|
|
220
|
+
return ok(toolResult(deps, rows.length ? `${rows.length} entr${rows.length === 1 ? 'y' : 'ies'} for "${needle}" (capped at 50).`
|
|
221
|
+
: `No catalog entry matches "${needle}". Absence here means "not observed by our lanes", not "does not exist".`, { matches: rows }, { ttlMs: snapshotTtlMs(deps) }));
|
|
222
|
+
}
|
|
223
|
+
case 'catalog_stats': {
|
|
224
|
+
const stats = catalogStats(deps.statePath);
|
|
225
|
+
return ok(toolResult(deps, `Open Catalog: ${stats.mirrored} mirrored (of ${stats.mirrorTotalUpstream} upstream), ${stats.discovered} discovery-crawled, ${stats.attested} with independently-checkable attestation.`, stats, { ttlMs: snapshotTtlMs(deps) }));
|
|
226
|
+
}
|
|
227
|
+
case 'reconcile': {
|
|
228
|
+
if (!deps.reconcile) {
|
|
229
|
+
return errorAnswer(400, id, E_INVALID_PARAMS, 'reconcile is not available on this deployment');
|
|
230
|
+
}
|
|
231
|
+
const q = {
|
|
232
|
+
asset: typeof args.asset === 'string' ? args.asset.trim() : '',
|
|
233
|
+
payer: typeof args.payer === 'string' ? args.payer.trim() : '',
|
|
234
|
+
nonce: typeof args.nonce === 'string' ? args.nonce.trim() : '',
|
|
235
|
+
...(typeof args.validBefore === 'number' ? { validBefore: args.validBefore } : {}),
|
|
236
|
+
};
|
|
237
|
+
const v = await deps.reconcile(q);
|
|
238
|
+
// A determinate verdict is immutable on-chain history; an
|
|
239
|
+
// indeterminate one can flip as soon as the rail answers or
|
|
240
|
+
// the window closes.
|
|
241
|
+
const ttlMs = v.outcome === 'indeterminate' ? 60_000 : 24 * 3_600_000;
|
|
242
|
+
return ok(toolResult(deps, `${v.outcome.toUpperCase()}: ${v.reason}`, v, { ttlMs }));
|
|
243
|
+
}
|
|
244
|
+
case 'verify_host': {
|
|
245
|
+
const domain = typeof args.domain === 'string' ? args.domain.trim().toLowerCase().replace(/\.$/, '') : '';
|
|
246
|
+
if (!HOSTNAME_RE.test(domain)) {
|
|
247
|
+
return errorAnswer(400, id, E_INVALID_PARAMS, 'verify_host requires a bare, valid hostname (no scheme, no path)');
|
|
248
|
+
}
|
|
249
|
+
const s = loadCatalog(deps.statePath);
|
|
250
|
+
const catalogEntry = s.discovered.find(d => d.domain.toLowerCase() === domain) ?? null;
|
|
251
|
+
let live;
|
|
252
|
+
if (!deps.resolveHost) {
|
|
253
|
+
live = { ok: false, error: 'live resolution not available on this deployment' };
|
|
254
|
+
}
|
|
255
|
+
else {
|
|
256
|
+
try {
|
|
257
|
+
const r = await deps.resolveHost(domain);
|
|
258
|
+
live = { ok: true, ...r };
|
|
259
|
+
}
|
|
260
|
+
catch (e) {
|
|
261
|
+
live = { ok: false, error: e instanceof Error ? e.message : String(e) };
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
// A refusal that names ONE field teaches an operator almost
|
|
265
|
+
// nothing: they cannot tell "one mechanical edit away" from
|
|
266
|
+
// "fundamentally wrong", and they learn one field per debugging
|
|
267
|
+
// round-trip. resolveX402 now reports every violation and flags
|
|
268
|
+
// when they are all fields THIS extension introduced, so surface
|
|
269
|
+
// that distinction in the verdict itself rather than burying it
|
|
270
|
+
// in an error string. (Raised by Melchiorre Oliva on #2979 after
|
|
271
|
+
// this tool refused his otherwise-valid manifest, 2026-08-18.)
|
|
272
|
+
const oneEditAway = !live.ok && typeof live.error === 'string'
|
|
273
|
+
&& live.error.includes('all violations are fields THIS extension introduces');
|
|
274
|
+
const verdict = live.ok
|
|
275
|
+
? (live.attestationUsable ? 'discoverable, attestation independently checkable'
|
|
276
|
+
: 'discoverable, no checkable attestation (treat as none per spec)')
|
|
277
|
+
: oneEditAway
|
|
278
|
+
? 'not discoverable YET — the manifest is valid apart from fields this discovery extension introduces; one mechanical edit away'
|
|
279
|
+
: (catalogEntry ? 'not resolvable now; was observed by our last crawl — freshness beats history'
|
|
280
|
+
: 'not discoverable: no x402 record resolvable and none observed by our crawl');
|
|
281
|
+
return ok(toolResult(deps, `${domain}: ${verdict}. Two observations — live resolution now, vs this catalog's last anchored crawl${catalogEntry ? ` (${catalogEntry.lastVerified})` : ' (absent)'}.`, {
|
|
282
|
+
domain, verdict, live,
|
|
283
|
+
// Explicit so a caller can count this population without
|
|
284
|
+
// parsing prose — the honest migration-cost denominator.
|
|
285
|
+
...(oneEditAway ? { oneEditAway: true } : {}),
|
|
286
|
+
catalog: catalogEntry
|
|
287
|
+
? { present: true, via: catalogEntry.via, lastVerified: catalogEntry.lastVerified, attestationVerifiable: catalogEntry.attestationVerifiable }
|
|
288
|
+
: { present: false },
|
|
289
|
+
},
|
|
290
|
+
// A live probe is only fresh for about as long as the
|
|
291
|
+
// facilitator's own manifest cache (60s).
|
|
292
|
+
{ ttlMs: 60_000 }));
|
|
293
|
+
}
|
|
294
|
+
default:
|
|
295
|
+
return errorAnswer(400, id, E_INVALID_PARAMS, `unknown tool: ${String(name)}`, {
|
|
296
|
+
available: CATALOG_MCP_TOOLS.map(t => t.name),
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
// ── The handler ──────────────────────────────────────────────────────
|
|
301
|
+
/** Map a body-parse failure (transport layer) to the spec's JSON-RPC shape. */
|
|
302
|
+
export function catalogMcpParseError(message = 'body is not valid JSON') {
|
|
303
|
+
return errorAnswer(400, null, E_PARSE, message);
|
|
304
|
+
}
|
|
305
|
+
export async function handleCatalogMcp(body, headers, deps) {
|
|
306
|
+
if (Array.isArray(body)) {
|
|
307
|
+
return errorAnswer(400, null, E_INVALID_REQUEST, 'JSON-RPC batching is not supported (removed in 2025-06-18)');
|
|
308
|
+
}
|
|
309
|
+
if (!isPlainObject(body) || body.jsonrpc !== '2.0' || typeof body.method !== 'string') {
|
|
310
|
+
return errorAnswer(400, null, E_INVALID_REQUEST, 'expected a single JSON-RPC 2.0 request object');
|
|
311
|
+
}
|
|
312
|
+
const method = body.method;
|
|
313
|
+
const rawId = body.id;
|
|
314
|
+
const id = typeof rawId === 'string' || typeof rawId === 'number' ? rawId : null;
|
|
315
|
+
const isNotification = rawId === undefined;
|
|
316
|
+
const params = isPlainObject(body.params) ? body.params : {};
|
|
317
|
+
// SEP-2243: when the routing headers are present they must not lie.
|
|
318
|
+
if (headers.mcpMethod !== undefined && headers.mcpMethod !== method) {
|
|
319
|
+
return errorAnswer(400, id, E_INVALID_REQUEST, `Mcp-Method header ("${headers.mcpMethod}") does not match body method ("${method}")`);
|
|
320
|
+
}
|
|
321
|
+
// ── Version gate ──
|
|
322
|
+
const hv = headers.protocolVersion;
|
|
323
|
+
let stateless = false;
|
|
324
|
+
if (hv === MCP_PROTOCOL_STATELESS) {
|
|
325
|
+
stateless = true;
|
|
326
|
+
}
|
|
327
|
+
else if (hv !== undefined && !MCP_PROTOCOL_LEGACY.includes(hv)) {
|
|
328
|
+
return errorAnswer(400, id, E_UNSUPPORTED_PROTOCOL, `unsupported protocol version: ${hv}`, { supported: MCP_SUPPORTED_VERSIONS });
|
|
329
|
+
}
|
|
330
|
+
// Absent header = a legacy client before/at initialize; the shim serves it.
|
|
331
|
+
if (stateless) {
|
|
332
|
+
const meta = isPlainObject(params._meta) ? params._meta : {};
|
|
333
|
+
if (meta[META_PROTOCOL_KEY] !== MCP_PROTOCOL_STATELESS) {
|
|
334
|
+
return errorAnswer(400, id, E_INVALID_REQUEST, `_meta["${META_PROTOCOL_KEY}"] must be present and match the MCP-Protocol-Version header`);
|
|
335
|
+
}
|
|
336
|
+
if (method === 'initialize' || method === 'ping' || method === 'logging/setLevel') {
|
|
337
|
+
return errorAnswer(404, id, E_METHOD_NOT_FOUND, `${method} was removed in ${MCP_PROTOCOL_STATELESS} — every request is self-contained`);
|
|
338
|
+
}
|
|
339
|
+
// server/discover is the bootstrap method — the one request a
|
|
340
|
+
// client may send before knowing what to declare.
|
|
341
|
+
if (!isNotification && method !== 'server/discover' && !isPlainObject(params.clientCapabilities)) {
|
|
342
|
+
return errorAnswer(400, id, E_MISSING_CLIENT_CAPABILITY, 'clientCapabilities is required on every stateless request');
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// Notifications: acknowledge and do nothing — this server keeps no
|
|
346
|
+
// session state to update. 202 with no body, per Streamable HTTP.
|
|
347
|
+
if (isNotification)
|
|
348
|
+
return { status: 202, body: null };
|
|
349
|
+
const ok = (result) => ({ status: 200, body: { jsonrpc: '2.0', id, result } });
|
|
350
|
+
switch (method) {
|
|
351
|
+
case 'initialize': {
|
|
352
|
+
// Legacy shim: negotiate DOWN to our newest legacy revision;
|
|
353
|
+
// deliberately NO session id — this server has no sessions,
|
|
354
|
+
// which was always legal (Mcp-Session-Id is optional pre-2575).
|
|
355
|
+
const requested = typeof params.protocolVersion === 'string' ? params.protocolVersion : '';
|
|
356
|
+
const negotiated = MCP_PROTOCOL_LEGACY.includes(requested)
|
|
357
|
+
? requested : MCP_PROTOCOL_LEGACY[0];
|
|
358
|
+
return ok(decorate({
|
|
359
|
+
protocolVersion: negotiated,
|
|
360
|
+
capabilities: { tools: { listChanged: false } },
|
|
361
|
+
serverInfo: CATALOG_MCP_SERVER_INFO,
|
|
362
|
+
instructions: INSTRUCTIONS,
|
|
363
|
+
}, deps));
|
|
364
|
+
}
|
|
365
|
+
case 'ping':
|
|
366
|
+
// Removed in 2026-07-28 (handled above); legacy clients use it
|
|
367
|
+
// as a keepalive and deserve a truthful empty result.
|
|
368
|
+
return ok(decorate({}, deps));
|
|
369
|
+
case 'server/discover':
|
|
370
|
+
return ok(decorate({
|
|
371
|
+
supportedVersions: MCP_SUPPORTED_VERSIONS,
|
|
372
|
+
capabilities: { tools: { listChanged: false }, extensions: {} },
|
|
373
|
+
serverInfo: CATALOG_MCP_SERVER_INFO,
|
|
374
|
+
instructions: INSTRUCTIONS,
|
|
375
|
+
}, deps, { ttlMs: 24 * 3_600_000, cacheScope: 'public' }));
|
|
376
|
+
case 'tools/list':
|
|
377
|
+
return ok(decorate({ tools: CATALOG_MCP_TOOLS }, deps, { ttlMs: 24 * 3_600_000, cacheScope: 'public', evidence: true }));
|
|
378
|
+
case 'tools/call': {
|
|
379
|
+
const args = isPlainObject(params.arguments) ? params.arguments : {};
|
|
380
|
+
return callTool(id, params.name, args, deps);
|
|
381
|
+
}
|
|
382
|
+
default:
|
|
383
|
+
return errorAnswer(404, id, E_METHOD_NOT_FOUND, `method not found: ${method}`);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
// ── Server Card (SEP-2127, .well-known/mcp.json) ─────────────────────
|
|
387
|
+
/**
|
|
388
|
+
* Same shape family as /.well-known/x402: one host, two well-knowns, one
|
|
389
|
+
* signed identity — the facilitator serves this next to the x402 manifest
|
|
390
|
+
* and signs it with the same per-serve Ed25519 lane, so the DNS-published
|
|
391
|
+
* key vouches for the MCP surface too.
|
|
392
|
+
*/
|
|
393
|
+
export function buildMcpServerCard(base, deps) {
|
|
394
|
+
return {
|
|
395
|
+
name: CATALOG_MCP_SERVER_INFO.name,
|
|
396
|
+
title: CATALOG_MCP_SERVER_INFO.title,
|
|
397
|
+
version: CATALOG_MCP_SERVER_INFO.version,
|
|
398
|
+
description: 'MCP access to The x402 Open Catalog — community-run, provenance-tagged, every entry re-derivable from public data; snapshot digests anchored on Flare Coston2.',
|
|
399
|
+
url: `${base}/mcp`,
|
|
400
|
+
transport: 'streamable-http',
|
|
401
|
+
protocol: { supportedVersions: MCP_SUPPORTED_VERSIONS, statelessOnly: false, sessions: 'none' },
|
|
402
|
+
capabilities: { tools: { listChanged: false }, extensions: {} },
|
|
403
|
+
tools: CATALOG_MCP_TOOLS.map(t => ({ name: t.name, description: t.description })),
|
|
404
|
+
evidence: evidenceBlock(deps),
|
|
405
|
+
related: { x402Manifest: `${base}/.well-known/x402`, catalogHttp: `${base}/catalog`, docs: base },
|
|
406
|
+
independence: 'community-run; independent of the x402 Foundation and of Coinbase',
|
|
407
|
+
};
|
|
408
|
+
}
|
|
409
|
+
//# sourceMappingURL=catalog-mcp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-mcp.js","sourceRoot":"","sources":["../src/catalog-mcp.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Census, DirectoryEntry, DirectoryVerdict } from './attested-directory.js';
|
|
2
|
+
export declare const RECONCILE_SCHEMA = "x402-census-reconciliation/1";
|
|
3
|
+
/**
|
|
4
|
+
* Iman Schrock's five categories (SCITT, 2026-08-16), mapped to discovery.
|
|
5
|
+
* The names are deliberately his; the mapping is stated so the borrowing is
|
|
6
|
+
* checkable rather than decorative.
|
|
7
|
+
*/
|
|
8
|
+
export type ReconcileCategory =
|
|
9
|
+
/** Both observers saw the host and agree on the verdict. */
|
|
10
|
+
'matched'
|
|
11
|
+
/** In A's population, absent from B's. NOT a claim that B missed it. */
|
|
12
|
+
| 'observed-by-a-only'
|
|
13
|
+
/** In B's population, absent from A's. */
|
|
14
|
+
| 'observed-by-b-only'
|
|
15
|
+
/** Both saw it, verdicts differ. No adjudication is offered or possible. */
|
|
16
|
+
| 'divergent'
|
|
17
|
+
/** At least one observer could not determine a verdict. */
|
|
18
|
+
| 'indeterminate';
|
|
19
|
+
export interface ReconcileRow {
|
|
20
|
+
domain: string;
|
|
21
|
+
category: ReconcileCategory;
|
|
22
|
+
a?: DirectoryVerdict;
|
|
23
|
+
b?: DirectoryVerdict;
|
|
24
|
+
/** Why this row is in this category, checkable against the columns. */
|
|
25
|
+
note: string;
|
|
26
|
+
}
|
|
27
|
+
export interface Reconciliation {
|
|
28
|
+
schema: typeof RECONCILE_SCHEMA;
|
|
29
|
+
reconciledAt: string;
|
|
30
|
+
/** Both censuses are identified by digest, never by nickname. */
|
|
31
|
+
a: {
|
|
32
|
+
observer: string;
|
|
33
|
+
digest: string;
|
|
34
|
+
size: number;
|
|
35
|
+
observedAt: string;
|
|
36
|
+
};
|
|
37
|
+
b: {
|
|
38
|
+
observer: string;
|
|
39
|
+
digest: string;
|
|
40
|
+
size: number;
|
|
41
|
+
observedAt: string;
|
|
42
|
+
};
|
|
43
|
+
/** Union of both target populations — the denominator, stated. */
|
|
44
|
+
size: number;
|
|
45
|
+
rowsRoot: string;
|
|
46
|
+
tally: Record<ReconcileCategory, number>;
|
|
47
|
+
/**
|
|
48
|
+
* Stated, not implied: this artifact does not decide who was right, and a
|
|
49
|
+
* reader who wants a verdict must go and observe for themselves.
|
|
50
|
+
*/
|
|
51
|
+
adjudication: 'none — two honest vantages may differ without either being wrong';
|
|
52
|
+
/** Clock skew between the two observations, which explains many divergences. */
|
|
53
|
+
observationSkewSeconds: number;
|
|
54
|
+
}
|
|
55
|
+
export declare function reconcile(aCensus: Census, aEntries: DirectoryEntry[], bCensus: Census, bEntries: DirectoryEntry[], reconciledAt: string, digestOf: (c: Census) => string): {
|
|
56
|
+
reconciliation: Reconciliation;
|
|
57
|
+
rows: ReconcileRow[];
|
|
58
|
+
};
|
|
59
|
+
/** Prove ONE host's reconciliation row without disclosing either census. */
|
|
60
|
+
export declare function proveRow(rows: ReconcileRow[], index: number): {
|
|
61
|
+
row: ReconcileRow;
|
|
62
|
+
index: number;
|
|
63
|
+
size: number;
|
|
64
|
+
proof: string[];
|
|
65
|
+
};
|
|
66
|
+
export declare function verifyRow(row: ReconcileRow, index: number, size: number, proof: string[], rowsRoot: string): boolean;
|
|
67
|
+
/** The digest a reconciliation is anchored under. */
|
|
68
|
+
export declare function reconciliationDigest(r: Reconciliation): string;
|
|
69
|
+
//# sourceMappingURL=census-reconcile.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"census-reconcile.d.ts","sourceRoot":"","sources":["../src/census-reconcile.ts"],"names":[],"mappings":"AA2CA,OAAO,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAExF,eAAO,MAAM,gBAAgB,iCAAiC,CAAC;AAE/D;;;;GAIG;AACH,MAAM,MAAM,iBAAiB;AACzB,4DAA4D;AAC1D,SAAS;AACX,wEAAwE;GACtE,oBAAoB;AACtB,0CAA0C;GACxC,oBAAoB;AACtB,4EAA4E;GAC1E,WAAW;AACb,2DAA2D;GACzD,eAAe,CAAC;AAEtB,MAAM,WAAW,YAAY;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,CAAC,CAAC,EAAE,gBAAgB,CAAC;IACrB,CAAC,CAAC,EAAE,gBAAgB,CAAC;IACrB,uEAAuE;IACvE,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,OAAO,gBAAgB,CAAC;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,iEAAiE;IACjE,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,CAAC,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1E,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC,iBAAiB,EAAE,MAAM,CAAC,CAAC;IACzC;;;OAGG;IACH,YAAY,EAAE,kEAAkE,CAAC;IACjF,gFAAgF;IAChF,sBAAsB,EAAE,MAAM,CAAC;CAClC;AA+BD,wBAAgB,SAAS,CACrB,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,EAC3C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,EAC3C,YAAY,EAAE,MAAM,EACpB,QAAQ,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,GAChC;IAAE,cAAc,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,YAAY,EAAE,CAAA;CAAE,CAgF1D;AAED,4EAA4E;AAC5E,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG;IAC3D,GAAG,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAC;CACnE,CAIA;AAED,wBAAgB,SAAS,CACrB,GAAG,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,QAAQ,EAAE,MAAM,GAClF,OAAO,CAET;AAED,qDAAqD;AACrD,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CAG9D"}
|