@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.
Files changed (117) hide show
  1. package/README.md +3 -3
  2. package/lib/authoring/backend.d.ts +13 -0
  3. package/lib/authoring/index.d.ts +1 -1
  4. package/lib/authoring/tools.js +78 -42
  5. package/lib/config/store.d.ts +10 -0
  6. package/lib/mcp/api/operations.gen.d.ts +238 -4
  7. package/lib/mcp/api/operations.gen.js +6967 -672
  8. package/lib/mcp/api/tools.js +21 -8
  9. package/lib/mcp/instructions.js +12 -12
  10. package/lib/mcp/server.d.ts +1 -1
  11. package/lib/mcp/server.js +3 -0
  12. package/lib/mcp/start.js +8 -7
  13. package/lib/mcp/success-response.js +5 -1
  14. package/lib/mcp/tools/agent/analyze.js +5 -4
  15. package/lib/mcp/tools/agent/attach.js +11 -7
  16. package/lib/mcp/tools/agent/build.js +5 -1
  17. package/lib/mcp/tools/agent/capture.d.ts +2 -2
  18. package/lib/mcp/tools/agent/capture.js +15 -11
  19. package/lib/mcp/tools/agent/check-attestor.d.ts +5 -0
  20. package/lib/mcp/tools/agent/check-attestor.js +37 -0
  21. package/lib/mcp/tools/agent/eval.js +4 -3
  22. package/lib/mcp/tools/agent/find.js +9 -10
  23. package/lib/mcp/tools/agent/how-it-works.js +1 -0
  24. package/lib/mcp/tools/agent/live-view.js +49 -22
  25. package/lib/mcp/tools/agent/pod-proof.js +7 -11
  26. package/lib/mcp/tools/agent/proof.d.ts +12 -0
  27. package/lib/mcp/tools/agent/proof.js +32 -0
  28. package/lib/mcp/tools/agent/propose.js +4 -3
  29. package/lib/mcp/tools/agent/publish.d.ts +2 -1
  30. package/lib/mcp/tools/agent/publish.js +12 -6
  31. package/lib/mcp/tools/agent/replay.js +10 -7
  32. package/lib/mcp/tools/agent/session.js +16 -8
  33. package/lib/mcp/tools/agent/shared.d.ts +2 -1
  34. package/lib/mcp/tools/agent/shared.js +29 -24
  35. package/lib/mcp/tools/agent/start-integration.d.ts +15 -0
  36. package/lib/mcp/tools/agent/start-integration.js +62 -0
  37. package/lib/mcp/tools/authenticate/authenticate.js +9 -11
  38. package/lib/mcp/tools/authenticate/build.js +2 -0
  39. package/lib/mcp/tools/authenticate/builder-access.js +1 -0
  40. package/lib/mcp/tools/authenticate/eth-key.d.ts +8 -0
  41. package/lib/mcp/tools/authenticate/eth-key.js +27 -15
  42. package/lib/mcp/tools/authenticate/import.js +18 -31
  43. package/lib/mcp/tools/authenticate/issue-org-token.d.ts +8 -0
  44. package/lib/mcp/tools/authenticate/issue-org-token.js +60 -0
  45. package/lib/mcp/tools/authenticate/issue.js +9 -9
  46. package/lib/mcp/tools/authenticate/org-key-store.d.ts +10 -0
  47. package/lib/mcp/tools/authenticate/org-key-store.js +23 -0
  48. package/lib/mcp/tools/authenticate/resolve-owner-key.js +10 -12
  49. package/lib/mcp/tools/mode/mode.js +2 -0
  50. package/lib/mcp/tools/verification/build.d.ts +3 -1
  51. package/lib/mcp/tools/verification/build.js +10 -2
  52. package/lib/mcp/tools/verification/callback-listener.d.ts +51 -0
  53. package/lib/mcp/tools/verification/callback-listener.js +163 -0
  54. package/lib/mcp/tools/verification/index.d.ts +2 -0
  55. package/lib/mcp/tools/verification/index.js +2 -0
  56. package/lib/mcp/tools/verification/proxy-callback-events.d.ts +59 -0
  57. package/lib/mcp/tools/verification/proxy-callback-events.js +300 -0
  58. package/lib/mcp/tools/verification/read-callback-events.d.ts +3 -0
  59. package/lib/mcp/tools/verification/read-callback-events.js +135 -0
  60. package/lib/mcp/tools/verification/result.d.ts +6 -0
  61. package/lib/mcp/tools/verification/result.js +11 -8
  62. package/lib/proof/check-attestor.d.ts +67 -0
  63. package/lib/proof/check-attestor.js +156 -0
  64. package/lib/tools/registry.d.ts +12 -0
  65. package/lib/tools/registry.js +1 -0
  66. package/package.json +2 -2
  67. package/skill/SKILL.builder.md +84 -75
  68. package/skill/SKILL.common.md +23 -10
  69. package/skill/builder-mode.md +140 -138
  70. package/skill/start-integration.md +74 -0
  71. package/skill/user-script.md +64 -0
  72. package/skill/verification-client-integration.md +40 -28
  73. package/src/authoring/backend.ts +15 -0
  74. package/src/authoring/index.ts +2 -0
  75. package/src/authoring/tools.ts +86 -42
  76. package/src/config/store.ts +11 -0
  77. package/src/mcp/api/operations.gen.ts +7011 -704
  78. package/src/mcp/api/tools.ts +21 -8
  79. package/src/mcp/instructions.ts +12 -12
  80. package/src/mcp/server.ts +4 -0
  81. package/src/mcp/start.ts +9 -7
  82. package/src/mcp/success-response.ts +5 -1
  83. package/src/mcp/tools/agent/analyze.ts +5 -4
  84. package/src/mcp/tools/agent/attach.ts +11 -7
  85. package/src/mcp/tools/agent/build.ts +7 -1
  86. package/src/mcp/tools/agent/capture.ts +20 -12
  87. package/src/mcp/tools/agent/check-attestor.ts +49 -0
  88. package/src/mcp/tools/agent/eval.ts +4 -3
  89. package/src/mcp/tools/agent/find.ts +9 -10
  90. package/src/mcp/tools/agent/how-it-works.ts +1 -0
  91. package/src/mcp/tools/agent/live-view.ts +49 -22
  92. package/src/mcp/tools/agent/pod-proof.ts +7 -11
  93. package/src/mcp/tools/agent/proof.ts +55 -0
  94. package/src/mcp/tools/agent/propose.ts +4 -3
  95. package/src/mcp/tools/agent/publish.ts +12 -4
  96. package/src/mcp/tools/agent/replay.ts +10 -7
  97. package/src/mcp/tools/agent/session.ts +16 -8
  98. package/src/mcp/tools/agent/shared.ts +39 -24
  99. package/src/mcp/tools/agent/start-integration.ts +84 -0
  100. package/src/mcp/tools/authenticate/authenticate.ts +9 -11
  101. package/src/mcp/tools/authenticate/build.ts +2 -0
  102. package/src/mcp/tools/authenticate/builder-access.ts +1 -0
  103. package/src/mcp/tools/authenticate/eth-key.ts +48 -18
  104. package/src/mcp/tools/authenticate/import.ts +21 -36
  105. package/src/mcp/tools/authenticate/issue-org-token.ts +84 -0
  106. package/src/mcp/tools/authenticate/issue.ts +9 -9
  107. package/src/mcp/tools/authenticate/org-key-store.ts +25 -0
  108. package/src/mcp/tools/authenticate/resolve-owner-key.ts +10 -12
  109. package/src/mcp/tools/mode/mode.ts +2 -0
  110. package/src/mcp/tools/verification/build.ts +10 -2
  111. package/src/mcp/tools/verification/callback-listener.ts +203 -0
  112. package/src/mcp/tools/verification/index.ts +2 -0
  113. package/src/mcp/tools/verification/proxy-callback-events.ts +374 -0
  114. package/src/mcp/tools/verification/read-callback-events.ts +160 -0
  115. package/src/mcp/tools/verification/result.ts +11 -8
  116. package/src/proof/check-attestor.ts +209 -0
  117. package/src/tools/registry.ts +14 -0
