Skip to content

x402 MCP retry omits payment metadata with Streamable HTTP transport #343

Description

@mohamedkuch

Reproduction

Using released @apify/mcpc 0.5.1 against an x402 MCP server:

  1. Connect a funded Base wallet with --x402 exact.
  2. Call a payment-required MCP tool.
  3. The server returns a valid payment-required tool result.
  4. mcpc signs the requested payment and retries.
  5. The retry receives the same payment-required result. No settlement occurs.

The failure reproduces against https://api.utilia.ink/base/mcp with the solana_priority_fees tool at $0.002 USDC. The wallet balance remains unchanged, so this is a safe pre-settlement failure.

Root cause

BridgeProcess.handlePaymentRequiredRetry() caches paymentSignatureBase64 and invokes the original SDK tool call again. The fetch middleware only injects params._meta["x402/payment"] when RequestInit.body is a string. The MCP SDK transport supplies a non-string body, so the cached payment is not inserted into the MCP request metadata. The HTTP PAYMENT-SIGNATURE header alone is not sufficient for servers following the x402 MCP transport contract.

Expected behavior

Decode the signed payload and attach it to params._meta["x402/payment"] on the single retry. Preserve existing caller metadata and apply the same behavior to regular, task, and detached tool calls. The payment must be attempted at most once per tool invocation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions