@reclaimprotocol/agent 0.1.39 → 0.1.40

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@reclaimprotocol/agent",
3
3
  "title": "Reclaim Agent",
4
- "version": "0.1.39",
4
+ "version": "0.1.40",
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",
@@ -84,7 +84,7 @@
84
84
  "@noble/hashes": "^2.2.0",
85
85
  "@puppeteer/browsers": "3.2.4",
86
86
  "@reclaimprotocol/attestor-core": "^5.1.6",
87
- "@reclaimprotocol/client": "0.1.39",
87
+ "@reclaimprotocol/client": "0.1.40",
88
88
  "@reclaimprotocol/tls": "^0.1.3",
89
89
  "chrome-remote-interface": "^0.33.0",
90
90
  "domhandler": "^6.0.0",
@@ -68,6 +68,12 @@ immediately with a `code` and `attachUrl` — it does NOT poll.
68
68
  The 2-day token is cached in `~/.reclaim/config.json` and reused on later runs
69
69
  (`RECLAIM_API_TOKEN` in the server env overrides it).
70
70
 
71
+ ### Backend mode
72
+
73
+ `get_devtools_mode` reports the active mode. `set_devtools_mode` persists a
74
+ switch to `~/.reclaim/config.json`, effective on the next server start. An
75
+ explicit `USE_OLD_DEVTOOLS` env var wins.
76
+
71
77
  <!-- topic: devtools-migration -->
72
78
  ## Import providers from devtools
73
79
 
@@ -316,6 +322,14 @@ with no secrets/cookies, as an anonymous visitor.
316
322
  — **show it to the developer as a fenced JSON block at the end**, with the
317
323
  provider JSON. That's the final result.
318
324
 
325
+ **Country.** `run_proof` sends the attestor's request from the developer's own
326
+ IP country, which is what `{{DYNAMIC_GEO}}` becomes when they verify; `egress`
327
+ in the result names the country. If a site that serves one country (for
328
+ example, a US airline) blocks the attestor, retry once with
329
+ `geoLocation: "US"`. If that verifies, pin it with
330
+ `update_draft({ geoLocation: "US" })` so the published version goes out from
331
+ there too.
332
+
319
333
  **`errorKind: "missing-owner-key"`** → no eth proof-owner key yet. Tell the
320
334
  developer what's happening and drive the bootstrap yourself — see topic
321
335
  `credentials`. No restart needed, and the existing `draftId` stays valid.
@@ -396,16 +410,17 @@ in, navigate to `initialUrl`; if a user script is present, run
396
410
  `test_user_script` with that script and `initialUrl`. When the existing capture
397
411
  has enough data, replay and prove every required request. Do not clear
398
412
  cookies or force another sign-in. Treat an unavailable or inconclusive retest as
399
- advisory and do not block publication. Ask whether the developer wants to keep
400
- the session for further edits; call `dispose_browser` only after they confirm.
401
- A `builder` session is quota-accounted, so don't leave it idle.
413
+ advisory and do not block publication. Don't ask whether to close the
414
+ browser. Mention once in the final summary that it stays open for provider
415
+ changes and you can close it on request; call `dispose_browser` only when the
416
+ developer says so. A `builder` session is quota-accounted, so close it as soon
417
+ as they say the work is done.
402
418
 
403
419
  <!-- topic: discover -->
404
420
  ## Discover and resolve existing providers
405
421
 
406
- Use this flow only when the developer asks to reuse existing providers or
407
- doesn't know what a site supports. Otherwise build a new provider (server
408
- instructions, "Choose the provider").
422
+ Use this flow only when the developer asks to reuse existing providers, names
423
+ one, or doesn't know what a site supports. Otherwise build a new provider.
409
424
 
410
425
  1. Ask which website their users prove data from.
411
426
  2. `discover_data_points({ domain })` → what's verifiable there. Confirm the
@@ -415,13 +430,17 @@ instructions, "Choose the provider").
415
430
  any `uncovered` points (author those with the checklist in topic
416
431
  `overview`, then re-resolve).
417
432
  4. Use only the data points the developer confirmed: show and read only those
418
- and ignore the rest. A provider that needs any change gets your own copy
419
- (server instructions, "Choose the provider"). Otherwise it's usable as-is;
420
- don't capture, replay, or prove it unless the developer asks.
433
+ and ignore the rest. A provider that needs any change (a missing data point, extra inputs, a different extraction) gets your own copy
434
+ (`create_provider_version` when your org owns it; otherwise
435
+ `create_provider`, then `create_provider_version` from a copy of its
436
+ config, trimmed to the requested data points). Otherwise it's published and
437
+ usable as-is; don't capture, replay, or prove it unless the developer asks.
438
+ When a requirement (site, account, or value) is ambiguous, ask one concise
439
+ question; don't guess.
421
440
  5. To try them: `create_verification_session({ providers: [{ providerId }, …],
422
441
  context, verificationClientUrl })` with EVERY resolved provider id and the
