@crawlcheck/sdk 1.0.8 → 1.1.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.
@@ -0,0 +1,33 @@
1
+ // Preflight as an MCP client extension: the official MCP TypeScript client, wrapped so `connect` and `callTool` are
2
+ // decided before anything is sent. Run: node mcp-preflight-demo.mjs (needs @modelcontextprotocol/sdk and @crawlcheck/sdk).
3
+ //
4
+ // 1. A server on a domain nothing vouches for -> the connect is refused; no packet leaves the client.
5
+ // 2. CrawlCheck's own MCP server (connect = require_confirmation) -> refused when nobody confirms, connected when a
6
+ // person says yes; the signed receipt is shown and verifies offline.
7
+ import { Client } from "@modelcontextprotocol/sdk/client/index.js";
8
+ import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
9
+ import { CrawlCheck, withPreflight, McpPreflightRefused } from "@crawlcheck/sdk";
10
+
11
+ const cc = new CrawlCheck();
12
+ const sent = [];
13
+ const watchedFetch = async (u, init) => { sent.push((init && init.method || "GET") + " " + String(u)); return fetch(u, init); }; // every request the transport makes
14
+
15
+ async function attempt(label, url, opts) {
16
+ const client = withPreflight(new Client({ name: "preflight-demo", version: "1.0.0" }), cc, opts);
17
+ const before = sent.length;
18
+ try {
19
+ await client.connect(new StreamableHTTPClientTransport(new URL(url), { fetch: watchedFetch }));
20
+ const tools = await client.listTools();
21
+ console.log(label + ": CONNECTED, " + tools.tools.length + " tools listed; receipt " + client.preflight.state.receipt.decision + " sha256 " + client.preflight.state.receipt.sha256.slice(0, 16));
22
+ await client.close();
23
+ } catch (e) {
24
+ if (!(e instanceof McpPreflightRefused)) throw e;
25
+ console.log(label + ": REFUSED at " + e.stage + " - " + e.why);
26
+ console.log(" decision " + (e.receipt && e.receipt.decision) + ", receipt sha256 " + (e.receipt && e.receipt.sha256 && e.receipt.sha256.slice(0, 16)) + ", verifies offline: " + (e.verification && e.verification.verified));
27
+ }
28
+ console.log(" requests the MCP transport sent: " + (sent.length - before));
29
+ }
30
+
31
+ await attempt("1. mcp.example.com (no record)", "https://mcp.example.com/mcp", {});
32
+ await attempt("2a. crawlcheck.io/mcp, nobody to confirm", "https://crawlcheck.io/mcp", {});
33
+ await attempt("2b. crawlcheck.io/mcp, a person confirms", "https://crawlcheck.io/mcp", { confirm: async (r) => { console.log(" confirm? " + r.decision + ": " + ((r.steps || [])[0] || {}).why); return true; } });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crawlcheck/sdk",
3
- "version": "1.0.8",
3
+ "version": "1.1.0",
4
4
  "description": "Typed client for the CrawlCheck API (generated from its OpenAPI document) and the zero-dependency offline verifier for evidence bundles and remediation receipts.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -14,6 +14,7 @@
14
14
  "files": [
15
15
  "dist",
16
16
  "test",
17
+ "examples",
17
18
  "README.md"
18
19
  ],
19
20
  "engines": {
@@ -41,5 +42,6 @@
41
42
  ],
42
43
  "scripts": {
43
44
  "test": "node --test test/*.test.js"
44
- }
45
+ },
46
+ "license": "MIT"
45
47
  }