Pi Coding Agent Mobile Proxy Setup
Give the Pi coding agent the Coronium MCP server through its mcp.json, and have the scripts it writes leave through a carrier line.
Pi is a minimal terminal coding agent you extend with packages, skills and prompt templates. It now reads MCP servers natively, so the Coronium server drops in as one entry, and its shell tool can send any script through a line.
Checked against the Pi documentation on 30 October 2026. Sources are listed at the end.
{
"mcpServers": {
"coronium": {
"command": "npx",
"args": ["-y", "coronium-proxy-mcp@2.3.0"],
"env": {
"CORONIUM_API_TOKEN": "${CORONIUM_API_TOKEN}",
"CORONIUM_TOOL_PROFILE": "directory"
},
"timeout": 200
}
}
}Before you start
Pi installed
With
npm install -g --ignore-scripts @earendil-works/pi-coding-agentor the install script on pi.dev. Pi needs Node 22.19 or newer, which also covers the Coronium server.The token in your environment
Create it in dashboard.coronium.io, Account, API Access and export
CORONIUM_API_TOKENin your shell profile. Pi expands${NAME}references inenv, so the config file holds a reference, not the token.A line, for scripts
The MCP tools work without one. Sending the scripts Pi writes through a carrier IP needs a line and its HTTP or SOCKS5 details.
What the agent gets
The Coronium MCP server is coronium-proxy-mcp on npm. The environment variable CORONIUM_TOOL_PROFILE decides which tools exist inside Pi. Counts below were read with tools/list on the current release.
| Profile | Tools | Money tools | Use it for |
|---|---|---|---|
| directory | 21 | None | An agent that checks, tests and rotates lines you already rent. The hosted server runs this profile. |
| read-only | 31 | None | Reporting: balances, lines, usage, payments and tickets, with nothing that changes state. |
| buyer | 12, or 13 with CORONIUM_ENABLE_SPENDING=1 | Buy only, and only with spending on | An agent that quotes, buys and runs a few lines after you approve each total. |
| full | 59, plus 6 money tools with spending on | Buy, renew, top up and cancel, only with spending on | Everything else: settings, webhooks, rotation timers and Node tools. The server default when the profile is unset. |
- directory
- Tools: 21
- Money tools: None
- An agent that checks, tests and rotates lines you already rent. The hosted server runs this profile.
- read-only
- Tools: 31
- Money tools: None
- Reporting: balances, lines, usage, payments and tickets, with nothing that changes state.
- buyer
- Tools: 12, or 13 with CORONIUM_ENABLE_SPENDING=1
- Money tools: Buy only, and only with spending on
- An agent that quotes, buys and runs a few lines after you approve each total.
- full
- Tools: 59, plus 6 money tools with spending on
- Money tools: Buy, renew, top up and cancel, only with spending on
- Everything else: settings, webhooks, rotation timers and Node tools. The server default when the profile is unset.
Start with directory. Its tools include coronium_list_free_modems, coronium_list_tariffs, coronium_get_proxies, coronium_test_modem, coronium_rotate_modem, coronium_get_rotation_status, coronium_replace_modem and coronium_get_renewal_quote. Names can change between releases, so let the agent read them from tools/list rather than from this page.
Add the Coronium server to Pi
Pi reads servers from ~/.pi/agent/mcp.json for your user and from .pi/mcp.json for a project. Use the user file for anything that carries a token.
Write the entry
Save the block at the top of this page as
~/.pi/agent/mcp.json, or merge it into the file if you already have servers. Stdio servers takecommand,args,envandcwd;commandis one executable, not a shell string.Checked against Pi docs: MCP
Or let Pi write it
pi mcp addwrites to the user file by default (-lwrites the project file) and accepts--envwith a${NAME}reference. Check the result in the file afterwards and add the profile and timeout if they are missing.Terminal pi mcp add coronium --env CORONIUM_API_TOKEN='${CORONIUM_API_TOKEN}' -- npx -y coronium-proxy-mcp@2.3.0Checked against Pi docs: MCP
Raise the timeout
Pi gives each MCP request 60 seconds unless an entry says otherwise. A rotation waits for the carrier, so set
"timeout": 200on the coronium entry.Checked against Pi docs: MCP
List and reload
pi mcp listconnects to every enabled server and prints its state, tools and errors, and exits with an error code if one is not connected. In a running session,/reloadpicks up the change and/mcpshows servers and tools.Terminal pi mcp listChecked against Pi docs: MCP
Or connect the hosted server
A remote server that uses OAuth needs only its URL in Pi. Add
"coronium-remote": { "url": "https://api.coronium.io/mcp" }undermcpServers, runpi mcp login coronium-remote, and sign in with your Coronium account. Pi stores the tokens in~/.pi/agent/mcp-auth.jsonand refreshes them.Checked against Pi docs: MCP
First tasks to try
Ask in plain words. The agent picks the tools; the names below are what it should call, so you can tell from its log whether it did.
โWhich countries have Coronium lines in stock right now, and what does 24 hours cost in each?โ
Calls
coronium_list_free_modemsthencoronium_list_tariffs. Reads live stock and plans. Nothing is bought.โShow my Coronium lines with their country, carrier, expiry and SOCKS5 URL.โ
Calls
coronium_get_proxies. Returns credentials. Treat the answer as a secret and keep it out of shared chats.โRotate my line called <name> and tell me the new IP once the rotation has finished.โ
Calls
coronium_rotate_modemthencoronium_get_rotation_status. A rotation answers done, rotating (poll the status, do not resubmit) or unchanged (the carrier kept the IP; wait about 60 seconds).
Rotation from a coding session
Inside a chat, ask Pi to rotate a line and it uses the MCP tools. Inside code it writes, the REST API does the same job with the same token, and that is what a scraper or test should call: rotate, then poll the status until it settles.
Leave at least 60 seconds between rotations of one line. A script that rotates per request gets refusals; rotate per batch, per account or per test run.
curl -s -X POST -H "Authorization: Bearer $CORONIUM_API_TOKEN" https://api.coronium.io/api/v3/modems/MODEM_ID/restart
curl -s -H "Authorization: Bearer $CORONIUM_API_TOKEN" https://api.coronium.io/api/v3/modems/MODEM_ID/rotation-statusScripts Pi writes, through the line
Pi works mostly through its shell tool, so the line belongs in the environment those commands run in. Export the line's details once, then any curl or Python script can read them. The first curl uses the HTTP port; the second uses SOCKS5 with --socks5-hostname, which sends the hostname to the line so DNS is resolved there.
Requests needs the extra requests[socks] package for SOCKS5, and its docs explain that socks5:// resolves names on your machine while socks5h:// resolves them on the proxy. The same docs warn that a password in an environment variable is a risk on a shared machine; there, read it from your secret store instead.
export CORONIUM_PROXY_HOST="CONNECTION_IP"
export CORONIUM_HTTP_PORT="HTTP_PORT"
export CORONIUM_SOCKS_PORT="SOCKS5_PORT"
export CORONIUM_PROXY_USER="USERNAME"
export CORONIUM_PROXY_PASS="PASSWORD"
curl -x "http://$CORONIUM_PROXY_USER:$CORONIUM_PROXY_PASS@$CORONIUM_PROXY_HOST:$CORONIUM_HTTP_PORT" https://api.ipify.org
curl --socks5-hostname "$CORONIUM_PROXY_USER:$CORONIUM_PROXY_PASS@$CORONIUM_PROXY_HOST:$CORONIUM_SOCKS_PORT" https://api.ipify.org
import os
import requests
line = "http://{}:{}@{}:{}".format(
os.environ["CORONIUM_PROXY_USER"], os.environ["CORONIUM_PROXY_PASS"],
os.environ["CORONIUM_PROXY_HOST"], os.environ["CORONIUM_HTTP_PORT"],
)
proxies = {"http": line, "https": line}
print(requests.get("https://api.ipify.org", proxies=proxies, timeout=30).text)
# SOCKS5: pip install "requests[socks]", then use socks5h:// so DNS
# is resolved through the line, not on this machine.Money tools stay off
Pi runs tools with the permissions of the Pi process, so the safest profile is the one that has nothing to spend with.
- Money tools appear only when
CORONIUM_ENABLE_SPENDING=1is set in the host environment and the profile isbuyer(buy only) orfull. A.envfile in the working directory cannot turn it on. - Every money call needs
confirm: true, a new idempotency key for each approved order, an explicit funding source and the exact approved total; any other live total is refused withprice_changed. - The server spends money already on the account. It has no way to add funds; a person does that in the dashboard.
Hardening the setup
Pi reads a project's .pi/mcp.json only after you grant that project trust, and a project entry with the same name replaces your user entry. Keep the Coronium entry in the user file, so a repository you clone cannot swap in its own server under the same name without you noticing.
- Create the API token in dashboard.coronium.io, Account, API Access and keep it in the host's config, never in a chat or a repository. Regenerating it in the dashboard revokes the old one.
- Give each agent its own line. Two agents on one line rotate each other's IP in the middle of a task.
- The answer to
coronium_get_proxiescontains proxy passwords. Treat it, the Reset Link and any OpenVPN profile as secrets. coronium_replace_modemis irreversible: the line gets a new device, new credentials and possibly a new carrier. Filter it out if the agent should never do that on its own.
Check it worked
Run the two curl commands from the scripts section: each prints the address the line gives you. Then open these pages in a browser that uses the same line.
- The IP and the carrier
- Open What Is My IP through the line. The country should be the line's country and the network should be the mobile carrier, not a hosting company.
- WebRTC
- Run the WebRTC leak test. The only public address it should report is the line's. Your own address showing up means the browser is leaking around the proxy.
- Timezone against the IP
- The IP and timezone check compares the clock the browser reports with the timezone of the IP. A mismatch is one of the first things anti-fraud systems look at.
From a terminal the agent can use, the same check is one request. Export the line's details once, then ask an IP echo service which address it sees:
export CORONIUM_PROXY_HOST="CONNECTION_IP"
export CORONIUM_HTTP_PORT="HTTP_PORT"
export CORONIUM_SOCKS_PORT="SOCKS5_PORT"
export CORONIUM_PROXY_USER="USERNAME"
export CORONIUM_PROXY_PASS="PASSWORD"
curl -x "http://$CORONIUM_PROXY_USER:$CORONIUM_PROXY_PASS@$CORONIUM_PROXY_HOST:$CORONIUM_HTTP_PORT" https://api.ipify.orgWhen it does not connect
| What you see | Likely cause | What to do |
|---|---|---|
pi mcp list shows coronium as not connected | The token reference is empty, npx is missing, or the JSON has a typo. | Check that CORONIUM_API_TOKEN is exported in the shell that starts Pi, then run pi mcp list again for the error text. |
| Rotation calls time out | The entry uses Pi's default 60-second request timeout. | Add "timeout": 200 to the entry and /reload. |
| curl returns a 407 error | Wrong username or password, or a port that does not match the scheme. | Copy the login again; use the HTTP Port with -x http:// and the SOCKS5 Port with --socks5-hostname. |
| The proxy URL breaks on the password | A password with characters such as @ or : was put into a URL as it is. | URL-encode the password in proxy URLs, or pass it separately where the client allows it. |
| Python fails on a socks5h URL | The SOCKS extra for Requests is not installed. | Run pip install "requests[socks]", or use the HTTP port instead. |
pi mcp listshows coronium as not connected- The token reference is empty,
npxis missing, or the JSON has a typo. - Check that
CORONIUM_API_TOKENis exported in the shell that starts Pi, then runpi mcp listagain for the error text. - Rotation calls time out
- The entry uses Pi's default 60-second request timeout.
- Add
"timeout": 200to the entry and/reload. - curl returns a 407 error
- Wrong username or password, or a port that does not match the scheme.
- Copy the login again; use the HTTP Port with
-x http://and the SOCKS5 Port with--socks5-hostname. - The proxy URL breaks on the password
- A password with characters such as
@or:was put into a URL as it is. - URL-encode the password in proxy URLs, or pass it separately where the client allows it.
- Python fails on a socks5h URL
- The SOCKS extra for Requests is not installed.
- Run
pip install "requests[socks]", or use the HTTP port instead.
Questions
Does the Pi coding agent support MCP?
Yes. Pi reads MCP servers from ~/.pi/agent/mcp.json and from a project's .pi/mcp.json, manages them with pi mcp add, list, remove, login and logout, and shows them in a session with /mcp.
How do I keep the API token out of mcp.json?
Write "${CORONIUM_API_TOKEN}" as the value in the env block and export the variable in your shell. Pi expands the reference when it starts the server. A value can also run a command with a leading exclamation mark, for example to read from a password manager.
Should the Coronium entry go in the user or the project config?
The user config, ~/.pi/agent/mcp.json. Pi reads a project file only after you trust the project, and a project entry with the same name replaces the user entry, so tokens and trusted servers belong at user level.
Can scripts Pi writes rotate the line?
Yes, through the REST API with the same token: POST /api/v3/modems/{id}/restart, then poll /rotation-status. Leave at least 60 seconds between rotations of one line.
SOCKS5 or HTTP for scripts?
Either. For SOCKS5, make sure DNS goes through the line: curl --socks5-hostname, or socks5h:// in Python Requests. With the HTTP port the proxy resolves hostnames by design.
How we checked
Every Pi config key, command and flag on this page was read from the pages below on 30 October 2026. The Coronium side comes from the dashboard and the live API. There are no screenshots: we quote the names instead of showing an account we do not run. If a label in Pi has moved since, the tool's own page is the one to trust.
- Pi on GitHubThe npm package, the install methods and the Node 22.19 requirement.
- Pi docs: MCPUser and project mcp.json, the mcpServers shape, ${NAME} references and command values, the 60-second default timeout, pi mcp add, list and login, /reload, /mcp, OAuth and mcp-auth.json, project trust.
- Requests: Proxies and SOCKSThe proxies argument, user and password in proxy URLs, requests[socks], socks5 against socks5h, and the warning about passwords in environment variables.
- curl manual: --socks5-hostnameSOCKS5 with the hostname resolved by the proxy.
- coronium-proxy-mcp on npmPackage and version; tool names read with tools/list on the current release on 30 October 2026.