coronium-proxy-mcp
OfficialOperate a Coronium mobile-proxy account and its billing, proxies, support, and pool access.
Authenticate with email/password, validate the cached token, and log out.
View account profile, spendable balance, crypto deposit addresses/balances, saved cards, low-balance thresholds, payments ledger, and modem-lifecycle webhook settings.
List/filter owned proxies, get full proxy details, check health, test connectivity, and download OpenVPN configs.
Rotate/restart proxies, poll rotation status, replace broken modems, set auto-rotation intervals, change proxy passwords, set metadata and OS fingerprints, re-apply modem settings, and cancel modems.
Browse countries, tariffs, free modem stock, and validate coupons.
Buy or renew modems using account balance, and check payment status.
List, read, create, reply to, and archive support tickets.
Work with pay-per-GB pool stock, keys, proxy URLs, top-ups, cancellations, purchases with balance, and sticky sessions.
Provides tools to download OpenVPN .ovpn configuration profiles for modems that support VPN tunnel access, enabling VPN connections through Coronium proxies.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@coronium-proxy-mcplist my available mobile proxies"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Coronium proxy MCP
A local stdio MCP server for customers of Coronium.io dedicated 4G/5G mobile proxies. Version 2.4.3. It lets an AI agent check balances, list owned proxies with ready-to-use HTTP and SOCKS5 URLs, test and rotate proxies, replace a proxy, download an OpenVPN profile, compare plans and live stock by country and carrier, quote a purchase or a renewal, and work with support tickets. If you turn spending on, it can also buy and renew from your account balance or a saved card, and move your own USDT or BTC into account credit, after you approve the exact total. Started without a token, it can open a new account for an agent (see Agents without a browser).
It talks only to the Coronium customer API at https://api.coronium.io/api/v3 (plus the public plan catalog on the same host). It has no admin, server or reseller-management tools. The same tools are also run by Coronium as a hosted server at https://api.coronium.io/mcp, for claude.ai, the Claude apps and Cowork, with sign-in through your Coronium account. Upgrading from 2.1.0 or 1.3.0? Read Migration from 2.1.0 or Migration from 1.3.0 in the changelog (2.0.0 was never published to npm).
Connect
Requires Node.js 20 or newer. Configure your MCP host to launch the pinned version:
{
"mcpServers": {
"coronium": {
"command": "npx",
"args": ["-y", "coronium-proxy-mcp@2.4.3"],
"env": {
"CORONIUM_API_TOKEN": "YOUR_CORONIUM_API_TOKEN",
"CORONIUM_TOOL_PROFILE": "directory"
}
}
}
}Create the API token in the dashboard (dashboard.coronium.io, Account, API Access). Keep it in your host's protected configuration or secret store, never in a repository or a conversation. CORONIUM_API_KEY is an alias for CORONIUM_API_TOKEN. Restart the host after changing configuration.
The token is the way in. No account yet? See Agents without a browser. There is no password tool by default: coronium_login only exists if you set CORONIUM_ENABLE_LOGIN_TOOL=1, because a password passed to a tool ends up in the conversation.
If you want an agent to buy for you, use the buyer profile and turn spending on:
{
"mcpServers": {
"coronium": {
"command": "npx",
"args": ["-y", "coronium-proxy-mcp@2.4.3"],
"env": {
"CORONIUM_API_TOKEN": "YOUR_CORONIUM_API_TOKEN",
"CORONIUM_TOOL_PROFILE": "buyer",
"CORONIUM_ENABLE_SPENDING": "1"
}
}
}
}Leave CORONIUM_ENABLE_SPENDING out and the same profile can look, quote and manage, but not pay.
Set the host's tool timeout above 180 seconds: rotation, replacement and payment calls wait for the backend. If a call times out, check its outcome before acting again. The process uses stdout only for MCP JSON-RPC.
Related MCP server: Proxytline MCP
Agents without a browser
An agent can open its own Coronium account, fund it and buy, with no browser and no dashboard visit. Nothing is included until it is paid for, and every purchase still needs the person's yes for the exact total.
With this MCP (stdio). Start it with no CORONIUM_API_TOKEN and the buyer profile. coronium_create_account (email, name, optional purpose and password) signs up, signs in and issues an API token, which the rest of the session uses. It returns the API token once, and the generated password once if you gave none; store both in a secret store. Then: coronium_get_crypto_balance, deposit USDT (TRC-20) or BTC, coronium_convert_crypto_to_credit (dry run, then confirmed), coronium_quote_purchase, and coronium_buy_modems_with_balance with funding_source: "account_credit".
{
"mcpServers": {
"coronium": {
"command": "npx",
"args": ["-y", "coronium-proxy-mcp@2.4.3"],
"env": {"CORONIUM_TOOL_PROFILE": "buyer", "CORONIUM_ENABLE_SPENDING": "1"}
}
}
}With curl. The same steps against the REST API (jq reads the JSON):
API=https://api.coronium.io
EMAIL=agent@your-domain.example; PASSWORD='a-long-random-password'
# 1. Sign up (a verification email is sent; nothing waits for it)
curl -s -X POST $API/api/v3/signup -H 'Content-Type: application/json' \
-d "{\"login\":\"$EMAIL\",\"password\":\"$PASSWORD\",\"name\":\"My agent\",\"purpose\":\"price monitoring\"}"
# 2. Sign in, then issue the long-lived API token (365 days)
SESSION=$(curl -s -X POST $API/api/v3/get-token -H 'Content-Type: application/json' \
-d "{\"login\":\"$EMAIL\",\"password\":\"$PASSWORD\"}" | jq -r .token)
TOKEN=$(curl -s $API/api/v1/account/api-token -H "Authorization: Bearer $SESSION" | jq -r .token)
# 3. Deposit addresses: send USDT (TRC-20) or BTC and wait for it to confirm
curl -s $API/api/v3/account/crypto-balance -H "Authorization: Bearer $TOKEN"
# 4. Move it into USD account credit: preview, then the real move (one way)
curl -s -X POST $API/api/v3/account/balance/convert -H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' -d '{"coin":"all","dry_run":true}'
curl -s -X POST $API/api/v3/account/balance/convert -H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" -H 'Content-Type: application/json' -d '{"coin":"all"}'
# 5. Plans and stock; the total is price x quantity
curl -s $API/api/v3/tariffs/available | jq '.data[] | {_id, name, country_code, price, period, stock}'
# 6. Buy, capped at the approved total; then read the proxies
curl -s -X POST $API/api/v3/payment/buy-with-account-credit -H "Authorization: Bearer $TOKEN" \
-H "Idempotency-Key: $(uuidgen)" -H 'Content-Type: application/json' \
-d '{"tariff_id":"TARIFF_ID","modemCount":1,"max_total_usd":APPROVED_TOTAL}'
curl -s $API/api/v3/account/proxies -H "Authorization: Bearer $TOKEN"Disposable and reserved email domains are refused. An address that already has an account signs up "ok" but the sign-in fails with a different password.
Hosted buyer server with the API token. Send the token as a Bearer header to https://api.coronium.io/mcp/buyer. That token can buy there, exactly as it can on the REST API, so keep it secret (environment variable or secret store, never in a repository or a chat). https://api.coronium.io/mcp never spends with any token.
claude mcp add --transport http coronium-buyer https://api.coronium.io/mcp/buyer \
--header "Authorization: Bearer $CORONIUM_API_TOKEN"Any MCP client that supports Streamable HTTP with headers:
{
"mcpServers": {
"coronium-buyer": {
"type": "http",
"url": "https://api.coronium.io/mcp/buyer",
"headers": {"Authorization": "Bearer ${CORONIUM_API_TOKEN}"}
}
}
}${CORONIUM_API_TOKEN} is expanded by Claude Code; in a client without variable expansion, keep this file out of version control.
Hosted server
Coronium runs this server over Streamable HTTP, so it works where a local server cannot: claude.ai, the Claude desktop and mobile apps, and Cowork, as well as Claude Code.
Works in claude.ai: add a custom connector with the URL https://api.coronium.io/mcp, then sign in with your Coronium account. A Coronium page opens; sign in to your dashboard in that browser if needed, check the app and the permissions, and approve. Nothing to install and no token to copy.
Claude Code: claude mcp add --transport http coronium https://api.coronium.io/mcp, then /mcp to sign in. The Claude Code plugin in this repository declares the same URL as its only server, coronium.
How it works:
Sign-in is OAuth 2.1 with PKCE (S256). Clients register dynamically or with a client ID metadata document. Access tokens last one hour; refresh tokens rotate on every use, and a reused refresh token ends that sign-in. Coronium stores only hashes of tokens.
https://api.coronium.io/mcpruns thedirectoryprofile (22 tools). Permissions:read(account, balance, proxies, plans, prices, tickets) andmanage(test, rotate and replace proxies, OpenVPN profiles, open and answer tickets). It has no tools that buy, renew, top up, cancel or refund, whatever you approve.https://api.coronium.io/mcp/buyeris a separate address for agents that buy, for use as a custom connector. It runs thebuyerprofile: 15 tools, or 20 when the connection may spend (the two buy tools, the two renew tools andconvert_crypto_to_credit). Purchases are off for every OAuth connection: the money tools appear only after you allow purchases for that one connection, on the consent page or later in the dashboard, with your password. Each purchase still needsconfirm: true, the quotedexpected_total_usdand a newidempotency_key, and the API refuses a higher total.See and disconnect connected apps at https://dashboard.coronium.io/api/v1/oauth/connections while signed in to the dashboard. Disconnecting stops an app at once.
API clients can also send a dashboard API token as the Bearer token. On
/mcpit getsreadandmanageand never spends. On/mcp/buyerit also getsspend, the same power it has on the REST API, so the money tools are listed without a dashboard switch. Keep it secret.coronium_get_capabilitiesreports the rule asspending_rule.The hosted server never lists
create_account. Open the account first with the local server or the REST API (see Agents without a browser), then connect with its API token.The hosted server keeps no customer data. Its logs hold the tool name and argument names, never values, credentials or ticket text.
Run your own copy over HTTP with npx -y -p coronium-proxy-mcp@2.4.3 coronium-proxy-mcp-http behind a TLS proxy. It needs an OAuth authorization server that answers the token check described in src/remote-auth.ts; settings: PORT (default 5031), HOST (default 127.0.0.1), MCP_PUBLIC_URL, MCP_ALLOWED_HOSTS, MCP_ALLOWED_ORIGINS and CORONIUM_BASE_URL. It refuses to start with CORONIUM_API_TOKEN, a password or CORONIUM_ENABLE_SPENDING in its environment, because it only acts with each caller's own sign-in.
Install from a listing
Claude Code plugin (hosted directory server, no money tools; sign in with your Coronium account in the browser, no token):
/plugin marketplace add coroniumio/coronium-proxy-mcp /plugin install coronium-mobile-proxies@coroniumThen run
/mcp, selectplugin:coronium-mobile-proxies:coroniumand choose Authenticate. Details: plugins/coronium-mobile-proxies.Official MCP Registry:
io.github.coroniumio/coronium-proxy-mcp(registry entry). Hosts that read the registry install the npm packagecoronium-proxy-mcpor connect to the hosted remotehttps://api.coronium.io/mcp.npm:
npx -y coronium-proxy-mcp@2.4.3with the environment shown under Connect.
Tool profiles
CORONIUM_TOOL_PROFILE decides which tools exist:
directoryregisters an explicit allowlist of 22 tools: balances (account credit, BTC and USDT), owned proxies with HTTP and SOCKS5 URLs, ready-to-use connection config (get_proxy_connection), health, connectivity test, rotation and its status, replacement, OpenVPN profile, countries, plans and stock by country and carrier, renewal quotes, tickets (list, read, create, reply), webhook read, and capabilities. It has no login tool, no OS fingerprint tools, no wallet creation, and no buy, renew, top-up or cancel tools.check_tokentakes no token argument. This is the profile the Coronium Claude Code plugin uses.buyerregisters 15 tools for an agent that buys and runs a few dedicated proxies, 20 with spending on: plans, stock,quote_purchase,get_renewal_quote, payment status, owned proxies,get_proxy_connection, test, rotate and rotation status, replace, balance, crypto balance, saved cards and capabilities. With spending on it addsbuy_modems_with_balance,buy_modems_with_card,renew_modems_with_balance,renew_modems_with_cardandconvert_crypto_to_credit. Without any configured token or login it also listscreate_account(16 tools, 21 with spending on; see Agents without a browser). No login tool and no token argument anywhere.full(the default when unset) registers every non-money tool, including settings, webhooks, pool keys and the Coronium Node tools: 60 tools, 69 with spending on. Likebuyer, it also listscreate_accountwhile no token or login is configured (61, or 70 with spending on). The login tool is not included unlessCORONIUM_ENABLE_LOGIN_TOOL=1.read-onlyregisters only the 32 tools that change nothing.CORONIUM_READ_ONLY=trueis an alias.
Spending is off by default. Money tools exist only when CORONIUM_ENABLE_SPENDING=1 is set and the profile is full (buy, renew, crypto to credit, pool purchase and top-up, cancel with refund) or buyer (buy, renew and crypto to credit). Without both, they are not registered and the HTTP client refuses money calls on its own (spending_disabled). Otherwise you pay in the dashboard.
Tools are always listed in alphabetical order, so the list is the same in every session.
Configuration
CORONIUM_API_TOKEN(orCORONIUM_API_KEY): the dashboard API token, kept in memory only. Leave it unset in thebuyerorfullprofile to let an agent open its own account withcreate_account.CORONIUM_TOOL_PROFILE:buyer,directory,fullorread-only. Any other value stops the server at startup.CORONIUM_ENABLE_SPENDING:1ortrueenables money tools in thefullandbuyerprofiles. Default off.CORONIUM_ENABLE_LOGIN_TOOL:1ortrueregisterscoronium_loginandcoronium_logoutin thefullandread-onlyprofiles. Default off. Never inbuyerordirectory.CORONIUM_BASE_URL: defaults tohttps://api.coronium.io/api/v3when unset or empty. An override must be HTTPS (loopback HTTP is allowed for tests) and must not contain credentials, a query or a fragment. Leave it unset in normal use so the token only goes to Coronium.
CORONIUM_ENABLE_SPENDING, CORONIUM_ENABLE_LOGIN_TOOL and CORONIUM_BASE_URL are read only from the host's environment or from the file named by DOTENV_CONFIG_PATH. A .env file that happens to be in the working directory cannot turn spending on or redirect the token.
CORONIUM_LOGIN(orCORONIUM_EMAIL) andCORONIUM_PASSWORD: older login from the host environment instead of a token. Still works, but prefer the token.CORONIUM_AUTO_LOGIN:0disables automatic login and refresh.TOKEN_ENCRYPTION_KEY: optional secret that lets a login token persist AES-256-GCM encrypted at~/.coronium/token.enc(directory 0700, file 0600). Without it nothing is written to disk.DOTENV_CONFIG_PATH: optional explicit.envpath.
How the tools behave
Proxies and URLs. get_proxies and get_proxy return http_url and socks5_url. When a proxy has separate HTTP and SOCKS5 logins, each URL uses its own login. Listing does not test a connection; test_modem runs the backend check and returns ok:true or ok:false.
Connection config. get_proxy_connection returns, for one owned proxy: the HTTP and SOCKS5 URLs, HTTP_PROXY/HTTPS_PROXY/ALL_PROXY values and export lines, and snippets for curl, Python requests and httpx, Node undici and axios, Playwright, Puppeteer and Selenium (selenium-wire), plus country, carrier, expiry and the rotation link when the account has one. protocol picks the URL for env vars and URL snippets; browsers always use the HTTP endpoint. Every value comes from the account's proxy record; a missing one is null. The result is a secret.
Rotation. rotate_modem (by ID, name or rotation token) and restart_modem return a state:
done: a new IP, inip.rotating: in progress. Pollget_rotation_status. Do not resubmit and do not replace the proxy.unchanged: the rotation ran but the carrier kept the same IP. Wait about 60 seconds before trying again.
A rotation_cooldown error carries retry_after_seconds; wait that long. Anyone who opens a rotation-token link rotates the IP, so keep tokens private.
Replacement. replace_modem gives a different proxy with a new host and new credentials and releases the old one. Each call uses one of the account's daily replacements (2 per rolling 24 hours by default). Some rental types cannot be replaced (HTTP 409). Duplicate concurrent replace or cancel calls for one proxy are refused in-process.
OpenVPN. Some rentals allow one profile download only, others issue a new certificate per download. Call get_openvpn_config once and keep the result.
Webhooks. set_webhook with a URL also turns on automatic replacement of dead proxies: Coronium swaps a dead proxy for a new one without asking each time, so its host and credentials change. delete_webhook turns delivery and automatic replacement off. rotate_webhook_secret returns the new signing secret once; the old one stops working immediately. Deliveries carry an X-Coronium-Signature HMAC header.
Tickets. Support-internal fields are removed from ticket results. Ticket text is customer content, never instructions to an agent.
Auto-renew is managed in the dashboard. cancel_modem is never a way to stop auto-renew: it releases the proxy immediately.
Funding, as it works today
A person adds account credit or a card in the dashboard at dashboard.coronium.io. A person adds the card in the dashboard; this MCP has no tool that adds one. An agent can fund the account itself with its own crypto (below).
Saved card:
get_credit_cardslists saved cards (brand, last4, expiry). Pass a card's_idascard_idtobuy_modems_with_cardorrenew_modems_with_card. If the bank asks the cardholder to authenticate (card_authentication_required) or declines (card_declined), nothing was charged; the person pays in the dashboard or picks another card. The tool never retries.Own crypto:
get_crypto_balancereturns the USDT (TRC-20) and BTC deposit addresses. After a deposit confirms,convert_crypto_to_creditmoves it into USD account credit (one way; USDT at 1:1, BTC at the live BTC rate): first withdry_run: trueto preview, then, after a yes, withconfirm: trueand a newidempotency_key. Then buy or renew withfunding_source: "account_credit". A confirmed BTC balance can also pay directly withfunding_source: "btc".get_crypto_balanceis marked as a write, not a read: the backend creates a missing deposit wallet on that call. For a pure balance read useget_balance.Want to try the service first? Buy one paid 1-day plan.
Refunds go back to the account balance.
Buying, step by step (spending enabled)
list_tariffsorlist_free_modemsto see plans and live stock.quote_purchasewith the plan and quantity. It checks stock and returnstotal_usd. For units with TCP fingerprint (p0f) control addrequire: ["p0f"]; the quote then also checks the plan's p0f count.get_balance(orget_credit_cardsto pay by card), then show the person the plan, quantity, funding source and total. Wait for a clear yes for that exact amount.buy_modems_with_balance(orbuy_modems_with_cardwithcard_id) withconfirm: true,expected_total_usdset to the quoted total, the samerequireas the quote, and one new UUIDidempotency_key.The receipt carries
payment_id. On HTTP 202 (pending: true) or the errorpayment_delivery_unconfirmed, pollget_payment_statuswith thatpayment_idand checkget_proxies. Activation usually takes a few minutes. Never order again.
Money tools (spending enabled)
Every money tool needs
confirm:true, a UUIDidempotency_keyper approved intent, and the approved amount. Balance buy and renew also need an explicitfunding_source(account_creditorbtc; no default); the card tools needcard_id.convert_crypto_to_creditpreviews withdry_run: trueand needsconfirmand a key only for the real move.expected_total_usd: the tool re-reads the live price (plan price and coupon, renewal quote, or pool plan price) right before sending and refuses withprice_changedwhen the total differs from the approved one, higher or lower. Buy and renew also send it to the server asmax_total_usd, so the server refuses (HTTP 409price_changed, nothing charged,details.quoteholds its current figure) when its total is higher. Neither is a price lock. Afterprice_changed, quote again, ask again, and use a newidempotency_keyfor the newly approved total.idempotency_keyis sent as theIdempotency-Keyheader on every buy, renew and crypto move. A repeat call with a key the account already sent (within 24 hours, in the same server process) skips the pre-checks and returns the first receipt, or the first error, withreplay: true. It never charges again, even when the first call bought the last unit in stock. The same key with a different payload is refused (idempotency_conflict). The key is 8 to 128 characters of letters, digits,-and_(a UUID fits); the API answers HTTP 400 "Invalid Idempotency-Key format" to any other key on the buy, renew and crypto-move routes.cancel_modemneedsmin_refund_usd. It re-runs the refund preview and refuses withrefund_changedwhen the refund is now lower.A coupon that gives no discount is refused (
coupon_invalid) instead of being charged at full price.require: ["p0f"]buys only units with p0f control and is refused before any charge (p0f_unavailable) when the plan has too few.want_p0f: trueis a deprecated alias for it.Buy and renew results carry
payment_id,pendingandnext_step; an error with a known payment carriespayment_idtoo. Pollget_payment_statuswith it. Without one, reconcile withget_paymentsandget_proxies.outcome:"unknown"means check before acting;outcome:"refunded_not_charged"means nothing was charged.No write is ever retried automatically. A payment key is bound to one payload for the process lifetime and concurrent identical calls share one request.
Results and errors
Successful tools return JSON text and structuredContent with the same {data, observed_at} object. observed_at is when this process handled the response, not a backend measurement time.
Errors set isError:true and carry {error} as JSON text (not structuredContent, which always matches the tool's output schema). error has code (always lowercase, for example payment_in_progress), message, recovery_hint (one sentence on what to do next), and when known status, backend_code (the original code when it differed), request_id, retry_after_seconds, idempotency_key, outcome and suggested_action. A 429 is classified by status and Retry-After, not by its code. When a plan is out of stock, the error lists up to five plans that are in stock now. Credential fields are redacted from error details. A failed balance read is an error, never zero.
Tool catalog
Every name begins with coronium_. "buyer" and "directory" mark the tools in those profiles. Exact arguments come from tools/list. The catalog lists all 72 tool schemas (also in docs/tool-catalog.json): 70 tools plus the opt-in coronium_login and coronium_logout. Of the 70, nine move money and need CORONIUM_ENABLE_SPENDING=1.
coronium_apply_modem_settings(write). Required:proxy,confirm.coronium_archive_ticket(write). Required:ticket_id,confirm.coronium_build_pool_proxy_url(write). Required:id.coronium_build_saved_pool_session_url(write). Required:id.coronium_buy_modems_with_balance(spends money, needs CORONIUM_ENABLE_SPENDING=1, buyer). Required:tariff_id,quantity,expected_total_usd,confirm,idempotency_key,funding_source.coronium_buy_modems_with_card(spends money, needs CORONIUM_ENABLE_SPENDING=1, buyer). Required:tariff_id,quantity,expected_total_usd,confirm,idempotency_key,card_id.coronium_buy_pool_with_balance(spends money, needs CORONIUM_ENABLE_SPENDING=1). Required:tariff_id,expected_total_usd,confirm,idempotency_key.coronium_cancel_modem(cancels with refund, needs CORONIUM_ENABLE_SPENDING=1). Required:proxy,min_refund_usd,confirm.coronium_cancel_pool_key(cancels with refund, needs CORONIUM_ENABLE_SPENDING=1). Required:id,confirm,idempotency_key.coronium_change_proxy_password(write). Required:proxy,confirm.coronium_check_coupon(read). Required:code.coronium_check_token(read, directory). Required: none.coronium_close_pool_session(write). Required:confirm.coronium_convert_crypto_to_credit(spends money, needs CORONIUM_ENABLE_SPENDING=1, buyer). Required: none.coronium_create_account(write, buyer). Required:email,name.coronium_create_ticket(write, directory). Required:subject,message,confirm.coronium_delete_saved_pool_session(write). Required:id,confirm.coronium_delete_webhook(write). Required:confirm.coronium_get_account(read, directory). Required: none.coronium_get_balance(read, buyer, directory). Required: none.coronium_get_capabilities(read, buyer, directory). Required: none.coronium_get_credit_cards(read, buyer). Required: none.coronium_get_crypto_balance(write, buyer). Required: none.coronium_get_low_balance_threshold(read). Required: none.coronium_get_openvpn_config(write, directory). Required:proxy.coronium_get_p0f_options(read). Required:proxy.coronium_get_payment_status(read, buyer). Required:payment_id.coronium_get_payments(read). Required: none.coronium_get_pool_carriers(read). Required:country.coronium_get_pool_stock(read). Required: none.coronium_get_proxies(read, buyer, directory). Required: none.coronium_get_proxy(read, directory). Required:proxy.coronium_get_proxy_connection(read, buyer, directory). Required:modem_id.coronium_get_proxy_health(read, directory). Required: none.coronium_get_renewal_quote(read, buyer, directory). Required:modems.coronium_get_rotation_status(read, buyer, directory). Required:proxy.coronium_get_speed_test(read). Required:proxy.coronium_get_subscriptions(read). Required: none.coronium_get_ticket(read, directory). Required:ticket_id.coronium_get_usage(read). Required:proxy.coronium_get_webhook(read, directory). Required: none.coronium_list_countries(read, directory). Required: none.coronium_list_free_modems(read, buyer, directory). Required: none.coronium_list_pool_keys(write). Required: none.coronium_list_pool_sessions(read). Required: none.coronium_list_pool_tariffs(read). Required: none.coronium_list_saved_pool_sessions(read). Required: none.coronium_list_tariffs(read, buyer, directory). Required: none.coronium_list_tickets(read, directory). Required: none.coronium_login(opt-in, needs CORONIUM_ENABLE_LOGIN_TOOL=1). Required: none.coronium_logout(opt-in, needs CORONIUM_ENABLE_LOGIN_TOOL=1). Required: none.coronium_preview_modem_cancellation(read). Required:proxy.coronium_quote_purchase(read, buyer). Required:tariff_id,quantity.coronium_renew_modems_with_balance(spends money, needs CORONIUM_ENABLE_SPENDING=1, buyer). Required:modems,funding_source,expected_total_usd,confirm,idempotency_key.coronium_renew_modems_with_card(spends money, needs CORONIUM_ENABLE_SPENDING=1, buyer). Required:modems,card_id,expected_total_usd,confirm,idempotency_key.coronium_replace_modem(write, buyer, directory). Required:proxy,confirm.coronium_reply_to_ticket(write, directory). Required:ticket_id,message,confirm.coronium_restart_modem(write). Required:proxy,confirm.coronium_revoke_openvpn(write). Required:proxy,confirm.coronium_rotate_modem(write, buyer, directory). Required:proxy_identifier,confirm.coronium_rotate_webhook_secret(write). Required:confirm.coronium_save_pool_session(write). Required:pool_key_id,label,params.coronium_set_low_balance_threshold(write). Required:thresholds.coronium_set_modem_metadata(write). Required:proxy,metadata.coronium_set_modem_os(write). Required:proxy,os,confirm.coronium_set_rotation_interval(write). Required:proxy,interval_seconds,confirm.coronium_set_webhook(write). Required:webhook_url,confirm.coronium_set_white_list(write). Required:proxy,white_list,confirm.coronium_start_speed_test(write). Required:proxy,confirm.coronium_test_modem(write, buyer, directory). Required:proxy.coronium_test_webhook(write). Required:confirm.coronium_topup_pool_key(spends money, needs CORONIUM_ENABLE_SPENDING=1). Required:id,tariff_id,expected_total_usd,confirm,idempotency_key.
Develop and verify
npm ci
npm run check
npm run docs:check
npm run test:packageTests run against a loopback backend with synthetic credentials and a temporary home directory. test/fixtures/v3-routes.json lists the public /api/v3 routes (method, path, auth and field shapes only), and a test checks that every tool's routes exist in it. No test spends money, rotates a real proxy, sends a ticket or touches production. The optional npm run test:public makes four unauthenticated catalog reads against production and is not part of CI.
Publishing uses .github/workflows/publish.yml on a publish-v<version> tag or a manual run from main, with npm trusted publishing or an NPM_TOKEN secret. After the npm release, .github/workflows/mcp-registry.yml publishes server.json to the MCP Registry on a registry-v<version> tag, signing in with GitHub OIDC.
Acceptable use
Coronium proxies are for lawful purposes such as app and website QA, ad verification, localisation testing and monitoring public information. Follow Coronium's Terms (https://www.coronium.io/terms-and-conditions) and the terms of every site you reach through a proxy. Do not use this server or Coronium proxies to create fake or bulk accounts, evade bans or rate limits, bypass security controls, send spam or commit fraud.
Contact
hello@coronium.io for support and security reports. License: MIT.
Available Tools
48 toolscoronium_apply_modem_settingsAInspect
Re-apply / re-push a modem's port settings on the server (useful after a config change or if a proxy stops responding but the modem is online).
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_archive_ticketBInspect
Archive a ticket (closes it from the customer side).
| Name | Required | Description | Default |
|---|---|---|---|
| ticket_id | Yes |
coronium_build_pool_proxy_urlAInspect
Build a usable proxy URL (or URLs) for an active pool key. Returns host gw.proxies.sx + credentials. Optional protocol (http|socks5), count, and country targeting.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Pool key id | |
| count | No | How many URLs to generate | |
| country | No | ISO-2 country to target, if supported by the key | |
| protocol | No |
coronium_buy_modems_with_balanceAInspect
Buy one or more modems using account_credit (USD wallet balance). Specify a tariff_id and quantity. Optionally include a coupon. Modems are auto-assigned from free stock matching the tariff's country pool.
| Name | Required | Description | Default |
|---|---|---|---|
| coupon | No | ||
| quantity | No | ||
| tariff_id | Yes | Tariff _id from coronium_list_tariffs. | |
| country_code | No | ISO-2 to constrain the assigned modems. |
coronium_buy_pool_with_balanceAInspect
Buy a pay-per-GB pool key using account balance. Pass a pool tariff_id (from coronium_list_tariffs; pool tariffs have a traffic cap).
| Name | Required | Description | Default |
|---|---|---|---|
| tariff_id | Yes | A pool tariff id |
coronium_cancel_modemAInspect
Cancel a modem subscription (no further auto-renew). The modem remains usable until its current tariff_expired_at. Refund policy applies per terms.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_cancel_pool_keyCInspect
Cancel a pool key.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Pool key id |
coronium_change_proxy_passwordAInspect
Rotate the HTTP/SOCKS proxy password. Generates a new random password server-side and returns it.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_check_couponAInspect
Validate a coupon code. Returns the discount %, fixed-amount, or error if invalid/expired.
| Name | Required | Description | Default |
|---|---|---|---|
| code | Yes |
coronium_check_tokenAInspect
Verify the cached token is still valid. Returns true/false. Useful before a long agentic session — if invalid, call coronium_login or rely on auto-login.
| Name | Required | Description | Default |
|---|---|---|---|
| token | No | Optional explicit token to validate. Defaults to the cached one. |
coronium_close_pool_sessionAInspect
Close a pool session. Pass session_key to close one, or omit it to close ALL of my pool sessions.
| Name | Required | Description | Default |
|---|---|---|---|
| session_key | No | Session key to close; omit to close all |
coronium_create_ticketCInspect
Open a new support ticket.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | ||
| subject | Yes | ||
| priority | No | normal |
coronium_get_accountAInspect
Get account profile (email, role, contact, business data) and overall balance summary.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_balanceAInspect
Get the customer's spendable balance. Shows account_credit (USD wallet — what's actually used to pay for proxies) plus any held crypto balances valued in USD. Crypto prices cached 60s; not shown per row.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_credit_cardsAInspect
List saved credit cards on file (Stripe). Returns last-4 digits + brand only.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_crypto_balanceAInspect
List crypto deposit addresses + balances (BTC, USDT, etc). Use these addresses to top up — incoming transfers convert to account_credit at deposit time. Account_credit itself is excluded; use coronium_get_balance for that.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_low_balance_thresholdAInspect
Get the configured low-balance email alert tiers (USD amounts). When account_credit drops below a tier, an alert email is sent. Endpoint shipped 2026-04-30.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_openvpn_configAInspect
Get the OpenVPN config blob for a modem. Some modems offer VPN tunnel access in addition to HTTP/SOCKS proxy; this returns the .ovpn content.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_get_p0f_optionsAInspect
List the valid OS fingerprint (p0f) values accepted by coronium_set_modem_os for a modem. Call this first so you don't guess the OS string.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_get_paymentsAInspect
Get the full payment + invoice ledger for the account (for reconciliation / spotting duplicates or overpayments). Differs from coronium_get_payment_status, which checks a single payment.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_payment_statusAInspect
Check the status of a payment by id. Useful after coronium_buy_modems_with_balance / coronium_renew_modems_with_balance to confirm settlement.
| Name | Required | Description | Default |
|---|---|---|---|
| payment_id | Yes |
coronium_get_pool_stockAInspect
Pool Gateway (pay-per-GB): live pool stock availability. Returns 503 if the pool tier is not enabled on this deployment.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_proxiesAInspect
List the user's mobile proxies. Returns one line per proxy with name, host:port, login, expiry, country.
| Name | Required | Description | Default |
|---|---|---|---|
| online_only | No | Only return modems currently online. | |
| country_code | No | ISO-2 filter, e.g. PL, US. | |
| expiring_within_days | No | Only return modems whose tariff expires within N days. |
coronium_get_proxyAInspect
Get full details for a single proxy by id or name. Includes credentials, expiry, external IP, rotation interval.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_get_proxy_healthAInspect
Liveness/health snapshot for all your proxies (per-modem reachability + recommendation). Call this before retrying through a proxy — stop hammering dead modems; swap them with coronium_replace_modem.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_get_rotation_statusAInspect
Poll rotation status for a modem. Returns idle | rotating | success | failed plus the current and previous external IPs. Backend stuck-rotation janitor (deployed 2026-04-30) auto-clears stale 'rotating' states within 5 min.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_get_ticketAInspect
Get full ticket detail including all replies.
| Name | Required | Description | Default |
|---|---|---|---|
| ticket_id | Yes |
coronium_get_webhookAInspect
Get the account's modem-lifecycle webhook URL (fires when a dead modem is auto-swapped). null = disabled (notifications via email).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_list_countriesAInspect
List countries that have stock available. Returns ISO-2 + display name + count of free modems.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_list_free_modemsAInspect
List free (purchasable) modems available right now. Useful before buying — confirms the country/tariff combination has live stock.
| Name | Required | Description | Default |
|---|---|---|---|
| country_code | No |
coronium_list_pool_keysAInspect
List my pay-per-GB pool keys (status, traffic remaining, tariff). Use coronium_build_pool_proxy_url to get a usable proxy URL for an active key.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_list_pool_sessionsAInspect
List my currently-open sticky pool sessions.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_list_tariffsAInspect
List available tariffs (price plans). Each entry has duration, price, supported countries, included GB. Use coronium_check_coupon before buying for coupon validation.
| Name | Required | Description | Default |
|---|---|---|---|
| country_code | No | Filter to tariffs offered in this country. |
coronium_list_ticketsBInspect
List the customer's support tickets. Returns id, subject, status, last update.
| Name | Required | Description | Default |
|---|---|---|---|
| status | No | open |
coronium_loginAInspect
Authenticate with email + password and cache an encrypted token at ~/.coronium/token.enc. Most other tools auto-login when CORONIUM_LOGIN/CORONIUM_PASSWORD are set in the env, so calling this manually is only needed for explicit re-auth or account switching.
| Name | Required | Description | Default |
|---|---|---|---|
| login | No | Coronium account email. Falls back to CORONIUM_LOGIN env. | |
| password | No | Coronium account password. Falls back to CORONIUM_PASSWORD env. |
coronium_logoutAInspect
Clear the cached token from ~/.coronium/token.enc. Subsequent calls will require re-authentication (manual or auto-login).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
coronium_renew_modems_with_balanceAInspect
Renew one or more existing modems for an additional tariff period using account_credit.
| Name | Required | Description | Default |
|---|---|---|---|
| coupon | No | ||
| modem_ids | Yes | Array of modem _id values. | |
| tariff_id | Yes | Tariff _id to renew under (typically the existing one). |
coronium_replace_modemAInspect
Swap a broken/dead modem for a working one of the same country/tariff. Used when a modem has consecutive ping failures or won't rotate. Subscription transfers — you keep the same expiry. Requires existing-customer auth.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). | |
| same_country | No | If true, refuse the swap unless replacement stock exists in the same country. |
coronium_reply_to_ticketCInspect
Add a reply to an existing ticket.
| Name | Required | Description | Default |
|---|---|---|---|
| message | Yes | ||
| ticket_id | Yes |
coronium_restart_modemAInspect
Trigger a rotation (new IP) on the customer's modem via authenticated /v3 endpoint. Idempotent in-flight: if a rotation is already pending, returns its status. Use coronium_get_rotation_status to poll.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_rotate_modemBInspect
Token-based rotation via the public reset service (default https://mreset.xyz). Doesn't require an API token — uses the per-modem rotation token embedded in the proxy record. Optionally polls until completion.
| Name | Required | Description | Default |
|---|---|---|---|
| max_wait_time | No | ||
| proxy_identifier | Yes | Modem name, portId, _id, or rotation token (UUID). | |
| wait_for_completion | No |
coronium_set_low_balance_thresholdAInspect
Set low-balance email alert tiers. The backend currently allows exactly these tier values: 100, 300, 500 (USD). Pass any subset — e.g. [100], [100,300], [100,300,500]. Email is sent when account_credit dips below each tier independently.
| Name | Required | Description | Default |
|---|---|---|---|
| thresholds | Yes | Subset of [100, 300, 500]. Empty array clears all tiers (turns off alerts). |
coronium_set_modem_metadataAInspect
Set a free-form metadata note on a modem (e.g. 'production-fb-account-X'). Visible only to the owner; useful for tagging proxies in agent workflows.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). | |
| metadata | Yes | Free-form string, ≤200 chars. |
coronium_set_modem_osAInspect
Set the p0f OS fingerprint preset (Android / iOS / Windows / etc) the modem should advertise. Useful when the destination platform fingerprints clients.
| Name | Required | Description | Default |
|---|---|---|---|
| os | Yes | Preset name. Common: 'android', 'ios', 'windows', 'linux', 'macos', 'auto', or 'off'. | |
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_set_rotation_intervalAInspect
Configure auto-rotation cadence (in seconds). 0 disables auto-rotate. Typical values: 60 (1 min), 300 (5 min), 1800 (30 min). Backend Rotator service polls and triggers per this interval.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). | |
| interval_seconds | Yes | Seconds between auto-rotations. 0 = manual only. |
coronium_set_webhookAInspect
Set or clear the modem-lifecycle webhook. When set, a dead modem is auto-swapped and your HTTPS endpoint receives a JSON POST with old_modem_id + new_modem_id. Pass null/empty to disable.
| Name | Required | Description | Default |
|---|---|---|---|
| webhook_url | No | HTTPS URL (≤500 chars), or null/empty to disable |
coronium_test_modemAInspect
Test connectivity through a proxy. Sends a request through the modem's HTTP/SOCKS endpoint and returns the observed external IP plus latency.
| Name | Required | Description | Default |
|---|---|---|---|
| proxy | Yes | Modem _id (24-char hex) or portId/name (e.g. cor_PL_181fd3aa). |
coronium_topup_pool_keyAInspect
Top up (add traffic/credit to) an existing pool key.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | Pool key id |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
48 tool updates
v1.3.0- First observed
coronium_apply_modem_settings - First observed
coronium_archive_ticket - First observed
coronium_build_pool_proxy_url - First observed
coronium_buy_modems_with_balance - First observed
coronium_buy_pool_with_balance - First observed
coronium_cancel_modem - First observed
coronium_cancel_pool_key - First observed
coronium_change_proxy_password - First observed
coronium_check_coupon - First observed
coronium_check_token - First observed
coronium_close_pool_session - First observed
coronium_create_ticket - First observed
coronium_get_account - First observed
coronium_get_balance - First observed
coronium_get_credit_cards - First observed
coronium_get_crypto_balance - First observed
coronium_get_low_balance_threshold - First observed
coronium_get_openvpn_config - First observed
coronium_get_p0f_options - First observed
coronium_get_payment_status - First observed
coronium_get_payments - First observed
coronium_get_pool_stock - First observed
coronium_get_proxies - First observed
coronium_get_proxy - First observed
coronium_get_proxy_health - First observed
coronium_get_rotation_status - First observed
coronium_get_ticket - First observed
coronium_get_webhook - First observed
coronium_list_countries - First observed
coronium_list_free_modems - First observed
coronium_list_pool_keys - First observed
coronium_list_pool_sessions - First observed
coronium_list_tariffs - First observed
coronium_list_tickets - First observed
coronium_login - First observed
coronium_logout - First observed
coronium_renew_modems_with_balance - First observed
coronium_replace_modem - First observed
coronium_reply_to_ticket - First observed
coronium_restart_modem - First observed
coronium_rotate_modem - First observed
coronium_set_low_balance_threshold - First observed
coronium_set_modem_metadata - First observed
coronium_set_modem_os - First observed
coronium_set_rotation_interval - First observed
coronium_set_webhook - First observed
coronium_test_modem - First observed
coronium_topup_pool_key
TDQS
Scored across 48 tools
Most tools have clearly distinct purposes, but a few pairs like restart_modem vs rotate_modem and list_pool_sessions vs list_pool_keys could be confused without reading descriptions. The consistent resource-oriented naming helps overall, but the large number of overlapping lifecycle actions creates minor ambiguity.
All tools follow a strict coronium_<verb>_<noun> pattern, with predictable verbs like list, get, set, create, cancel, and buy. This consistency makes it easy to guess tool behavior and reduces cognitive load despite the large count.
At 48 tools, this server is far beyond the typical well-scoped count of 3-15, and even exceeds the 25+ threshold for 'too many.' While the API serves a broad domain, the sheer number of tools imposes a heavy selection burden on agents and suggests the surface could be consolidated or split into separate servers.
The tool set covers the full lifecycle for modems, proxies, pool keys, account management, payments, webhooks, and support tickets. Operations like buy, renew, cancel, rotate, test, replace, and health checks are all present, with no obvious missing features or dead ends.
Related MCP Connectors
Control dedicated 4G mobile and residential proxies on mobileproxy.space from AI agents.
Residential and mobile proxies and Private modems for AI agents: proxy URLs, stock, rotation, top-up
Create and manage residential and mobile proxies: geo targeting, usage limits, spend reports.
Give AI agents real phone numbers, messages, and voice calls via MCP.
Related MCP Servers
- AlicenseAqualityBmaintenanceEnables AI agents to autonomously buy and operate mobile proxies via MCP, supporting both API key and on-chain USDC payments for tasks like port creation, IP rotation, and traffic management.44555 npmMIT
- FlicenseAqualityDmaintenanceMCP server that wraps the Proxyline proxy provider API, exposing all methods as MCP tools for AI assistants. Enables managing proxies, orders, countries, IPs, balance, and tags through natural language.114 npm-
- AlicenseAqualityBmaintenanceMCP server that gives Claude and other agents direct control over mobile proxies, enabling proxy management and rotation tasks.28115 npmMIT
- AlicenseNot gradedqualityAmaintenanceConnects MCP-compatible AI agents to an anti-detection browser backend, enabling web navigation, interaction, search, extraction, downloads, and session reuse across multi-tab workflows.899 npmMIT