@reclaimprotocol/agent 0.1.32 → 0.1.34
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/lib/authoring/backend.d.ts +13 -0
- package/lib/authoring/index.d.ts +1 -1
- package/lib/authoring/tools.js +78 -42
- package/lib/config/store.d.ts +10 -0
- package/lib/mcp/api/operations.gen.d.ts +247 -4
- package/lib/mcp/api/operations.gen.js +6519 -337
- package/lib/mcp/api/tools.d.ts +10 -2
- package/lib/mcp/api/tools.js +55 -4
- package/lib/mcp/instructions.js +11 -11
- package/lib/mcp/server.d.ts +1 -1
- package/lib/mcp/server.js +3 -0
- package/lib/mcp/start.js +6 -1
- package/lib/mcp/success-response.js +5 -1
- package/lib/mcp/tools/agent/analyze.js +5 -4
- package/lib/mcp/tools/agent/attach.js +11 -7
- package/lib/mcp/tools/agent/build.js +3 -1
- package/lib/mcp/tools/agent/capture.d.ts +2 -2
- package/lib/mcp/tools/agent/capture.js +15 -11
- package/lib/mcp/tools/agent/eval.js +4 -3
- package/lib/mcp/tools/agent/find.js +9 -10
- package/lib/mcp/tools/agent/how-it-works.js +1 -0
- package/lib/mcp/tools/agent/live-view.js +10 -7
- package/lib/mcp/tools/agent/pod-proof.js +7 -11
- package/lib/mcp/tools/agent/propose.js +4 -3
- package/lib/mcp/tools/agent/publish.d.ts +2 -1
- package/lib/mcp/tools/agent/publish.js +12 -6
- package/lib/mcp/tools/agent/replay.js +10 -7
- package/lib/mcp/tools/agent/session.js +16 -8
- package/lib/mcp/tools/agent/shared.js +3 -2
- package/lib/mcp/tools/agent/start-integration.d.ts +15 -0
- package/lib/mcp/tools/agent/start-integration.js +61 -0
- package/lib/mcp/tools/authenticate/authenticate.js +9 -11
- package/lib/mcp/tools/authenticate/build.js +2 -0
- package/lib/mcp/tools/authenticate/builder-access.js +1 -0
- package/lib/mcp/tools/authenticate/eth-key.d.ts +8 -0
- package/lib/mcp/tools/authenticate/eth-key.js +27 -15
- package/lib/mcp/tools/authenticate/import.js +18 -31
- package/lib/mcp/tools/authenticate/issue-org-token.d.ts +8 -0
- package/lib/mcp/tools/authenticate/issue-org-token.js +60 -0
- package/lib/mcp/tools/authenticate/issue.js +9 -9
- package/lib/mcp/tools/authenticate/org-key-store.d.ts +10 -0
- package/lib/mcp/tools/authenticate/org-key-store.js +23 -0
- package/lib/mcp/tools/authenticate/resolve-owner-key.js +10 -12
- package/lib/mcp/tools/mode/mode.js +2 -0
- package/lib/mcp/tools/verification/result.js +52 -12
- package/lib/tools/registry.d.ts +12 -0
- package/lib/tools/registry.js +1 -0
- package/package.json +2 -2
- package/skill/SKILL.builder.md +77 -73
- package/skill/SKILL.common.md +2 -1
- package/skill/builder-mode.md +135 -120
- package/skill/start-integration.md +49 -0
- package/skill/user-script.md +64 -0
- package/skill/verification-client-integration.md +131 -28
- package/src/authoring/backend.ts +15 -0
- package/src/authoring/index.ts +2 -0
- package/src/authoring/tools.ts +86 -42
- package/src/config/store.ts +11 -0
- package/src/mcp/api/operations.gen.ts +6563 -373
- package/src/mcp/api/tools.ts +70 -5
- package/src/mcp/instructions.ts +11 -11
- package/src/mcp/server.ts +4 -0
- package/src/mcp/start.ts +6 -1
- package/src/mcp/success-response.ts +5 -1
- package/src/mcp/tools/agent/analyze.ts +5 -4
- package/src/mcp/tools/agent/attach.ts +11 -7
- package/src/mcp/tools/agent/build.ts +5 -1
- package/src/mcp/tools/agent/capture.ts +20 -12
- package/src/mcp/tools/agent/eval.ts +4 -3
- package/src/mcp/tools/agent/find.ts +9 -10
- package/src/mcp/tools/agent/how-it-works.ts +1 -0
- package/src/mcp/tools/agent/live-view.ts +10 -7
- package/src/mcp/tools/agent/pod-proof.ts +7 -11
- package/src/mcp/tools/agent/propose.ts +4 -3
- package/src/mcp/tools/agent/publish.ts +12 -4
- package/src/mcp/tools/agent/replay.ts +10 -7
- package/src/mcp/tools/agent/session.ts +16 -8
- package/src/mcp/tools/agent/shared.ts +7 -2
- package/src/mcp/tools/agent/start-integration.ts +83 -0
- package/src/mcp/tools/authenticate/authenticate.ts +9 -11
- package/src/mcp/tools/authenticate/build.ts +2 -0
- package/src/mcp/tools/authenticate/builder-access.ts +1 -0
- package/src/mcp/tools/authenticate/eth-key.ts +48 -18
- package/src/mcp/tools/authenticate/import.ts +21 -36
- package/src/mcp/tools/authenticate/issue-org-token.ts +84 -0
- package/src/mcp/tools/authenticate/issue.ts +9 -9
- package/src/mcp/tools/authenticate/org-key-store.ts +25 -0
- package/src/mcp/tools/authenticate/resolve-owner-key.ts +10 -12
- package/src/mcp/tools/mode/mode.ts +2 -0
- package/src/mcp/tools/verification/result.ts +58 -13
- package/src/tools/registry.ts +14 -0
|
@@ -3,6 +3,7 @@ import assert from 'node:assert';
|
|
|
3
3
|
import { apiUrl, orgSecret } from "../../../consts.js";
|
|
4
4
|
import { defineTool } from "../../server.js";
|
|
5
5
|
import { resolveDecryptionKey } from "../authenticate/decrypt-key.js";
|
|
6
|
+
import { savedOrgKey } from "../authenticate/org-key-store.js";
|
|
6
7
|
/** Statuses that can carry a Builder-managed terminal result. */
|
|
7
8
|
const TERMINAL = new Set([
|
|
8
9
|
'success',
|
|
@@ -11,16 +12,24 @@ const TERMINAL = new Set([
|
|
|
11
12
|
'cancelled',
|
|
12
13
|
'expired',
|
|
13
14
|
]);
|
|
15
|
+
/** Events whose delivery is a signed result; the rest are plaintext event
|
|
16
|
+
* notifications. Mirrors `verification_result_events()`. */
|
|
17
|
+
const RESULT_EVENTS = new Set([
|
|
18
|
+
'verification_success',
|
|
19
|
+
'verification_rejected',
|
|
20
|
+
'verification_error',
|
|
21
|
+
'verification_cancelled',
|
|
22
|
+
]);
|
|
14
23
|
/**
|
|
15
24
|
* Resolve the org secret used to authenticate verification reads. Auth is a
|
|
16
|
-
* single per-org bearer secret (`rorg_…`), not an eth signature
|
|
17
|
-
* `RECLAIM_ORG_SECRET`.
|
|
25
|
+
* single per-org bearer secret (`rorg_…`), not an eth signature: the call's
|
|
26
|
+
* `orgToken`, else `RECLAIM_ORG_SECRET`.
|
|
18
27
|
*/
|
|
19
|
-
function resolveOrgSecret() {
|
|
20
|
-
const secret = orgSecret()?.trim();
|
|
21
|
-
assert(secret, new Error('
|
|
22
|
-
'
|
|
23
|
-
'
|
|
28
|
+
function resolveOrgSecret(orgToken) {
|
|
29
|
+
const secret = orgToken?.trim() || orgSecret()?.trim() || savedOrgKey();
|
|
30
|
+
assert(secret, new Error('No organization API key. Verification reads authenticate with the org '
|
|
31
|
+
+ 'secret (rorg_…): run issue_org_token to save a key, pass orgToken, '
|
|
32
|
+
+ 'or export RECLAIM_ORG_SECRET for the MCP server.'));
|
|
24
33
|
return secret;
|
|
25
34
|
}
|
|
26
35
|
/**
|
|
@@ -36,8 +45,12 @@ function resolveOrgSecret() {
|
|
|
36
45
|
export function verificationResultTool() {
|
|
37
46
|
return defineTool({
|
|
38
47
|
name: 'get_verification_result',
|
|
39
|
-
description: 'Fetches and verifies a terminal Builder result for one session
|
|
40
|
-
+ '
|
|
48
|
+
description: 'Fetches and verifies a terminal Builder result for one session, '
|
|
49
|
+
+ 'while Builder still holds it: until its callback is delivered, or '
|
|
50
|
+
+ '7 days undelivered. The callback is the normal way to get results. '
|
|
51
|
+
+ 'Authenticates with the org API key: `orgToken`, else '
|
|
52
|
+
+ '`RECLAIM_ORG_SECRET`, else the key saved by `issue_org_token`. '
|
|
53
|
+
+ 'Encrypted deliveries also require '
|
|
41
54
|
+ 'the matching ETH decryption key. Returns `ready: false` until a '
|
|
42
55
|
+ 'payload is available. Invalid results fail verification and are not '
|
|
43
56
|
+ 'returned. Use `list_verification_events` to diagnose '
|
|
@@ -50,10 +63,21 @@ export function verificationResultTool() {
|
|
|
50
63
|
type: 'string',
|
|
51
64
|
description: 'The verification session id from create_verification_session.',
|
|
52
65
|
},
|
|
66
|
+
orgToken: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
pattern: '^rorg_',
|
|
69
|
+
maxLength: 200,
|
|
70
|
+
description: 'The organization API key (`rorg_…`): from '
|
|
71
|
+
+ '`issue_org_token`, or the app\'s RECLAIM_ORG_SECRET. '
|
|
72
|
+
+ 'Defaults to the MCP server\'s RECLAIM_ORG_SECRET, then the '
|
|
73
|
+
+ 'key saved by `issue_org_token`. Never echo it back to the '
|
|
74
|
+
+ 'user.',
|
|
75
|
+
},
|
|
53
76
|
},
|
|
54
77
|
},
|
|
78
|
+
annotations: { readOnlyHint: true, openWorldHint: true },
|
|
55
79
|
}, async (args) => {
|
|
56
|
-
const secret = resolveOrgSecret();
|
|
80
|
+
const secret = resolveOrgSecret(args.orgToken);
|
|
57
81
|
// Optional eth decryption key — absent ⇒ plaintext-only.
|
|
58
82
|
const decryptionKey = await resolveDecryptionKey();
|
|
59
83
|
const reclaim = ReclaimVerification.create({
|
|
@@ -70,13 +94,29 @@ export function verificationResultTool() {
|
|
|
70
94
|
const resultRes = await reclaim.api('GetVerificationResult', {
|
|
71
95
|
params: { sessionId: args.reclaimSessionId },
|
|
72
96
|
});
|
|
73
|
-
const
|
|
97
|
+
const signed = resultRes.data.items
|
|
98
|
+
.filter((item) => RESULT_EVENTS.has(item.event));
|
|
99
|
+
if (!signed.length) {
|
|
100
|
+
return {
|
|
101
|
+
reclaimSessionId: args.reclaimSessionId,
|
|
102
|
+
status,
|
|
103
|
+
ready: false,
|
|
104
|
+
note: 'Session is terminal but no result is stored: none submitted '
|
|
105
|
+
+ 'yet, or no callback subscription covers its ending event.',
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
// Builder keeps a result (which can carry proofs) only until its
|
|
109
|
+
// callback is delivered, or 7 days undelivered.
|
|
110
|
+
const items = signed.flatMap((item) => (item.payload === null ? [] : [{ ...item, payload: item.payload }]));
|
|
74
111
|
if (!items.length) {
|
|
75
112
|
return {
|
|
76
113
|
reclaimSessionId: args.reclaimSessionId,
|
|
77
114
|
status,
|
|
78
115
|
ready: false,
|
|
79
|
-
|
|
116
|
+
delivered: signed.some((item) => (item.deliveryStatus === 'delivered')),
|
|
117
|
+
note: 'Builder no longer holds this result: it was delivered to '
|
|
118
|
+
+ 'the callback (read it there), or went undelivered for 7 days. '
|
|
119
|
+
+ 'See list_verification_deliveries.',
|
|
80
120
|
};
|
|
81
121
|
}
|
|
82
122
|
// Each item's `payload` is an ECIES ciphertext encrypted to the org's
|
package/lib/tools/registry.d.ts
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
import type { JSONSchema } from 'zod/v4/core';
|
|
2
|
+
/** MCP tool hints that let a client decide when to ask for approval. */
|
|
3
|
+
export interface ToolAnnotations {
|
|
4
|
+
/** The tool never changes state. */
|
|
5
|
+
readOnlyHint?: boolean;
|
|
6
|
+
/** The tool can delete or overwrite state. */
|
|
7
|
+
destructiveHint?: boolean;
|
|
8
|
+
/** Repeating a call with the same input has no further effect. */
|
|
9
|
+
idempotentHint?: boolean;
|
|
10
|
+
/** The tool reaches systems outside this machine. */
|
|
11
|
+
openWorldHint?: boolean;
|
|
12
|
+
}
|
|
2
13
|
export interface ToolDefinition {
|
|
3
14
|
name: string;
|
|
4
15
|
description: string;
|
|
5
16
|
inputSchema: JSONSchema.ObjectSchema;
|
|
17
|
+
annotations?: ToolAnnotations;
|
|
6
18
|
}
|
|
7
19
|
export interface RegisteredTool {
|
|
8
20
|
definition: ToolDefinition;
|
package/lib/tools/registry.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reclaimprotocol/agent",
|
|
3
3
|
"title": "Reclaim Agent",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.34",
|
|
5
5
|
"description": "Reclaim Protocol tools for AI coding agents. Reclaim lets your app verify data points about its users, such as a follower count, an account balance, or an order history. This package is the Reclaim MCP server: it gives your agent the tools to find, build, test, and fix data verification providers by capturing and replaying browser requests, drafting provider recipes, running zkTLS proofs, and publishing provider versions.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "./lib/index.js",
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
84
84
|
"@noble/hashes": "^2.2.0",
|
|
85
85
|
"@reclaimprotocol/attestor-core": "^5.1.5",
|
|
86
|
-
"@reclaimprotocol/client": "0.1.
|
|
86
|
+
"@reclaimprotocol/client": "0.1.34",
|
|
87
87
|
"@reclaimprotocol/tls": "^0.1.3",
|
|
88
88
|
"chrome-remote-interface": "^0.33.0",
|
|
89
89
|
"domhandler": "^6.0.0",
|
package/skill/SKILL.builder.md
CHANGED
|
@@ -11,32 +11,38 @@ Builder.
|
|
|
11
11
|
|
|
12
12
|
## The loop, at a glance
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
- [ ] 4.
|
|
25
|
-
|
|
26
|
-
- [ ] 5. `
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
Build a new org-private provider for the claim the developer described. Ask
|
|
15
|
+
one question if the site, account, or value is ambiguous. Copy this checklist
|
|
16
|
+
and check off each step. Read the linked topic before a step you don't know.
|
|
17
|
+
|
|
18
|
+
- [ ] 1. Name the data points: only the values the claim must prove, usually
|
|
19
|
+
one or two. No identity or profile fields.
|
|
20
|
+
- [ ] 2. `attach_browser`, then `list_tabs` → `start_capture(tabId)` ⇒
|
|
21
|
+
**`captureId`**. → topics `browser`, `capture`
|
|
22
|
+
- [ ] 3. Open the sign-in page and wait for the developer to sign in
|
|
23
|
+
(`wait_for_page`). → topic `capture`
|
|
24
|
+
- [ ] 4. Write the navigation script: sign-in redirect, then each data
|
|
25
|
+
point's page in order. → topic `user-script`
|
|
26
|
+
- [ ] 5. `test_user_script({ script, keep: true })`. Fix and retest until it
|
|
27
|
+
reaches every page, also after a reload.
|
|
28
|
+
- [ ] 6. Capture by letting the script navigate: `find_requests_containing` →
|
|
29
|
+
`analyze_request_constraints` → pick an **authenticated** request per
|
|
30
|
+
data point. → topic `capture`
|
|
31
|
+
- [ ] 7. `propose_provider(captureId, requestId, …)` ⇒ **`draftId`**
|
|
32
|
+
(`targets` = the data points). → topic `draft`
|
|
33
|
+
- [ ] 8. Parameterize user-specific URL segments; mark secrets.
|
|
34
|
+
→ topic `params`
|
|
35
|
+
- [ ] 9. `replay_request(captureId, draftId)`, then again with
|
|
31
36
|
`withoutSecrets: true`. → topic `prove`
|
|
32
|
-
- [ ]
|
|
37
|
+
- [ ] 10. `run_proof(captureId, draftId, ownerAddress)`.
|
|
33
38
|
→ topics `prove`, `credentials`
|
|
34
|
-
- [ ]
|
|
35
|
-
`create_provider_version_from_capture`
|
|
39
|
+
- [ ] 11. `create_provider` (or a new version of a provider your org owns) →
|
|
40
|
+
`create_provider_version_from_capture` (publishes the kept script as
|
|
41
|
+
`webSettings.jsUserScripts`) → `publish_provider_version` or
|
|
36
42
|
`submit_provider_version_for_review`. → topic `publish`
|
|
37
43
|
|
|
38
|
-
|
|
39
|
-
proven draft in one call. See topic `publish`.
|
|
44
|
+
Data points on different requests? Run steps 7-10 once per request, then
|
|
45
|
+
publish every proven draft in one call. See topic `publish`.
|
|
40
46
|
|
|
41
47
|
<!-- topic: contributions -->
|
|
42
48
|
|
|
@@ -84,7 +90,7 @@ integration. Prefer Builder for new integrations.
|
|
|
84
90
|
2. **Pick a tab and start the capture.** `list_tabs`, then
|
|
85
91
|
`start_capture(tabId)` ⇒ a **`captureId`**: the session handle every browser
|
|
86
92
|
and inspect tool takes as its first argument (`navigate`, `eval_in_page`,
|
|
87
|
-
`wait_for_page`, `
|
|
93
|
+
`wait_for_page`, `list_requests`, `find_requests_containing`,
|
|
88
94
|
`propose_provider`). If a tab is already on the right origin use it,
|
|
89
95
|
otherwise the first is usually fine. Capturing from the start is harmless —
|
|
90
96
|
it also records the login navigation. Then `navigate(captureId, url)` to
|
|
@@ -93,13 +99,18 @@ integration. Prefer Builder for new integrations.
|
|
|
93
99
|
|
|
94
100
|
3. <!-- common: login-detect -->
|
|
95
101
|
|
|
96
|
-
4. **
|
|
97
|
-
|
|
98
|
-
`
|
|
102
|
+
4. **Write and keep the navigation script** (topic `user-script`) as soon as
|
|
103
|
+
the developer is signed in, or the sign-in URL is known. Test it with
|
|
104
|
+
`test_user_script` and `keep: true`. The script visits each data point's
|
|
105
|
+
page; build its URLs from what you know about the site and read page state
|
|
106
|
+
with `eval_in_page` when needed (for example, GitHub's
|
|
107
|
+
`meta[name="user-login"]`'s `content`).
|
|
99
108
|
|
|
100
|
-
5. **Trigger the
|
|
101
|
-
|
|
102
|
-
|
|
109
|
+
5. **Trigger the requests by letting the script navigate.** Capture has been
|
|
110
|
+
live since step 2. Reload the page (`eval_in_page(captureId,
|
|
111
|
+
"location.reload()")`) so the kept script runs from the start. Don't click
|
|
112
|
+
by hand or ask the developer to; if a request needs an interaction, add it
|
|
113
|
+
to the script.
|
|
103
114
|
|
|
104
115
|
6. <!-- common: identify-value -->
|
|
105
116
|
|
|
@@ -126,8 +137,9 @@ integration. Prefer Builder for new integrations.
|
|
|
126
137
|
under that `draftId`; the secrets never enter the transcript, so you carry the
|
|
127
138
|
`draftId`, not the provider JSON, into replay/prove.
|
|
128
139
|
|
|
129
|
-
**Extracting more than one value?**
|
|
130
|
-
contains all of them** and draft them
|
|
140
|
+
**Extracting more than one value?** Add a value only when the claim needs it.
|
|
141
|
+
Prefer a **single request whose response contains all of them** and draft them
|
|
142
|
+
together — one `responseMatches` +
|
|
131
143
|
`responseRedactions` pair per value. Find that request by running
|
|
132
144
|
`find_requests_containing` for each value and picking a `requestId` common to
|
|
133
145
|
all. Then pass a `targets` array, each entry with its `value` (exactly as it
|
|
@@ -136,7 +148,7 @@ appears) and a distinct `name`:
|
|
|
136
148
|
```
|
|
137
149
|
propose_provider(captureId, requestId, name, targets: [
|
|
138
150
|
{ value: "Scratch-net", name: "username" },
|
|
139
|
-
{ value: "
|
|
151
|
+
{ value: "2019", name: "member_since_year" },
|
|
140
152
|
])
|
|
141
153
|
```
|
|
142
154
|
|
|
@@ -313,16 +325,13 @@ parameterization applied. `initialUrl` is the page where the user logs in / the
|
|
|
313
325
|
value is displayed (for example, `https://github.com/Syed`) — **not** the API
|
|
314
326
|
endpoint URL inside the provider.
|
|
315
327
|
|
|
316
|
-
**1.
|
|
317
|
-
`
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
`github-username`, `title` such as "GitHub Username"). It starts PRIVATE with an
|
|
324
|
-
empty seed version. Routing every run through `create_provider` is what stacks
|
|
325
|
-
duplicates in "My providers".
|
|
328
|
+
**1. Resolve the `providerId`.** For a new claim, call
|
|
329
|
+
`create_provider(orgId, domain, slug, title, description)` (`orgId` from
|
|
330
|
+
`list_orgs`; `domain` such as `github.com`, `slug` such as `github-username`,
|
|
331
|
+
`title` such as "GitHub Username"). It starts PRIVATE with an empty seed
|
|
332
|
+
version. Use an existing `providerId` only when your org owns the provider and
|
|
333
|
+
you are revising it: the capture lands as a NEW VERSION on it. For another
|
|
334
|
+
org's provider that almost fits, create your own provider and version.
|
|
326
335
|
|
|
327
336
|
**2. Persist the version.**
|
|
328
337
|
`create_provider_version_from_capture(providerId, provider, initialUrl, notes)`
|
|
@@ -339,12 +348,13 @@ or archive an existing version to apply provider changes.
|
|
|
339
348
|
required at verification time. This proves that every request matched; it
|
|
340
349
|
does not automatically bind a value extracted from one response to another
|
|
341
350
|
request.
|
|
342
|
-
- **
|
|
343
|
-
|
|
344
|
-
`
|
|
345
|
-
pagination)
|
|
346
|
-
a `verifyRequestProof({ providerId })` use case, read topic
|
|
347
|
-
session-unique URL there makes verifyRequestProof
|
|
351
|
+
- **Navigation script:** the script kept with `test_user_script` (`keep: true`)
|
|
352
|
+
is published as `webSettings.jsUserScripts`. Pass `jsUserScripts` only to
|
|
353
|
+
override it. → topic `user-script`. For extra requests the script may fire
|
|
354
|
+
(for example, pagination), pass `allowedJsRequests`. Before populating it for
|
|
355
|
+
a `verifyRequestProof({ providerId })` use case, read topic
|
|
356
|
+
`hash-validation`: a session-unique URL there makes `verifyRequestProof`
|
|
357
|
+
reject every real proof.
|
|
348
358
|
|
|
349
359
|
**3. `requiredContext` is derived for you.** The publish tool scans the recipe's
|
|
350
360
|
url/body for `{{context.<name>}}` placeholders and emits a JSON Schema requiring
|
|
@@ -367,10 +377,8 @@ developer it's awaiting admin review.
|
|
|
367
377
|
context params — for example, `context: { "username": "…" }` in
|
|
368
378
|
`create_verification_session`. Quote the `requiredContext` from the created
|
|
369
379
|
version verbatim — a session missing those fields gets a 400, and verification
|
|
370
|
-
matches the supplied values exactly. Then
|
|
371
|
-
|
|
372
|
-
new app — unless they already said (see "Using a provider" in the server
|
|
373
|
-
instructions).
|
|
380
|
+
matches the supplied values exactly. Then continue as the server
|
|
381
|
+
instructions say under "What the developer wants".
|
|
374
382
|
|
|
375
383
|
**6. If the response includes `_notes` for an attached browser, follow them for
|
|
376
384
|
an optional authenticated-state retest.** Only when its profile is still signed
|
|
@@ -383,34 +391,30 @@ the session for further edits; call `dispose_browser` only after they confirm.
|
|
|
383
391
|
A `builder` session is quota-accounted, so don't leave it idle.
|
|
384
392
|
|
|
385
393
|
<!-- topic: discover -->
|
|
386
|
-
## Discover and resolve providers
|
|
394
|
+
## Discover and resolve existing providers
|
|
387
395
|
|
|
388
|
-
|
|
389
|
-
|
|
396
|
+
Use this flow only when the developer asks to reuse existing providers or
|
|
397
|
+
doesn't know what a site supports. Otherwise build a new provider (server
|
|
398
|
+
instructions, "Choose the provider").
|
|
390
399
|
|
|
391
400
|
1. Ask which website their users prove data from.
|
|
392
401
|
2. `discover_data_points({ domain })` → what's verifiable there. Confirm the
|
|
393
402
|
data points with the developer.
|
|
394
403
|
3. `discover_resolve({ domain, dataPoints })` → the smallest provider set
|
|
395
404
|
(`providers`, greedy combine), the `requiredContext` inputs to collect, and
|
|
396
|
-
any `uncovered` points (author those with the
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
5.
|
|
403
|
-
`
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
`merge.mergeable` only signals the set *could* collapse into one provider — you
|
|
410
|
-
still pass them all; the Builder runs them in one session.
|
|
411
|
-
|
|
412
|
-
For client integration, result verification, or TEE binding, read topic
|
|
413
|
-
`integration`.
|
|
405
|
+
any `uncovered` points (author those with the checklist in topic
|
|
406
|
+
`overview`, then re-resolve).
|
|
407
|
+
4. Use only the data points the developer confirmed: show and read only those
|
|
408
|
+
and ignore the rest. A provider that needs any change gets your own copy
|
|
409
|
+
(server instructions, "Choose the provider"). Otherwise it's usable as-is;
|
|
410
|
+
don't capture, replay, or prove it unless the developer asks.
|
|
411
|
+
5. To try them: `create_verification_session({ providers: [{ providerId }, …],
|
|
412
|
+
context, verificationClientUrl })` with EVERY resolved provider id and the
|
|
413
|
+
collected context. The server instructions ("Try a provider without an
|
|
414
|
+
app") cover the callback and polling. To integrate: topic `integration`.
|
|
415
|
+
|
|
416
|
+
`merge.mergeable` only signals the set *could* collapse into one provider. Pass
|
|
417
|
+
them all; the Builder runs them in one session.
|
|
414
418
|
|
|
415
419
|
<!-- topic: integration -->
|
|
416
420
|
|
package/skill/SKILL.common.md
CHANGED
|
@@ -424,7 +424,8 @@ conversation.
|
|
|
424
424
|
1. **`resolve_owner_key`** returns only the derived address.
|
|
425
425
|
- `{ ready: true, address }` → call `run_proof` with it. No prompts.
|
|
426
426
|
- `{ ready: false }` → ask the developer once: **their own key** →
|
|
427
|
-
`import_credentials({
|
|
427
|
+
`import_credentials({ keyFile })` (a path to a file holding the key; never
|
|
428
|
+
ask them to paste it),
|
|
428
429
|
or **a fresh one** → `issue_credentials({})` (a fine default for test
|
|
429
430
|
proofs — owner identity doesn't matter). Either writes to the project
|
|
430
431
|
`.env` (mode 0600, added to `.gitignore`), never to `~/.reclaim`. Then
|