360 Secure SkillHub
360 安全技能中心

MPP Router — Service Discovery

按类别或关键词检索 MPP Router 实时服务目录,按 verified_mode 标注 charge、session、unverified 并据此给出调用建议;读取上游文档确认请求格式,再交接给 pay-per-call 完成 Stellar USDC 支付与重试。目录不缓存超过一分钟,支付前保留确认环节。

shawnmuggle
shawnmuggle
热度 60.26
最近更新 2026-08-11 10:17:52
分类:搜索依赖:代码执行 / 第三方 API应用场景:API 集成 / 工作流 / 研究 / 推荐

安装技能

复制下面的话术发给你的 Agent,它会通过 secure-skills 检索并安装该技能。

执行命令安装此 skill: npx secure-skills-cli add mpprouter-discover
Metadata
name
mpprouter-discover
description
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.

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 mpprouter or mpp router by name

Flow

  1. Discover — GET https://apiserver.mpprouter.dev/v1/services/catalog returns the live service list.
  2. Match — pick the service whose id or category best fits the user's intent. Ask the user if ambiguous.
  3. Read docs — check the matched service's docs field:
    • If docs.llms_txt exists → 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.
  4. Invoke — {method} {base_url}{public_path} with the correct request body. Use the method field from the catalog entry — most services are POST, but a few are GET; do not assume. Expect 402 Payment Required with a Stellar challenge in WWW-Authenticate: Payment request=....
  5. Pay — hand off to pay-per-call with the 402 challenge; it produces a signed credential.
  6. Retry — re-POST the same body with Authorization: Payment <credential>. Receive the upstream response + Payment-Receipt header.

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 (plus tavily_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's charge_rozo_verified / charge_rozo_verified_at fields — newly verified services appear there in real time — and the tx-hash audit trail of verification payments is published in rozo-mpprouter/docs/verified-runs.json.
  • session (⚠ session-only) — upstream merchant is session-mode only. The router now correctly advertises stellar.intents: ["channel"] (no charge) for these services. To use them, the agent must have a registered Stellar channel contract — see the stellar-agent-wallet root SKILL.md "Out of scope" section. Affected: anthropic_messages, openai_chat, openrouter_chat, tempo_rpc. Charge-mode clients cannot call these services. (gemini_generate is currently payment_status: unavailable — the upstream merchant's Google API key is invalid; do not offer it.)
  • unverified (· unverified) — the router hasn't labeled verified_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:

  1. Fetch the catalog fresh.
  2. Find the best service match.
  3. 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-auto ceiling). "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 a session service.
    • 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.