Skip to content

Buying: the agent side of the toll

Every other page here is written for the side that gets paid. This one is the other side: what it takes for an agent to discover tolled sources, price them, pay, and cite what it bought.

There are two ways in, and they share a brain.

  • @naulon/wayfarer: the CLI agent. Give it a topic and a budget; it discovers candidates, ranks them by relevance per dollar, pays only the ones worth citing, and answers from what it bought.
  • @naulon/wayfarer-mcp: the same loop exposed over the Model Context Protocol, so any MCP client (Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, Cline, or your own host) gets the tools directly.
npx -y @naulon/wayfarer-mcp        # the stdio MCP server

The tools

Tool Cost What it does
naulon_status free Run this first: reports the buyer wallet, where discovery is configured to look, and plain-language guidance for what to do next. A hosted endpoint adds the spendable balance and the budget left.
naulon_discover free Candidate teasers for a topic: slug, title, summary. Start here.
naulon_appraise free Relevance and rationale for teasers already held.
naulon_quote free The x402 402 probe: real price and terms, no spend.
naulon_pay_and_read spends Pays the toll; returns the content, a settlement reference, and a citation license.
naulon_read_held free Re-reads an article on a license you already hold, proof-signed when the license is wallet-bound.
naulon_research spends The whole discover → quote → pay → ground loop as one call.
naulon_ask spends Hosted only: a grounded, numbered-citation answer.

The free tools carry readOnlyHint: true. The tools that spend carry destructiveHint: true, because a payment cannot be taken back, so a client can render "safe" and "spends money" differently and confirm before a spend. That distinction is worth preserving in any host you build.

What the model is not allowed to decide

The spend envelope is server configuration, never a tool argument. A model plans inside the envelope; it cannot widen it, and neither can a prompt injected into a page the agent reads.

Variable What it fixes
WAYFARER_BUDGET_USDC The session ceiling.
TOLLGATE_URL The single gate every payment resolves against. A pinned gate is one publisher by design.
WAYFARER_ALLOW_DOMAINS An allowlist of publisher hosts, applied to every paid tool. Setting it replaces the single-gate pin, which is how one agent buys across many publishers while staying bounded.
WAYFARER_DENY_DOMAINS Hosts never paid. Deny wins over allow.
WAYFARER_PER_DOMAIN_CAP Maximum paid reads per publisher per session.
WAYFARER_APPROVAL_USDC A toll at or above this becomes a human approval instead of a payment.
WAYFARER_KILL_SWITCH Hard stop: refuse all new spend. Free re-reads of held licenses still work.

A blank or malformed domain list reads as unset, meaning no restriction, never as an empty allowlist that would silently deny everything. That asymmetry is deliberate: the failure of a config string should be visible as "no policy", not as an agent that mysteriously buys nothing.

Paying safely

Two smaller knobs exist because of things that actually go wrong on the wire:

  • WAYFARER_TOLL_TOLERANCE_BPS (default 0). Pricing and paying are two separate requests, so the toll can move in between. The agent re-quotes at pay time and aborts if the live total exceeds the quoted total by more than this tolerance in basis points. The default aborts on any increase; a price drop is always fine.
  • WAYFARER_MIN_VALIDITY_SECONDS (default 60) is a floor on the buyer's EIP-3009 validity window. If a gate advertises too short a window, the signed authorization can expire before the relayer submits it and the settle fails with authorization_validity_too_short. The window only ever widens to this floor.

Discovery

With nothing configured, the tools refuse rather than fabricate a source. Pick where to look:

  • CATALOG_URL: a catalog of {slug, title, summary}. Defaults to the naulon fleet directory, so zero-config discovery resolves to a real corpus.
  • PUBLISHER_URL: one publisher's site; the agent reads ${PUBLISHER_URL}/rss.xml.
  • RSS_URL: an explicit feed.

Precedence is RSS_URL > PUBLISHER_URL > CATALOG_URL.

Respecting the publisher's terms

Before a tool pays, it resolves the publisher's RSL licence (@naulon/sdk/rsl) for the URL and checks it against a shared spend gate. The read is refused when the licence governing the URL does not grant ai-input, prohibits the agent's user class or region, or names an OLP licence server whose token the agent does not yet hold. Silence in a published licence is not permission, and no budget or approval setting overrides the refusal. When that server is naulon's own, the agent gets the licence with its agent token (NAULON_AGENT_TOKEN_ID and NAULON_AGENT_TOKEN), and without one it buys the read over x402 instead: the same gate sells it and mints its licence, so the purchase is the licence from that server's authority. A publisher with no licence at all is not refused: ordinary 402 pricing applies.

What you keep after paying

A payment returns a citation license: a signed receipt the agent stores and can re-present for a free re-read inside its TTL, and which anyone can verify independently. That is what makes a citation checkable later rather than a claim. The full spec is in citation-license.md. Licenses are cached at WAYFARER_LICENSE_PATH, so a re-read spans runs.

Running with no credentials at all settles in mock mode: the whole loop works, nothing moves on-chain. Set PAYMENT_MODE=gateway with a funded BUYER_PRIVATE_KEY to pay for real. Every variable named here is in configuration.md.

Paying from any x402 client

A tolled page answers an automated request with 402. You do not need naulon's tools to pay it.

  1. Read the offer. PAYMENT-REQUIRED is base64 JSON (x402 v2). accepts[0] names the network (a CAIP-2 id such as eip155:5042, which is Arc), the USDC contract, the amount in atomic units (6 decimals) and the recipient. Its error field and the JSON body's howToPay say the same in words.
  2. Fund once, on that network. When accepts[0].extra.name is GatewayWalletBatched, payment draws on a Circle Gateway balance, not on your wallet. Deposit USDC into the Gateway Wallet contract named in extra.verifyingContract, on that chain, before your first payment. Circle's nanopayments guide covers the deposit: https://developers.circle.com/gateway/nanopayments
  3. Sign and retry. Sign accepts[0] and repeat the request with the base64 payload in the PAYMENT-SIGNATURE header. One signed object pays the author and is served. When the 402 carries a naulonLegs extension, an array with one signed payload per leg, in order, pays the whole ask.

A refused payment answers 402 again with failure.code, a failure.remedy saying what to change, and the facilitator's own words in failure.detail.

If you are an assistant that cannot pay, the body's forYourUser.text is written for you to pass on: people read every tolled page free in a browser. Send Accept: text/markdown to get the whole 402 as prose.