@reclaimprotocol/agent 0.1.33 → 0.1.35
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/README.md +3 -3
- 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 +6967 -672
- package/lib/mcp/api/tools.js +21 -8
- package/lib/mcp/instructions.js +12 -12
- package/lib/mcp/server.d.ts +1 -1
- package/lib/mcp/server.js +3 -0
- package/lib/mcp/start.js +8 -7
- 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 +5 -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/check-attestor.d.ts +5 -0
- package/lib/mcp/tools/agent/check-attestor.js +37 -0
- 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 +49 -22
- package/lib/mcp/tools/agent/pod-proof.js +7 -11
- package/lib/mcp/tools/agent/proof.d.ts +12 -0
- package/lib/mcp/tools/agent/proof.js +32 -0
- 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.d.ts +2 -1
- package/lib/mcp/tools/agent/shared.js +29 -24
- package/lib/mcp/tools/agent/start-integration.d.ts +15 -0
- package/lib/mcp/tools/agent/start-integration.js +62 -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/build.d.ts +3 -1
- package/lib/mcp/tools/verification/build.js +10 -2
- package/lib/mcp/tools/verification/callback-listener.d.ts +51 -0
- package/lib/mcp/tools/verification/callback-listener.js +163 -0
- package/lib/mcp/tools/verification/index.d.ts +2 -0
- package/lib/mcp/tools/verification/index.js +2 -0
- package/lib/mcp/tools/verification/proxy-callback-events.d.ts +59 -0
- package/lib/mcp/tools/verification/proxy-callback-events.js +300 -0
- package/lib/mcp/tools/verification/read-callback-events.d.ts +3 -0
- package/lib/mcp/tools/verification/read-callback-events.js +135 -0
- package/lib/mcp/tools/verification/result.d.ts +6 -0
- package/lib/mcp/tools/verification/result.js +11 -8
- package/lib/proof/check-attestor.d.ts +67 -0
- package/lib/proof/check-attestor.js +156 -0
- 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 +84 -75
- package/skill/SKILL.common.md +23 -10
- package/skill/builder-mode.md +140 -138
- package/skill/start-integration.md +74 -0
- package/skill/user-script.md +64 -0
- package/skill/verification-client-integration.md +40 -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 +7011 -704
- package/src/mcp/api/tools.ts +21 -8
- package/src/mcp/instructions.ts +12 -12
- package/src/mcp/server.ts +4 -0
- package/src/mcp/start.ts +9 -7
- 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 +7 -1
- package/src/mcp/tools/agent/capture.ts +20 -12
- package/src/mcp/tools/agent/check-attestor.ts +49 -0
- 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 +49 -22
- package/src/mcp/tools/agent/pod-proof.ts +7 -11
- package/src/mcp/tools/agent/proof.ts +55 -0
- 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 +39 -24
- package/src/mcp/tools/agent/start-integration.ts +84 -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/build.ts +10 -2
- package/src/mcp/tools/verification/callback-listener.ts +203 -0
- package/src/mcp/tools/verification/index.ts +2 -0
- package/src/mcp/tools/verification/proxy-callback-events.ts +374 -0
- package/src/mcp/tools/verification/read-callback-events.ts +160 -0
- package/src/mcp/tools/verification/result.ts +11 -8
- package/src/proof/check-attestor.ts +209 -0
- package/src/tools/registry.ts +14 -0
package/skill/builder-mode.md
CHANGED
|
@@ -1,146 +1,148 @@
|
|
|
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
|
+
Session creation returns 409 while the org has no callback subscription.
|
|
46
|
+
`read_callback_events` creates the org's pull listener, which satisfies that
|
|
47
|
+
check and holds results for you to read. No tunnel or public URL is needed.
|
|
48
|
+
|
|
49
|
+
1. Call `read_callback_events`.
|
|
50
|
+
2. `create_verification_session`, then give the developer `verificationUrl`.
|
|
51
|
+
3. Poll `get_verification_session` until it is terminal.
|
|
52
|
+
4. Call `read_callback_events({ sessionId })` for the verified result.
|
|
53
|
+
|
|
54
|
+
When you set up a new provider build, call `check_attestor` once. If it fails,
|
|
55
|
+
tell the developer before they spend time on the build.
|
|
56
|
+
|
|
57
|
+
## Secrets
|
|
58
|
+
|
|
59
|
+
- Never print, echo, or ask the developer to paste an org key (`rorg_…`) or
|
|
60
|
+
private key.
|
|
61
|
+
- `issue_org_token` writes the key to the project's env file
|
|
62
|
+
(`RECLAIM_ORG_SECRET`) and returns only its last four characters. Session
|
|
63
|
+
and org-token tools use that key when you omit `orgToken`.
|
|
64
|
+
- `issue_credentials` and `import_credentials({ keyFile })` write the proof
|
|
65
|
+
owner key to the env file. Use these tools, not shell commands that read
|
|
66
|
+
secret files.
|
|
67
|
+
|
|
68
|
+
## Integrating into an app
|
|
69
|
+
|
|
70
|
+
Call `start_integration`, then read `how_it_works({ topic: "integration" })`
|
|
71
|
+
for the HTTP session workflow, the `api=2` boundary, result verification, and
|
|
72
|
+
TEE binding. Edit the app with your file tools. Use the HTTP API
|
|
73
|
+
(`POST /verifications/sessions`, open `verificationUrl`, poll
|
|
74
|
+
`GET /verifications/sessions/{sessionId}`, read the callback) rather than
|
|
75
|
+
`@reclaimprotocol/client`. The only exception is `results.receive` on the
|
|
76
|
+
callback, or when the developer asks for the client package.
|
|
77
|
+
|
|
78
|
+
For local development, call `proxy_callback_events({ port, path })` to forward
|
|
79
|
+
events to the app's callback route on localhost. The local listener works only
|
|
80
|
+
while this MCP server runs. Production needs a webhook:
|
|
81
|
+
`create_org_callback_subscription` with the deployed app's public URL. Without
|
|
82
|
+
one, session creation returns 409.
|
|
83
|
+
|
|
84
|
+
Management tools (`list_orgs`, `create_org_callback_subscription`,
|
|
85
|
+
`issue_org_token`) use the developer's sign-in. Session tools
|
|
86
|
+
(`create_verification_session`, `get_verification_session`,
|
|
87
|
+
`list_verification_events`, `list_verification_deliveries`,
|
|
88
|
+
`retry_verification_callback`, `read_callback_events`,
|
|
89
|
+
`proxy_callback_events`) are the production API and use the org key.
|
|
90
|
+
|
|
91
|
+
**Existing `@reclaimprotocol/js-sdk` projects.** If `package.json` depends on
|
|
92
|
+
`@reclaimprotocol/js-sdk`, ask first:
|
|
64
93
|
|
|
65
94
|
> 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
|
-
|
|
95
|
+
> server to legacy devtools mode), or migrate to the Builder HTTP API?
|
|
96
|
+
|
|
97
|
+
- **Keep:** `set_devtools_mode({ mode: "old" })`, then tell them to restart or
|
|
98
|
+
reconnect the MCP server. An explicit `USE_OLD_DEVTOOLS` env var overrides
|
|
99
|
+
it. After the restart, read `get_js_sdk_integration_guide`.
|
|
100
|
+
- **Migrate:** stay in Builder mode and follow topic `integration`.
|
|
101
|
+
|
|
102
|
+
## Authoring a provider
|
|
103
|
+
|
|
104
|
+
Provider versions are immutable. Every change creates a new semantic version
|
|
105
|
+
(default: patch bump; larger only when the developer directs). Never use an
|
|
106
|
+
in-place update or archive tool.
|
|
107
|
+
|
|
108
|
+
**The flow:** `attach_browser` → `start_capture` ⇒ `captureId` → sign in →
|
|
109
|
+
navigation script (`test_user_script` with `keep: true`) → capture through the
|
|
110
|
+
script → `find_requests_containing` → `propose_provider` ⇒ `draftId` →
|
|
111
|
+
`replay_request` → `run_proof` → `create_provider_version_from_capture` →
|
|
112
|
+
`publish_provider_version` (private) or `submit_provider_version_for_review`
|
|
113
|
+
(public). Get the checklist from `how_it_works({ topic: "overview" })`.
|
|
114
|
+
|
|
115
|
+
- **Data points:** propose only values the claim needs, usually one or two.
|
|
116
|
+
Never add identity or profile fields. Name each for what it proves.
|
|
117
|
+
- **Browser:** ask who signs in. The developer themselves: `dedicated` or
|
|
118
|
+
`attach` (local). Someone else, or a phone-only site: `container` (Docker,
|
|
119
|
+
free, shareable with `share_browser_view`) or `builder` (hosted,
|
|
120
|
+
**chargeable**). Say which costs money.
|
|
121
|
+
- **Public endpoints:** after `replay_request` succeeds, re-run it with
|
|
122
|
+
`withoutSecrets: true`. If the value still extracts, the endpoint is public
|
|
123
|
+
and the proof binds to nobody. Find an auth-bound request.
|
|
124
|
+
- **Drafting limits** (topics `draft`, `params`): never `hash` a value that
|
|
125
|
+
also appears in the request URL. A param named with `SECRET` may appear in a
|
|
126
|
+
URL only within a small character budget (2 under `key-update`, 12 under
|
|
127
|
+
`zk`).
|
|
85
128
|
|
|
86
129
|
## Evidence contract
|
|
87
130
|
|
|
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;
|
|
131
|
+
Tool results are the source of truth. Never say a browser attached, a user
|
|
132
|
+
signed in, a request was captured, a proof passed, or a version was created or
|
|
133
|
+
published unless a tool result says so.
|
|
134
|
+
|
|
135
|
+
Treat every ID, version, URL, and value as opaque: copy it from the latest tool
|
|
136
|
+
result. Never invent or reconstruct one. When state is unclear, call the
|
|
137
|
+
relevant get/list tool or `how_it_works`. State uncertainty plainly.
|
|
138
|
+
|
|
139
|
+
**Guide:** `how_it_works({})` lists topics. Fetch only the one for your next
|
|
140
|
+
step.
|
|
141
|
+
|
|
142
|
+
**Authentication:** call `get_me`. On 401, `authenticate({})` returns `code`
|
|
143
|
+
and `attachUrl`. Give the developer the URL, then poll `authenticate({ code })`
|
|
144
|
+
until LINKED (topic `auth`).
|
|
145
|
+
|
|
146
|
+
**Backend mode:** `get_devtools_mode` reports the active mode.
|
|
144
147
|
`set_devtools_mode` persists a switch to `~/.reclaim/config.json`, effective on
|
|
145
|
-
the
|
|
146
|
-
persisted choice.
|
|
148
|
+
the next server start. An explicit `USE_OLD_DEVTOOLS` env var wins.
|
|
@@ -0,0 +1,74 @@
|
|
|
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. Set up the app
|
|
16
|
+
|
|
17
|
+
Setup does not need the provider, so it runs in parallel with step 3 or before it.
|
|
18
|
+
|
|
19
|
+
**Delegation.** If you can run subagents, hand this step to one subagent and start step 3 now: step 3 needs the developer at the browser, step 2 does not. Give the subagent a self-contained brief:
|
|
20
|
+
|
|
21
|
+
```
|
|
22
|
+
Goal: let this app's users prove "{{goal}}" with Reclaim.
|
|
23
|
+
Repository: <absolute path>. Organization: <org ID>.
|
|
24
|
+
Task: do step 2 of the plan below and report the file paths you changed, the
|
|
25
|
+
callback route URL, and the env variable that holds the provider ID.
|
|
26
|
+
Do not build the provider. Never print or commit the org key.
|
|
27
|
+
<paste the step 2 checklist>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Without subagents, do step 2 first.
|
|
31
|
+
|
|
32
|
+
- [ ] Detect the app's framework and package manager from the repository, and use them. Read `how_it_works({ topic: "integration" })`.
|
|
33
|
+
- [ ] 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`.
|
|
34
|
+
- [ ] Add a backend route that creates a verification session (`POST /verifications/sessions`) and returns `verificationUrl`. Read the provider ID from server config (an env variable such as `RECLAIM_PROVIDER_ID`), so the route works before the provider exists.
|
|
35
|
+
- [ ] Add a callback route that verifies each result with `results.receive` from `@reclaimprotocol/client`, then stores only the requested data points.
|
|
36
|
+
- [ ] Add a frontend Verify button that opens `verificationUrl`, and shows the stored result when it arrives.
|
|
37
|
+
- [ ] Start the app. Call `proxy_callback_events({ port, path })` with the callback route's port and path. It forwards the org's verification events to that route on localhost, with no public URL.
|
|
38
|
+
<!-- ifnot:providerIds -->
|
|
39
|
+
- [ ] Call `check_attestor` once. If it fails, tell the developer before they spend time on the provider build: this machine cannot reach the attestor.
|
|
40
|
+
<!-- endif -->
|
|
41
|
+
|
|
42
|
+
## 3. Get the provider
|
|
43
|
+
|
|
44
|
+
<!-- if:providerIds -->
|
|
45
|
+
- [ ] 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.
|
|
46
|
+
- [ ] 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 4.
|
|
47
|
+
<!-- endif -->
|
|
48
|
+
<!-- ifnot:providerIds -->
|
|
49
|
+
Build a new organization-private provider for exactly "{{goal}}". Do not search published providers first.
|
|
50
|
+
|
|
51
|
+
- [ ] If the site, the account, or the value to prove is unclear, ask one concise question. Otherwise do not ask.
|
|
52
|
+
- [ ] Choose the minimum data points: only the values the claim needs, usually one or two. Add no profile or identity extras.
|
|
53
|
+
- [ ] 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.
|
|
54
|
+
- [ ] Call `how_it_works` with topics `overview`, `user-script`, `capture`, and `publish` before you start. Do not repeat their detail here.
|
|
55
|
+
- [ ] 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.
|
|
56
|
+
- [ ] Open the sign-in page with `navigate`. The developer signs in; use `wait_for_login`.
|
|
57
|
+
- [ ] 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.
|
|
58
|
+
- [ ] 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.
|
|
59
|
+
- [ ] While the script drives the browser, find the request that returns each data point (`find_requests_containing`, then `analyze_request_constraints`).
|
|
60
|
+
- [ ] Call `propose_provider` with only the needed data points.
|
|
61
|
+
- [ ] Call `replay_request`, then `replay_request` with `withoutSecrets: true` to confirm the request is auth-bound.
|
|
62
|
+
- [ ] Call `resolve_owner_key`, then `run_proof`.
|
|
63
|
+
- [ ] Call `create_provider_version_from_capture`. It publishes the kept script as `jsUserScripts`. Follow its `_notes`, then publish the version.
|
|
64
|
+
- [ ] Call `dispose_browser` after asking the developer.
|
|
65
|
+
<!-- endif -->
|
|
66
|
+
|
|
67
|
+
## 4. Wire the provider and test end to end
|
|
68
|
+
|
|
69
|
+
- [ ] Set the provider ID in the app's server config.
|
|
70
|
+
- [ ] Confirm the callback route is forwarding: `proxy_callback_events` with no `stop` returns its status.
|
|
71
|
+
- [ ] Tell the developer exactly how to test: open the app, click Verify, sign in, and see the stored result.
|
|
72
|
+
- [ ] After they click Verify, read the delivered events from `proxy_callback_events` status (`recent`) or `read_callback_events`. If the result did not arrive, call `list_verification_deliveries` and fix the cause. Repeat until the app shows the stored result.
|
|
73
|
+
- [ ] Ask the developer to set up the production callback. The local listener works only while this coding agent's MCP server runs; once it stops, the deployed app receives no results. Call `create_org_callback_subscription` with the deployed app's public callback route URL for all five session-ending events: `verification_success`, `verification_rejected`, `verification_error`, `verification_cancelled`, and `session_expired`.
|
|
74
|
+
- [ ] If they have no deployed URL yet, tell them: "When you deploy, ask me to run `create_org_callback_subscription` with your public callback URL, or results will not reach the app."
|
package/skill/user-script.md
CHANGED
|
@@ -47,6 +47,70 @@ Do not clear cookies or force another sign-in; inconclusive coverage must not
|
|
|
47
47
|
block publication. This browser check does not emulate a client-specific
|
|
48
48
|
interceptor.
|
|
49
49
|
|
|
50
|
+
## Write the navigation script first
|
|
51
|
+
|
|
52
|
+
Write the navigation script as soon as the developer is signed in, or as soon
|
|
53
|
+
as you know the sign-in page. Then capture through it, so authoring, testing,
|
|
54
|
+
and verification follow the same path.
|
|
55
|
+
|
|
56
|
+
The script does two things:
|
|
57
|
+
|
|
58
|
+
1. **Signed out:** send the user to the sign-in page.
|
|
59
|
+
2. **Signed in:** visit each page that holds a data point, in order. Data
|
|
60
|
+
points can live on different pages. Keep a step index in `sessionStorage` so
|
|
61
|
+
the script survives reloads and repeated runs.
|
|
62
|
+
|
|
63
|
+
Loop: `test_user_script({ script, keep: true })` → fix → retest. With `keep:
|
|
64
|
+
true` the script stays installed for every later navigation in the authoring
|
|
65
|
+
browser, as it does at verification. `create_provider_version_from_capture`
|
|
66
|
+
publishes it as `webSettings.jsUserScripts` unless you pass your own.
|
|
67
|
+
|
|
68
|
+
```js
|
|
69
|
+
(() => {
|
|
70
|
+
const SIGN_IN = '/login'
|
|
71
|
+
const STEPS = [
|
|
72
|
+
{ path: '/account', ready: () => document.querySelector('#dob') },
|
|
73
|
+
{ path: '/settings/profile', ready: () => document.querySelector('#plan') },
|
|
74
|
+
]
|
|
75
|
+
const signedIn = () => document.querySelector('[data-user-menu]')
|
|
76
|
+
&& !document.querySelector('a[href="/login"]')
|
|
77
|
+
let tries = 0
|
|
78
|
+
const timer = setInterval(() => {
|
|
79
|
+
if(++tries > 120) {
|
|
80
|
+
return clearInterval(timer)
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if(!signedIn()) {
|
|
84
|
+
// stay put on the sign-in page; also covers unknown pages
|
|
85
|
+
if(location.pathname !== SIGN_IN) {
|
|
86
|
+
clearInterval(timer)
|
|
87
|
+
location.assign(SIGN_IN)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
const i = Number(sessionStorage.getItem('rc-step') || 0)
|
|
94
|
+
const step = STEPS[i]
|
|
95
|
+
if(!step) {
|
|
96
|
+
return clearInterval(timer)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if(location.pathname !== step.path) {
|
|
100
|
+
clearInterval(timer)
|
|
101
|
+
return location.assign(step.path)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if(step.ready()) {
|
|
105
|
+
sessionStorage.setItem('rc-step', String(i + 1))
|
|
106
|
+
}
|
|
107
|
+
}, 500)
|
|
108
|
+
})()
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Adapt the selectors to the site. Each new tab starts at the first step, and a
|
|
112
|
+
reload resumes at the current step.
|
|
113
|
+
|
|
50
114
|
## `window.Reclaim` — rarely needed
|
|
51
115
|
|
|
52
116
|
`window.Reclaim` is an optional bridge for a handful of edge cases. Most
|
|
@@ -2,31 +2,42 @@
|
|
|
2
2
|
|
|
3
3
|
## Set up an application with the coding agent
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
For "add Reclaim to my app", call `start_integration` first and follow its
|
|
6
|
+
plan. Don't ask whether to try, integrate, or create an app. Ask one short
|
|
7
|
+
question only when intent is unclear. The steps below are the detail behind
|
|
8
|
+
that plan.
|
|
9
|
+
|
|
10
|
+
Inspect the app's frontend, backend, package manager, configuration, and
|
|
11
|
+
callback conventions. Complete the integration in its codebase and run its
|
|
12
|
+
relevant checks. The MCP tools configure Builder resources; your file tools
|
|
13
|
+
edit the app.
|
|
9
14
|
|
|
10
15
|
If the app depends on `@reclaimprotocol/js-sdk`, ask the developer first:
|
|
11
|
-
keep it (
|
|
12
|
-
server), or migrate to the
|
|
13
|
-
|
|
14
|
-
`
|
|
15
|
-
|
|
16
|
-
1.
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
2.
|
|
20
|
-
`
|
|
21
|
-
|
|
22
|
-
register
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
16
|
+
keep it (`set_devtools_mode({ mode: "old" })`, then they restart the MCP
|
|
17
|
+
server), or migrate to the session flow below. When migrating, remove
|
|
18
|
+
`@reclaimprotocol/js-sdk` and replace its `ReclaimProofRequest` and
|
|
19
|
+
`verifyProof` calls.
|
|
20
|
+
|
|
21
|
+
1. `get_devtools_mode` confirms Builder mode. `get_me` or `authenticate` signs
|
|
22
|
+
in the developer. Find the organization with `list_orgs`; call `create_org`
|
|
23
|
+
only when they want a new one.
|
|
24
|
+
2. Receive callbacks. Local development: call
|
|
25
|
+
`proxy_callback_events({ port, path })` to forward the org's events to the
|
|
26
|
+
app's callback route on localhost; no public URL. Deployed app (required for
|
|
27
|
+
production): register a
|
|
28
|
+
public callback URL with `create_org_callback_subscription`, including
|
|
29
|
+
all five session-ending events. If the
|
|
30
|
+
app needs encrypted results, register its public key with `set_org_keypair`;
|
|
31
|
+
keep the private key only in the backend. `set_org_keypair` refuses to
|
|
32
|
+
replace an existing key unless you pass `replace: true`; pass it only when
|
|
33
|
+
the developer asks.
|
|
34
|
+
3. Org key: reuse the `RECLAIM_ORG_SECRET` the app already has. Otherwise an
|
|
35
|
+
organization owner calls `issue_org_token`. It writes the key to the
|
|
36
|
+
project's env file (default `.env`, variable `RECLAIM_ORG_SECRET`) and
|
|
37
|
+
returns only the last four characters and the file path. Make sure that file
|
|
38
|
+
is gitignored. Never print the key, put it in the conversation, or ask the
|
|
39
|
+
developer to paste it. Keep it out of frontend bundles, logs, and source
|
|
40
|
+
control.
|
|
30
41
|
4. Prefer plain HTTP from the backend (see [Code to write](#code-to-write)).
|
|
31
42
|
Create sessions with `POST /verifications/sessions`
|
|
32
43
|
(`Authorization: Bearer $RECLAIM_ORG_SECRET`), save each returned session ID
|
|
@@ -60,8 +71,7 @@ The MCP session tools (`create_verification_session`,
|
|
|
60
71
|
`delete_callback_subscription`, `bind_verification_session_tee_nonce`, and
|
|
61
72
|
`get_verification_result`) call these same production endpoints with the org
|
|
62
73
|
key: pass it as `orgToken`, or let them fall back to the MCP server's
|
|
63
|
-
`RECLAIM_ORG_SECRET`. Use them
|
|
64
|
-
integration end to end.
|
|
74
|
+
`RECLAIM_ORG_SECRET`. Use them to test the integration end to end.
|
|
65
75
|
|
|
66
76
|
## Code to write
|
|
67
77
|
|
|
@@ -69,10 +79,12 @@ Use the API base URL the developer's Builder runs at (production:
|
|
|
69
79
|
`https://build.reclaimprotocol.org`). Every call authenticates with
|
|
70
80
|
`authorization: Bearer $RECLAIM_ORG_SECRET`.
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
Deployed apps subscribe a callback once (or use
|
|
83
|
+
`create_org_callback_subscription`); local development uses
|
|
84
|
+
`proxy_callback_events` instead. Session creation returns 409 while the org has
|
|
85
|
+
no subscription, and a result is only delivered to
|
|
74
86
|
subscriptions that include the event the session ends with, so subscribe to all
|
|
75
|
-
five:
|
|
87
|
+
five session-ending events:
|
|
76
88
|
|
|
77
89
|
```bash
|
|
78
90
|
curl -X POST https://build.reclaimprotocol.org/verifications/callback-subscriptions \
|
package/src/authoring/backend.ts
CHANGED
|
@@ -37,6 +37,18 @@ export interface Draft {
|
|
|
37
37
|
extractions: Extraction[]
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
/** A navigation script installed for every later page load of the authoring
|
|
41
|
+
* session. `identifier` is the CDP registration, so it can be removed. */
|
|
42
|
+
export interface KeptScript {
|
|
43
|
+
script: string
|
|
44
|
+
identifier?: string
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/** Holds the session's kept script, replaced by each `keep` call. */
|
|
48
|
+
export interface KeptScriptRef {
|
|
49
|
+
keptScript?: KeptScript
|
|
50
|
+
}
|
|
51
|
+
|
|
40
52
|
/** Per-session draft store: `propose` puts, `replay`/`run_proof` get by id. */
|
|
41
53
|
export interface DraftStore {
|
|
42
54
|
put(draft: Draft): string
|
|
@@ -75,6 +87,9 @@ export interface AuthoringBackend {
|
|
|
75
87
|
* out. Cloud authoring enables this; local MCP keeps its existing
|
|
76
88
|
* behavior. */
|
|
77
89
|
readonly readOnlyPageEval?: boolean
|
|
90
|
+
/** Where `test_user_script` keeps its script. Absent for hosts that do not
|
|
91
|
+
* publish it (the cloud loop synthesizes its own navigation script). */
|
|
92
|
+
readonly kept?: KeptScriptRef
|
|
78
93
|
/** Send a raw CDP command scoped to this session's page. */
|
|
79
94
|
sendCdp(method: string, params?: Record<string, unknown>): Promise<unknown>
|
|
80
95
|
/** Resolve once `method` (a CDP event) fires on this session's page, or
|