{
  "markdown": "<p align=\"center\">\n  <a href=\"https://trustysquire.ai\" target=\"_blank\" rel=\"noopener noreferrer\">\n    <img width=\"84\" height=\"84\" src=\"https://trustysquire.ai/logo.svg\" alt=\"Trusty Squire shield\" />\n  </a>\n</p>\n\n<h1 align=\"center\">Trusty Squire</h1>\n\n<p align=\"center\">\n  <a href=\"https://www.npmjs.com/package/@trusty-squire/mcp\"><img src=\"https://img.shields.io/npm/v/@trusty-squire/mcp?logo=npm&color=cb3837\" alt=\"npm version\" /></a>\n  <a href=\"https://www.npmjs.com/package/@trusty-squire/mcp\"><img src=\"https://img.shields.io/npm/dm/@trusty-squire/mcp?color=cb3837\" alt=\"npm downloads\" /></a>\n  <a href=\"https://github.com/Trusty-Squire/trusty-squire/actions/workflows/ci.yml\"><img src=\"https://img.shields.io/github/actions/workflow/status/Trusty-Squire/trusty-squire/ci.yml?branch=main&label=CI&logo=github\" alt=\"CI status\" /></a>\n  <a href=\"https://github.com/Trusty-Squire/trusty-squire/stargazers\"><img src=\"https://img.shields.io/github/stars/Trusty-Squire/trusty-squire?logo=github&color=eac54f\" alt=\"GitHub stars\" /></a>\n  <a href=\"https://github.com/Trusty-Squire/trusty-squire/blob/main/LICENSE\"><img src=\"https://img.shields.io/badge/license-MIT-blue\" alt=\"license\" /></a>\n</p>\n\n<p align=\"center\"><strong>Empower agents with auth and payments.</strong></p>\n<p align=\"center\">MCP tools to automate auth and pay — your keys and card never leave the vault.</p>\n\nTrusty Squire is an **MCP server that lets Claude Code, Codex, Cursor, OpenCode, Goose, and other coding agents sign up, provision, and purchase on your behalf**. It opens a real browser, works through signup, sign-in, setup, and checkout flows one step at a time, clears the bot-detection and email-verification steps that make operator tools stall, and hands the job back to a person only when one is actually required. That covers wiring up OAuth and API keys for the app you're building as much as it covers paying a checkout, sending a gift, or booking something — the same operator primitives drive all of it.\n\nProvider secrets and payment cards are write-only: the agent's credential tools return references and authenticated results, never stored plaintext. The raw secret never needs to enter the agent's context, so it can't be pasted into a commit, leaked in a log, or read back out over chat. Backend access is a host-scoped, rate-limited, independently revocable grant, so a leaked token is killed without rotating the provider key — and you connect Google or GitHub yourself in a real browser, so the agent never types your password. Full [threat model below](#security-and-threat-model).\n\n## One prompt\n\n```text\nAdd Google OAuth to this app in one prompt: create the OAuth client, save the client secret, and wire it in without putting the raw key in chat, code, or .env.\n```\n\nYour coding agent plans the job. Trusty Squire operates the website, stores the generated key, and can issue your backend a scoped grant. The backend calls the provider through Trusty Squire, which injects the provider key on the server side.\n\nOther useful asks:\n\n- “Set up Stripe payments for this app and keep the API key out of this conversation.”\n- “Create a Render API key for deployment automation and keep it out of this conversation.”\n- “Pay this checkout with my saved work card and ask me to approve it on my phone.”\n- “Send a gift to my friend without sharing their address with me.”\n- “Book this dinner reservation for me.”\n- “That app grant leaked. Revoke it without rotating the provider key.”\n\nFor supported card checkouts, save a card in the Vault from a passkey-capable\ndevice or let your first `operate_pay` approval link collect one just in time.\nWhen no card is specified, Trusty Squire uses the only saved card, starts the\nadd-card ceremony if none exists, or asks you to choose when several exist. The\nnew card is encrypted in your browser with a passkey-derived key and bound to\nthat purchase before approval; if you add it but do not approve in time, it\nremains saved for a faster retry.\n\nRecognized Visa, Mastercard, Amex, Discover, Diners Club, and JCB cards show\ntheir network mark in the Vault while keeping the full bank/network label. Open\na card row to see its masked number; `reveal` runs the passkey ceremony in your\nbrowser before showing the number, name, expiry, and billing address. The CVV is\nnever shown, even after reveal. The Activity page also records card additions\nand removals, payments, and app-grant changes without storing a PAN or CVV.\n\n`operate_pay` requires a non-empty item and reason (calls that omit either\nreceive a validation error). On a single-page checkout it prefers a machine-read\ncheckout total, sends you a short-lived approval link, and submits only after you\napprove the purchase. A clean visible labeled total wins; when none is readable,\nstrict schema.org `Order`/`Invoice.totalPaymentDue` structured data can supply the\namount and currency. If neither source exposes a total, caller-supplied\n`amount_cents` and `currency` become the authoritative approval amount; an omitted\nmerchant name falls back to the checkout URL's hostname. Product and offer prices\nnever qualify as machine-read checkout totals. An unambiguous ISO currency on the\npage remains authoritative. A notation that cannot identify one ISO currency by\nitself, such as a shared currency symbol or an FX-preview selector, falls through to\nthe currency already selected or approved for the purchase instead of refusing the\ncheckout. Any live amount or currency drift still fails closed; the authoritative\nbinding contract lives in the [security model](SECURITY.md#client-encrypted-card-data).\nApproval, 3-D Secure, Activity, and notification amounts use the currency's minor-unit\nprecision (for example, whole yen for JPY and two decimals for USD). The anonymous\napproval page shows the merchant, checkout origin, amount and currency, item, and\nreason directly from the short-lived server record before one passkey ceremony\nauthorizes those canonical payment values. You also see the requesting MCP client\n(for example, Hermes) and the bound card's label plus last four digits (or its label\nalone for a legacy card) before clicking **Approve payment** to relay the\noperator-sealed final authorization. Before submitting that authorization, you\ncan instead choose **Deny payment**; a denial closes that approval attempt and\nprevents any later operator confirmation. When the pre-submission\ncheckout can be machine-read, the payment is refused if its merchant, origin, amount,\nor currency has changed since approval. If that resume read cannot recover a total,\nTrusty Squire reuses the original mandate-bound checkout values. Card entry requires the PAN,\nexpiry, and CVV fields; cardholder name and other explicitly labeled billing fields\nare filled best-effort, so a missing name field does not abort the payment. Sealing\nand cleanup touch only those selected payment controls; merchant shipping address and\ncountry controls remain untouched. If the checkout has a selected merchant-saved card\nalongside the newly filled card, Trusty Squire selects the sole unambiguous new-card\nradio and verifies both that choice and the filled fields again immediately before\nsubmission; ambiguous choices, selected saved-card options, and failed verification\nare refused with `payment_card_selection_ambiguous`. A charge is treated as\ndispatched only after the browser observes a concrete charge/order request, a\nterminal merchant outcome, or genuine 3-D Secure evidence; native form validation\nalone does not claim a dispatch. A submit is reported as `payment_submitted` only\nafter the checkout reaches a new merchant order-confirmation URL with a substantive\norder or receipt identity. The browser completes 3-D Secure natively, including\nout-of-band bank-app challenges — Trusty Squire never manipulates or intercepts the\nchallenge; it uses read-only checks while polling for that same order-confirmation\nsignal. At that last observable boundary, a mismatch between the released card and\nissuer, network, or last-four evidence rendered by the 3-D Secure issuer/app is\nreturned as a structured `warning` with `kind: \"payment_instrument_mismatch\"` and\nexpected-versus-observed evidence. The warning persists through resumable\n`operate_payment_status` calls; it neither changes the payment status nor cancels,\napproves, or modifies the challenge, so the cardholder retains the decision whether\nto continue. A dispatched attempt with no confirmed merchant outcome and no genuine\n3-D Secure evidence remains `payment_outcome_unknown`, including across resumable\nstatus checks; Trusty Squire never relabels that uncertainty as 3-D Secure. A detected\nchallenge that remains unresolved on timeout stays `payment_3ds_required` with\n`needs_user.wall: \"3ds\"`, handing control back for user completion. Neither status is\nsuccess or permits blind resubmission: manually check the merchant's order state\nbefore any retry.\n\n`operate_pay` surfaces the approval link before its bounded server-side wait. It\nmay wait up to one minute for approval, denial, or expiry; if it returns\n`approval_pending` first, call `operate_pay` again with the same arguments. That\ncall resumes the same approval and one-passkey boundary instead of creating a new\nlink. `operate_payment_status` is a non-charging alternative for inspecting the\npre-charge approval and is the continuation tool for an already-submitted unknown\nor 3-D Secure outcome. Its `wait_seconds` accepts 0-60 (default 0) to bound-wait\ninstead of taking an instant peek. Denial or expiry is terminal for that session's\nattempt: repeated calls return the same result and never mint a replacement\napproval. Close the session and start a fresh one before making a genuinely new\npayment attempt.\n\nEvery payment response includes its `session_id`. Pass that same ID to every\nfollow-up payment call. Omitting `session_id` remains compatible only while this\nMCP process has exactly one session; it never selects a newest or arbitrary checkout.\n\nSome split checkouts collect the card before the final order-confirmation step. On the\ncard-entry page, `operate_pay { phase: \"fill_card\" }` first reads the live total. A\nsubtotal qualifies as that payable amount only when the same order summary says\nshipping is free; recommendation and related-product prices are excluded. If that\npage exposes no total, caller-supplied `amount_cents` and `currency` take precedence\nas the approval amount. If they are omitted, Trusty Squire may use the most recent real\ntotal observed earlier in the same browser session, such as the cart subtotal, only\nwhen the checkout origin still matches. One phone approval\nbinds that amount and releases the card; Trusty Squire fills the card without\nsubmitting and its role in the purchase ends there. It fills only the merchant's own\nHTTPS frames or recognized payment-provider frames. The card stays in the page as\nsealed, observation-masked fields while the agent advances to the review step and\nplaces the order. Verify the live final total against the approved\n`amount_cents`/currency yourself before placing the order; Trusty Squire no longer\nre-reads the total or submits anything. For `click` and `js_click`, a control whose\nlabel looks like pay/place-order may fire only once for that approval. A second\nrecognized attempt is refused and requires a fresh `operate_pay` approval in a new\nsession. Non-charge-labeled clicks, key presses, and `oauth_click` remain ungated.\nAfter a recognized click dispatches, Trusty Squire best-effort records a secret-free\n`payment_place_order_attempted` Activity event bound to the approval, optional\nmandate, approved amount/currency, merchant, and opaque card reference. This records\nan attempt, not a verified charge outcome.\n\n`operate_pay { phase: \"confirm\" }` just releases the session's pending-fill lock and\nreports the approved terms back — it makes no browser or provider call, records no\naudit event itself, and never charges. It can be called any time after the fill — it does not\nneed to happen before you place the order, and it never reads a total or verifies an\namount. If a payment gets stuck or a card is declined, recover with `operate_finish`\nand start a fresh session; `operate_pay` does not support refilling a different card\nmid-session.\n\nBefore an initial single-page or `fill_card` call, Trusty Squire follows the actual\nvisible card-number field and hands the checkout back when that field is hosted by\nPayPal or Braintree. A separate PayPal express button does not block fillable merchant\nor Shopify PCI card fields. Trusty Squire does not sign in to PayPal or use vaulted\nPayPal credentials. After any submit that has not yet reached a confirmed order,\nTrusty Squire waits 180 seconds by default for native completion, including\nout-of-band bank-app approval. A linked Telegram chat receives a challenge-specific\nnudge only after 3-D Secure is detected. Standard cross-processor 3-D Secure signals and recognized\nCardinalCommerce or Stripe challenge frames classify the first case only when the\ncontaining frame is visibly rendered. Hidden 3-D Secure Method pre-authentication and\ncaptcha-hosted frames never count as 3-D Secure, and an ordinary Shopify PCI card-field\nhost alone does not either. It reports a visible decline and hands an unresolved outcome\nback on timeout, noting whether the Telegram nudge actually went out.\n`three_ds_wait_seconds` accepts whole seconds from 0 to 600; set it to `0` on\n`operate_pay` to skip the notification and waiting and receive the handoff\nimmediately.\n\nConnect Telegram under Vault Settings to receive secret-free alerts for\ncredential, card, payment, and app-grant lifecycle changes. Routine credential\nretrieval and proxy access stay in Activity instead of sending a push for every\nrequest.\n\n## Install\n\n```bash\nnpx @trusty-squire/mcp connect\n```\n\n`connect` signs you in with Google or GitHub, detects your coding agent, and merges the `squire` MCP server into its existing configuration. On a machine with a user-visible desktop, sign-in opens a local Chrome window. On a headless Linux server, including an SSH/TTY session with an inherited virtual display, interactive login starts a login-scoped Xvfb and noVNC stack and prints a URL you can open on another device. The default quick tunnel and every local helper are torn down when that login completes, times out, fails, or is interrupted. Operators may instead set both `TS_LOGIN_PUBLIC_HOSTNAME` and `TS_LOGIN_LOCAL_PORT` to reuse an externally managed named tunnel; Trusty Squire still tears down its per-login display and local listener, but never creates or stops that external tunnel. If that tunnel's fixed local port is busy, login reports it and uses a one-off quick tunnel for that sign-in instead. Restart the agent and ask for the finished website outcome. Trusty Squire is free to start.\n\n`connect` is also the only way to sign in again: `--force-relogin` switches the bound account and `--force-relogin=google` or `--force-relogin=github` refreshes one provider session. It reports success only after re-checking the browser profile and finding that Google session live, so a run that binds the machine but leaves no usable session fails loudly with the command to retry rather than reporting a working install.\n\nLocal state is kept separately for each connected account, and `connect` pins\nthat account in the agent's MCP configuration; connecting another account does\nnot replace the first account's state. To remove just one account, run\n`npx @trusty-squire/mcp logout --account=<id>`; without `--account`, `logout`\nremoves the most recently connected account. `--account` requires a nonempty\naccount ID.\n\nTo choose a target explicitly:\n\n```bash\nnpx @trusty-squire/mcp connect --target=codex\n```\n\nSupported targets: `claude-code`, `cursor`, `codex`, `opencode`, `goose`, `cline`, `continue`, and `hermes`.\n\nThe isolated `operate_*` browser runtime currently requires Linux and a local Chrome connection;\nremote CDP, macOS, and Windows operator sessions are not supported in this migration stage.\n\n## What happens\n\n1. Your coding agent names the website and the outcome it needs: an account,\n   authenticated setup, app publishing, a purchase, a gift, or a booking.\n2. Trusty Squire works through the service flow one step at a time. Every task\n   opens its own fresh browser profile and restores the snapshot's non-Google\n   signed-in state, so independent sessions can run concurrently without opening\n   the canonical login profile. Google state is restored inside the serialized\n   `oauth_login` or legacy `oauth_click` boundary; sanctioned Gmail verification\n   uses a separate temporary identity browser.\n3. If the flow produces an API key or client secret, Trusty Squire captures it\n   into the vault without returning the raw value through its credential tools.\n4. The agent can make an authenticated request, create a host-scoped app grant,\n   or use a saved card for a supported checkout after you approve the purchase.\n5. Eligible successful flows can become signed registry skills, so later runs can replay verified steps instead of rediscovering every click.\n\nIf a site requires phone verification, a hard CAPTCHA, an unresolved 3-D Secure\nchallenge, an unsupported payment method, or another human decision, the run\nhands control back and tells you. It does not guess or pretend the task completed.\n\n## Supported services\n\nDiscovery pages are generated only for services with an active skill in the Trusty Squire registry. The first five detailed pages cover Braintrust, Cerebras, Clerk, DeepInfra, and Zilliz Cloud. Each sample has explicit signup evidence in its active registry record and a provider request checked against official API documentation. The service hub also lists every active registry entry; the remaining detail pages stay unpublished until their workflow and unique content pass review.\n\nBrowse the [active service catalog](https://trustysquire.ai/services). Maintainers can detect registry drift before merging with:\n\n```bash\npnpm seo:verify-services\n```\n\nThe registry controls which service pages exist. An external list is never used to claim support.\n\n## Keep provider keys out of agent context\n\nAsk the agent to create a scoped backend grant:\n\n```text\nGrant this backend access to Clerk through Trusty Squire with a limit of 100 requests per hour.\n```\n\nBefore minting the grant, make `api.clerk.com` the credential's primary allowed host in the Vault. The egress proxy refuses every other upstream host. This explicit policy step is required when the signup host and provider API host differ.\n\nThe agent calls the real MCP tool with the service and requested limit:\n\n```text\ngrant_app_access({\n  service: \"clerk\",\n  rate_limit_per_hour: 100\n})\n```\n\nRate limits are opt-in. Omitting `rate_limit_per_hour` creates an unlimited\ngrant; host scoping, auditing, and revocation still apply. When a grant reaches\nan explicit hourly limit, the proxy returns `429 rate_limited` with\n`scope: \"grant\"`, `Retry-After`, and window/reset metadata.\n\nThe result contains a host-scoped egress `base_url` and a `token`, not the Clerk secret key. The token is returned once through the MCP result and remains valid until revoked. That means the scoped grant token can enter agent context; it is not the provider key. Move it directly into backend-only deployment secret storage, never browser code, logs, or source control. If you need zero grant-token exposure to the model, use `use_credential` for agent-initiated requests instead. Trusty Squire removes the grant authorization at the boundary and injects the vaulted provider credential into the upstream request.\n\n## Security and threat model\n\n- Provider credentials are encrypted in the vault and are write-only to agent credential tools. Those tools return references or authenticated results, not stored plaintext.\n- The raw provider key is injected only into the outbound provider request. It does not need to land in chat, generated code, the consuming app, or the project's `.env` file.\n- App grants are host-scoped, auditable, rate-limitable, and independently revocable. A leaked grant can be revoked without rotating the provider key.\n- You connect Google or GitHub in a real browser. Trusty Squire does not ask the coding agent to type those passwords.\n- Saved cards are encrypted in your browser with a passkey-derived key. For a\n  single-page payment, your phone releases the card only after approving the\n  exact purchase details shown on the approval page. On a split checkout, one\n  amount-bound approval releases the card; Trusty Squire's role ends at the fill\n  and the caller places the order and verifies the final total itself. The API\n  temporarily relays only operator-sealed card ciphertext and its signed mandate.\n  Trusty Squire's API and the coding-agent model never receive plaintext PAN or\n  CVV. See the\n  [security model](https://github.com/trusty-squire/trusty-squire/blob/main/SECURITY.md#client-encrypted-card-data)\n  for the signed mandate's binding contract.\n- Browser screenshots and diagnostics can contain whatever a website visibly rendered. Treat diagnostic artifacts as sensitive and do not ask an agent to re-observe a page after a secret is shown.\n- Trusty Squire does not bypass phone verification, hard CAPTCHAs, 3-D Secure,\n  payment authorization, or decisions that belong to a person. It stops for\n  human input.\n\nSee the [security model](https://github.com/trusty-squire/trusty-squire/blob/main/SECURITY.md)\nfor the card and credential trust boundaries, and\n[architecture](https://github.com/trusty-squire/trusty-squire/blob/main/docs/ARCHITECTURE.md)\nfor the system and data flows.\n\n## MCP tools\n\nThe default MCP registry exposes 20 tools. The essential operator surface is\n`operate_start`, `operate_observe`, `operate_observe_query`, `operate_act`,\n`operate_pay`, `operate_payment_status`, `operate_finish`,\n`operate_recipe_run`, and `operate_recipe_save` — every former standalone\nworkflow/lifecycle/login tool name was dropped and its behavior folded into\n`operate_act` as a `kind` (or into `operate_finish`'s `outcome`); no delegating\naliases remain. Continue a pending pre-charge approval by re-calling\n`operate_pay` with the same arguments; use\n`operate_payment_status(wait_seconds)` as a non-charging alternative and for\npost-submit outcome checks. `operate_screenshot(session_id,\nframe_index?, frame_url_contains?, full_page?)` is a read-only debugging capture\n(page or one isolated frame, e.g. a cross-origin 3-D Secure/captcha challenge)\nreturned as an actual MCP image. It refuses during an active card fill, when the\nrequested capture still contains a sealed or card-shaped value, or when any\nincluded frame cannot be checked; capture-time pixel redaction remains a second\nsafety fence.\nThe maintainer-only `list_extract_failures` → `get_extract_failure`\nDOM-diagnostics pair is excluded from that surface; set\n`TRUSTY_SQUIRE_DIAGNOSTICS=1` in the MCP server environment to opt into the\n22-tool diagnostics profile.\n\nOperate sessions default to Compact V2 observations: a screened\n`format:\"compact-v2\"` response with a finite stage, safe title/heading\nsemantics, and opaque generation-bound controls in `safe_table`. Raw page text,\nURLs, DOM values, and snapshot files are not part of that format. Use\n`operate_observe_query` with task words or `overflow.next_cursor` to retrieve a\nnamed or paged control while matching stays inside the live browser. A browser\naction invalidates the current handles; on `reobserve_required`, observe again\nand select a new handle. Exact cursorless `Google` and `GitHub` queries briefly\nrefresh controls that hydrate or gain labels after the initial observation, but\nstill return only a current sealed handle. `detail:\"full\"` remains inside the V2\nseal. Maintainers can select the legacy V1 `el_table`/snapshot contract with\n`TRUSTY_SQUIRE_OBSERVE_V2=off`, or exercise V2 without emitting it with\n`shadow`; the detailed wire and migration contract lives in\n[DESIGN-observe-compact.md](docs/DESIGN-observe-compact.md).\n\n- Rejected tool calls return a JSON `error` envelope with a stable `code` and\n  message. Malformed and unknown calls fail only that request; they do not stop\n  the shared stdio process or discard its active in-memory operator session.\n  `server_unavailable` includes `retry.max_attempts: 1`: retry once, and never\n  kill or restart the shared operator process.\n- `operate_start`, `operate_observe`, `operate_observe_query`, and `operate_act`\n  open a website, inspect the current state, and perform one browser action at a time. Ordinary controls\n  inside same- and cross-origin frames are included in observations (as finite\n  frame facts in Compact V2 and `frame_origin` in V1); known captcha challenge\n  frames stay behind the dedicated captcha flow. Same-registrable-domain frames\n  are reachable, cross-domain frames\n  must pass the same domain scope as `goto`/`allow_host`, opaque frames are\n  refused, and `type_secret` never targets any cross-domain frame. Frame refs\n  currently support `click`, `js_click`, `type`, `type_secret`, and `select`;\n  `upload`, `oauth_click`, and `oauth_login` fail closed. If a visible control\n  has no observed ref, explicitly selected V1 sessions let the four\n  locator-capable actions (`click`, `js_click`, `type`, and `type_secret`) use a\n  live `text=…`/`css=…` locator; that one-off fallback is not replayable.\n  Compact V2 accepts only a handle from its current sealed action map.\n  When a `click` or `js_click` opens a new tab or popup (`target=_blank`, a\n  `window.open` control), the operator follows it the way a person would: the\n  newly opened page becomes the active page, so the next `operate_observe` or\n  `operate_act` reads it. This is how an emailed verification or magic link is\n  followed. Do not try to `extract` the link's href instead — a single-use login\n  token is sealed and is never returned as text; following the tab navigates the\n  browser without exposing it. Payment is excluded: during a sealed card fill or\n  a live place-order/3-D Secure approval the active page never changes.\n  In a live operator session, in-page XHR/fetch calls to merchant API sibling\n  subdomains are automatically in scope only when they share the registrable\n  domain of a host trusted at session start. Calls outside the session scope fail\n  promptly instead of hanging; page-load resources continue normally, and a\n  mid-session `allow_host` does not seed sibling-domain widening. A small set of\n  always-in-scope hosts (recognized payment-provider frames, OAuth/captcha\n  providers, and 3-D Secure ACS/directory-server hosts) is exempt from that\n  session-start-trust requirement — otherwise a checkout's own out-of-band 3DS\n  challenge could never complete its own status poll.\n  Every operator task uses the user's Chrome profile directly. Before it starts,\n  the operator checks the live Google My Account identity; if the profile is\n  signed out, it returns a clear login handoff before navigating to the service.\n  To route only that browser session through a proxy, pass `proxy` to\n  `operate_start` as an HTTP or HTTPS URL (credentials are optional), or as an\n  unauthenticated SOCKS5 URL. The value is launch-only and sensitive: it is not\n  returned in session status, action traces, or saved recipes. Omitting it uses\n  direct egress.\n  Under Compact V2, an expired, forged, wrong-generation, cross-page, or drifted\n  `@e:` handle fails opaquely with `reobserve_required`; re-observe and choose a\n  current handle. Under V1, DOM churn returns `target_stale` with the last\n  observation generation, `reobserve_required: true`, best-effort label-keyed\n  `replacement_candidates`, and `retry_policy: \"do_not_retry_old_ref\"`.\n  Malformed `operate_act` calls return `error.code: \"invalid_arguments\"` and an\n  `error.guidance` repair object with the allowed kinds, missing fields, a valid\n  example, and a safe alternative instead of only a validation string.\n  For a provider login, pass the observed provider-button ref to the atomic\n  `oauth_login` action. It retains the product tab across provider-owned popup\n  redirects and closes, then returns the post-login product observation even if\n  `detail` is `none`. Every `oauth_login` and legacy `oauth_click` is serialized\n  from action start through completion and a short release cooldown; other\n  session work remains parallel. The whole serialized action has a 30-second\n  deadline. If Google does not complete in time, the call returns\n  `google_session` re-login guidance and closes that operator session without\n  replacing the saved identity; start a fresh session after reconnecting.\n  `oauth_click` and `oauth_settle` remain for\n  legacy replay compatibility. If an observation races that legacy transition,\n  the response reports `oauth.state: \"in_progress\"` and directs the host to\n  observe again.\n- `operate_act` also owns eight consolidated workflow/lifecycle kinds — the\n  entire operator surface beyond navigation, payment, finish, and recipe\n  replay is reached through `operate_act`'s `kind`:\n  - `select_many` accepts an ordered label/ref-to-option map for coupled\n    variant, shipping, or similar selectors. It applies selections\n    sequentially, re-observes after every success, tolerates partial failure,\n    and returns each field's `selected` or `failed` outcome plus a current\n    observation.\n  - `cart_add` is the retry-safe add-to-cart path. Give it the canonical\n    product identity, selected-variant options hash, and a stable idempotency\n    key; it post-verifies the exact cart line and returns `added` or\n    `already_in_cart`, `cart_delta` (`+1`, `0`, or `unknown`), and the canonical\n    cart URL when observable, without clicking again for the same product and\n    variant. Cart and checkout observations expose an informational,\n    best-effort `checkout_state` with stage, product and variant identity,\n    quantity, separately observed subtotal and shipping, payable total when\n    known, canonical cart URL, and one `next_action`. The `single` and\n    `fill_card` payment phases derive their authoritative approval amount\n    independently of this state, preferring live checkout data according to the\n    payment guide above.\n  - `extract` captures a generated credential into a sealed slot or the vault.\n  - `solve_captcha` drives the in-session captcha gate and returns the\n    fail-fast `needs_user` handoff when it cannot be cleared.\n  - `await_verification` reads the user's own inbox for an email verification\n    code/link by default, with sender-scoped search and sealed-OTP transfer\n    through `into_slot`. Advanced configuration or\n    `grant_inbox_consent:false` can opt out.\n  - `login_prepare_signup`, `login_store_signup`, and `login_load_saved` own\n    the sealed username/password lifecycle. `login_prepare_signup` seals the\n    user's captured email and a generated password, `login_store_signup`\n    vaults those slots with explicit login-host policy, and `login_load_saved`\n    retrieves an allowed saved login through encrypted browser-fill into\n    sealed session slots. Raw values never enter the tool result.\n- Observed card controls are marked `payment_field` and\n  `interaction: \"vaulted_card_only\"`, with `operate_pay { phase: \"fill_card\" }`\n  as the recommended action. Typing a Luhn-valid, card-number-shaped value\n  manually through `operate_act` is refused with `safe_alternative: \"operate_pay\"`\n  and the missing prerequisite `verified_cart_total`.\n- `operate_finish` closes the session and optionally accepts a nested `outcome`.\n  `none` only closes; `credentials` requires `store` and preserves credential\n  extraction, vault storage, and auto-promotion; `result` requires `summary` or\n  `data`. A result is eligible to save portable login state only when\n  `verify_recipe` confirms it or `data.confirmed` is `true`; credential outcomes\n  qualify only after unblocked extraction and vault storage. `none`, failed or\n  unconfirmed outcomes, and payment-sensitive sessions preserve the prior saved\n  snapshot. Finish first stops new calls and drains calls already using that\n  session within a bounded terminal transition, then closes its browser and\n  schedules private-profile removal. Sessions also close automatically after 10 minutes without an\n  operation and begin terminal teardown at 30 minutes; only an active payment\n  receives the short bounded close grace. Callers should finish promptly instead\n  of treating an open browser as durable background state.\n- `operate_recipe_save` saves a postcondition-verified local recipe under a\n  closed task verb plus the service's registrable domain. It records stable target\n  attributes and exact provenance for Squire-supplied values, not observed refs\n  or plaintext secrets. Recipes that pass a share-eligibility check (no\n  personal or secret-shaped literals) and a registrable-domain lock are also\n  written live to the shared registry, making them immediately reusable by\n  other installs without a promotion step. `operate_recipe_run` binds the\n  replaying user's own values and replays those steps, preferring the local\n  recipe and falling back to the shared one. A recipe cannot navigate outside\n  the site it was recorded for; normal keyed replay refuses a violation before\n  navigation and continues with cold driving. On one ordinary missed step,\n  replay returns a local repair point and can continue in the same session.\n  Older name-only recipes remain planning hints.\n- `list_payment_cards` returns saved-card labels and opaque references;\n  `operate_pay` accepts an explicit `session_id` and `phase` of `\"single\"`\n  (the default, also implied by omitting phase), `\"fill_card\"`, or `\"confirm\"`.\n  It can use a selected card, the only card on file, or a just-in-time\n  add-card approval. The single-page flow fills the checkout and applies the\n  post-submit outcome wait described above before handing back unresolved\n  outcomes. Split checkouts use the `fill_card` then `confirm` flow described\n  above.\n  `operate_payment_status` follows the [payment guide](#one-prompt) bounded-wait\n  contract. It returns the session ID and includes it in every follow-up tool\n  hint, so an approval or submitted outcome is always observed in its originating\n  browser. Malformed calls return the same\n  `error.guidance` repair fields as `operate_act`, including a safe resolution\n  when `card_ref` and `card_label` conflict.\n- `list_credentials` and `use_credential` find saved credentials and make authenticated API calls without returning raw values.\n- `edit_credential` changes only an existing credential's non-secret name,\n  `allowed_hosts`, or `login_hosts`; `delete_credential` soft-deletes one. Each\n  first returns a Telegram/passkey approval link bound to the operation, exact\n  credential reference, and edit before→after. Resume with only the returned\n  `approval_id`. Neither tool can read or alter the secret value; use\n  `store_credential` to rotate a secret.\n- `grant_app_access` and `revoke_app_access` create and remove scoped backend access.\n- `audit_log` reports credential activity without exposing credential values. It\n  defaults to a shaped security ledger: lifecycle events and anomalies (non-2xx,\n  429, rejected calls) as rows, routine proxied egress collapsed into per\n  credential/host/burst rollups with per-grant running totals. Pass a rollup's\n  `id` as `expand` for its individual calls, or `view: \"raw\"` for the flat\n  per-request stream.\n\n## One README for GitHub and npm\n\nThis root file is the canonical README. The npm pack lifecycle copies it into `@trusty-squire/mcp` byte-for-byte, then removes the generated package-local copy after packing. GitHub and npm therefore publish the same product explanation.\n\n## Development\n\n```bash\ngit clone https://github.com/Trusty-Squire/trusty-squire.git\ncd trusty-squire\n./scripts/bootstrap.sh\n```\n\nAfter bootstrap, `pnpm typecheck` and `pnpm test` should pass. Stop local services with `docker compose -f docker-compose.dev.yml down`; add `-v` to reset their data.\n\nRequirements: Node 20.11.0 (`.nvmrc`), pnpm 8.15+, Docker, and Docker Compose.\n\nRepository map:\n\n```text\ntrusty-squire/\n├── apps/\n│   ├── api/        Accounts, OAuth, machine tokens, proxy, inbox, vault, and billing\n│   ├── mcp/        MCP server, browser operation tools, and credential tools\n│   ├── registry/   Signed website skills and verification service\n│   └── web/        Marketing site and vault UI\n└── packages/\n    ├── vault/         Encrypted credential storage and audit log\n    ├── skill-schema/  Shared schema for replayable website skills\n    └── recipe-schema/ Shared wire schema for operator replay recipes\n```\n\nProduct and public-web changes should follow [PRODUCT.md](https://github.com/trusty-squire/trusty-squire/blob/main/docs/PRODUCT.md) and [DESIGN.md](https://github.com/trusty-squire/trusty-squire/blob/main/docs/DESIGN.md).\n\n## License\n\n[MIT](https://github.com/trusty-squire/trusty-squire/blob/main/LICENSE) © Trusty Squire\n",
  "bytes": 36951,
  "sha": "c8eaa3d98a7db415086ca175efe434a190f797e806492403c07d07fbd3e44565",
  "repo_slug": "trusty-squire/trusty-squire",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_trusty_squire_mcp_bc0b655a/readme"
}