423
- collected context. The server instructions ("Try a provider without an
424
- app") cover the callback and polling. To integrate: topic `integration`.
442
+ collected context. Topic `integration` ("Try a provider without an app")
443
+ covers the callback and polling, and the integration steps.
425
444
 
426
445
  `merge.mergeable` only signals the set *could* collapse into one provider. Pass
427
446
  them all; the Builder runs them in one session.
@@ -74,6 +74,14 @@ and are NOT interchangeable.
74
74
  `reclaim_authenticate` ran earlier, the old-devtools token has expired — re-run
75
75
  it. Don't assume `authenticate_builder` fixes it.
76
76
 
77
+ ### Backend mode
78
+
79
+ The BUILDER backend (generated API tools, orgs, verification sessions, public
80
+ review) is one switch away. `get_devtools_mode` reports the active mode and
81
+ why; `set_devtools_mode` persists a switch to `~/.reclaim/config.json`,
82
+ effective on the NEXT server start. An explicit `USE_OLD_DEVTOOLS` env var wins
83
+ over the persisted choice.
84
+
77
85
  <!-- topic: browser -->
78
86
  <!-- common: browser -->
79
87
 
@@ -320,8 +328,17 @@ applies them.
320
328
  There's no create-then-version step and no org / public-review workflow here.
321
329
  When done, tell the developer the version is live, then ask once how they want
322
330
  to use it — try it now, integrate it into an existing backend or frontend, or
323
- create a new app — unless they already said (see "Using a provider" in the
324
- server instructions).
331
+ create a new app — unless they already said:
332
+
333
+ > Want to (1) try it right now here, (2) integrate it into an existing backend
334
+ > or frontend (this directory or another path), or (3) create a new app for it?
335
+
336
+ Try it now → `scaffold_reclaim_demo_server` with its `providerId`. Integrate,
337
+ or new app → `get_js_sdk_integration_guide`, then work in the path they named.
338
+
339
+ A provider found with `get_me_providers` or `get_provider_info` is published
340
+ and usable as-is. Don't capture, `replay_request`, or `run_proof` against it
341
+ unless the developer asks you to check or test it.
325
342
 
326
343
  **If the response includes `_notes` for an attached browser, follow them for an
327
344
  optional authenticated-state retest.** Only when its profile is still signed in,
@@ -329,9 +346,10 @@ navigate to `initialUrl`; if `customInjection` is present, run
329
346
  `test_user_script` with that script and `initialUrl`. When the existing capture
330
347
  has enough data, replay and prove every required request. Do not clear
331
348
  cookies or force another sign-in. Treat an unavailable or inconclusive retest as
332
- advisory and do not block the completed provider. Ask whether the developer
333
- wants to keep the session for further edits; call `dispose_browser` only after
334
- they confirm.
349
+ advisory and do not block the completed provider. Don't ask whether to close the
350
+ browser. Mention once in the final summary that it stays open for provider
351
+ changes and you can close it on request; call `dispose_browser` only when the
352
+ developer says so.
335
353
 
336
354
  <!-- topic: never-do -->
337
355
  ## Things to never do
@@ -1,186 +1,51 @@
1
1
  # Builder mode
2
2
 
3
- Reclaim provider-authoring tools run against the Builder backend: generated
4
- Builder API tools, credential and verification helpers, and browser authoring
5
- tools.
3
+ Provider-authoring and verification tools for the Builder backend.
6
4
 
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."**
5
+ **A provider is a recipe for extracting a data point from a site. A verification is an end-user session that proves a data point with a provider. Never call a provider a "verification."**
10
6
 
11
- ## What the developer wants
7
+ ## Routing
12
8
 
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.
9
+ - "Add Reclaim to my app" or similar: call `start_integration` first and follow its plan. Don't ask what they want to do with the result.
10
+ - A claim they describe (for example, "prove the user is over 18 on example.com"): build a new org-private provider for exactly that claim. Use an existing provider only when they name one or ask to reuse one (topic `discover`).
11
+ - Intent unclear: ask one short question.
19
12
 
20
- ### Work order
13
+ ## Authoring rules
21
14
 
22
- Do the steps that need the developer first: sign in to Builder, attach the
23
- browser, capture, and prove the provider. They show early whether a proof is
24
- possible on the site. Write app code after the proof works, or while you wait
25
- on the developer.
15
+ - Do the steps that need the developer first (sign in, attach the browser, capture, prove). Write app code after the proof works, or while you wait.
16
+ - Call `attach_browser()` with no arguments. Don't ask which browser to use.
17
+ - Propose only the data points the claim needs.
18
+ - Provider versions are immutable: every change creates a new version.
26
19
 
27
- ### Asking the developer
20
+ ## Asking the developer
28
21
 
29
- When you need an answer or an action from the developer before you can
30
- continue, end your turn with the question. Don't ask a blocking question
31
- through a background or asynchronous question tool: the developer may never
32
- see it. Put every link they need, such as a sign-in or verification URL, in
33
- that same message.
22
+ - When you need an answer or an action, end your turn with the question. Don't use a background or asynchronous question tool: the developer may never see it.
23
+ - Put every link they need, such as a sign-in or verification URL, in that same message.
24
+ - Ask each question once. Act on the answer; don't ask again.
34
25
 
35
- ### Choose the provider
26
+ ## Permission blocks
36
27
 
37
- Default: build a new provider for the claim the developer described. Use an
38
- existing provider only when they name one or ask to reuse one.
28
+ When a permission check blocks a tool call or command:
39
29
 
40
- With an existing provider, use only the data points the developer asked for.
41
- Show the developer only those, collect only the inputs they need, and read
42
- only those from results. Ignore the provider's other data points.
43
-
44
- Make your own copy when it needs any change, for example it lacks a requested
45
- data point, requires inputs the developer didn't ask for, or extracts a value
46
- differently:
47
-
48
- - Your org owns it: create a new provider version.
49
- - Another org owns it: `create_provider`, then `create_provider_version` from a
50
- copy of its config, trimmed to the requested data points.
51
-
52
- Requirement ambiguous (site, account, or value): ask one concise question.
53
- Don't guess.
54
-
55
- A provider used as-is is published and ready. Don't capture, `replay_request`,
56
- or `run_proof` against it unless the developer asks.
57
-
58
- ### Try a provider without an app
59
-
60
- Session creation returns 409 while the org has no callback subscription.
61
- `read_callback_events` creates the org's pull listener, which satisfies that
62
- check and holds results for you to read. No tunnel or public URL is needed.
63
-
64
- 1. Call `read_callback_events`.
65
- 2. `create_verification_session`, then give the developer `verificationUrl`.
66
- 3. Poll `get_verification_session` until it is terminal.
67
- `list_verification_events` shows progress. Don't read the hosted
68
- verification page for progress: it streams the site as an image, so text
69
- and DOM checks of it come back empty.
70
- 4. Call `read_callback_events({ sessionId })` for the verified result.
71
-
72
- When you set up a new provider build, call `check_attestor` once. If it fails,
73
- tell the developer before they spend time on the build.
30
+ 1. Don't retry it or work around it.
31
+ 2. In one message, name the blocked tool or command, what it does, and what approving it means.
32
+ 3. Ask for approval in words that name that exact action, for example: "Approve running `npm run dev` to start the example app?" A vague question doesn't cover it.
74
33
 
75
34
  ## Secrets
76
35
 
77
- - Never print, echo, or ask the developer to paste an org key (`rorg_…`) or
78
- private key.
79
- - `issue_org_token` writes the key to the project's env file
80
- (`RECLAIM_ORG_SECRET`) and returns only its last four characters. Session
81
- and org-token tools use that key when you omit `orgToken`.
82
- - `issue_credentials` and `import_credentials({ keyFile })` write the proof
83
- owner key to the env file. Use these tools, not shell commands that read
84
- secret files.
85
-
86
- ## Integrating into an app
87
-
88
- Call `start_integration` and follow its order: prove the provider first, then
89
- write app code. Read `how_it_works({ topic: "integration" })`
90
- for the HTTP session workflow, the `api=2` boundary, result verification, and
91
- TEE binding. Edit the app with your file tools. Use the HTTP API
92
- (`POST /verifications/sessions`, open `verificationUrl`, poll
93
- `GET /verifications/sessions/{sessionId}`, read the callback) rather than
94
- `@reclaimprotocol/client`. The only exception is `results.receive` on the
95
- callback, or when the developer asks for the client package.
96
-
97
- The app's frontend renders every state and every failure, never only a
98
- spinner. Follow "UI states" in `how_it_works({ topic: "integration" })`. The
99
- callback route responds `error.retryable ? 503 : 200` for a thrown
100
- `ResultVerificationError`; a result that failed verification gets 2xx.
101
-
102
- For local development, call `proxy_callback_events({ port, path })` to forward
103
- events to the app's callback route on localhost. The local listener works only
104
- while this MCP server runs. It keeps events in order per session and retries
105
- a session the app rejects with backoff, so other sessions keep flowing. When
106
- its status lists `blocked` sessions, read that session's callback route
107
- response and logs, and fix the app. Production needs a webhook:
108
- `create_org_callback_subscription` with the deployed app's public URL. Without
109
- one, session creation returns 409.
110
-
111
- Management tools (`list_orgs`, `create_org_callback_subscription`,
112
- `issue_org_token`) use the developer's sign-in. Session tools
113
- (`create_verification_session`, `get_verification_session`,
114
- `list_verification_events`, `list_verification_deliveries`,
115
- `retry_verification_callback`, `read_callback_events`,
116
- `proxy_callback_events`) are the production API and use the org key.
117
-
118
- **Existing `@reclaimprotocol/js-sdk` projects.** If `package.json` depends on
119
- `@reclaimprotocol/js-sdk`, ask first:
120
-
121
- > This project uses `@reclaimprotocol/js-sdk`. Keep it (I switch this MCP
122
- > server to legacy devtools mode), or migrate to the Builder HTTP API?
123
-
124
- - **Keep:** `set_devtools_mode({ mode: "old" })`, then tell them to restart or
125
- reconnect the MCP server. An explicit `USE_OLD_DEVTOOLS` env var overrides
126
- it. After the restart, read `get_js_sdk_integration_guide`.
127
- - **Migrate:** stay in Builder mode and follow topic `integration`.
128
-
129
- ## Authoring a provider
130
-
131
- Provider versions are immutable. Every change creates a new semantic version
132
- (default: patch bump; larger only when the developer directs). Never use an
133
- in-place update or archive tool.
134
-
135
- **The flow:** `attach_browser` → `start_capture` ⇒ `captureId` → sign in →
136
- navigation script (`test_user_script` with `keep: true`) → capture through the
137
- script → `find_requests_containing` → `propose_provider` ⇒ `draftId` →
138
- `replay_request` → `run_proof` → `create_provider_version_from_capture` →
139
- `publish_provider_version` (private) or `submit_provider_version_for_review`
140
- (public). Get the checklist from `how_it_works({ topic: "overview" })`.
141
-
142
- - **Data points:** propose only values the claim needs, usually one or two.
143
- Never add identity or profile fields. Name each for what it proves.
144
- - **Browser:** call `attach_browser()` with no arguments. It opens a visible
145
- local browser with the persistent Reclaim profile, and falls back to Chrome
146
- for Testing itself when no installed browser can be attached. Don't ask
147
- which browser or who signs in. Use another `mode` only when that fails too,
148
- or when the developer explicitly asks for it (topic `browser`). Tell the
149
- developer once, as a side note, that a shareable link can be set up if a
150
- volunteer is helping them sign in; don't ask about it or set it up unless
151
- they ask.
152
- - **Public endpoints:** after `replay_request` succeeds, re-run it with
153
- `withoutSecrets: true`. If the value still extracts, the endpoint is public
154
- and the proof binds to nobody. Find an auth-bound request.
155
- - **Country:** `run_proof` sends the attestor's request from the developer's
156
- own IP country, which is what `{{DYNAMIC_GEO}}` becomes when they verify;
157
- `egress` in the result says which country. If a site that serves one
158
- country (for example, a US airline) blocks the attestor, retry once with
159
- `geoLocation: "US"`. If that verifies, pin it with
160
- `update_draft({ geoLocation: "US" })` so the published version goes out
161
- from there too.
162
- - **Drafting limits** (topics `draft`, `params`): never `hash` a value that
163
- also appears in the request URL. A param named with `SECRET` may appear in a
164
- URL only within a small character budget (2 under `key-update`, 12 under
165
- `zk`).
36
+ - Never print, echo, or ask the developer to paste an org key (`rorg_…`) or private key.
37
+ - `issue_org_token` writes the org key to the project's env file (`RECLAIM_ORG_SECRET`) and returns only its last four characters. `issue_credentials` and `import_credentials({ keyFile })` write the proof-owner key there. Use these tools, not shell commands that read secret files.
166
38
 
167
39
  ## Evidence contract
168
40
 
169
- Tool results are the source of truth. Never say a browser attached, a user
170
- signed in, a request was captured, a proof passed, or a version was created or
171
- published unless a tool result says so.
41
+ Tool results are the source of truth. Never say a browser attached, a user signed in, a request was captured, a proof passed, or a version was created or published unless a tool result says so.
172
42
 
173
- Treat every ID, version, URL, and value as opaque: copy it from the latest tool
174
- result. Never invent or reconstruct one. When state is unclear, call the
175
- relevant get/list tool or `how_it_works`. State uncertainty plainly.
43
+ Treat every ID, version, URL, and value as opaque: copy it from the latest tool result. Never invent or reconstruct one. When state is unclear, call the relevant get/list tool or `how_it_works`. State uncertainty plainly.
176
44
 
177
- **Guide:** `how_it_works({})` lists topics. Fetch only the one for your next
178
- step.
45
+ ## Guide
179
46
 
180
- **Authentication:** call `get_me`. On 401, `authenticate({})` returns `code`
181
- and `attachUrl`. Give the developer the URL, then poll `authenticate({ code })`
182
- until LINKED (topic `auth`).
47
+ `how_it_works({})` lists topics. Fetch only the one for your next step:
183
48
 
184
- **Backend mode:** `get_devtools_mode` reports the active mode.
185
- `set_devtools_mode` persists a switch to `~/.reclaim/config.json`, effective on
186
- the next server start. An explicit `USE_OLD_DEVTOOLS` env var wins.
49
+ - `overview`: authoring checklist; `prove`, `publish`, `browser`: the details behind each step.
50
+ - `integration`: app integration, trying a session without an app, existing `@reclaimprotocol/js-sdk` projects.
51
+ - `auth`: sign-in (`get_me`, then `authenticate` on 401) and backend mode.
package/skill/old-mode.md CHANGED
@@ -1,100 +1,45 @@
1
- Reclaim provider-authoring tools, running against the OLD DEVTOOLS backend —
2
- intentionally reduced: no generated API tools, no organizations, no public
3
- review flow. Only GET/POST requests can be captured into providers.
1
+ # Legacy devtools mode
4
2
 
5
- **A `provider` is a recipe for extracting a data point from a site. A
6
- `verification` is an end-user session that proves a data point using one. Never
7
- call a provider a "verification."**
3
+ Provider-authoring tools for the old devtools backend. The tool surface is reduced: no generated API tools, no organizations, no public review. Only GET and POST requests can be captured.
8
4
 
9
- **Provider versions are immutable.** Every recipe or configuration change
10
- creates a new semantic version. Default to a patch bump; use a major/minor bump
11
- or exact higher version when the user directs it. Never edit an existing
12
- version.
5
+ **A `provider` is a recipe for extracting a data point from a site. A `verification` is an end-user session that proves a data point with a provider. Never call a provider a "verification."**
6
+
7
+ ## Routing
8
+
9
+ - A provider found with `get_me_providers` or `get_provider_info` is published and usable as-is. Don't capture, replay, or prove it unless the developer asks.
10
+ - Before using a provider, found or just created, ask once how they want to use it (try it, integrate it, or build a new app), unless they already said. Topic `publish` has the options.
11
+ - Call `attach_browser()` with no arguments. Don't ask which browser to use.
12
+
13
+ ## Asking the developer
14
+
15
+ - When you need an answer or an action, end your turn with the question and every link they need. Don't use a background or asynchronous question tool: the developer may never see it.
16
+ - Ask each question once. Act on the answer; don't ask again.
17
+
18
+ ## Permission blocks
19
+
20
+ When a permission check blocks a tool call or command:
21
+
22
+ 1. Don't retry it or work around it.
23
+ 2. In one message, name the blocked tool or command, what it does, and what approving it means.
24
+ 3. Ask for approval in words that name that exact action, for example: "Approve running `npm run dev` to start the demo server?"
25
+
26
+ ## Authoring rules
27
+
28
+ - Provider versions are immutable: every change creates a new version, default a patch bump. Never edit an existing version.
29
+ - Publishing without `providerId` registers a new provider. Check `get_me_providers` first to avoid duplicates.
30
+ - `reclaim_authenticate` authorizes this mode. On an auth error, run it again (topic `auth`).
13
31
 
14
32
  ## Evidence contract
15
33
 
16
- Tool results are the source of truth. Never say that a browser attached, a user
17
- logged in, a request was captured, a proof passed, or a version was created or
18
- published unless the corresponding tool result says it happened. A planned tool
19
- call is not a completed action.
20
-
21
- Treat every ID, semantic version, URL, request value, and error as opaque: copy
22
- it from the latest tool result exactly. Never invent, autocomplete, reconstruct,
23
- shorten, or reuse one from memory. When state is missing or ambiguous, inspect
24
- it with the relevant get/list/status tool or call `how_it_works` before
25
- answering. State uncertainty plainly instead of guessing.
26
-
27
- **Ask blocking questions by ending your turn.** When you need an answer or an
28
- action from the developer before you can continue, end your turn with the
29
- question and every link they need. Don't use a background or asynchronous
30
- question tool for it: the developer may never see it.
31
-
32
- **Use the guide as needed.** Call `how_it_works({})` for its topic index, then
33
- fetch only the topic relevant to the next tool call.
34
-
35
- **Open the browser without asking.** Call `attach_browser()` with no
36
- arguments: it opens a visible browser on the developer's machine with the
37
- persistent Reclaim profile, and falls back to Chrome for Testing itself when
38
- no installed browser can be attached. Don't ask which browser or who signs in.
39
- Use another `mode` only when that fails too, or when the developer explicitly
40
- asks for it (topic `browser`). Tell the developer once, as a side note, that a
41
- shareable link can be set up if a volunteer is helping them sign in; don't ask
42
- about it or set it up unless they ask.
43
-
44
- **The flow:** `reclaim_authenticate` once → `attach_browser()` (no arguments: a
45
- visible local browser) → `start_capture` ⇒ **`captureId`** →
46
- drive the page (`navigate`,
47
- `wait_for_page`, `eval_in_page`) → inspect (`list_requests`, `get_request`,
48
- `find_requests_containing`) → `propose_provider` ⇒ **`draftId`** →
49
- `replay_request(captureId, draftId)` → `run_proof(captureId,
50
- draftId)` → `create_provider_version_from_capture`.
51
-
52
- `reclaim_authenticate` itself always uses a local Chrome over loopback CDP. It
53
- never uses the container, remote Builder, custom-CDP, or shared authoring
54
- browser; those choices begin only at `attach_browser` after dashboard sign-in.
55
-
56
- **Publishing and ownership:** with NO `providerId`, publish REGISTERS A NEW
57
- provider — re-running creates a duplicate. Pass a `providerId` from
58
- `get_me_providers` (the only provider-listing tool here) to add a version to an
59
- existing provider instead; you can only version a provider you own. For a
60
- multi-request provider pass `providers: [draftA, draftB, …]` so each becomes a
61
- parallel `requestData` entry on the one version.
62
-
63
- **Using a provider.** A provider found with `get_me_providers` or
64
- `get_provider_info` is published and usable as-is. Don't capture,
65
- `replay_request`, or `run_proof` against it unless the developer asks you to
66
- check or test it. Before using a provider, found or just created, ask once how
67
- they want to use it (skip this if they already said):
68
-
69
- > Want to (1) try it right now here, (2) integrate it into an existing backend
70
- > or frontend (this directory or another path), or (3) create a new app for it?
71
-
72
- Try it now → `scaffold_reclaim_demo_server` with its `providerId`. Integrate,
73
- or new app → `get_js_sdk_integration_guide`, then work in the path they named.
74
-
75
- **Two independent auth systems — don't confuse them.** `reclaim_authenticate`
76
- authorizes everything in this mode; its Firebase token is short-lived (~1h), so
77
- an auth error on publish or `get_me_providers` means re-run it.
78
- `authenticate_builder` covers only two Builder-exclusive features: allocating a
79
- remote browser (`attach_browser mode="builder"`) and
80
- `list_builder_organizations`. It authorizes nothing else. `get_devtools_mode`
81
- reports both.
82
-
83
- **Never prove a public endpoint.** After `replay_request` succeeds, re-run it
84
- with `withoutSecrets: true`. If the value still extracts, the endpoint is public
85
- and the proof binds to nobody — find an auth-bound request instead.
86
-
87
- **Templating:** bare `{{name}}` placeholders are extracted from the response.
88
- Values the CONSUMER supplies at verification time use `{{context_<name>}}` —
89
- this backend does NOT support the builder's dotted `{{context.<name>}}` form.
90
-
91
- **Diagnosing a session:** `session_analytics_logs` returns a session's
92
- milestone events; `session_logs` returns the log entries the SDK emitted, each
93
- with its event type — that is where a failed match, redaction, or claim shows
94
- up. Both take a `sessionId`; see topic `troubleshooting` for how to read them.
95
-
96
- **Backend mode:** the BUILDER backend (generated API tools, orgs, verification
97
- sessions, public review) is one switch away. `get_devtools_mode` reports the
98
- active mode and why; `set_devtools_mode` persists a switch to
99
- `~/.reclaim/config.json`, effective on the NEXT server start. An explicit
100
- `USE_OLD_DEVTOOLS` env var wins over the persisted choice.
34
+ Tool results are the source of truth. Never say a browser attached, a user logged in, a request was captured, a proof passed, or a version was created or published unless a tool result says so. A planned call is not a completed action.
35
+
36
+ Treat every ID, version, URL, request value, and error as opaque: copy it from the latest tool result. Never invent, reconstruct, or reuse one from memory. When state is unclear, call the relevant get/list/status tool or `how_it_works`. State uncertainty plainly.
37
+
38
+ ## Guide
39
+
40
+ `how_it_works({})` lists topics. Fetch only the one for your next step:
41
+
42
+ - `overview`: the authoring checklist.
43
+ - `auth`: sign-in, and backend mode (switching to Builder).
44
+ - `publish`: ownership, multi-request providers, using a provider.
45
+ - `troubleshooting`: `session_analytics_logs` and `session_logs` for a failed session.
@@ -4,7 +4,7 @@ Follow this plan end to end. Mark each step done as you go. Do not ask the devel
4
4
 
5
5
  **Order.** Do the steps that need the developer first: sign in to Builder, attach the browser, capture, and prove the provider (step 2). These need the developer at the browser, and they show early whether a proof is possible on this site. Write app code (step 3) after the proof works, or while you wait on the developer. Never spend a long stretch on app code before the developer has signed in and the browser is attached.
6
6
 
7
- **Asking the developer.** When you need an answer or an action from the developer before you can continue, end your turn with the question. Don't use background or asynchronous question tools for blocking questions: the developer may never see them. Put every link the developer needs, such as a sign-in or verification URL, in that same message.
7
+ **Asking the developer.** When you need an answer or an action, end your turn with the question. Don't use background or asynchronous question tools: the developer may never see them. Put every link they need in that same message. Ask each question once.
8
8
 
9
9
  ## 1. Sign in and pick the organization
10
10
 
@@ -15,6 +15,7 @@ Follow this plan end to end. Mark each step done as you go. Do not ask the devel
15
15
  <!-- ifnot:orgId -->
16
16
  - [ ] Call `list_orgs`. Use the only organization, or ask the developer which one when there are several.
17
17
  <!-- endif -->
18
+ - [ ] Call `get_org_keypair`. If the org has a key pair (any `canEncryptResult`), the app's callback must pass `orgEthPrivateKey` to `results.receive`: it decrypts encrypted results and verifies TEE-bound proofs. In the same message as any other step 1 question, ask the developer to choose one: reuse the existing key (they put its private key in the app's server env file as `RECLAIM_ORG_ETH_PRIVATE_KEY` themselves, never in chat), or rotate it (`issue_org_keypair` with `replace: true`; other apps holding the old key stop working with new results). If `canEncryptResult` is true, they can also turn encryption off with `update_org_keypair({ orgId, canEncryptResult: false })`, which keeps the key. Name the exact action in your question. Act on the answer in step 3.
18
19
 
