Payment-aware MCP client orchestration.
Wraps a JSON-RPC send function: if the response is payment-required
(-32042 or payment-required result metadata), or a -32043 re-challenge
carrying a non-empty challenge list, selects a challenge through
MPP.Client.SelectionPolicy, asks on_payment_required for approval, pays
via MPP.Client.MultiProvider, and retries the original request with the
credential attached.
Total payment attempts per call/4 are bounded at two: the initial
-32042 payment plus at most one re-payment on a -32043 that carries
challenges. A -32043 without challenges surfaces immediately. This is a
deliberate divergence from mppx maxPaymentAttempts = 3
(refs/mppx/src/mcp/client/McpClient.ts) so a malicious server cannot drain
a client wallet through repeated re-challenges.
Approval runs after challenge selection and before each payment —
matching refs/mppx/src/mcp/client/McpClient.ts. A declined approval neither
pays nor retries.
client = MPP.Client.MCP.new(provider: my_provider)
MPP.Client.MCP.call(client, request, &MyTransport.send/1)API Functions
| Function | Arity | Description | Param Kinds |
|---|---|---|---|
call | 4 | Send a JSON-RPC request, paying at most twice (-32042 plus one -32043 re-challenge). | client: value, request: value, send_fun: value, opts: value |
new | 1 | Build a payment-aware MCP client from provider and policy options. | opts: value |
Summary
Functions
Send request through send_fun, paying on -32042 and at most once more
on a -32043 that carries challenges.
Build a payment-aware MCP client.
Types
@type approval() :: (MPP.Challenge.t() -> boolean())
@type t() :: %MPP.Client.MCP{ on_payment_required: approval() | nil, provider: MPP.Client.MultiProvider.t(), selection: MPP.Client.SelectionPolicy.t() }
Functions
Send request through send_fun, paying on -32042 and at most once more
on a -32043 that carries challenges.
send_fun receives the JSON-RPC request map and must return a JSON-RPC
response map. Per-call :on_payment_required overrides the client hook;
pass nil to bypass it (mppx onPaymentRequired: null). The approval hook
fires on every payment. After two payment attempts the terminal response is
returned as-is.
Build a payment-aware MCP client.
Options
:provider— required. AnMPP.Client.MultiProvider, a{module, config}tuple, or a provider module:selection—MPP.Client.SelectionPolicy.t(). Defaults to:server_order, or{:accept_payment, entries}when:accept_paymentis set:accept_payment— preference entries used as the default ranking policy:on_payment_required—(MPP.Challenge.t() -> boolean())invoked after challenge selection and before payment. Omitted ornilauto-approves.