@reclaimprotocol/agent 0.1.43 → 0.1.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/mcp/api/operations.gen.d.ts +17 -0
- package/lib/mcp/api/operations.gen.js +151 -1
- package/lib/mcp/instructions.js +4 -0
- package/lib/mcp/tools/agent/publish.js +8 -1
- package/lib/mcp/tools/agent/start-integration.d.ts +1 -0
- package/lib/mcp/tools/agent/start-integration.js +20 -3
- package/lib/mcp/tools/verification/build.js +2 -0
- package/lib/mcp/tools/verification/wait-for-ai-session.d.ts +46 -0
- package/lib/mcp/tools/verification/wait-for-ai-session.js +228 -0
- package/package.json +2 -2
- package/skill/SKILL.builder.md +2 -0
- package/skill/ai-sessions.md +87 -0
- package/skill/builder-mode.md +3 -3
- package/skill/interception.md +36 -1
- package/skill/start-ai-session-integration.md +58 -0
- package/skill/start-integration.md +2 -0
- package/skill/verification-client-integration.md +3 -0
- package/src/mcp/api/operations.gen.ts +157 -1
- package/src/mcp/instructions.ts +4 -0
- package/src/mcp/tools/agent/publish.ts +8 -1
- package/src/mcp/tools/agent/start-integration.ts +22 -3
- package/src/mcp/tools/verification/build.ts +2 -0
- package/src/mcp/tools/verification/wait-for-ai-session.ts +304 -0
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# AI sessions: the first route for a backend integration
|
|
2
|
+
|
|
3
|
+
An AI session proves a claim about a user's account on a website. You describe
|
|
4
|
+
the claim. An AI agent completes it in a remote browser. You need no provider,
|
|
5
|
+
no capture, and no org keypair: Builder manages a hidden AI app key for each
|
|
6
|
+
org.
|
|
7
|
+
|
|
8
|
+
## When to use it
|
|
9
|
+
|
|
10
|
+
Use AI sessions first for any claim about a user's account on a site, for
|
|
11
|
+
example "prove the user is a student at example.edu". Prefer them over
|
|
12
|
+
authoring a provider and creating regular sessions. Fall back to the provider
|
|
13
|
+
route only as [Fall back to a provider](#fall-back-to-a-provider) describes.
|
|
14
|
+
|
|
15
|
+
## Set up
|
|
16
|
+
|
|
17
|
+
1. Sign in (`get_me`, then `authenticate` on 401; topic `auth`) and pick the
|
|
18
|
+
org with `list_orgs`.
|
|
19
|
+
2. Call `issue_org_token`. It writes `RECLAIM_ORG_SECRET` to the env file.
|
|
20
|
+
Never print the key.
|
|
21
|
+
3. Add at least one callback subscription with `create_callback_subscription`.
|
|
22
|
+
For local development, call `proxy_callback_events({ port, path })` as
|
|
23
|
+
topic `integration` describes. Without a subscription, creating a session
|
|
24
|
+
returns 409.
|
|
25
|
+
|
|
26
|
+
## Try it first
|
|
27
|
+
|
|
28
|
+
1. Call `create_ai_verification_session`:
|
|
29
|
+
- `prompt`: the claim in plain words.
|
|
30
|
+
- `dataPoints`: `{ name, description, isOptional }` items. Include exactly
|
|
31
|
+
one required identifier. Other fields are optional. `isOptional` defaults
|
|
32
|
+
to `false`. Names match `^[A-Za-z_][A-Za-z0-9_]{0,63}$`. Describe each
|
|
33
|
+
one. Never invent values.
|
|
34
|
+
- `loginUrls`: the portal URLs, when the developer knows them.
|
|
35
|
+
- Omit `verificationClientUrl`. Only the portals verification client
|
|
36
|
+
supports AI sessions today, and it is the default. Don't pass another
|
|
37
|
+
client.
|
|
38
|
+
- Leave `isEmailVerificationAllowed` `false`. The email option isn't
|
|
39
|
+
working yet.
|
|
40
|
+
2. Call `wait_for_ai_session`. Put the session's `verificationUrl` in the same
|
|
41
|
+
message as your question to the developer, and end your turn. Then wait
|
|
42
|
+
until the session is terminal.
|
|
43
|
+
3. Inspect the outcome with `get_verification_session`,
|
|
44
|
+
`list_verification_events`, `list_verification_deliveries`, and
|
|
45
|
+
`read_callback_events`.
|
|
46
|
+
|
|
47
|
+
## Write the backend code
|
|
48
|
+
|
|
49
|
+
Keep every secret on the server.
|
|
50
|
+
|
|
51
|
+
1. Create the session server-side: `POST /verifications/ai-sessions` with the
|
|
52
|
+
org token. Use `reclaim.api('CreateAiVerificationSession', …)` from
|
|
53
|
+
`@reclaimprotocol/client`, or `fetch`.
|
|
54
|
+
2. Return only `verificationUrl` to the frontend. The frontend opens it in an
|
|
55
|
+
iframe or a new tab.
|
|
56
|
+
3. Receive the result on the callback endpoint. Verify it with
|
|
57
|
+
`reclaim.results.receive(body, { reclaimSessionId })` (client 0.1.44 or
|
|
58
|
+
later accepts results that have no provider). Topic `integration` has the
|
|
59
|
+
full route, including idempotent storage and `503` for retryable errors.
|
|
60
|
+
4. Read the values from the verified proofs' `extractedParameters`. Every
|
|
61
|
+
required data point is present.
|
|
62
|
+
5. Handle the three outcomes:
|
|
63
|
+
- `verification_success`: use the verified data.
|
|
64
|
+
- `verification_rejected`: read `reasonCode`. `missing-data-points` means a
|
|
65
|
+
required data point is missing. `context-mismatch` means the context
|
|
66
|
+
differs from the session's.
|
|
67
|
+
- `verification_error`: record the failure and offer a retry.
|
|
68
|
+
|
|
69
|
+
## Verifying results
|
|
70
|
+
|
|
71
|
+
Builder checks regular sessions against provider recipes. AI-session proofs
|
|
72
|
+
come from Popcorn. Builder verifies them with the ai-sdk `verifyProofs`, then
|
|
73
|
+
checks the required data points and the context pin. AI results omit
|
|
74
|
+
`provider_id` and `resolved_version`. Verify both kinds with
|
|
75
|
+
`reclaim.results.receive` from `@reclaimprotocol/client` 0.1.44 or later.
|
|
76
|
+
Older clients reject AI results.
|
|
77
|
+
|
|
78
|
+
## Fall back to a provider
|
|
79
|
+
|
|
80
|
+
Switch to the provider route (`start_integration` with route `provider`:
|
|
81
|
+
capture, provider, regular sessions) when:
|
|
82
|
+
|
|
83
|
+
- Lookup fails: 404 (no login page) or 422 (not verifiable).
|
|
84
|
+
- The session is rejected after one adjusted retry.
|
|
85
|
+
- The user can't finish it, or it errors or expires repeatedly.
|
|
86
|
+
- `503` persists.
|
|
87
|
+
- The developer prefers a deterministic provider.
|
package/skill/builder-mode.md
CHANGED
|
@@ -6,8 +6,8 @@ Provider-authoring and verification tools for the Builder backend.
|
|
|
6
6
|
|
|
7
7
|
## Routing
|
|
8
8
|
|
|
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
|
|
9
|
+
- "Add Reclaim to my app" or similar: call `start_integration` first (it defaults to AI sessions) and follow its plan. Don't ask what they want to do with the result.
|
|
10
|
+
- A claim about a user's account on a site (for example, "prove the user is a student at example.edu"): use AI sessions first (topic `ai-sessions`). Author a provider only as the fallback, or when they name or ask to reuse one (topic `discover`).
|
|
11
11
|
- Intent unclear: ask one short question.
|
|
12
12
|
|
|
13
13
|
## Authoring rules
|
|
@@ -48,5 +48,5 @@ Treat every ID, version, URL, and value as opaque: copy it from the latest tool
|
|
|
48
48
|
`how_it_works({})` lists topics. Fetch only the one for your next step:
|
|
49
49
|
|
|
50
50
|
- `overview`: authoring checklist; `prove`, `publish`, `browser`: the details behind each step.
|
|
51
|
-
- `integration`: app integration, trying a session without an app, existing `@reclaimprotocol/js-sdk` projects.
|
|
51
|
+
- `ai-sessions`: the first route for proving a claim; `integration`: app integration, trying a session without an app, existing `@reclaimprotocol/js-sdk` projects.
|
|
52
52
|
- `auth`: sign-in (`get_me`, then `authenticate` on 401) and backend mode.
|
package/skill/interception.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
- The field, per backend
|
|
6
6
|
- Which mechanism to pick, and when to use any of them at all
|
|
7
7
|
- When a site won't load, or won't let the user sign in — ask which clients
|
|
8
|
-
ship it, bisect, then the remedies
|
|
8
|
+
ship it, bisect, then the remedies (including the in-app Hawkeye hook mode)
|
|
9
9
|
- The document-replay flag, and why the two backends invert its polarity
|
|
10
10
|
- Recognizing live interception on a provider you didn't author
|
|
11
11
|
- Related topics
|
|
@@ -169,6 +169,41 @@ the page differently: old-devtools supports `HAWKEYE`, `MSWJS`, `XHOOK`, and
|
|
|
169
169
|
`CDP`; Builder supports `HAWKEYE`, `MSWJS`, and `CDP`. `CDP` operates below the
|
|
170
170
|
page's JavaScript but is not supported by every in-page client.
|
|
171
171
|
|
|
172
|
+
### In-app SDK: change how Hawkeye hooks `fetch`
|
|
173
|
+
|
|
174
|
+
Under `HAWKEYE`, the InApp SDK can wrap the page's `fetch` three ways, and a
|
|
175
|
+
site can break under one and work under another. Suspect this when the provider
|
|
176
|
+
works in Portals or Builder but the in-app page stalls: for example, a bot-check
|
|
177
|
+
or "one moment" screen that never clears, a sign-in form that never appears, or
|
|
178
|
+
the site's own scripts failing on requests they normally make. Try it before
|
|
179
|
+
removing interception, because it keeps the interceptor working.
|
|
180
|
+
|
|
181
|
+
Set the mode on the provider version, keeping `interceptorType: "HAWKEYE"`:
|
|
182
|
+
|
|
183
|
+
```json
|
|
184
|
+
"clientOptions": { "inapp": { "interceptorOptions": {
|
|
185
|
+
"interceptorType": "HAWKEYE",
|
|
186
|
+
"interceptorSettings": "{\"interceptionMethod\":\"GETTER_SETTER\"}"
|
|
187
|
+
} } }
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
`interceptorSettings` is a JSON object **string**. `interceptionMethod` is one
|
|
191
|
+
of:
|
|
192
|
+
|
|
193
|
+
- `PROXY` (default): wraps `fetch` in a `Proxy`, so `fetch.toString()` still
|
|
194
|
+
looks native.
|
|
195
|
+
- `GETTER_SETTER`: rebuilds each call as `new Request(input, init)`, and keeps
|
|
196
|
+
wrapping if the page reassigns `window.fetch`. Try this first.
|
|
197
|
+
- `DIRECT_REPLACEMENT`: the same wrapper, assigned once.
|
|
198
|
+
|
|
199
|
+
`GETTER_SETTER` and `DIRECT_REPLACEMENT` make `fetch.toString()` non-native. Some
|
|
200
|
+
anti-bot vendors check for that, so confirm with a real in-app verification;
|
|
201
|
+
authoring never exercises the in-app client. Optional `disableFormIntercept`
|
|
202
|
+
(default `true`) and `delayFormSubmitForFetch` (default `false`) go in the same
|
|
203
|
+
object. Keys you leave out keep the SDK's defaults, and other interceptor types
|
|
204
|
+
ignore `interceptorSettings`. If no mode works, go back to the bisect steps
|
|
205
|
+
above.
|
|
206
|
+
|
|
172
207
|
⚠️ **The direct-claim remedy needs a client that consumes `window.Reclaim`.**
|
|
173
208
|
The InApp SDK, browser extension, portals, and Builder's built-in client do. The
|
|
174
209
|
built-in client uses the page-supplied request to generate the proof;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Plan: let users prove "{{goal}}" in this app with a Builder AI session
|
|
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
|
+
An AI session needs no provider. The user prompt and data points tell Builder what to prove, and Builder finds the site and the login page. Only the portals verification client supports AI sessions today, so omit `verificationClientUrl` (portals is the default). Start with the steps that need the developer (sign in, try a session), and write app code while you wait.
|
|
6
|
+
|
|
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
|
+
|
|
9
|
+
## 1. Sign in and pick the organization
|
|
10
|
+
|
|
11
|
+
- [ ] Call `reclaim_authenticate` if you are not signed in. Give the developer the returned `signInUrl` to approve in their browser (end your turn first if `browserOpened` is false), then call `wait_for_sign_in`.
|
|
12
|
+
<!-- if:orgId -->
|
|
13
|
+
- [ ] Use organization `{{orgId}}` for every call below.
|
|
14
|
+
<!-- endif -->
|
|
15
|
+
<!-- ifnot:orgId -->
|
|
16
|
+
- [ ] Call `list_orgs`. Use the only organization, or ask the developer which one when there are several.
|
|
17
|
+
<!-- endif -->
|
|
18
|
+
|
|
19
|
+
## 2. Get an org token
|
|
20
|
+
|
|
21
|
+
- [ ] If `RECLAIM_ORG_SECRET` is not in the server env file, 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, and confirm the env file is in `.gitignore`.
|
|
22
|
+
|
|
23
|
+
## 3. Make sure results have a destination
|
|
24
|
+
|
|
25
|
+
- [ ] Call `list_callback_subscriptions`. If the organization has none, call `create_callback_subscription` for the session-ending events: `verification_success`, `verification_rejected`, `verification_error`, `verification_cancelled`, and `session_expired`.
|
|
26
|
+
- [ ] For local development, start the app's backend and 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. The proxy works only while this coding agent's MCP server runs.
|
|
27
|
+
- [ ] For production, ask the developer for the public callback URL, and call `create_org_callback_subscription` with it. 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."
|
|
28
|
+
|
|
29
|
+
## 4. Read the guide
|
|
30
|
+
|
|
31
|
+
- [ ] Call `how_it_works({ topic: "ai-sessions" })` and follow it for request fields, session states, and error codes. Don't repeat its detail here.
|
|
32
|
+
|
|
33
|
+
## 5. Try a session
|
|
34
|
+
|
|
35
|
+
- [ ] Call `create_ai_verification_session` with:
|
|
36
|
+
- `prompt`: a sentence for "{{goal}}", written as the claim to prove.
|
|
37
|
+
- `dataPoints`: the values the claim needs. Mark one identifier required. Mark the others optional. Add no profile or identity extras.
|
|
38
|
+
- `loginUrls`: the site's sign-in URLs, when you know them.
|
|
39
|
+
- [ ] Call `wait_for_ai_session` with the returned session ID, until the lookup is ready.
|
|
40
|
+
- [ ] Share the returned `verificationUrl` with the developer, in the same message as the ask: "Open this link, sign in to the site, and tell me when you are done." End your turn.
|
|
41
|
+
- [ ] After they reply, call `wait_for_ai_session` until the session reaches a terminal status. Use `read_callback_events({ sessionId })` to see the delivered result.
|
|
42
|
+
- [ ] The hosted verification page streams the target site as an image, so text or DOM checks of that page come back empty. Check progress with `wait_for_ai_session`, `list_verification_events`, and `get_verification_session`, not by reading the page.
|
|
43
|
+
|
|
44
|
+
## 6. Write the backend integration
|
|
45
|
+
|
|
46
|
+
Write this while you wait on the developer. Don't let it delay a step that needs them.
|
|
47
|
+
|
|
48
|
+
- [ ] Detect the app's framework and package manager from the repository, and use them. Read `how_it_works({ topic: "integration" })`.
|
|
49
|
+
- [ ] Add a backend route that calls `POST /verifications/ai-sessions` server-side, with the same prompt, data points, and login URLs as step 5, and returns `verificationUrl`. Never call it from the browser: it needs the org key.
|
|
50
|
+
- [ ] Add a callback route that verifies each result with `reclaim.results.receive` from `@reclaimprotocol/client` version 0.1.44 or later, then stores only the requested data points. Store every failure on the verification session record and log it server-side. Respond `error.retryable ? 503 : 200`. A result that failed verification gets 2xx, because retrying can't fix it.
|
|
51
|
+
- [ ] Add a status route the frontend polls, and a frontend Verify button that opens `verificationUrl`. Render every state in "UI states" in `how_it_works({ topic: "integration" })`, including **Try again** on failure.
|
|
52
|
+
- [ ] If the org has a key pair (`get_org_keypair`), pass `orgEthPrivateKey` from `RECLAIM_ORG_ETH_PRIVATE_KEY` to `results.receive`. The developer puts that key in the env file, never in chat.
|
|
53
|
+
- [ ] If a permission check blocks a command, follow "Permission blocks" in the server instructions.
|
|
54
|
+
|
|
55
|
+
## 7. Fall back to a provider when the session cannot work
|
|
56
|
+
|
|
57
|
+
- [ ] If `wait_for_ai_session` recommends a fallback, adjust the `dataPoints` or `loginUrls` as its result suggests and create one more session.
|
|
58
|
+
- [ ] If the retry also recommends a fallback, call `start_integration` with `route: "provider"` and the same `goal`, and follow the plan it returns. Keep the backend work from step 6: the provider plan reuses the callback route.
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# Plan: let users prove "{{goal}}" in this app
|
|
2
2
|
|
|
3
|
+
This is the provider route: the fallback when a Builder AI session cannot prove the claim, or the route you chose explicitly.
|
|
4
|
+
|
|
3
5
|
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
6
|
|
|
5
7
|
**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.
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Integrate a Builder verification client
|
|
2
2
|
|
|
3
|
+
For a claim about a user's account on a site, start with topic `ai-sessions`.
|
|
4
|
+
This guide covers the provider route and the shared callback details.
|
|
5
|
+
|
|
3
6
|
## Set up an application with the coding agent
|
|
4
7
|
|
|
5
8
|
For "add Reclaim to my app", call `start_integration` first and follow its
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// AUTO-GENERATED by packages/app/scripts/mcp-tools-gen.ts
|
|
2
|
-
// from packages/app/openapi.yaml (spec v0.1.0, source sha256:
|
|
2
|
+
// from packages/app/openapi.yaml (spec v0.1.0, source sha256:cbe3daf2a1f3).
|
|
3
3
|
// The hash catches drift the version misses (a spec can change without a
|
|
4
4
|
// version bump) — do not remove it as "redundant" with the version.
|
|
5
5
|
// Run `npm run openapi:gen --workspace=packages/app` to regenerate. Do not edit by hand.
|
|
@@ -125,6 +125,7 @@ export const MCP_TOOLS = {
|
|
|
125
125
|
"revenue",
|
|
126
126
|
"usage",
|
|
127
127
|
"goals",
|
|
128
|
+
"ai-session-prompts",
|
|
128
129
|
"tools",
|
|
129
130
|
"agents",
|
|
130
131
|
"funnel"
|
|
@@ -505,6 +506,117 @@ export const MCP_TOOLS = {
|
|
|
505
506
|
}),
|
|
506
507
|
annotations: {"openWorldHint":false},
|
|
507
508
|
},
|
|
509
|
+
"CreateAiVerificationSession": {
|
|
510
|
+
description: "Start an AI verification session from a prompt\n\nStarts an AI verification session from a plain-language prompt and optional dataPoints/loginUrls; returns the session with verificationUrl to share with the user. Needs the org token and at least one callback subscription (409 otherwise). No provider or org keypair needed: Builder manages the AI app key. Poll with get_ai_verification_session or wait_for_ai_session.",
|
|
511
|
+
inputSchema: toZod({
|
|
512
|
+
"type": "object",
|
|
513
|
+
"properties": {
|
|
514
|
+
"params": {
|
|
515
|
+
"type": "object",
|
|
516
|
+
"properties": {
|
|
517
|
+
|
|
518
|
+
}
|
|
519
|
+
},
|
|
520
|
+
"query": {
|
|
521
|
+
"type": "object",
|
|
522
|
+
"properties": {
|
|
523
|
+
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"body": {
|
|
527
|
+
"type": "object",
|
|
528
|
+
"additionalProperties": false,
|
|
529
|
+
"description": "Body for `POST /verifications/ai-sessions`. Send a `prompt`, at least one entry in `dataPoints`, or both.",
|
|
530
|
+
"properties": {
|
|
531
|
+
"prompt": {
|
|
532
|
+
"type": "string",
|
|
533
|
+
"minLength": 0,
|
|
534
|
+
"maxLength": 10000,
|
|
535
|
+
"description": "What to verify, in plain language, such as \"verify I'm a student at Manipal University\". Required unless `dataPoints` has at least one item. Builder rejects a prompt that contains credentials, card numbers, instructions for the AI, or a sensitive claim. The prompt and the data point lines together can't exceed 10,000 characters."
|
|
536
|
+
},
|
|
537
|
+
"dataPoints": {
|
|
538
|
+
"type": "array",
|
|
539
|
+
"maxItems": 32,
|
|
540
|
+
"description": "The values to verify. Required unless you send a `prompt`. Names must be unique, and at least one data point must be required (its `isOptional` is `false` or absent). When you send data points, Builder keeps them and adds only optional data points that the prompt implies. When you send none, Builder chooses the data points from the prompt. Every required data point must appear in the verified proofs. If one is missing, the session ends as `rejected` with `reasonCode` `missing-data-points`.",
|
|
541
|
+
"items": {
|
|
542
|
+
"type": "object",
|
|
543
|
+
"additionalProperties": false,
|
|
544
|
+
"required": [
|
|
545
|
+
"name",
|
|
546
|
+
"description"
|
|
547
|
+
],
|
|
548
|
+
"properties": {
|
|
549
|
+
"name": {
|
|
550
|
+
"type": "string",
|
|
551
|
+
"maxLength": 64,
|
|
552
|
+
"pattern": "^[A-Za-z_][A-Za-z0-9_]{0,63}$",
|
|
553
|
+
"description": "Name of the value, such as `username`. Starts with a letter or underscore, followed by up to 63 letters, digits, or underscores."
|
|
554
|
+
},
|
|
555
|
+
"description": {
|
|
556
|
+
"type": "string",
|
|
557
|
+
"minLength": 1,
|
|
558
|
+
"maxLength": 300,
|
|
559
|
+
"description": "What the value is and why it proves the claim."
|
|
560
|
+
},
|
|
561
|
+
"isOptional": {
|
|
562
|
+
"type": "boolean",
|
|
563
|
+
"description": "Defaults to `false`. If `true`, the claim can be proven without this value, and the proofs can omit it. If `false` or absent, the data point is required, and a session whose proofs omit it ends as `rejected` with `reasonCode` `missing-data-points`."
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
},
|
|
568
|
+
"loginUrls": {
|
|
569
|
+
"type": "array",
|
|
570
|
+
"maxItems": 10,
|
|
571
|
+
"description": "Pages where the user signs in, such as `https://portal.example.edu/login`. Builder shows them first as candidates with source `caller`, and skips the web search. Each URL must use `http` or `https`, can't contain credentials, and must resolve to a public host.",
|
|
572
|
+
"items": {
|
|
573
|
+
"type": "string",
|
|
574
|
+
"format": "uri",
|
|
575
|
+
"maxLength": 2048
|
|
576
|
+
}
|
|
577
|
+
},
|
|
578
|
+
"isEmailVerificationAllowed": {
|
|
579
|
+
"type": "boolean",
|
|
580
|
+
"description": "Defaults to `false`. If `true`, the share page offers the user a choice to verify using email instead of signing in. If you omit it, the page doesn't offer that choice."
|
|
581
|
+
},
|
|
582
|
+
"context": {
|
|
583
|
+
"type": "object",
|
|
584
|
+
"maxProperties": 50,
|
|
585
|
+
"additionalProperties": true,
|
|
586
|
+
"description": "Values you already know, such as `{\"fullName\": \"Asha Rao\"}`. Builder merges them over the values the prompt states and returns the result in `context`. Must not contain `attestationNonce` or `attestationNonceData`; bind those after you create the session. Also must not contain `reclaimSessionId`, `extractedParameters`, or `builderSessionId`. Omit if you have none."
|
|
587
|
+
},
|
|
588
|
+
"verificationClientUrl": {
|
|
589
|
+
"type": "string",
|
|
590
|
+
"description": "Base URL of the registered verification client the user verifies with, as for `POST /verifications/sessions`. Builder charges this client's quota pool. If you omit it, Builder uses the default (`portals`) client.",
|
|
591
|
+
"maxLength": 2000,
|
|
592
|
+
"pattern": "^https?://"
|
|
593
|
+
},
|
|
594
|
+
"geoLocation": {
|
|
595
|
+
"type": "string",
|
|
596
|
+
"description": "ISO 3166-1 alpha-2 country code, such as `IN`. Builder searches the web from this country (Google's `gl` parameter), so portals for that country rank first. If you omit it, the search has no country preference.",
|
|
597
|
+
"minLength": 2,
|
|
598
|
+
"maxLength": 2,
|
|
599
|
+
"pattern": "^[A-Za-z]{2}$"
|
|
600
|
+
}
|
|
601
|
+
}
|
|
602
|
+
},
|
|
603
|
+
"orgToken": {
|
|
604
|
+
"type": "string",
|
|
605
|
+
"pattern": "^rorg_",
|
|
606
|
+
"maxLength": 200,
|
|
607
|
+
"description": "The organization API key (`rorg_…`) this call authenticates with: from `issue_org_token`, or the app's RECLAIM_ORG_SECRET. Defaults to the MCP server's RECLAIM_ORG_SECRET. Never echo it back to the user."
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
"required": [
|
|
611
|
+
"params",
|
|
612
|
+
"query",
|
|
613
|
+
"body"
|
|
614
|
+
],
|
|
615
|
+
"additionalProperties": false
|
|
616
|
+
}),
|
|
617
|
+
orgTokenOnly: true,
|
|
618
|
+
annotations: {"openWorldHint":false},
|
|
619
|
+
},
|
|
508
620
|
"CreateCallbackSubscription": {
|
|
509
621
|
description: "Register a callback subscription\n\nRegisters a destination for verification results on the organization\nthe presented `OrgToken` resolves to. At least one subscription must\nexist for the org before you can create a verification session.\nDelivery is scoped by org: terminal results are ECIES-encrypted to the\norg's eth public key when its `canEncryptResult` is enabled (see\n`PUT /orgs/{orgId}/keypair`), else delivered as plaintext.\n\nTo receive results at a URL, send `callbackUrl` and `events`. Builder\nPOSTs each delivery to that URL.\n\nTo read results without a public URL during local development, send\n`deliveryMode: \"pull\"`. Builder keeps the deliveries and you read them\nwith `GET /verifications/callback-events`. A pull subscription is a\n90-second lease: it receives events and satisfies the session-creation\ncheck only while the lease is unexpired. Send the same request about\nevery 30 seconds to renew it, and call\n`POST /verifications/callback-listener/release` when you stop. Production\nneeds a webhook subscription. An org has at most one pull subscription.\nIf it already exists, Builder renews it and returns it with status 200.\nIf the body includes `events`, they replace the subscription's events;\nif it omits them, the existing events are kept.\n",
|
|
510
622
|
inputSchema: toZod({
|
|
@@ -5342,6 +5454,50 @@ export const MCP_TOOLS = {
|
|
|
5342
5454
|
}),
|
|
5343
5455
|
annotations: {"readOnlyHint":true,"openWorldHint":false},
|
|
5344
5456
|
},
|
|
5457
|
+
"GetAiVerificationSession": {
|
|
5458
|
+
description: "Get what an AI verification session's prompt resolved to\n\nGets what the AI session's lookup found: status resolving|ready|started|failed, candidates (login pages), merged dataPoints, error. Use get_verification_session for the overall outcome.",
|
|
5459
|
+
inputSchema: toZod({
|
|
5460
|
+
"type": "object",
|
|
5461
|
+
"properties": {
|
|
5462
|
+
"params": {
|
|
5463
|
+
"type": "object",
|
|
5464
|
+
"properties": {
|
|
5465
|
+
"sessionId": {
|
|
5466
|
+
"type": "string",
|
|
5467
|
+
"format": "uuid",
|
|
5468
|
+
"description": "Verification session id (UUID v7 when supported). Also echoed in the result payload as `reclaimSessionId`."
|
|
5469
|
+
}
|
|
5470
|
+
},
|
|
5471
|
+
"required": [
|
|
5472
|
+
"sessionId"
|
|
5473
|
+
],
|
|
5474
|
+
"additionalProperties": false
|
|
5475
|
+
},
|
|
5476
|
+
"query": {
|
|
5477
|
+
"type": "object",
|
|
5478
|
+
"properties": {
|
|
5479
|
+
|
|
5480
|
+
}
|
|
5481
|
+
},
|
|
5482
|
+
"body": {
|
|
5483
|
+
"type": "object"
|
|
5484
|
+
},
|
|
5485
|
+
"orgToken": {
|
|
5486
|
+
"type": "string",
|
|
5487
|
+
"pattern": "^rorg_",
|
|
5488
|
+
"maxLength": 200,
|
|
5489
|
+
"description": "The organization API key (`rorg_…`) this call authenticates with: from `issue_org_token`, or the app's RECLAIM_ORG_SECRET. Defaults to the MCP server's RECLAIM_ORG_SECRET. Never echo it back to the user."
|
|
5490
|
+
}
|
|
5491
|
+
},
|
|
5492
|
+
"required": [
|
|
5493
|
+
"params",
|
|
5494
|
+
"query"
|
|
5495
|
+
],
|
|
5496
|
+
"additionalProperties": false
|
|
5497
|
+
}),
|
|
5498
|
+
orgTokenOnly: true,
|
|
5499
|
+
annotations: {"readOnlyHint":true,"openWorldHint":false},
|
|
5500
|
+
},
|
|
5345
5501
|
"GetMe": {
|
|
5346
5502
|
description: "Get the authenticated user\n\nGets the authenticated caller's own profile: id, email, and name. Requires a signed-in user session, not an OrgToken. Use it to confirm who the current credentials belong to.",
|
|
5347
5503
|
inputSchema: toZod({
|
package/src/mcp/instructions.ts
CHANGED
|
@@ -49,6 +49,7 @@ const SHARED_TOPIC_FILES: Record<string, string> = {
|
|
|
49
49
|
/** Detailed topics that exist only in Builder mode. */
|
|
50
50
|
const BUILDER_TOPIC_FILES: Record<string, string> = {
|
|
51
51
|
'contributions': 'community-contributions.md',
|
|
52
|
+
'ai-sessions': 'ai-sessions.md',
|
|
52
53
|
'integration': 'verification-client-integration.md',
|
|
53
54
|
}
|
|
54
55
|
|
|
@@ -78,6 +79,9 @@ const TOPIC_SUMMARIES: Record<string, string> = {
|
|
|
78
79
|
+ 'providers, and going live.',
|
|
79
80
|
'discover': 'Reusing existing providers: finding, resolving, copying one '
|
|
80
81
|
+ 'that needs changes, and creating a verification session.',
|
|
82
|
+
'ai-sessions': 'The first route for a backend integration: prove a claim '
|
|
83
|
+
+ 'about a user\'s account with create_ai_verification_session, no '
|
|
84
|
+
+ 'provider or capture. Setup, backend code, and when to fall back.',
|
|
81
85
|
'integration': 'After start_integration: org key and keypair, callback '
|
|
82
86
|
+ '(local proxy_callback_events or deployed webhook), frontend and '
|
|
83
87
|
+ 'backend over the HTTP session API, js-sdk projects, trying a '
|
|
@@ -360,7 +360,14 @@ export function createVersionFromCaptureTool(
|
|
|
360
360
|
interceptorSettings: {
|
|
361
361
|
type: 'string',
|
|
362
362
|
description:
|
|
363
|
-
'Free-form JSON config for the chosen interceptor
|
|
363
|
+
'Free-form JSON config for the chosen interceptor, '
|
|
364
|
+
+ 'as a JSON object string. For HAWKEYE in the '
|
|
365
|
+
+ 'in-app SDK: {"interceptionMethod": PROXY | '
|
|
366
|
+
+ 'GETTER_SETTER | DIRECT_REPLACEMENT}, plus '
|
|
367
|
+
+ 'optional disableFormIntercept and '
|
|
368
|
+
+ 'delayFormSubmitForFetch. Try GETTER_SETTER when '
|
|
369
|
+
+ 'the in-app page stalls but Portals works; see '
|
|
370
|
+
+ 'topic interception.',
|
|
364
371
|
},
|
|
365
372
|
isDocumentRequestReplayEnabled: {
|
|
366
373
|
type: 'boolean',
|
|
@@ -8,6 +8,7 @@ interface StartIntegrationArgs {
|
|
|
8
8
|
userRequest?: string
|
|
9
9
|
orgId?: string
|
|
10
10
|
providerIds?: string[]
|
|
11
|
+
route?: 'ai-session' | 'provider'
|
|
11
12
|
}
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -22,7 +23,10 @@ export function startIntegrationTool(): RegisteredTool {
|
|
|
22
23
|
name: 'start_integration',
|
|
23
24
|
description:
|
|
24
25
|
'Returns a step-by-step plan for adding Reclaim verification to the '
|
|
25
|
-
+ 'current codebase
|
|
26
|
+
+ 'current codebase. Recommends Builder AI sessions first: no '
|
|
27
|
+
+ 'provider to build, just a prompt and data points. Use route '
|
|
28
|
+
+ '"provider" to fall back to provider authoring, which is what '
|
|
29
|
+
+ 'this describes: sign in to Builder, attach the browser, capture, '
|
|
26
30
|
+ 'and prove the provider first, then set up the app (session route, '
|
|
27
31
|
+ 'callback, Verify button, local event proxy) after the proof or '
|
|
28
32
|
+ 'while waiting on the developer, bootstrapping from the '
|
|
@@ -60,7 +64,16 @@ export function startIntegrationTool(): RegisteredTool {
|
|
|
60
64
|
maxItems: 10,
|
|
61
65
|
items: { type: 'string' },
|
|
62
66
|
description:
|
|
63
|
-
'Existing provider IDs to use.
|
|
67
|
+
'Existing provider IDs to use. Implies route "provider".',
|
|
68
|
+
},
|
|
69
|
+
route: {
|
|
70
|
+
type: 'string',
|
|
71
|
+
enum: ['ai-session', 'provider'],
|
|
72
|
+
description:
|
|
73
|
+
'"ai-session" (default when providerIds is empty) plans a '
|
|
74
|
+
+ 'Builder AI session. "provider" (default with providerIds) '
|
|
75
|
+
+ 'plans provider authoring; use it as the fallback when an '
|
|
76
|
+
+ 'AI session cannot prove the claim.',
|
|
64
77
|
},
|
|
65
78
|
},
|
|
66
79
|
},
|
|
@@ -80,9 +93,15 @@ export function renderStartIntegration(args: StartIntegrationArgs): string {
|
|
|
80
93
|
orgId: args.orgId,
|
|
81
94
|
providerIds,
|
|
82
95
|
}
|
|
96
|
+
// An explicit route wins, so 'ai-session' ignores providerIds.
|
|
97
|
+
const route = args.route
|
|
98
|
+
?? (providerIds ? 'provider' : 'ai-session')
|
|
99
|
+
const file = route === 'ai-session'
|
|
100
|
+
? 'start-ai-session-integration.md'
|
|
101
|
+
: 'start-integration.md'
|
|
83
102
|
const template = readFileSync(
|
|
84
103
|
fileURLToPath(
|
|
85
|
-
new URL(
|
|
104
|
+
new URL(`../../../../skill/${file}`, import.meta.url),
|
|
86
105
|
),
|
|
87
106
|
'utf8',
|
|
88
107
|
)
|
|
@@ -2,6 +2,7 @@ import type { RegisteredTool } from '../../server.ts'
|
|
|
2
2
|
import { proxyCallbackEventsTool } from './proxy-callback-events.ts'
|
|
3
3
|
import { readCallbackEventsTool } from './read-callback-events.ts'
|
|
4
4
|
import { verificationResultTool } from './result.ts'
|
|
5
|
+
import { waitForAiSessionTool } from './wait-for-ai-session.ts'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Builder-mode verification tools: higher-level orchestrations over the
|
|
@@ -20,5 +21,6 @@ export function buildVerificationTools(): RegisteredTool[] {
|
|
|
20
21
|
verificationResultTool(),
|
|
21
22
|
readCallbackEventsTool(),
|
|
22
23
|
proxyCallbackEventsTool(),
|
|
24
|
+
waitForAiSessionTool(),
|
|
23
25
|
]
|
|
24
26
|
}
|