19
20
  ## 2. Get the provider and prove it
20
21
 
@@ -39,7 +40,7 @@ Build a new organization-private provider for exactly "{{goal}}". Do not search
39
40
  - [ ] Call `replay_request`, then `replay_request` with `withoutSecrets: true` to confirm the request is auth-bound.
40
41
  - [ ] Call `run_proof`. It creates a local test signing key if none exists; tell the developer once afterwards.
41
42
  - [ ] Call `create_provider_version_from_capture`. It publishes the kept script as `jsUserScripts`. Follow its `_notes`, then publish the version.
42
- - [ ] Call `dispose_browser` after asking the developer.
43
+ - [ ] Don't ask whether to close the browser. Mention once in your final summary that it stays open for provider changes and you can close it on request. Call `dispose_browser` only when the developer says so.
43
44
  <!-- endif -->
44
45
 
45
46
  ## 3. Set up the app
@@ -65,21 +66,23 @@ Do this yourself, not in a subagent.
65
66
 
66
67
  - [ ] Call `create_example_app` with the workspace root you were started in as `projectDir`. It writes the example there and sets its backend to the latest `@reclaimprotocol/client`. Don't clone the repository or create a subdirectory: commands you run inside a clone count as running external code, and permission checks may block them.
67
68
  - [ ] Call `issue_org_token` with the same `projectDir` and `envFile: "packages/backend/.env"`.
