Skip to main content
Glama

check_resource_decision

Decide before paying an x402 resource or serving a payer, and return ALLOW_PAY or REFUSE with safe_to_pay and policy reasons.

Instructions

Pre-payment decision for an x402 resource (role=payer) or pre-service decision for a payer (role=payee). Decide on decision (ALLOW_PAY | REFUSE) and safe_to_pay (boolean); pay only on ALLOW_PAY. WARN and BLOCK are both REFUSE under the default allow-only policy. An error is REFUSE too. measurement carries the full decision body: facts (L0 liveness, L1 settle-through, L2 conformance), reason_codes, freshness, evidence, and the rules_version that produced the recommendation. The L1 reason codes name whose gap it is: l1_not_attempted (vet402 signed no paid attempt), l1_inconclusive (settled purchases exist, but each paid response was a 4xx vet402 attributes to its own request shape - a gap in vet402's measurement, not evidence against the seller; facts.l1.n_inconclusive carries the count and those rows do not count toward a BLOCK), l1_never_delivered (a conclusive paid response existed and nothing was delivered), l1_delivered.

Each row of evidence[] names its own source: vet402 for a row from vet402's own L0-L2 record, subgraph for a row read from The Graph's x402 subgraph with the caller's own Graph key (that row carries subgraphId, block.number, deployment and queriedAt, which is what shows live index data rather than a static snapshot). This route returns vet402 rows. Do not add counts across sources: they count different things, and the two can disagree about the same wallet.

Your own policy (role=payer only): pass amountUsd (what the 402 asks), maxPerTxUsd (your ceiling, default 1), minL1Deliveries (floor on vet402's delivered L1 purchases) and/or requireVet402Allow (default true: a WARN refuses with payee_recommendation_not_allow, as in the SDK; false waives the WARN and needs minL1Deliveries >= 1 or the server answers 400 invalid_policy). The server then adds measurement.caller_policy with verdict ALLOW | REFUSE and reason_codes in the SDK's own words: price_above_ceiling, insufficient_delivery_evidence, payee_recommendation_block, payee_recommendation_not_allow, evidence_unavailable. A caller_policy REFUSE makes this tool REFUSE and those words are in refuse_reasons. caller_policy never rewrites recommendation; not_evaluated lists what the server did not check (min_subgraph_receipts is always there - The Graph is read only with your own key, through pay_if_trusted).

Tool call template

Replace each placeholder with a value matching the input schema. Only required parameters are included; add optional parameters as needed.

{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "tools/call",
  "params": {
    "arguments": {
      "resourceId": "<resourceId>"
    },
    "name": "check_resource_decision"
  }
}

Input Schema

NameRequiredDescriptionDefault
roleNopayer (default): should my agent pay this resource? payee: should this seller serve this payer?
payerNoRequired when role=payee: chain:address, or a bare 0x / base58 address
amountUsdNoWhat the 402 asks, in USD; compared with maxPerTxUsd server-side (role=payer only)
resourceIdYesresource_id — sha256(method + " " + canonical_url). Get it from /api/v1/resolve?q=<url>
maxPerTxUsdNoYour per-payment ceiling in USD (default 1)
callerDialectNoYour x402 client dialect; a mismatch with the seller's wall is a WARN
minL1DeliveriesNoFloor on vet402's delivered L1 purchases for this resource
requireVet402AllowNoDefault true (a WARN refuses with payee_recommendation_not_allow). false waives a WARN and needs minL1Deliveries >= 1

Schema Changelog

Changes observed during successful MCP inspections.

  1. First observedv0.1.0

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description does heavy lifting: it states that errors and WARN/BLOCK all map to REFUSE, that a caller_policy REFUSE propagates into refuse_reasons, that caller_policy never rewrites recommendation, and that invalid_policy yields a 400. The reason-code taxonomy (l1_not_attempted, l1_inconclusive, etc.) is unusually explicit. It stops short of stating read-only/idempotency or auth/rate-limit expectations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The decision-relevant information is front-loaded, but the body is a dense multi-clause wall of jargon with long parentheticals that make it slow to parse. Much of the L1 reason-code enumeration could be compressed without losing signal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter tool with no annotations and no output schema, the description is thorough: it covers return payload shape (facts, reason_codes, freshness, evidence, rules_version), cross-source evidence semantics, policy verdicts, and the not_evaluated caveat. Remaining gaps are auth/side-effect disclosure rather than decision mechanics.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds genuine meaning beyond the schema: how amountUsd interacts with maxPerTxUsd server-side, that requireVet402Allow=false requires minL1Deliveries>=1 else a 400, and what the caller_policy block returns. This is above-baseline parameter context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line names a specific decision verb (pre-payment / pre-service ALLOW_PAY vs REFUSE) and the resource it operates on, with the role split stated up front. It distinguishes itself from pay_if_trusted only indirectly ('through pay_if_trusted'), so sibling differentiation is present but not crisp.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an operative rule ('pay only on ALLOW_PAY') and explains the payer-policy knobs with defaults, which is real usage guidance. But it never states plainly when an agent should call this versus pay_if_trusted or check_payee_trust, leaving the routing decision to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.