1. Discover the chain and template

Call inspect with subject: "chains", then subject: "functions". Confirm the requested chain is configured. Select a template whose semantics match the operator's request.

For example, if advertised:

{"tool":"inspect","arguments":{"subject":"function","function_slug":"erc20.token_balance"}}

Read its params and row schemas, descriptions, and defaults. The catalog's Function names are metric templates; they are not MCP tools.

2. Bind the scope

The following addresses and chain are placeholders. Substitute operator-supplied values, and use exactly the parameter names advertised by the selected template.

{"tool":"bind","arguments":{"function_slug":"erc20.token_balance","chain_id":1,"params":{"tokens":["<TOKEN_ADDRESS>"],"owners":["<WALLET_ADDRESS>"]}}}

Proceed only on outcome: "success". Save the returned bound_function_id. Binding creates an identity and scope, not an indexed dataset. created: false does not prove the requested window is covered.

3. Check coverage and choose the window

{"tool":"inspect","arguments":{"subject":"bound_function","bound_function_id":"<BOUND_FUNCTION_ID>"}}

Read materialized, materializing, and active_jobs. Choose a requested half-open block interval [from_block, to_block) using the correct chain's head and the operator's intended period. The head is not a finality guarantee. Example block numbers below illustrate syntax; they do not prescribe a useful query window.

4. Materialize missing blocks

{"tool":"materialize","arguments":{"bound_function_id":"<BOUND_FUNCTION_ID>","from_block":100,"to_block":110}}

If a quote is returned, inspect outcome, lines, amount, and accepts. Obtain or confirm spending authorization. Prepare the signed payload for an offered rail using the server's instructions.

{"tool":"pay_quote","arguments":{"quote_id":"<QUOTE_ID>","payload":"<SIGNED_X402_JSON_TEXT>"}}

payload is JSON text inside a string, not a private key. It can be omitted only on a mock settlement deployment. Save the payment ID and receipt.

{"tool":"materialize","arguments":{"payment_id":"<PAYMENT_ID>"}}

A successful accepted job can still be running. Inspect the returned job.job_id and the bound function's coverage before reading. Start paid execution within the quote's 120-second lifetime.

5. Read values

{"tool":"read","arguments":{"bound_function_id":"<BOUND_FUNCTION_ID>","from_block":100,"to_block":110}}

Reading has its own pay gate. If it returns payment_required, settle that read quote, then invoke read with only its returned payment_id.

A successful read returns bare values, one row per block and key with all its attributes, typed by the Function’s row schema from inspect. Within fully covered blocks, absent rows follow the Function's declared emission rules; an unavailable window is not a zero balance.

6. Verify the source window

Use the same bound identity and exact half-open window; there is no attribute selector:

{"tool":"provenance","arguments":{"bound_function_id":"<BOUND_FUNCTION_ID>","from_block":100,"to_block":110}}

Keep the result identity, exact window, values, source block hashes, and applicable digest together. See provenance verification for limits and interpretation.