# Builder mode

Reclaim provider-authoring tools run against the Builder backend. They include
generated Builder API tools, credential and verification helpers, and browser
authoring tools.

## Claimant-facing Builder sessions

This integration is separate from provider authoring. When it is relevant,
read `how_it_works({ topic: "integration" })` for the exact `api=2` boundary,
bridge routes, result verification, legacy-proof contract, and optional TEE
binding. A URL without `api=2` stays on its existing legacy path.

**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 using one. Never
call a provider a "verification."**

**Provider versions are immutable in agent workflows.** Every recipe or
configuration change creates a new semantic version. Default to a patch bump;
use a major/minor bump or exact higher version when the user directs it. Never
use an in-place provider-version update or archive tool.

**Use the guide as needed.** Call `how_it_works({})` for its topic index, then
fetch only the topic relevant to the next tool call.

**Authentication:** try `get_me` first. On 401, `authenticate({})` returns a
device-pairing `code` + `attachUrl` — give the user the URL, then poll
`authenticate({ code })` until LINKED. Tokens cache ~2 days.
(→ `how_it_works({ topic: "auth" })`)

**Ask who is doing the signing in, then offer a browser.** "Yourself, or does
someone else need to log in?" decides half of `attach_browser`'s list. Doing it
themselves → `dedicated` or `attach`, both local, neither shareable. Someone
else, or a phone-only site → `container` (the Reclaim runtime in Docker, free,
shareable with `share_browser_view`) or `builder` (hosted, no install,
**chargeable**). Say which costs money, and say `container` exists at all:
nobody guesses it.

**The flow:** `attach_browser` (ask the developer which browser source — local
Chrome, the Reclaim runtime in Docker, a remote Builder browser, or a CDP URL
they supply) → `start_capture`
⇒ **`captureId`** (the handle every browser/inspect tool takes first) → drive
the page (`navigate`, `wait_for_page`, `eval_in_page`, `get_cookies`) → inspect
(`list_requests`, `get_request`, `find_requests_containing`) →
`propose_provider` ⇒ **`draftId`** (recipe + captured secrets, held server-side
— secrets never enter the transcript) → `replay_request(captureId, draftId)` →
`run_proof(captureId, draftId, ownerAddress)` → resolve a `providerId` →
`create_provider_version_from_capture` (lands on the draft branch) →
`publish_provider_version` (PRIVATE) or `submit_provider_version_for_review`
(PUBLIC).

**Reuse before create.** `create_provider_version_from_capture` needs a
`providerId`. Search your existing providers with `providers` (by domain / data
point) BEFORE calling `create_provider` — routing every run through
`create_provider` is what stacks duplicates in "My providers".

**Never prove a public endpoint.** After `replay_request` succeeds, re-run it
with `withoutSecrets: true`. If the value still extracts, the endpoint is public
and the proof binds to nobody — find an auth-bound request instead.

**Two hard constraints when drafting** (details in topics `draft` / `params`):
never `hash`/OPRF a value that also appears in the request URL; any param named
with `SECRET` may be used in a URL only within a tiny TOTAL character budget (2
under `key-update`, 12 under `zk`), checked at verification time.

**Backend mode:** this server can instead run against the devtools backend with
a reduced tool set. `get_devtools_mode` reports the active mode and why;
`set_devtools_mode` persists a switch to `~/.reclaim/config.json`, effective on
the NEXT server start. An explicit `USE_OLD_DEVTOOLS` env var wins over the
persisted choice.
