@reclaimprotocol/agent 0.1.33 → 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 +238 -4
- package/lib/mcp/api/operations.gen.js +6433 -328
- package/lib/mcp/api/tools.js +21 -8
- 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/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 +10 -7
- 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 -74
- package/skill/SKILL.common.md +2 -1
- package/skill/builder-mode.md +135 -138
- package/skill/start-integration.md +49 -0
- package/skill/user-script.md +64 -0
- package/skill/verification-client-integration.md +28 -22
- 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 +6477 -364
- package/src/mcp/api/tools.ts +21 -8
- package/src/mcp/instructions.ts +11 -11
- package/src/mcp/server.ts +4 -0
- 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 +10 -7
- package/src/tools/registry.ts +14 -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,35 +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
|
-
|
|
410
|
-
`merge.mergeable` only signals the set *could* collapse into one provider — you
|
|
411
|
-
still pass them all; the Builder runs them in one session.
|
|
412
|
-
|
|
413
|
-
For client integration, result verification, or TEE binding, read topic
|
|
414
|
-
`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.
|
|
415
418
|
|
|
416
419
|
<!-- topic: integration -->
|
|
417
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
|
package/skill/builder-mode.md
CHANGED
|
@@ -1,146 +1,143 @@
|
|
|
1
1
|
# Builder mode
|
|
2
2
|
|
|
3
|
-
Reclaim provider-authoring tools run against the Builder backend
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
3
|
+
Reclaim provider-authoring tools run against the Builder backend: generated
|
|
4
|
+
Builder API tools, credential and verification helpers, and browser authoring
|
|
5
|
+
tools.
|
|
6
|
+
|
|
7
|
+
**A provider is a recipe for extracting a data point from a site. A
|
|
8
|
+
verification is an end-user session that proves a data point with a provider.
|
|
9
|
+
Never call a provider a "verification."**
|
|
10
|
+
|
|
11
|
+
## What the developer wants
|
|
12
|
+
|
|
13
|
+
- **"Add Reclaim to my app" or similar:** call `start_integration` first and
|
|
14
|
+
follow the plan it returns. Don't ask what they want to do with the result.
|
|
15
|
+
- **A claim they describe** (for example, "prove the user is over 18 on
|
|
16
|
+
example.com"): build a new org-private provider for exactly that claim. See
|
|
17
|
+
"Choose the provider".
|
|
18
|
+
- **Intent unclear:** ask one short question.
|
|
19
|
+
|
|
20
|
+
### Choose the provider
|
|
21
|
+
|
|
22
|
+
Default: build a new provider for the claim the developer described. Use an
|
|
23
|
+
existing provider only when they name one or ask to reuse one.
|
|
24
|
+
|
|
25
|
+
With an existing provider, use only the data points the developer asked for.
|
|
26
|
+
Show the developer only those, collect only the inputs they need, and read
|
|
27
|
+
only those from results. Ignore the provider's other data points.
|
|
28
|
+
|
|
29
|
+
Make your own copy when it needs any change, for example it lacks a requested
|
|
30
|
+
data point, requires inputs the developer didn't ask for, or extracts a value
|
|
31
|
+
differently:
|
|
32
|
+
|
|
33
|
+
- Your org owns it: create a new provider version.
|
|
34
|
+
- Another org owns it: `create_provider`, then `create_provider_version` from a
|
|
35
|
+
copy of its config, trimmed to the requested data points.
|
|
36
|
+
|
|
37
|
+
Requirement ambiguous (site, account, or value): ask one concise question.
|
|
38
|
+
Don't guess.
|
|
39
|
+
|
|
40
|
+
A provider used as-is is published and ready. Don't capture, `replay_request`,
|
|
41
|
+
or `run_proof` against it unless the developer asks.
|
|
42
|
+
|
|
43
|
+
### Try a provider without an app
|
|
44
|
+
|
|
45
|
+
Use the production API the app will use. Session creation returns 409 while the
|
|
46
|
+
org has no callback subscription, and results are stored only for subscriptions
|
|
47
|
+
to the event the session ends with.
|
|
48
|
+
|
|
49
|
+
1. If the org has none, register a temporary subscription for all five ending
|
|
50
|
+
events with `create_org_callback_subscription` (for example, a tunnel to a
|
|
51
|
+
local listener that saves the body it receives).
|
|
52
|
+
2. `create_verification_session`, then give the developer `verificationUrl`.
|
|
53
|
+
3. Poll `get_verification_session` until it is terminal. Report the outcome
|
|
54
|
+
from the listener's body, or with `get_verification_result` (works only
|
|
55
|
+
until the callback is delivered).
|
|
56
|
+
4. `delete_org_callback_subscription` only after that. Deleting it also
|
|
57
|
+
deletes its stored results.
|
|
58
|
+
|
|
59
|
+
## Secrets
|
|
60
|
+
|
|
61
|
+
- Never print, echo, or ask the developer to paste an org key (`rorg_…`) or
|
|
62
|
+
private key.
|
|
63
|
+
- `issue_org_token` writes the key to the project's env file
|
|
64
|
+
(`RECLAIM_ORG_SECRET`) and returns only its last four characters. Session
|
|
65
|
+
and org-token tools use that key when you omit `orgToken`.
|
|
66
|
+
- `issue_credentials` and `import_credentials({ keyFile })` write the proof
|
|
67
|
+
owner key to the env file. Use these tools, not shell commands that read
|
|
68
|
+
secret files.
|
|
69
|
+
|
|
70
|
+
## Integrating into an app
|
|
71
|
+
|
|
72
|
+
Call `start_integration`, then read `how_it_works({ topic: "integration" })`
|
|
73
|
+
for the HTTP session workflow, the `api=2` boundary, result verification, and
|
|
74
|
+
TEE binding. Edit the app with your file tools. Use the HTTP API
|
|
75
|
+
(`POST /verifications/sessions`, open `verificationUrl`, poll
|
|
76
|
+
`GET /verifications/sessions/{sessionId}`, read the callback) rather than
|
|
77
|
+
`@reclaimprotocol/client`. The only exception is `results.receive` on the
|
|
78
|
+
callback, or when the developer asks for the client package.
|
|
79
|
+
|
|
80
|
+
Management tools (`list_orgs`, `create_org_callback_subscription`,
|
|
81
|
+
`issue_org_token`) use the developer's sign-in. Session tools
|
|
82
|
+
(`create_verification_session`, `get_verification_session`,
|
|
83
|
+
`list_verification_events`, `list_verification_deliveries`,
|
|
84
|
+
`retry_verification_callback`) are the production API and use the org key.
|
|
85
|
+
|
|
86
|
+
**Existing `@reclaimprotocol/js-sdk` projects.** If `package.json` depends on
|
|
87
|
+
`@reclaimprotocol/js-sdk`, ask first:
|
|
64
88
|
|
|
65
89
|
> This project uses `@reclaimprotocol/js-sdk`. Keep it (I switch this MCP
|
|
66
|
-
> server to legacy devtools mode), or migrate to the Builder
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
> server to legacy devtools mode), or migrate to the Builder HTTP API?
|
|
91
|
+
|
|
92
|
+
- **Keep:** `set_devtools_mode({ mode: "old" })`, then tell them to restart or
|
|
93
|
+
reconnect the MCP server. An explicit `USE_OLD_DEVTOOLS` env var overrides
|
|
94
|
+
it. After the restart, read `get_js_sdk_integration_guide`.
|
|
95
|
+
- **Migrate:** stay in Builder mode and follow topic `integration`.
|
|
96
|
+
|
|
97
|
+
## Authoring a provider
|
|
98
|
+
|
|
99
|
+
Provider versions are immutable. Every change creates a new semantic version
|
|
100
|
+
(default: patch bump; larger only when the developer directs). Never use an
|
|
101
|
+
in-place update or archive tool.
|
|
102
|
+
|
|
103
|
+
**The flow:** `attach_browser` → `start_capture` ⇒ `captureId` → sign in →
|
|
104
|
+
navigation script (`test_user_script` with `keep: true`) → capture through the
|
|
105
|
+
script → `find_requests_containing` → `propose_provider` ⇒ `draftId` →
|
|
106
|
+
`replay_request` → `run_proof` → `create_provider_version_from_capture` →
|
|
107
|
+
`publish_provider_version` (private) or `submit_provider_version_for_review`
|
|
108
|
+
(public). Get the checklist from `how_it_works({ topic: "overview" })`.
|
|
109
|
+
|
|
110
|
+
- **Data points:** propose only values the claim needs, usually one or two.
|
|
111
|
+
Never add identity or profile fields. Name each for what it proves.
|
|
112
|
+
- **Browser:** ask who signs in. The developer themselves: `dedicated` or
|
|
113
|
+
`attach` (local). Someone else, or a phone-only site: `container` (Docker,
|
|
114
|
+
free, shareable with `share_browser_view`) or `builder` (hosted,
|
|
115
|
+
**chargeable**). Say which costs money.
|
|
116
|
+
- **Public endpoints:** after `replay_request` succeeds, re-run it with
|
|
117
|
+
`withoutSecrets: true`. If the value still extracts, the endpoint is public
|
|
118
|
+
and the proof binds to nobody. Find an auth-bound request.
|
|
119
|
+
- **Drafting limits** (topics `draft`, `params`): never `hash` a value that
|
|
120
|
+
also appears in the request URL. A param named with `SECRET` may appear in a
|
|
121
|
+
URL only within a small character budget (2 under `key-update`, 12 under
|
|
122
|
+
`zk`).
|
|
85
123
|
|
|
86
124
|
## Evidence contract
|
|
87
125
|
|
|
88
|
-
Tool results are the source of truth. Never say
|
|
89
|
-
|
|
90
|
-
published unless
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
**
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
`authenticate({ code })` until LINKED. Tokens cache ~2 days.
|
|
105
|
-
(→ `how_it_works({ topic: "auth" })`)
|
|
106
|
-
|
|
107
|
-
**Ask who is doing the signing in, then offer a browser.** "Yourself, or does
|
|
108
|
-
someone else need to log in?" decides half of `attach_browser`'s list. Doing it
|
|
109
|
-
themselves → `dedicated` or `attach`, both local, neither shareable. Someone
|
|
110
|
-
else, or a phone-only site → `container` (the Reclaim runtime in Docker, free,
|
|
111
|
-
shareable with `share_browser_view`) or `builder` (hosted, no install,
|
|
112
|
-
**chargeable**). Say which costs money, and say `container` exists at all:
|
|
113
|
-
nobody guesses it.
|
|
114
|
-
|
|
115
|
-
**The flow:** `attach_browser` (ask the developer which browser source — local
|
|
116
|
-
Chrome, the Reclaim runtime in Docker, a remote Builder browser, or a CDP URL
|
|
117
|
-
they supply) → `start_capture`
|
|
118
|
-
⇒ **`captureId`** (the handle every browser/inspect tool takes first) → drive
|
|
119
|
-
the page (`navigate`, `wait_for_page`, `eval_in_page`, `get_cookies`) → inspect
|
|
120
|
-
(`list_requests`, `get_request`, `find_requests_containing`) →
|
|
121
|
-
`propose_provider` ⇒ **`draftId`** (recipe + captured secrets, held server-side
|
|
122
|
-
— secrets never enter the transcript) → `replay_request(captureId, draftId)` →
|
|
123
|
-
`run_proof(captureId, draftId, ownerAddress)` → resolve a `providerId` →
|
|
124
|
-
`create_provider_version_from_capture` (lands on the draft branch) →
|
|
125
|
-
`publish_provider_version` (PRIVATE) or `submit_provider_version_for_review`
|
|
126
|
-
(PUBLIC).
|
|
127
|
-
|
|
128
|
-
**Reuse before create.** `create_provider_version_from_capture` needs a
|
|
129
|
-
`providerId`. Search your existing providers with `providers` (by domain / data
|
|
130
|
-
point) BEFORE calling `create_provider` — routing every run through
|
|
131
|
-
`create_provider` is what stacks duplicates in "My providers".
|
|
132
|
-
|
|
133
|
-
**Never prove a public endpoint.** After `replay_request` succeeds, re-run it
|
|
134
|
-
with `withoutSecrets: true`. If the value still extracts, the endpoint is public
|
|
135
|
-
and the proof binds to nobody — find an auth-bound request instead.
|
|
136
|
-
|
|
137
|
-
**Two hard constraints when drafting** (details in topics `draft` / `params`):
|
|
138
|
-
never `hash`/OPRF a value that also appears in the request URL; any param named
|
|
139
|
-
with `SECRET` may be used in a URL only within a tiny TOTAL character budget (2
|
|
140
|
-
under `key-update`, 12 under `zk`), checked at verification time.
|
|
141
|
-
|
|
142
|
-
**Backend mode:** this server can instead run against the devtools backend with
|
|
143
|
-
a reduced tool set. `get_devtools_mode` reports the active mode and why;
|
|
126
|
+
Tool results are the source of truth. Never say a browser attached, a user
|
|
127
|
+
signed in, a request was captured, a proof passed, or a version was created or
|
|
128
|
+
published unless a tool result says so.
|
|
129
|
+
|
|
130
|
+
Treat every ID, version, URL, and value as opaque: copy it from the latest tool
|
|
131
|
+
result. Never invent or reconstruct one. When state is unclear, call the
|
|
132
|
+
relevant get/list tool or `how_it_works`. State uncertainty plainly.
|
|
133
|
+
|
|
134
|
+
**Guide:** `how_it_works({})` lists topics. Fetch only the one for your next
|
|
135
|
+
step.
|
|
136
|
+
|
|
137
|
+
**Authentication:** call `get_me`. On 401, `authenticate({})` returns `code`
|
|
138
|
+
and `attachUrl`. Give the developer the URL, then poll `authenticate({ code })`
|
|
139
|
+
until LINKED (topic `auth`).
|
|
140
|
+
|
|
141
|
+
**Backend mode:** `get_devtools_mode` reports the active mode.
|
|
144
142
|
`set_devtools_mode` persists a switch to `~/.reclaim/config.json`, effective on
|
|
145
|
-
the
|
|
146
|
-
persisted choice.
|
|
143
|
+
the next server start. An explicit `USE_OLD_DEVTOOLS` env var wins.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# Plan: let users prove "{{goal}}" in this app
|
|
2
|
+
|
|
3
|
+
Follow this plan end to end. Mark each step done as you go. Do not ask the developer whether to integrate: integrating into this codebase is the goal.
|
|
4
|
+
|
|
5
|
+
## 1. Sign in and pick the organization
|
|
6
|
+
|
|
7
|
+
- [ ] Call `reclaim_authenticate` if you are not signed in. The developer approves in their browser.
|
|
8
|
+
<!-- if:orgId -->
|
|
9
|
+
- [ ] Use organization `{{orgId}}` for every call below.
|
|
10
|
+
<!-- endif -->
|
|
11
|
+
<!-- ifnot:orgId -->
|
|
12
|
+
- [ ] Call `list_orgs`. Use the only organization, or ask the developer which one when there are several.
|
|
13
|
+
<!-- endif -->
|
|
14
|
+
|
|
15
|
+
## 2. Get a provider
|
|
16
|
+
|
|
17
|
+
<!-- if:providerIds -->
|
|
18
|
+
- [ ] Use these existing providers: {{providerIds}}. Read each with `get_provider` and keep only the data points "{{goal}}" needs. Show the developer and use only those; ignore the rest.
|
|
19
|
+
- [ ] If a provider needs any change (a missing data point, inputs the developer didn't ask for, a different value), make your own copy as the server instructions describe ("Choose the provider"). Otherwise skip to step 3.
|
|
20
|
+
<!-- endif -->
|
|
21
|
+
<!-- ifnot:providerIds -->
|
|
22
|
+
Build a new organization-private provider for exactly "{{goal}}". Do not search published providers first.
|
|
23
|
+
|
|
24
|
+
- [ ] If the site, the account, or the value to prove is unclear, ask one concise question. Otherwise do not ask.
|
|
25
|
+
- [ ] Choose the minimum data points: only the values the claim needs, usually one or two. Add no profile or identity extras.
|
|
26
|
+
- [ ] If the developer names an existing provider, use only the data points they asked for and ignore the rest. If it needs any change, make your own copy: a new version when the organization owns it, otherwise a new organization provider from a copy of its config.
|
|
27
|
+
- [ ] Call `how_it_works` with topics `overview`, `user-script`, `capture`, and `publish` before you start. Do not repeat their detail here.
|
|
28
|
+
- [ ] Call `attach_browser` without `mode`, ask the developer which browser to use, then call it again with their choice. Use `start_capture` on the tab.
|
|
29
|
+
- [ ] Open the sign-in page with `navigate`. The developer signs in; use `wait_for_login`.
|
|
30
|
+
- [ ] Write the navigation script first. Signed out, it goes to the sign-in page. After sign-in, it visits each data page in order. It must stay correct across reloads.
|
|
31
|
+
- [ ] Test it with `test_user_script` and `keep: true`. The kept script stays installed for every later navigation and is published with the provider version.
|
|
32
|
+
- [ ] While the script drives the browser, find the request that returns each data point (`find_requests_containing`, then `analyze_request_constraints`).
|
|
33
|
+
- [ ] Call `propose_provider` with only the needed data points.
|
|
34
|
+
- [ ] Call `replay_request`, then `replay_request` with `withoutSecrets: true` to confirm the request is auth-bound.
|
|
35
|
+
- [ ] Call `resolve_owner_key`, then `run_proof`.
|
|
36
|
+
- [ ] Call `create_provider_version_from_capture`. It publishes the kept script as `jsUserScripts`. Follow its `_notes`, then publish the version.
|
|
37
|
+
- [ ] Call `dispose_browser` after asking the developer.
|
|
38
|
+
<!-- endif -->
|
|
39
|
+
|
|
40
|
+
## 3. Integrate into this codebase
|
|
41
|
+
|
|
42
|
+
- [ ] Read `how_it_works({ topic: "integration" })`.
|
|
43
|
+
- [ ] Detect the app's framework and package manager from the repository, and use them.
|
|
44
|
+
- [ ] Call `issue_org_token` with the organization, this project's absolute path, and the server env file. It writes the key to that file and never returns it. Never print or commit the key. Confirm the env file is in `.gitignore`.
|
|
45
|
+
- [ ] Add a backend route that creates a verification session (`POST /verifications/sessions`) for the provider and returns `verificationUrl`.
|
|
46
|
+
- [ ] Add a callback route that verifies each result with `results.receive` from `@reclaimprotocol/client`, then stores only the requested data points.
|
|
47
|
+
- [ ] Call `create_org_callback_subscription` for the result events, pointing at the callback route. Use a tunnel for local development.
|
|
48
|
+
- [ ] Add a frontend Verify button that opens `verificationUrl`, and shows the stored result when it arrives.
|
|
49
|
+
- [ ] Run the app, then tell the developer exactly how to test end to end: open the app, click Verify, sign in, and see the stored result.
|