# Swapper - XMR to USDC swaps

> Swap Monero (XMR) <-> native USDC on Arbitrum One. No account or API key required. For AI agents.

- name: xyz.xmrtousdc/monero-swap
- version: 0.6.0
- connection class: R0 (autonomous)
- trust: 82/100 flags: no-repository
- quality: 84/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/xyz.xmrtousdc%2Fmonero-swap
- tools: https://api.protogrid.dev/v1/servers/xyz.xmrtousdc%2Fmonero-swap/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "monero-swap": {
      "type": "http",
      "url": "https://xmrtousdc.xyz/mcp"
    }
  }
}
```


## Trust

- hygiene: 80
- liveness: 99
- freshness: 100
- provenance: 55
- drivers: +dns-namespace +website +reachable +uptime-97% +updated-8d-ago -no-repository
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 84/100 (good)

### protocol: 100 (weight 25)

- pass `protocol.modern`: supports 2026-07-28 (server/discover)
- pass `protocol.stateless`: answers without a session
- pass `protocol.transport`: streamable HTTP
- pass `protocol.list_ttl`: tool list is cacheable (ttlMs 600000)

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 100 (weight 30)

- pass `tools.descriptions`: every tool has a description
- pass `tools.description_length`: descriptions are concise
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 11 of 11 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- pass `tools.token_cost`: about 2,486 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 25 (weight 15)

- warn `stability.changes`: 7 tool changes in 30 days
- fail `stability.rug_pull`: 1 tools kept their name but changed most of their description in 30 days; review before trusting them

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 11, about 2,486 tokens to load them all
- tool set hash: 6a2c9f1b2f97b8b6b8dc2fe6817c6959
- tools last changed: 2026-10-13T19:14:45.831Z
- badge: [![protogrid quality](https://protogrid.dev/badge/xyz.xmrtousdc/monero-swap.svg)](https://protogrid.dev/servers/xyz.xmrtousdc/monero-swap)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

- 2026-10-13 `request_agent_key` added
  - Optional. Issues a key that identifies this agent; quotes made with it (get_quote agentKey) and their orders use the agent fee (swapper://trust). The operator sees the name and contact given.
- 2026-10-13 `submit_feedback` added
  - Optional, after a swap: a rating 1-5 and a comment. The published average counts one rating per completed Swapper order; a comment marked publishable is shown after operator review.
- 2026-10-13 `get_support_ticket` added
  - Support's answer on your ticket: status, awaiting, thread. Answers take minutes to hours.
- 2026-10-13 `create_support_ticket` changed (description, inputSchema, outputSchema) **meaning changed**
  - before: 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 support@xmrtousdc.xyz).
  - after: Stuck or failed swap, or a question: Support answers (get_support_ticket). Follow up with ticketId + replyToken. Never seed phrases or keys.
- 2026-10-13 `get_swap_status` changed (description, inputSchema)
  - before: 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.
  - after: 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. Call it before funding or showing a deposit again. payment: what your wallet will sign; sign only if paymentCheck.safeToSend.
- 2026-10-13 `create_swap` changed (description, outputSchema)
  - before: 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.
  - after: 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. An order cannot be cancelled; unfunded, it expires. 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.safeToSend. Next: get_swap_status.
- 2026-10-13 `get_quote` changed (description, inputSchema, outputSchema)
  - before: 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.
  - after: Step 1. Quote Monero (XMR) <-> native USDC on Arbitrum One; no account or API key. Creates no order. 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. Next: create_swap with next.arguments.

Full history: https://api.protogrid.dev/v1/servers/xyz.xmrtousdc%2Fmonero-swap/changes

## Remotes

- https://xmrtousdc.xyz/mcp (streamable-http, auth none, reachable true, uptime30d 0.9677419)

## Packages

_none_

## Tools (11)

- `create_support_ticket`: Stuck or failed swap, or a question: Support answers (get_support_ticket). Follow up with ticketId + replyToken. Never seed phrases or keys.
- `create_swap`: 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. An order cannot be cancelled; unfunded, it expires. 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.safeToSend. Next: get_swap_status.
- `get_capabilities`: Optional. Chains, limits (provider minimum, USD), quote window, idempotency, validation rules, polling and the flow.
- `get_funding_options`: 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).
- `get_quote`: Step 1. Quote Monero (XMR) <-> native USDC on Arbitrum One; no account or API key. Creates no order. 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. Next: create_swap with next.arguments.
- `get_support_ticket`: Support's answer on your ticket: status, awaiting, thread. Answers take minutes to hours.
- `get_swap_status`: 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. Call it before funding or showing a deposit again. payment: what your wallet will sign; sign only if paymentCheck.safeToSend.
- `list_swaps`: 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).
- `plan_swap`: 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.
- `request_agent_key`: Optional. Issues a key that identifies this agent; quotes made with it (get_quote agentKey) and their orders use the agent fee (swapper://trust). The operator sees the name and contact given.
- `submit_feedback`: Optional, after a swap: a rating 1-5 and a comment. The published average counts one rating per completed Swapper order; a comment marked publishable is shown after operator review.
