Skavio x402 MCP: why x402 payment challenges are not ordinary API errors
Separating payment negotiation from generic error handling lets a client inspect the terms, enforce spending limits and report uncertain outcomes accurately. With Skavio x402 MCP, a validated PaymentRequired response belongs in that negotiation path—not in an automatic retry loop or an automatic approval path. Build the implementation around five steps: detection, validation, approval, a payment-bearing retry, and separate settlement and result checks.
1. Detect the challenge before an error handler discards it
Skavio x402 MCP documents free MCP tool discovery and the free `skavio_catalog` tool. Discovering a tool is distinct from invoking a paid one: connecting a generic MCP client does not enable paid execution. An unpaid call to a paid tool can return a machine-readable `PaymentRequired` result. The transport matters. Under the x402 MCP specification, a payment challenge is represented as a tool result with `isError: true`, not necessarily as a top-level JSON-RPC error. Inspect `structuredContent` first; if necessary, fall back to parsing JSON in `content[0].text`. A handler that turns every `isError` result into a generic exception can discard the information needed to continue safely. For an HTTP integration, x402 v2 uses HTTP 402 and a base64-encoded `PaymentRequired` object in the `PAYMENT-REQUIRED` header. Preserve that protocol data before applying generic HTTP-error handling. Neither `isError` nor HTTP 402 is sufficient to classify the response. Missing payment, invalid payment and settlement failure can share these error indicators. Validate the payload and its meaning before deciding that a new payment is appropriate.
2. Validate what the client is being asked to pay
Recognizing a challenge should start a requirements check, not a wallet operation. Validate the v2 schema, then compare the payment requirements with the intended tool call and your client’s supported payment configuration. An unexpected or malformed requirement should stop the payment path. Skavio documents Base mainnet, identified as `eip155:8453`, with native Circle USDC for payment. Do not confuse the network of a transaction being inspected with the network required to pay for that inspection.
- Confirm that the resource matches the intended request and that the client supports the stated payment scheme.
- Check the network, native USDC asset identity and recipient against trusted configuration—not merely a familiar token name.
- Read the amount in atomic token units, check the timeout and reject terms outside the approved policy.
3. Make spending approval a separate client decision
A valid payment request establishes what the service asks for. It does not establish that the wallet owner has authorized the expense. Before signing, require either explicit approval for the call or an owner-approved spending policy that covers it. A useful policy includes allowed tools and recipients, a per-call ceiling, a total workflow budget and a condition for stopping when terms change. These are recommended client controls; x402’s core specification does not provide client budget management. This distinction matters in multi-step agent workflows. Permission to inspect a catalog is not permission to pay for every tool the agent discovers. If the client lacks x402 payment support—or approval is denied—surface that state clearly and stop. Do not repeatedly invoke the unpaid tool in the hope that the challenge will disappear.
4. Retry the intended call with the documented payment metadata
After validation and approval, an x402-aware client can construct the signed `PaymentPayload` and retry the intended tool with the same approved arguments. Skavio documents the payment location as `params._meta["x402/payment"]`. Resending the original unpaid request does not satisfy a missing-payment requirement. Keep the transport contracts distinct. HTTP payment-bearing retries use `PAYMENT-SIGNATURE`; that header is not a substitute for the documented MCP metadata field. Follow the [Skavio x402 MCP documentation](https://getskavio.com/x402/docs/) for the integration you are building. Bound the retry path. If a response reports invalid payment or settlement failure, classify that outcome rather than treating it as a fresh instruction to sign again. Skavio-specific duplicate-payment protection, idempotency behavior and exactly-once charging were not established for this MCP workflow in the supplied documentation review.
5. Reconcile settlement and tool output independently
A wallet signature is not settlement evidence. The core x402 facilitator’s `/verify` operation is read-only, so successful verification is not evidence that settlement occurred either. The MCP transport defines settlement information in `result._meta["x402/payment-response"]`. Inspect the reported settlement outcome separately from the tool’s returned content. Payment evidence does not establish that the requested inspection returned a usable result; a useful-looking result should not substitute for checking the payment outcome. If the connection fails after a payment-bearing request was submitted, report the outcome as uncertain until it can be reconciled. Do not authorize another payment merely because the client timed out. This is a recommended recovery policy, not a claim that Skavio guarantees network finality or automatic refunds. Test these distinctions before enabling funded calls. The important assertion is not simply that an error was caught, but that the client reached the correct state without unintended spending.
- Test both structured challenges and the text fallback, plus malformed payloads and unsupported requirements.
- Verify that denied approval stops before signing, and that invalid payment and settlement failure remain distinct outcomes.
- Simulate an interrupted paid response and require reconciliation rather than an automatic second payment.