Swapper

Monero to USDC swap API

Quote, open and track XMR ⇄ USDC swaps on Arbitrum One from your backend, bot or AI agent: a public HTTPS API and a remote MCP server, with no API key, no account and no KYC. Swapper never holds funds.

REST API basehttps://xmrtousdc.xyz/api/v1
MCP endpointhttps://xmrtousdc.xyz/mcp

A quote in one call

A quote needs no key and creates nothing. Pass direction (x2u sells XMR, u2x buys XMR) and amount, what the user sends, as a decimal string (digits and one dot):

curl -sS https://xmrtousdc.xyz/api/v1/agent/swap/quote \
  -H "content-type: application/json" \
  -d '{"direction":"x2u","amount":"0.8","to":"0xYOUR_ARBITRUM_ADDRESS"}'

What to read in the response:

Know what the user wants to receive? Send receiveAmount instead of amount, with direction: "u2x", and Swapper finds the USDC to send:

curl -sS https://xmrtousdc.xyz/api/v1/agent/swap/quote \
  -H "content-type: application/json" \
  -d '{"direction":"u2x","receiveAmount":"1","to":"YOUR_MONERO_ADDRESS"}'

Open the order and track it

Create the order from the quote alone, with an idempotency-key header: a new random UUID per order, reused only to retry that same create. No confirmation step is required.

KEY=$(uuidgen)   # a new random key per order; reuse it only to retry this create
curl -sS https://xmrtousdc.xyz/api/v1/agent/swap/create \
  -H "content-type: application/json" \
  -H "idempotency-key: $KEY" \
  -d '{"quoteId":"QUOTE_ID"}'

The response carries data.order.orderId, data.destination (the payout address recorded with the order), data.payable, data.deposit (one-time address, exact amount, expiry) and, while payable is true, data.deposit.payment: a wallet-ready transfer (a monero: URI, or an EIP-681 link plus an unsigned ERC-20 transaction). Send it once, unchanged, only if data.destination is the user's own address. Then long-poll the status until terminal is true:

curl -sS "https://xmrtousdc.xyz/api/v1/agent/swap/status/ORDER_ID?waitSec=25&sinceState=waiting_for_funding"

Core endpoints

MethodPathPurpose
GET/api/v1/agent/quickstartDiscovery, trust metadata, example calls (always reachable).
GET/api/v1/agent/capabilitiesDirections, live chains, defaults, validation rules, limits, funding pointer.
POST/api/v1/agent/swap/quoteEstimate a swap: {direction, amount | receiveAmount, to?, chain?}, or {requoteOf} to re-quote; returns quoteId + terms (an estimate, not guaranteed; no published minimum), valid 300 s.
POST/api/v1/agent/swap/create{quoteId} (+ to if the quote had none) and a required idempotency-key; no confirmation step is required. Returns payable, deposit (payment only while payable), destination, origin, trackUrl.
GET/api/v1/agent/swap/status/{orderId}Live order state, payable, evidence, attention and next; ?waitSec=0..25&sinceState= long-polls for the next change.
GET/api/v1/agent/swap/ordersFind my swaps: ?idempotencyKey= (the create key) or ?sessionId= (addresses redacted).
GET/api/v1/chainsChain list incl. minSwapUsd per chain (the provider minimum recent quotes reported; null when none is known).

Every endpoint, error code and order state, with a full JavaScript loop and a system prompt for your agent: REST API reference.

Connect an AI agent over MCP

Agents in MCP clients get the same flow as tools (get_quote, create_swap, get_swap_status, get_funding_options, list_swaps, plan_swap, get_capabilities, create_support_ticket), with no key and no OAuth:

ClientSetup
Claude Codeclaude mcp add --transport http swapper https://xmrtousdc.xyz/mcp
Claude (claude.ai and Claude Desktop)Customize -> Connectors -> + Add -> Add custom connector -> https://xmrtousdc.xyz/mcp (Authentication: No sign in)
ChatGPTchatgpt.com/plugins -> + -> Add custom MCP server -> Server URL https://xmrtousdc.xyz/mcp, No authentication -> Create as a plugin
Cursor~/.cursor/mcp.json: { "mcpServers": { "swapper": { "url": "https://xmrtousdc.xyz/mcp" } } }
VS Code.vscode/mcp.json: { "servers": { "swapper": { "type": "http", "url": "https://xmrtousdc.xyz/mcp" } } }
Codex CLIcodex mcp add swapper --url https://xmrtousdc.xyz/mcp
Gemini CLIgemini mcp add --transport http swapper https://xmrtousdc.xyz/mcp
Devin Desktop (formerly Windsurf)mcp_config.json: { "mcpServers": { "swapper": { "serverUrl": "https://xmrtousdc.xyz/mcp" } } }
Stdio-only clients (mcp-remote){ "command": "npx", "args": ["-y", "mcp-remote", "https://xmrtousdc.xyz/mcp"] }

Step-by-step setup for each client, the prompts, an example conversation and the safety model: Monero MCP server.

Rules for a safe integration

Machine-readable docs

Questions

Do I need an API key or an account?

No. The API and the MCP server are public: no key, no account, no KYC. Requests are rate limited per IP; on HTTP 429, wait for Retry-After and retry the same call.

Does the API hold or move funds?

No. Creating an order only returns deposit instructions; nothing moves until a wallet signs the deposit (the user's own, or an agent's wallet acting for the user). Swapper never holds your funds. Each order gets a one-time deposit address from the swap provider, which holds the deposit only while the swap executes, then pays out (or refunds).

Can an AI agent run a swap on its own?

Yes. No step waits for a person: an agent may quote, create and fund an order on its own. Funds move only when the sender's wallet signs, only while the order is payable and, over MCP, after Swapper's paymentCheck confirms the transfer is exactly the deposit.

REST or MCP?

Both run the same flow against the same orders. MCP suits agents in MCP clients (Claude, ChatGPT, Cursor and others); REST suits backends, bots and scripts. An order created over one can be found and tracked over the other.

What does it cost to use the API?

Calls are free. Swapper earns an integrator fee that is already included in the quoted rate (currently 1%; every quote states it in terms.fees.integratorFee). Nothing is added on top of the quote apart from the network fee for sending the deposit.

Which networks and assets are supported?

Monero (XMR) on the Monero network and native USDC on Arbitrum One (chain ID 42161, contract 0xaf88d065e77c8cC2239327C5EDb3A432268e5831), in both directions. GET /api/v1/agent/capabilities lists the live chains, defaults and validation rules.

Is the API available everywhere?

No. Requests from restricted regions, currently including the United States, receive HTTP 451 (geo_blocked) on trading endpoints; discovery endpoints such as the quickstart stay reachable.

Integration help: agent@xmrtousdc.xyz. Swapping by hand instead? Monero to USDC · USDC to Monero.

Open the swap app →