MCP server
The same client, exposed over MCP so an agent can price and send payouts directly. Newline-delimited JSON-RPC 2.0 over stdio — that is the whole transport, which is why there is no SDK dependency here either.
Running it#
# Claude Code
claude mcp add avvio-payments -- npx -y @avvio/payments mcp
# Any MCP client, by config
{
"mcpServers": {
"avvio-payments": {
"command": "npx",
"args": ["-y", "@avvio/payments", "mcp"],
"env": { "AVVIO_API_KEY": "ak_test_…", "AVVIO_ORG_ID": "cmsx…" }
}
}
}Give an agent a test key. doctor and every tool report which mode the key is in, and a test key cannot move real money.
Tools#
15 tools, read from the server's own tool list at build time. Money-moving tools require confirm: true as a separate argument, so a half-parsed instruction cannot become a payment.
| Tool | Effect | What it does |
|---|---|---|
list_corridors | reads | List every currency this organization can pay out to, with the beneficiary fields each one requires. Read this instead of hardcoding a form — field names differ by corridor and can change. |
get_requirements | reads | The exact beneficiary fields needed to pay out in one currency, with validation patterns. Call this before create_beneficiary. |
quote | reads | Indicative price for a corridor with no beneficiary needed: what the recipient gets, the fee, the rate, and the corridor minimum and maximum. Use this while a user is still choosing an amount. It is an estimate, not a locked rate. |
create_beneficiary | writes | Register who is being paid. Scope it to the end user paying them via endUserId, so each of your users only ever sees their own beneficiaries. Returns destinationAccountId, which send_payout needs. |
list_beneficiaries | reads | Beneficiaries saved for one end user. Always pass endUserId for anything shown to a user; omitting it returns the whole organization. |
send_payout | confirm: true | MOVES MONEY. Prices the payout and executes it, debiting your balance. Requires confirm:true. If it times out, the outcome is unknown — call again with the same idempotencyKey rather than starting over. |
get_payout | reads | Current state of one payout. Always live — this is authoritative, more so than a webhook you may have missed. |
list_payouts | reads | Recent payouts for this organization. |
funding_accounts | reads | Where to wire money to top up the balance that payouts debit. |
list_events | reads | The change feed: one row per payout transition, with a sequence cursor. This is the reconciliation primitive — carry nextSince back as since and you observe every revision. A payout that completed and was then returned by the bank appears here as a second row. |
get_balance | reads | The organization’s available balance. Check this before sending: an underfunded payout is refused, and the refusal is a 400 rather than a queued payment. |
get_funding | reads | Deposit instructions for a payout that requires funding: the address, the exact amount, the network, and an expiry. Only some routings need this; the payout says so with requiresFunding. |
create_payout_link | writes | Mint a one-time link that collects the recipient’s own bank details and pays them, so you never handle the details yourself. The link is a credential: it is the only thing needed to be paid, so send it to the person being paid and nobody else. |
confirm_funding | confirm: true | Report the transaction that funded a payout. We read the chain before recording it: a hash that does not fund this payout is refused and nothing is written, so a rejection is always safe to correct. One transfer funds exactly one payout. |
cancel_payout | confirm: true | Stop a payout that has NOT been funded yet — the recovery for one created by mistake. Once funded it cannot be cancelled and you get PAYOUT_NOT_CANCELABLE, which is the honest answer rather than a cancellation that does not happen. |
Arguments#
get_requirements
| Argument | Type | Required | Description |
|---|---|---|---|
currency | string | yes | ISO code, e.g. MXN |
quote
| Argument | Type | Required | Description |
|---|---|---|---|
amount | string | yes | Amount to send, e.g. "200.00" |
to | string | yes | Destination currency, e.g. MXN |
from | string | — | Source currency. Defaults to USD. |
create_beneficiary
| Argument | Type | Required | Description |
|---|---|---|---|
name | string | yes | |
email | string | — | |
country | string | — | ISO-3166 alpha-2, e.g. MX |
currency | string | yes | |
endUserId | string | — | Your id for the person SENDING the money. |
externalId | string | — | Your own id for this beneficiary. Makes creation idempotent. |
details | object | yes | Corridor fields from get_requirements, e.g. {"clabeNumber":"012..."} |
list_beneficiaries
| Argument | Type | Required | Description |
|---|---|---|---|
endUserId | string | — |
send_payout
| Argument | Type | Required | Description |
|---|---|---|---|
amount | string | yes | |
destinationAccountId | string | yes | From create_beneficiary or list_beneficiaries. |
endUserId | string | — | |
endUserName | string | — | |
reference | string | — | Your payment reference. |
purposeOfPayment | string | — | |
expectDestinationAmount | string | — | What you told the payer they would receive. The send is refused if the binding quote drifts more than 2% from it. |
idempotencyKey | string | yes | REQUIRED. A unique id you generate for this payout. If the call times out, call again with this SAME value — that replays the original payout instead of sending a second one. |
confirm | boolean | yes | Must be true. Explicit acknowledgement that this moves money. |
get_payout
| Argument | Type | Required | Description |
|---|---|---|---|
payoutId | string | yes |
list_events
| Argument | Type | Required | Description |
|---|---|---|---|
since | string | — | A sequence from a previous page. Digits only. |
limit | number | — | 1-500, default 100. |
payoutId | string | — | Only this payout’s transitions. |
get_funding
| Argument | Type | Required | Description |
|---|---|---|---|
payoutId | string | yes |
create_payout_link
| Argument | Type | Required | Description |
|---|---|---|---|
amount | string | yes | Decimal string, e.g. "200.00". |
destinationCurrency | string | yes | ISO code, e.g. MXN |
endUserId | string | yes | Your id for the person being paid. |
reference | string | — | |
expiresInMinutes | number | — | 1-10080, default 60. |
confirm_funding
| Argument | Type | Required | Description |
|---|---|---|---|
payoutId | string | yes | |
transactionHash | string | yes | 0x-prefixed 32-byte hex. |
confirm | boolean | yes | Must be true. This commits funds you have already sent. |
cancel_payout
| Argument | Type | Required | Description |
|---|---|---|---|
payoutId | string | yes | |
confirm | boolean | yes | Must be true. Cancelling is irreversible. |