A Stellar USDC wallet skill for AI agents. Pay for 402-gated APIs via MPP Router or x402 facilitators, check balances, manage USDC trustlines, swap XLM→USDC on the Classic DEX, pay a Stellar deposit address directly with a memo, and bridge/send USDC cross-chain to Ethereum, Arbitrum, Base, BSC, Polygon, Solana, or back to Stellar via Rozo. Client-only, sponsored mode, testnet and mainnet. Triggers on "stellar wallet", "pay per call stellar", "x402 stellar", "mpprouter", "check stellar balance", "swap xlm to usdc", "add usdc trustline", "bridge from stellar", "send usdc cross-chain", "pay this deposit address with memo", "fund this invoice on stellar", "pay for api with stellar", or when the user shares a G... address with a payment intent.
Coding
MPP Router — Service Discovery
Try itDiscover paid API services available via MPP Router (apiserver.mpprouter.dev) that accept Stellar USDC payments. Triggers on prompts like "summarize X using parallel.ai via MPPRouter", "search with exa via mpp", "find a service for <task>", "list mpp services", "what APIs can I pay for with stellar". Fetches the live service catalog, picks a matching service, and hands off to the pay-per-call sub-skill to actually invoke it.
What it does
Discover paid API services available via MPP Router (apiserver.mpprouter.dev) that accept Stellar USDC payments. Triggers on prompts like "summarize X using parallel.ai via MPPRouter", "search with exa via mpp", "find a service for <task>", "list mpp services", "what APIs can I pay for with stellar". Fetches the live service catalog, picks a matching service, and hands off to the pay-per-call sub-skill to actually invoke it.
The skill document
discover-mpprouter
High-level discovery for the MPP Router service catalog. Lets agents find and call paid APIs on Stellar mainnet without hardcoding URLs.
What is MPP Router?
MPP Router is a Stellar-native 402 proxy. It takes USDC payments on stellar:pubnet and forwards your request to upstream merchant APIs — Parallel.ai, Exa, Firecrawl, OpenRouter, and more. You pay once in Stellar USDC and get back whatever the upstream merchant returns. No need to hold USDC on Base/Tempo.
Mainnet only. The router does not run on testnet.
When to trigger
- "Summarize https://stripe.com/docs using parallel.ai search via MPPRouter"
- "Search for X via exa through mpp"
- "Scrape this page with firecrawl — use stellar to pay"
- "List available MPP services"
- "What paid APIs can I call with stellar USDC?"
- User mentions
mpprouterormpp routerby name
Flow
- Discover —
GET https://apiserver.mpprouter.dev/v1/services/catalogreturns the live service list. - Match — pick the service whose
idorcategorybest fits the user's intent. Ask the user if ambiguous. - Read docs — check the matched service's
docsfield:- If
docs.llms_txtexists → fetch it and read the API schema to build the correct request body. The router forwards bodies as-is — it does not transform or validate them. - If only
docs.api_reference→ read that instead. - If only
docs.homepage→ browse it for the API format. - If no docs at all → ask the user for the request body format, or try a minimal probe.
- If
- Invoke —
{method} {base_url}{public_path}with the correct request body. Use themethodfield from the catalog entry — most services are POST, but a few are GET; do not assume. Expect402 Payment Requiredwith a Stellar challenge inWWW-Authenticate: Payment request=.... - Pay — hand off to
pay-per-callwith the 402 challenge; it produces a signed credential. - Retry — re-POST the same body with
Authorization: Payment. Receive the upstream response +Payment-Receiptheader.
Service catalog
The catalog is live and large (~500 services). Always call
/v1/services/catalog fresh — never hardcode a list, never cache for
more than a minute.
Payment-mode labels (IMPORTANT for the LLM)
The catalog exposes a verified_mode field per service. The discover
skill reads it and tags each record with a payment_mode string:
charge(✓ verified charge) — end-to-end verified to work with this skill's Stellar charge flow. Safe to call. Known-good as of 2026-08-10 (12):anthropic_chat_completions,coingecko_simple_price,deepgram_deepgram_list-models,deepseek_chat,exa_search,firecrawl_scrape,grok_grok_chat,groq_chat,mistral_mistral_chat,parallel_search,perplexity_perplexity_chat,storage_upload(plustavily_tavily_search, first paid-verified 2026-08-10). Every service on this list was verified with a real paid call through the production Router. For the live view, read the catalog'scharge_rozo_verified/charge_rozo_verified_atfields — newly verified services appear there in real time — and the tx-hash audit trail of verification payments is published inrozo-mpprouter/docs/verified-runs.json.session(⚠ session-only) — upstream merchant is session-mode only. The router now correctly advertisesstellar.intents: ["channel"](nocharge) for these services. To use them, the agent must have a registered Stellar channel contract — see thestellar-agent-walletroot SKILL.md "Out of scope" section. Affected:anthropic_messages,openai_chat,openrouter_chat,tempo_rpc. Charge-mode clients cannot call these services. (gemini_generateis currentlypayment_status: unavailable— the upstream merchant's Google API key is invalid; do not offer it.)unverified(· unverified) — the router hasn't labeledverified_mode(or labeled it as the literal string"false", which is a router-side catalog-generator bug). ~97% of the catalog is in this bucket. Most of these work but we can't prove it without a paid probe. Treat as cautiously optimistic: acceptable to call on user request, but warn the user that it's not formally verified.
Decision rule for the LLM
When the user asks to call a paid API via MPP Router:
- Fetch the catalog fresh.
- Find the best service match.
- Check its
payment_mode:charge→ proceed to pay-per-call. This is still a real-money mainnet payment: pay-per-call's own confirmation gate applies (it prompts before every mainnet payment unless the user has set a session--max-autoceiling). "Verified" describes the service record, not permission to spend without the user seeing it.session→ do not call it by default. Tell the user: "This service is currently in session-only mode on MPP Router. Paying via Stellar charge mode would succeed but the upstream would reject the receipt, so you'd lose the fee with no result. Waiting on a router-side fix. Alternative service?" The ONE exception: the user, after reading exactly that warning, explicitly says to proceed anyway and accepts the fee is likely lost — then proceed. There is no other path to calling asessionservice.unverified→ proceed (through the same confirmation gate) but surface a brief caveat in your response ("this service isn't formally verified for Stellar charge mode; proceeding anyway — let me know if the call fails after payment").
Service record shape
Discover enriches each record with a payment_mode field (one of
charge, session, unverified) derived from verified_mode. This
is the field the LLM should branch on — it normalizes the router's
raw verified_mode string (which can be missing or literally
"false") into a fixed vocabulary.
{
"id": "exa_search",
"name": "Exa – Search the web",
"category": "search",
"description": "Search the web",
"public_path": "/v1/services/exa/search",
"method": "POST",
"price": "$0.005/request",
"payment_method": "stellar",
"network": "stellar-mainnet",
"asset": "USDC",
"status": "active",
"methods": { "stellar": { "intents": ["charge", "channel"] } },
"docs": {
"homepage": "https://docs.exa.ai",
"llms_txt": "https://docs.exa.ai/llms.txt"
},
"verified_mode": "charge",
"payment_mode": "charge"
}
docs field — upstream API documentation
The router forwards request bodies as-is without transformation. Clients
must know each upstream API's request format. The docs field provides
the upstream's own documentation:
| Sub-field | What it is | How the agent should use it |
|---|---|---|
llms_txt | LLM-readable docs (69/88 providers) | Read this first. Fetch it and parse the API schema to construct the correct request body. |
api_reference | Full API reference (8/88 providers) | Detailed endpoint docs — use when llms_txt is missing or insufficient. |
homepage | Docs homepage (82/88 providers) | Fallback — browse or scrape if neither of the above is available. |
Decision rule: if docs.llms_txt exists, fetch and read it before
calling the service. If not, check docs.api_reference. If neither
exists, warn the user that you may need them to supply the request body
format, or try docs.homepage.
19 providers have no llms_txt — these include Google Gemini, Google
Maps, Nansen, Parallel, Allium, AgentMail, and several Tempo-proxied
third-party APIs.
How to run
# List all services
./node_modules/.bin/tsx skills/discover/run.ts
# Filter by category
./node_modules/.bin/tsx skills/discover/run.ts --category search
# Match a free-text intent (uses simple keyword match)
./node_modules/.bin/tsx skills/discover/run.ts --query "web search"
# JSON output for piping
./node_modules/.bin/tsx skills/discover/run.ts --json
Full end-to-end example
# Discover which service to use — capture path, method, and the
# catalog-advertised payment expectations so pay-per-call can refuse
# a 402 that tries to redirect funds or inflate the price.
SERVICE_JSON=$(./node_modules/.bin/tsx skills/discover/run.ts --query "web search" --pick-one --json)
SERVICE=$(echo "$SERVICE_JSON" | jq -r '.public_path')
METHOD=$(echo "$SERVICE_JSON" | jq -r '.method')
EXPECT_AMT=$(echo "$SERVICE_JSON" | jq -r '.expect.amount_usdc // empty')
EXPECT_TO=$(echo "$SERVICE_JSON" | jq -r '.expect.pay_to // empty')
# Call it — pay-per-call handles the 402 → pay → retry loop.
# The --expect-* flags cross-check the 402 challenge against the
# catalog. Any drift aborts before signing.
./node_modules/.bin/tsx skills/pay-per-call/run.ts "https://apiserver.mpprouter.dev$SERVICE" \
--method "$METHOD" \
--body '{"query": "Summarize https://stripe.com/docs"}' \
${EXPECT_AMT:+--expect-amount "$EXPECT_AMT"} \
${EXPECT_TO:+--expect-pay-to "$EXPECT_TO"}
Anti-patterns
- ❌ Don't hardcode service paths — the catalog is the source of truth.
- ❌ Don't pay twice for one call — credentials are single-use and HMAC-bound to amount/currency/recipient.
- ❌ Don't use testnet — MPP Router is mainnet-only.
- ❌ Don't cache the catalog for more than a minute — prices and service availability can change.
Related skills
Pay for and use AI services via MoltsPay protocol. Trigger: User asks to generate video, use a paid service, etc. Auto-discovers services from /.well-known/a...
Safely inspect Stripe payments, customers, invoices, and subscriptions
Search, read, and update Slack messages, channel history, canvases, and users via Slack's hosted MCP server. Thin pass-through to Slack's official MCP; the l...
Ask questions and read documentation about any GitHub repository using DeepWiki MCP. Use when you need to understand a codebase, find specific APIs, or get c...
Use OKX OnchainOS MCP through UXC for token discovery, market data, wallet balance, and swap execution planning. Use when tasks need OKX MCP tools such as to...