@sheafhq/mcp-tools 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +11 -3
- package/dist/tools.d.ts +3 -1
- package/dist/tools.js +20 -10
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,13 +3,21 @@
|
|
|
3
3
|
// (Claude Desktop, Cline, custom runtime) and speaks JSON-RPC over stdio.
|
|
4
4
|
//
|
|
5
5
|
// Environment variables (all optional):
|
|
6
|
-
// SHEAF_RECORDER_URL
|
|
6
|
+
// SHEAF_RECORDER_URL explicit recorder override. If unset, tries
|
|
7
|
+
// https://api.sheafhq.io and falls back to
|
|
8
|
+
// https://sheaf-recorder.goldencalf.workers.dev.
|
|
7
9
|
// SHEAF_BASE_RPC Base mainnet RPC for anchor verification
|
|
8
10
|
// (default: https://mainnet.base.org)
|
|
9
11
|
import { runServer } from "./server.js";
|
|
12
|
+
const DEFAULT_URLS = [
|
|
13
|
+
"https://api.sheafhq.io",
|
|
14
|
+
"https://sheaf-recorder.goldencalf.workers.dev",
|
|
15
|
+
];
|
|
16
|
+
const recorderUrls = process.env.SHEAF_RECORDER_URL
|
|
17
|
+
? [process.env.SHEAF_RECORDER_URL]
|
|
18
|
+
: DEFAULT_URLS;
|
|
10
19
|
const ctx = {
|
|
11
|
-
|
|
12
|
-
"https://sheaf-recorder.goldencalf.workers.dev",
|
|
20
|
+
recorderUrls,
|
|
13
21
|
baseRpc: process.env.SHEAF_BASE_RPC ?? "https://mainnet.base.org",
|
|
14
22
|
};
|
|
15
23
|
runServer(ctx);
|
package/dist/tools.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export type ToolContext = {
|
|
2
|
-
|
|
2
|
+
/** Primary + fallback recorder base URLs. First entry is reported as
|
|
3
|
+
* `source_url` in responses. Fallback only kicks in on fetch error. */
|
|
4
|
+
recorderUrls: string[];
|
|
3
5
|
baseRpc: string;
|
|
4
6
|
};
|
|
5
7
|
export declare function chainHead(ctx: ToolContext, args: {
|
package/dist/tools.js
CHANGED
|
@@ -5,12 +5,24 @@
|
|
|
5
5
|
// All three tools are READ-only against the Sheaf recorder. No wallet, no
|
|
6
6
|
// settlement, no mutation. Safe to expose to any agent.
|
|
7
7
|
import { verify } from "@sheafhq/verify";
|
|
8
|
+
async function fetchWithFallback(ctx, path, init) {
|
|
9
|
+
let lastErr;
|
|
10
|
+
for (const base of ctx.recorderUrls) {
|
|
11
|
+
try {
|
|
12
|
+
const response = await fetch(base + path, init);
|
|
13
|
+
return { response, sourceUrl: base + path };
|
|
14
|
+
}
|
|
15
|
+
catch (err) {
|
|
16
|
+
lastErr = err;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
throw lastErr ?? new Error("no recorder URLs configured");
|
|
20
|
+
}
|
|
8
21
|
export async function chainHead(ctx, args) {
|
|
9
22
|
if (!args.chain_id || typeof args.chain_id !== "string") {
|
|
10
23
|
throw new Error("chain_id (string) is required");
|
|
11
24
|
}
|
|
12
|
-
const
|
|
13
|
-
const r = await fetch(url);
|
|
25
|
+
const { response: r, sourceUrl } = await fetchWithFallback(ctx, `/chains/${encodeURIComponent(args.chain_id)}/head`);
|
|
14
26
|
if (r.status === 404) {
|
|
15
27
|
return {
|
|
16
28
|
chain_id: args.chain_id,
|
|
@@ -29,7 +41,7 @@ export async function chainHead(ctx, args) {
|
|
|
29
41
|
event_count: body.event_count,
|
|
30
42
|
created_at_unix: body.created_at,
|
|
31
43
|
updated_at_unix: body.updated_at,
|
|
32
|
-
source_url:
|
|
44
|
+
source_url: sourceUrl,
|
|
33
45
|
};
|
|
34
46
|
}
|
|
35
47
|
export async function getProofFor(ctx, args) {
|
|
@@ -40,8 +52,7 @@ export async function getProofFor(ctx, args) {
|
|
|
40
52
|
throw new Error("seq (non-negative integer) is required");
|
|
41
53
|
}
|
|
42
54
|
// First find out which epoch the event is in.
|
|
43
|
-
const
|
|
44
|
-
const evRes = await fetch(evUrl);
|
|
55
|
+
const { response: evRes } = await fetchWithFallback(ctx, `/events/${encodeURIComponent(args.chain_id)}/${args.seq}`);
|
|
45
56
|
if (evRes.status === 404) {
|
|
46
57
|
throw new Error(`no event at ${args.chain_id}/${args.seq}`);
|
|
47
58
|
}
|
|
@@ -58,8 +69,7 @@ export async function getProofFor(ctx, args) {
|
|
|
58
69
|
note: "Event is signed and chained but not yet included in an on-chain anchor. Call again after the next epoch anchor to get a Merkle inclusion proof.",
|
|
59
70
|
};
|
|
60
71
|
}
|
|
61
|
-
const
|
|
62
|
-
const proofRes = await fetch(proofUrl);
|
|
72
|
+
const { response: proofRes, sourceUrl } = await fetchWithFallback(ctx, `/epoch/${ev.epoch_id}/proof/${encodeURIComponent(args.chain_id)}/${args.seq}`);
|
|
63
73
|
if (!proofRes.ok) {
|
|
64
74
|
throw new Error(`recorder returned HTTP ${proofRes.status} on proof fetch`);
|
|
65
75
|
}
|
|
@@ -75,7 +85,7 @@ export async function getProofFor(ctx, args) {
|
|
|
75
85
|
siblings: proof.siblings,
|
|
76
86
|
anchor: proof.anchor,
|
|
77
87
|
verification_note: proof.verification_note,
|
|
78
|
-
source_url:
|
|
88
|
+
source_url: sourceUrl,
|
|
79
89
|
};
|
|
80
90
|
}
|
|
81
91
|
export async function verifyBundle(ctx, args) {
|
|
@@ -111,7 +121,7 @@ export async function verifyBundle(ctx, args) {
|
|
|
111
121
|
// verification is self-contained; fall back to /.well-known if missing.
|
|
112
122
|
let recorderKey = b.issuer?.public_key_base64 ?? "";
|
|
113
123
|
if (!recorderKey) {
|
|
114
|
-
const r = await
|
|
124
|
+
const { response: r } = await fetchWithFallback(ctx, `/.well-known/sheaf-public-key`);
|
|
115
125
|
if (!r.ok) {
|
|
116
126
|
throw new Error(`could not fetch recorder public key: HTTP ${r.status}`);
|
|
117
127
|
}
|
|
@@ -136,7 +146,7 @@ export async function verifyBundle(ctx, args) {
|
|
|
136
146
|
checks: result.checks,
|
|
137
147
|
reason: result.reason,
|
|
138
148
|
anchor_block: result.anchor_block,
|
|
139
|
-
recorder: ctx.
|
|
149
|
+
recorder: ctx.recorderUrls[0],
|
|
140
150
|
anchorer_checked: anchorer,
|
|
141
151
|
};
|
|
142
152
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sheafhq/mcp-tools",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "MCP server exposing Sheaf read tools (chain_head, get_proof_for, verify_bundle). Lets any MCP-compatible agent query the Sheaf recorder and verify receipts offline. Pairs with @sheafhq/mcp-recorder (transparent event capture) but ships as a separate, opt-in tool surface so the recorder stays purely transparent.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/cli.js",
|