Skip to main content
The MCP server is a Model Context Protocol façade over the public API. Every endpoint reachable with an 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

Then in a Claude Code session: /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

Edit claude_desktop_config.json (macOS: ~/Library/Application Support/Claude/, Windows: %APPDATA%\Claude\):
Restart Claude Desktop. The ProxyJam tools appear in the tools menu.

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 require confirm=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.
If step 3 errors out (network hiccup, etc.) you can safely retry with the same 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 via resources/read.

Response formats

Tools that return tabular data accept response_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.
Non-list tools always return JSON.

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:
If 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 as ToolError with the full HTTP response body and the X-Correlation-ID. Example:
The LLM sees the entire body, so it can either retry with a corrected argument or pass the error back to the user with a clear explanation.

Idempotency

Every destructive tool that hits a POST 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).
If you need any of these, use the HTTP API directly.

Self-hosting

The MCP server is also distributed inside the backend repo as src/apps/mcp/. Run it locally with:
Environment variables: In docker-compose the service is started by default; tail logs with make mcp-logs.

Troubleshooting

Tool calls return Missing 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.