X-API-Key is also reachable as an
MCP tool — so LLM agents can list catalog offers, place orders,
manage proxies, and inspect wallet balances directly, without you
hand-writing HTTP calls.
The server is a thin proxy in front of /public/v1: same auth model,
same idempotency, same rate limits.
Get an API key
Generate one in your dashboard → API Keys, then keep the raw value safe (it is shown only once). See Authentication for the full flow.Connect
Claude Code
/mcp to see registered servers, or
just ask Claude something like “list my proxy orders” — it will
discover and call the right tool.
Claude Desktop
Editclaude_desktop_config.json
(macOS: ~/Library/Application Support/Claude/,
Windows: %APPDATA%\Claude\):
OpenAI Agents SDK
Generic FastMCP client (Python)
Tool catalog
Money-spending tools default to dry-run.
create_proxy_order,
extend_proxy_period, and buy_proxy_bandwidth require
confirm=true to actually charge the wallet. Without it they
return a preview with the offer, current balance, and what would
happen. Always supply an idempotency_key (any unique string,
typically a UUIDv4) so retries replay the stored answer instead of
double-charging.Catalog
list_offers
List available proxy offers, optionally filtered.
Returns a flat table — one row per offer, with
kind, id, name,
country_code, mode, ip_version, is_available, currency,
locations (JSON-encoded list of {region, city}, empty when none is
known), and options (JSON-encoded list of tariff variants; each variant
carries a price in the row’s currency). Use id as offer_id in
create_proxy_order.
A location narrows the choice of ISP, not a delivery guarantee: an
order is placed against the whole pool of the matched ISP, so a specific
city is not guaranteed. While location filtering is not enabled for your
platform, passing
region or city returns the same 403 the HTTP API
would (check the isp.city.enable flag via GET /flags first).Orders
Reads
Destructive — dry-run by default
These requireconfirm=true + an idempotency_key to actually
execute. Without confirm=true they return a preview and don’t touch
the API mutation path.
Non-destructive mutations
No dry-run because nothing is charged.Wallet
End-to-end example: place an order
Three calls — discover, preview, confirm.idempotency_key — PostgresIdempotencyStore returns the
stored answer instead of creating a second batch of orders.
Reference resources
Static enums are exposed as MCP resources so they don’t bloat tool descriptions. Most clients let the agent fetch resources on demand viaresources/read.
Response formats
Tools that return tabular data acceptresponse_format:
csv(default) — one header row, one data row per record; nested values are JSON-encoded inside a single cell. Roughly half the tokens of equivalent JSON.json— list of objects; use when you need to script over nested structures.
Paginated tools
list_my_orders and list_wallet_transactions always wrap the rows
in a pagination envelope so the LLM knows when more pages exist:
has_more is true, request the next page with
offset = previous offset + returned. Loop until has_more is
false.
Errors
Tools surface upstream errors verbatim asToolError with the full
HTTP response body and the X-Correlation-ID. Example:
Idempotency
Every destructive tool that hits aPOST endpoint takes
idempotency_key. The MCP server forwards it as Idempotency-Key on
the HTTP request, and the API persists (key, response) pairs.
Replays return the original answer (so confirm=true on a previously
created order won’t double-charge).
Use a fresh key per logical operation:
- Place an order → one key.
- A retry of the same order → same key.
- A different order → new key.
Out of scope
The MCP server intentionally does not expose:/users/*and/auth/*— account management requires JWT, not an API key./payments/*— payment intents are user-initiated through the dashboard./api-keys/*— you cannot manage keys through a key (security).
Self-hosting
The MCP server is also distributed inside the backend repo assrc/apps/mcp/. Run it locally with:
In docker-compose the service is started by default; tail logs with
make mcp-logs.
Troubleshooting
Tool calls returnMissing API key — the X-API-Key header isn’t
reaching the server. In Claude Desktop check the headers block in
claude_desktop_config.json; in Claude Code re-run claude mcp add
with --header.
HTTP 401 Invalid API key — the key is wrong, revoked, or
expired. Generate a new one via the dashboard.
Tools list is empty — the MCP client cached an old session.
Restart Claude Desktop / reconnect the Claude Code server.
HTTP 422 on list_offers — only the values listed in
ref://offer-kinds are accepted for kind. Earlier docs mentioned
mobile_rotating — that’s wrong, use mobile.