@@ -1,146 +1,148 @@
1
1
  # Builder mode
2
2
 
3
- Reclaim provider-authoring tools run against the Builder backend. They include
4
- generated Builder API tools, credential and verification helpers, and browser
5
- authoring tools.
6
-
7
- ## Claimant-facing Builder sessions
8
-
9
- This integration is separate from provider authoring.
10
-
11
- **Using a provider.** A provider found with `providers`, `discover_resolve`, or
12
- another lookup is published and usable as-is. Don't capture, `replay_request`,
13
- or `run_proof` against it unless the developer asks you to check or test it.
14
- Before using a provider, found or just created, ask once whether they just want
15
- to try it or want it in an app (skip this if they already said):
16
-
17
- > Want to (1) just try it right now, (2) integrate it into an existing backend
18
- > or frontend (this directory or another path), or (3) create a new app for it?
19
-
20
- - **Just try it:** no app or client package, but the same production API the
21
- app will use. You need an org API key (`rorg_…`): reuse one the developer
22
- already has, else `issue_org_token` (owner only; the key is shown once).
23
- Session creation returns 409 while the org has no callback subscription, and
24
- the result is only stored for subscriptions to the event the session ends
25
- with. If the org has none, register a temporary one for all five ending
26
- events with `create_org_callback_subscription` (for example, a tunnel to a
27
- local listener that saves the body it receives). Then call
28
- `create_verification_session` with `orgToken`, give the developer
29
- `verificationUrl` to open, poll `get_verification_session` (with `orgToken`)
30
- until it is terminal, and report the outcome: from the body your listener
31
- received, or with `get_verification_result` (with `orgToken`), which only
32
- works until the callback is delivered. Delete the temporary subscription with
33
- `delete_org_callback_subscription` only after that: deleting it also deletes
34
- its stored results.
35
- - **Integrate, or new app:** follow the setup below in the path they named.
36
-
37
- **Org API key vs. sign-in.** Management tools (`list_orgs`,
38
- `create_org_callback_subscription`, `issue_org_token`, …) use the developer's
39
- sign-in. Session tools (`create_verification_session`,
40
- `get_verification_session`, `list_verification_events`,
41
- `list_verification_deliveries`, `retry_verification_callback`) are the
42
- production API a backend calls, so they take the org key as `orgToken`
43
- (defaulting to this server's `RECLAIM_ORG_SECRET`). Never print the key back to
44
- the developer.
45
-
46
- **Prefer the HTTP API over `@reclaimprotocol/client`** for every option:
47
- create sessions with `POST /verifications/sessions`, open `verificationUrl`,
48
- poll `GET /verifications/sessions/{sessionId}`, and take the result on the
49
- callback. Use the client package only when the developer asks for it — the one
50
- exception is `results.receive`, to verify the result on your callback.
51
-
52
- When integrating into an app, read `how_it_works({ topic: "integration" })`,
53
- then configure the organization with generated tools (`list_orgs`,
54
- `create_org`, `create_org_callback_subscription`, and owner-only
55
- `issue_org_token`) and edit the app's frontend and backend with the coding
56
- agent's file tools. The guide
57
- covers the HTTP session workflow, exact `api=2` boundary, result
58
- verification, request-proof contract, and optional TEE binding. A URL without
59
- `api=2` stays on its existing legacy path.
60
-
61
- **Existing `@reclaimprotocol/js-sdk` projects.** If the app's `package.json`
62
- depends on `@reclaimprotocol/js-sdk`, ask the developer before doing anything
63
- else:
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 integration
67
- > (Builder HTTP API)?
68
-
69
- - **Keep js-sdk:** call `set_devtools_mode({ mode: "old" })`, then tell them to
70
- restart or reconnect the MCP server; the switch applies on the next start. An
71
- explicit `USE_OLD_DEVTOOLS` env var overrides it. After the restart, read
72
- `get_js_sdk_integration_guide`.
73
- - **Migrate:** stay in Builder mode. Follow `how_it_works({ topic:
74
- "integration" })` to replace `@reclaimprotocol/js-sdk` with the Builder
75
- HTTP session flow and update the app's code.
76
-
77
- **A `provider` is a recipe for extracting a data point from a site. A
78
- `verification` is an end-user session that proves a data point using one. Never
79
- call a provider a "verification."**
80
-
81
- **Provider versions are immutable in agent workflows.** Every recipe or
82
- configuration change creates a new semantic version. Default to a patch bump;
83
- use a major/minor bump or exact higher version when the user directs it. Never
84
- use an in-place provider-version update or archive tool.
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 that a browser attached, a user
89
- logged in, a request was captured, a proof passed, or a version was created or
90
- published unless the corresponding tool result says it happened. A planned tool
91
- call is not a completed action.
92
-
93
- Treat every ID, semantic version, URL, request value, and error as opaque: copy
94
- it from the latest tool result exactly. Never invent, autocomplete, reconstruct,
95
- shorten, or reuse one from memory. When state is missing or ambiguous, inspect
96
- it with the relevant get/list/status tool or call `how_it_works` before
97
- answering. State uncertainty plainly instead of guessing.
98
-
99
- **Use the guide as needed.** Call `how_it_works({})` for its topic index, then
100
- fetch only the topic relevant to the next tool call.
101
-
102
- **Authentication:** try `get_me` first. On 401, `authenticate({})` returns a
103
- device-pairing `code` + `attachUrl` — give the user the URL, then poll
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 NEXT server start. An explicit `USE_OLD_DEVTOOLS` env var wins over 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."
@@ -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
- When asked to integrate Reclaim into an app, inspect that app's frontend,
6
- backend, package manager, configuration, and callback conventions. Complete
7
- the integration in its codebase and run its relevant checks. The MCP tools
8
- configure Builder resources; the coding agent's file tools edit the app.
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 (call `set_devtools_mode({ mode: "old" })` and have them restart the MCP
12
- server), or migrate to the Builder session flow below. When
13
- migrating, remove `@reclaimprotocol/js-sdk` and replace its
14
- `ReclaimProofRequest` and `verifyProof` calls with the session flow below.
15
-
16
- 1. Use `get_devtools_mode` to confirm Builder mode and `get_me` or
17
- `authenticate` to sign in as the developer. Find the intended organization
18
- with `list_orgs`; call `create_org` only when a new organization is wanted.
19
- 2. Register a callback URL owned by the app's backend with
20
- `create_org_callback_subscription`. Include terminal success, rejection,
21
- error, cancellation, and expiry events. If the app needs encrypted results,
22
- register its public key with `set_org_keypair`; retain the private key only
23
- in the backend.
24
- 3. Reuse a `RECLAIM_ORG_SECRET` the app already has. Otherwise an organization
25
- owner calls `issue_org_token`; its `orgSecret` is shown once. Write it with
26
- your file tools into the backend's env file (for example
27
- `RECLAIM_ORG_SECRET=rorg_…` in `.env`) and make sure that file is
28
- gitignored. Keep it out of frontend bundles, logs, source control, and the
29
- final response.
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, or `curl` with the key from `.env`, to test the
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
- Subscribe a callback once (or use `create_org_callback_subscription`). Session
73
- creation returns 409 while the org has none, and a result is only delivered to
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 \
@@ -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
@@ -4,6 +4,8 @@ export type {
4
4
  AuthoringBackend,
5
5
  Draft,
6
6
  DraftStore,
7
+ KeptScript,
8
+ KeptScriptRef,
7
9
  ProveOptions,
8
10
  SecretParams,
9
11
  } from './backend.ts'