68
- - [ ] Only when the developer asks for session binding or encrypted results: call `issue_org_keypair` with the same `projectDir` and `envFile` (add `encryptResults: true` for encrypted results). It writes `RECLAIM_ORG_ETH_PRIVATE_KEY` and registers the public key. Then pass `orgEthPrivateKey: process.env.RECLAIM_ORG_ETH_PRIVATE_KEY` to `reclaim.sessions.create` in `packages/backend/src/routes/verifications.ts` (binding) and to `reclaim.results.receive` in `packages/backend/src/routes/callback.ts` (decryption and TEE proof checks), and add an empty `RECLAIM_ORG_ETH_PRIVATE_KEY=` line to `packages/backend/example.env`.
69
- - [ ] From the workspace root, run `npm install`, then `npm run dev`. The backend listens on port 3000; the app opens at <http://localhost:5173>. If a permission check blocks either command, don't work around it: end your turn, say which command was blocked and that it installs and runs the Reclaim example app, and ask the developer to approve it.
70
- - [ ] Call `proxy_callback_events({ port: 3000, path: "/reclaim/callback" })`.
71
- - [ ] Skip the rest of this step. In step 4, the provider goes in `packages/backend/config.json`: replace the example entry with `{ "id": "<provider ID>", "name": "<what it proves>" }`, then restart the backend, because it reads the file at startup.
69
+ - [ ] Key pair, by the step 1 answer. No key pair on the org and the developer wants none: skip. Reuse: the developer has put the key in `packages/backend/.env`. Rotate, or no key pair and the developer asks for binding or encrypted results: call `issue_org_keypair` with the same `projectDir` and `envFile` (`encryptResults: true` for encrypted results, `replace: true` to rotate). It writes `RECLAIM_ORG_ETH_PRIVATE_KEY` and backs up a replaced key to `<envFile>.backup`; tell the developer that path (never the key). Turn encryption off with `update_org_keypair`. The example's callback (`packages/backend/src/routes/callback.ts`) passes `RECLAIM_ORG_ETH_PRIVATE_KEY` to `reclaim.results.receive`; if it doesn't, add `orgEthPrivateKey: process.env.RECLAIM_ORG_ETH_PRIVATE_KEY` there. For session binding, also pass it to `reclaim.sessions.create` in `packages/backend/src/routes/verifications.ts`.
70
+ - [ ] From the workspace root, run `npm install`. Then follow the `next` array that `create_example_app` returned for the dev command, ports, log location, notes, and the `proxy_callback_events` call. Don't assume default ports.
71
+ - [ ] Run the dev server in the background with its output redirected to a log file, and read that file for backend output. Don't depend on the shell's own output.
72
+ - [ ] After you restart the backend, its in-memory store is empty. Ask the developer for a new verification; don't retry the old session.
73
+ - [ ] If a permission check blocks a command, follow "Permission blocks" in the server instructions.
74
+ - [ ] Skip the rest of this step. In step 4, the provider goes in `packages/backend/config.json`: replace the example entry with `{ "id": "<provider ID>", "name": "<what it proves>" }`, then restart the backend, because it reads the file at startup. Then ask for a new verification.
72
75
 
