Tollbridge Docs

MCP

Connect agents to Tollbridge over stdio or Streamable HTTP — the tool catalog with x402 + prepaid-credit payment semantics.

Tollbridge ships an MCP server (apps/mcp over the transport-independent packages/mcp catalog) whose twenty-seven tools are thin 1:1 proxies of the API surfaces — same data assembly, same PRICING objects (zero price literals), zod-validated structured outputs only.

The tool catalog

ToolProxied surfacePrice keyFree/paid
tollbridge_market_stateGET /v1/market/{asset}—FREE (open-data carve-out)
tollbridge_liquidation_riskGET /v1/market/{asset}/risksignals.evaluatePAID
tollbridge_funding_opportunitiesGET /v1/funding/opportunitiessignals.evaluatePAID
tollbridge_wallet_intelligenceGET /v1/wallet/{chain}/{address}wallet.profilePAID
tollbridge_transaction_riskPOST /v1/risk/transactionrisk.assessPAID
tollbridge_token_riskPOST /v1/risk/tokenrisk.assessPAID
tollbridge_decisionPOST /v1/decisionsdecision.deepPAID
tollbridge_pricingGET /v1/pricing—FREE
tollbridge_scoutPOST /v1/billing/scout—FREE (first 3 entry-tier questions per payer address)
tollbridge_get_decisionGET /v1/decisions/{decision_id}—FREE
tollbridge_get_resolutionGET /v1/resolutions/{decision_id}—FREE
tollbridge_lineageGET /v1/lineage/{decision_id}—FREE
tollbridge_calibrationGET /v1/calibration—FREE
tollbridge_sheetGET /v1/sheet—FREE
tollbridge_blotterGET /v1/blotter—FREE
tollbridge_feedGET /v1/feed—FREE
tollbridge_open_clocksGET /v1/clocks/open—FREE
tollbridge_universeGET /v1/universe—FREE
tollbridge_wallet_stateGET /v1/wallet/{chain}/{address}/statewallet.statePAID
tollbridge_callPOST /v1/calls—FREE (a calibration game — no wagering, no payout)
tollbridge_callsGET /v1/calls/scoreboard—FREE
tollbridge_standPOST /v1/standings—FREE registration (each run bills its question at settle time)
tollbridge_standsGET /v1/standings—FREE
tollbridge_hookPOST /v1/hook-endpointsbilling.addon.hookPAID add-on
tollbridge_exportPOST /v1/exportsbilling.export.asset_periodPAID add-on
tollbridge_get_intelligenceGET /v1/intelligence—FREE (the measured record)
tollbridge_list_releasesGET /v1/intelligence/releases—FREE (the release feed — deltas and rejections)

question_id for the deep decision takes any catalog signal (S01..S11) — see Decisions. Its asset argument is any symbol tollbridge_universe lists (not only BTC/ETH/SOL); an unknown or delisted symbol is a typed 404.

Agent first-run (step 0: Scout)

Before an agent can ask anything it needs a payer. tollbridge_scout grants the free allowance — the first 3 entry-tier questions per payer address (1,000 credits each) — to a Base address and returns the readable balance; no x402 facilitator required:

{
  "jsonrpc": "2.0",
  "id": 0,
  "method": "tools/call",
  "params": { "name": "tollbridge_scout", "arguments": { "payer": "0x957B4b908Fce18e44ECcB08331fcaf2BE7728510" } }
}

It is idempotent: an address that already holds its free allowance answers granted: false with the balance, never a second grant. The same allowance is served over HTTP at POST /v1/billing/scout.

Connect — Streamable HTTP (stateless)

/mcp is a stateless Streamable HTTP endpoint: each POST builds a fresh server, JSON responses (no SSE stream), no session state. Discover it at GET /.well-known/mcp.json.

{
  "mcpServers": {
    "tollbridge": {
      "type": "http",
      "url": "https://api.tollbridge.app/mcp"
    }
  }
}

The POST accept header must offer application/json, text/event-stream; malformed JSON bodies are refused with a typed 400 (JSON-RPC -32700) before the transport sees them.

Connect — stdio

The same server runs over stdio for local agents:

{
  "mcpServers": {
    "tollbridge": {
      "type": "stdio",
      "command": "tollbridge-mcp",
      "args": []
    }
  }
}

All logs go to stderr (protocol cleanliness); --self-check runs the full server on fixture seams with no env and no network. The production wiring uses the real provider stack and the payments ledger, exactly like the HTTP server.

