Swapper - XMR to USDC swaps
XMR <-> USDC (Arbitrum One) swaps for AI agents. Swapper never holds funds. 8 tools, 3 prompts.
使うべきか
品質と安全性
ツール定義とプロトコルへの準拠に関する自動分析に基づいています。
コンテキストコスト
これは、サーバーのツールがモデルのコンテキストに読み込まれるたびに消費されるおおよそのトークン数です。数が多いほど、ほかのタスクに使える注意が減ります。
インストール
ワンクリックインストール
これを `claude_desktop_config.json` ファイルに追加してください:
{
"mcpServers": {
"swapper": {
"url": "https://xmrtousdc.xyz/mcp"
}
}
}リモートエンドポイント
https://xmrtousdc.xyz/mcpstreamable-httpできること
ツール一覧
ツール(8)
🟢get_quote(amount, receiveAmount, direction, to, basis, ...)
Step 1. Quote Monero (XMR) <-> native USDC on Arbitrum One; no KYC, account or API key. Read-only; quotes are estimates. Buy XMR ("get me 1 XMR"): {direction:"u2x", receiveAmount:"1"}. Sell XMR: {direction:"x2u", amount:"0.5"}. direction plus exactly one of amount (what the user sends) or receiveAmount (what they want). Pass to if known; re-quote with {requoteOf}. Next: create_swap with next.arguments; no confirmation step is required.
入力スキーマ
{
"type": "object",
"properties": {
"amount": {
"type": "string",
"pattern": "^(?:[0-9]+(?:\\.[0-9]+)?|\\.[0-9]+)$",
"description": "What the user SENDS (x2u: XMR, u2x: USDC). Digits and one dot; no commas or units."
},
"receiveAmount": {
"type": "string",
"pattern": "^(?:[0-9]+(?:\\.[0-9]+)?|\\.[0-9]+)$",
"description": "What the user wants to RECEIVE (u2x: XMR, x2u: USDC); needs direction.",
"examples": [
"1"
]
},
"direction": {
"type": "string",
"enum": [
"x2u",
"u2x"
],
"description": "Required. u2x: send USDC, get XMR. x2u: send XMR, get USDC."
},
"to": {
"type": "string",
"description": "Destination from the user: x2u an Arbitrum One 0x address, u2x a Monero address. Never guess."
},
"basis": {
"type": "string",
"enum": [
"estimate",
"minimum"
],
"description": "receiveAmount target met by the estimate (default) or the provider minimum (only if one is published)."
},
"requoteOf": {
"type": "string",
"pattern": "^q_[a-f0-9]{32}$",
"description": "Re-quote this quoteId's stored parameters; pass it alone."
},
"chain": {
"type": "string",
"description": "Default arbitrum (42161)."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"quoteId": {
"type": [
"string",
"null"
]
},
"direction": {
"type": "string"
},
"acceptUntil": {
"type": [
"string",
"null"
]
},
"expiresInSec": {
"type": [
"integer",
"null"
]
},
"acceptWindowSec": {
"type": [
"integer",
"null"
]
},
"guaranteed": {
"type": "boolean"
},
"quote": {
"type": [
"object",
"null"
]
},
"destination": {
"type": [
"string",
"null"
]
},
"belowProviderMinimum": {
"type": [
"boolean",
"null"
]
},
"minimumSwapUsd": {
"type": [
"number",
"null"
]
},
"target": {
"type": [
"object",
"null"
]
},
"delta": {
"type": [
"object",
"null"
]
},
"prerequisites": {
"type": [
"object",
"null"
]
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟡create_swap(quoteId, to, idempotencyKey, quoteIntentDigest, detail)
Step 2. Creates the order from get_quote's next.arguments (quoteId, plus to if the quote had none): one order per quote; moves no funds. Retry with the same arguments: the default idempotencyKey returns the same order. Fund once, only while payable is true: before signing deposit.payment, get_swap_status {orderId, payment} must return paymentCheck.matches. Next: get_swap_status.
入力スキーマ
{
"type": "object",
"properties": {
"quoteId": {
"type": "string",
"pattern": "^q_[a-f0-9]{32}$",
"description": "From get_quote's next.arguments."
},
"to": {
"type": "string",
"description": "Destination, only if the quote had none (next.missing). Never guess."
},
"idempotencyKey": {
"type": "string",
"pattern": "^[A-Za-z0-9:_-]{8,128}$",
"description": "Optional; default q_<quoteId>. Reuse on every retry. A custom key: a fresh random UUID per intent.",
"examples": [
"75d26b1d-11b6-4283-9a06-8a612dcc4ffd"
]
},
"quoteIntentDigest": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "From next.arguments: create fails if the quote's terms differ."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"required": [
"quoteId"
],
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"orderId": {
"type": [
"string",
"null"
]
},
"replayed": {
"type": "boolean"
},
"recovered": {
"type": "boolean"
},
"payable": {
"type": "boolean"
},
"payableReason": {
"type": [
"string",
"null"
]
},
"deposit": {
"type": [
"object",
"null"
]
},
"expectedReceive": {
"type": [
"object",
"null"
]
},
"destination": {
"type": [
"string",
"null"
]
},
"reconfirmRequired": {
"type": "boolean"
},
"trackUrl": {
"type": [
"string",
"null"
]
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟢get_swap_status(orderId, waitSec, sinceState, verify, payment, ...)
Step 3. waiting_for_funding -> deposit_detected -> swap_processing -> completed, or refunding / terminal_failure (outcome refunded, failed, expired). Long-poll with waitSec 25 and sinceState = the last state; repeat next until terminal. deposit.payment may be used only while payable is true. Call it before funding or showing a deposit again. payment: what your wallet will sign; sign only if paymentCheck.matches.
入力スキーマ
{
"type": "object",
"properties": {
"orderId": {
"type": "string",
"description": "From create_swap or list_swaps."
},
"waitSec": {
"type": "integer",
"minimum": 0,
"description": "Long-poll seconds for a change from sinceState (max 25; more is capped)."
},
"sinceState": {
"type": "string",
"enum": [
"waiting_for_funding",
"deposit_detected",
"swap_processing",
"refunding",
"completed",
"terminal_failure",
"unknown"
],
"description": "State from your previous call."
},
"verify": {
"type": "string",
"description": "Destination address (optional extra check)."
},
"payment": {
"type": "string",
"maxLength": 20000,
"description": "Raw tx hex, tx JSON, monero:/ethereum: URI or calldata."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"required": [
"orderId"
],
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"orderId": {
"type": [
"string",
"null"
]
},
"status": {
"type": [
"string",
"null"
]
},
"terminal": {
"type": "boolean"
},
"outcome": {
"type": [
"string",
"null"
]
},
"mayChange": {
"type": "boolean"
},
"payable": {
"type": "boolean"
},
"payableReason": {
"type": [
"string",
"null"
]
},
"deposit": {
"type": [
"object",
"null"
]
},
"destination": {
"type": [
"string",
"null"
]
},
"received": {
"type": [
"object",
"null"
]
},
"receivedBelowMinimum": {
"type": "boolean"
},
"evidence": {
"type": [
"object",
"null"
]
},
"attention": {
"type": "array"
},
"paymentCheck": {
"type": [
"object",
"null"
]
},
"waited": {
"type": [
"object",
"null"
]
},
"trackUrl": {
"type": [
"string",
"null"
]
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟢get_funding_options(direction, from, amount, detail)
Offline. How to get what the user sends: native USDC (not USDC.e) plus a little ETH for gas on Arbitrum One (u2x, default), or XMR in their own wallet (x2u). Pass from {chain, asset} (and amount) for one ordered checklist: quote, fund, re-quote (requoteOf).
入力スキーマ
{
"type": "object",
"properties": {
"direction": {
"type": "string",
"enum": [
"u2x",
"x2u"
],
"description": "u2x (default): the user sends USDC. x2u: XMR."
},
"from": {
"type": "object",
"additionalProperties": false,
"description": "Where the funds are now.",
"properties": {
"chain": {
"type": "string",
"description": "arbitrum, ethereum, another chain, or exchange (or its name)."
},
"asset": {
"type": "string",
"description": "E.g. USDC, USDC.e, ETH, XMR."
}
}
},
"amount": {
"type": "string",
"pattern": "^(?:[0-9]+(?:\\.[0-9]+)?|\\.[0-9]+)$",
"description": "Send amount from a quote, if known."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"direction": {
"type": "string"
},
"matched": {
"type": [
"boolean",
"null"
]
},
"route": {
"type": [
"object",
"null"
]
},
"checklist": {
"type": "array",
"items": {
"type": "string"
}
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟢list_swaps(idempotencyKey, sessionId, detail)
Find orders when the orderId is lost (new chat, crash, unknown create outcome): pass the idempotencyKey create_swap used (default q_<quoteId>), or a sessionId. Read-only; addresses redacted; states can lag. Next: get_swap_status (live state, payable).
入力スキーマ
{
"type": "object",
"properties": {
"idempotencyKey": {
"type": "string",
"pattern": "^[A-Za-z0-9:_-]{8,128}$",
"description": "The key create_swap used (default q_<quoteId>)."
},
"sessionId": {
"type": "string",
"description": "Session UUID, instead of idempotencyKey."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"lookup": {
"type": "string"
},
"payable": {
"type": "boolean"
},
"payableReason": {
"type": [
"string",
"null"
]
},
"orders": {
"type": "array"
},
"note": {
"type": [
"string",
"null"
]
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟢plan_swap(direction, amount, receiveAmount, to, detail)
Optional, offline. Checks a partial request (direction, amount or receiveAmount, to) and returns the next question for the user. Skip it when you have what get_quote needs.
入力スキーマ
{
"type": "object",
"properties": {
"direction": {
"type": "string",
"description": "u2x or x2u, as the user said it."
},
"amount": {
"type": "string",
"description": "What the user sends."
},
"receiveAmount": {
"type": "string",
"description": "What the user wants to receive."
},
"to": {
"type": "string",
"description": "Destination from the user: x2u an Arbitrum One 0x address, u2x a Monero address. Never guess."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"missingInputs": {
"type": "array",
"items": {
"type": "string"
}
},
"validationErrors": {
"type": "array",
"items": {
"type": "string"
}
},
"question": {
"type": [
"object",
"null"
]
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟢get_capabilities(detail)
Optional. Chains, limits (provider minimum, USD), quote window, idempotency, validation rules, polling and the flow.
入力スキーマ
{
"type": "object",
"properties": {
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"contractVersion": {
"type": "string"
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}🟡create_support_ticket(message, orderId, category, walletAddress, sessionId, ...)
For a failed or stuck swap: orderId and what happened; never seed phrases or private keys. Returns ticketId; no tool reads replies (follow up at [email protected]).
入力スキーマ
{
"type": "object",
"properties": {
"message": {
"type": "string",
"minLength": 3,
"maxLength": 2000,
"description": "What happened: what was sent, when, what the user sees."
},
"orderId": {
"type": "string",
"description": "ord_... of the affected order."
},
"category": {
"type": "string",
"description": "Short topic, e.g. \"stuck\", \"refund\". Default \"agent\"."
},
"walletAddress": {
"type": "string",
"description": "Public address involved (sending wallet or destination)."
},
"sessionId": {
"type": "string",
"description": "Session UUID, if known."
},
"detail": {
"type": "string",
"enum": [
"lean",
"full"
]
}
},
"required": [
"message"
],
"additionalProperties": false
}出力スキーマ
{
"type": "object",
"properties": {
"ok": {
"type": "boolean"
},
"operation": {
"type": "string"
},
"state": {
"type": "string"
},
"ticketId": {
"type": [
"string",
"null"
]
},
"userMessage": {
"type": "string"
},
"next": {
"type": "object",
"required": [
"tool",
"arguments"
],
"properties": {
"tool": {
"type": [
"string",
"null"
]
},
"arguments": {
"type": "object"
}
}
},
"error": {
"type": "object"
},
"data": {
"type": "object"
}
},
"required": [
"ok",
"operation",
"next"
]
}コミュニティ
エビデンス