73
76
  **Existing app.** Add verification to it:
74
77
 
75
78
  - [ ] Detect the app's framework and package manager from the repository, and use them. Read `how_it_works({ topic: "integration" })`.
76
- - [ ] 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`.
79
+ - [ ] 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; it backs up a replaced value to `<envFile>.backup`, so tell the developer that path. Never print or commit the key. Confirm the env file is in `.gitignore`.
77
80
  - [ ] 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.
78
- - [ ] Only when the developer asks for session binding or encrypted results: call `issue_org_keypair` with the server env file (`encryptResults: true` for encrypted results), and pass `orgEthPrivateKey` from that env variable to `sessions.create` and `results.receive`.
81
+ - [ ] Key pair, by the step 1 answer. Reuse: the developer has put the key in the server env file. Rotate, or no key pair and the developer asks for binding or encrypted results: call `issue_org_keypair` with the server env file (`encryptResults: true` for encrypted results, `replace: true` to rotate). It backs up a replaced key to `<envFile>.backup`; tell the developer that path (never the key). Turn encryption off with `update_org_keypair`. Whenever the org has a key pair, pass `orgEthPrivateKey` from `RECLAIM_ORG_ETH_PRIVATE_KEY` to `sessions.create` and `results.receive`.
79
82
  - [ ] Add a callback route that verifies each result with `results.receive` from `@reclaimprotocol/client`, then stores only the requested data points. Store every failure on the verification session record and log it server-side: a failure event (`verification_rejected`, `verification_error`, `verification_cancelled`, `session_expired`), or a thrown `ResultVerificationError` (`error.reason` plus each failing proof's `reason`). Respond `error.retryable ? 503 : 200`. A result that failed verification gets 2xx, because retrying can't fix it. Read the exact pattern in `how_it_works({ topic: "integration" })`.
80
83
  - [ ] Add a status route the frontend polls. It returns the stored status, data points, and failure reason. While the app has no result, it also reads `GET /verifications/sessions/{sessionId}`, so a session that ended in Builder never stays pending.
81
84
  - [ ] Add a frontend Verify button that opens `verificationUrl`, and render every state in "UI states" in `how_it_works({ topic: "integration" })`: idle, waiting in the other tab, verifying, verified (with the data points), failed (plain-language reason and **Try again**), and expired or cancelled (**Try again**). Never leave a spinner as the only feedback.
82
- - [ ] 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.
85
+ - [ ] Start the app in the background with output redirected to a log file. 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.
83
86
 
84
87
  ## 4. Wire the provider and test end to end
85
88