Payment semantics

  1. Unpaid call to a PAID tool → a payment_required result — a normal result, NOT an error: x402 v2 requirements built from PRICING (scheme/network/asset/amount-atomic/payTo) plus a how_to_pay block. The challenge class structurally cannot carry data — a fabricated paid result is impossible.
  2. Paid call → sign EIP-3009 (transferWithAuthorization, USDC on Base) and embed the payload at _meta["tollbridge.dev/x402-payment"] (or the base64 PAYMENT-SIGNATURE HTTP header), then retry the SAME call.
  3. Success → ok result with the §I honesty meta and the settlement receipt at meta.settlement. The payment is recorded before the handler runs; a failed handler never settles (authorization flow — the client is uncharged).
  4. Failures → PAYMENT_INVALID (bad signature/requirements mismatch), PAYMENT_REPLAYED (spent nonce), honest PROVIDER_DOWN/STALE_DATA refusals with typed envelopes.

Prepaid credits — agents on the same ledger as the site

A paid tool also settles on Scout credits — the exact ledger the web app uses. Pass payer (your Base address) as a tool argument, or send x-tollbridge-payer: 0x<address> on the MCP HTTP request. The call debits the balance at the PRICING-derived rate; a refusal reverses the debit and returns the typed refusal — a refusal is the immune system, never a product, so it never keeps the charge. An empty balance returns the payment_required challenge with payment.reason: INSUFFICIENT_BALANCE, and you can always fall back to x402. There is no live x402 facilitator registered on this deployment, so the credit rail is the working payer path.

{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "tools/call",
  "params": {
    "name": "tollbridge_decision",
    "arguments": { "asset": "BTC", "chain": "base", "question_id": "S06_funding_anomaly" },
    "_meta": {
      "tollbridge.dev/x402-payment": "<base64 PaymentPayload>"
    }
  }
}

Agent recipe (the honest loop)

The honest loop for a live question — scout first, never ask while a horizon is open:

  1. Scout (FREE, first run) — tools/call tollbridge_scout { "payer": "0x<base-address>" } (or POST /v1/billing/scout) grants the one-time 200-credit Scout lot and returns the balance (idempotent). Read the full credit journal at GET /v1/billing/draws?payer=.

  2. Latest (FREE) — GET /v1/decisions/latest?question_id=<question_id>&asset=<asset>: the current tile on that pair, or an explicit empty answer when none is on record.

  3. Resolution (FREE) — GET /v1/resolutions/<decision_id>: either a terminal outcome (realized / obtains / not / unresolvable + the predicted/realized sentence) or { "status": "pending", "horizon_end": "…" }.

  4. Ask — only when the latest resolution is terminal and the question is available. The available set is DERIVED (the resolution-evaluator registry ∧ the emit gates), never a hand list — read tollbridge_sheet (or GET /v1/signals) for the authoritative set:

    {
      "jsonrpc": "2.0",
      "id": 2,
      "method": "tools/call",
      "params": {
        "name": "tollbridge_decision",
        "arguments": {
          "question_id": "S06_funding_anomaly",
          "asset": "BTC",
          "payer": "0x<your-base-address>"
        }
      }
    }

    The same ask over HTTP is POST /v1/decisions with the same body and the x-tollbridge-payer header. The call debits your prepaid Scout credits; a refusal reverses the debit and returns the typed refusal (out_of_scope / stale_input / insufficient_sample).

  5. Else wait — do NOT ask while the horizon is open. Sleep until horizon_end, re-read step 2, and ask only once it is terminal. The blocked questions (S02/S03/S04 — no market-wide liquidation tape on record yet) refuse + refund by design and are off the default rail. Read tollbridge_sheet for the derived available/blocked sets rather than trusting any static list.

The same object is served on HTTP and MCP: a resolution, a ledger tile and a tool result never disagree.

Honesty laws (carried over from the API)

  • tollbridge_market_state is free — it never consults the payment gate.
  • Every ok result carries the EXPLICIT §I meta: request_id, timestamp, state, probabilities, confidence (null on raw data), freshness, horizon (null on raw data), data_sources, methodology_version, pricing (null on free), settlement (null until settled).
  • The funding-opportunities assumptions ship verbatim with economics_modeled: "none"; the response states "This response is not a profit claim or execution advice".
  • Refusals (stale_input / insufficient_confidence / suppress) are honest decisions, never made-up numbers.

On this page