The carrier CLI
Your entire eSIM fleet from the terminal. 40+ deterministic commands across six domains, a natural-language fallback, MCP stdio mode, and a white-label storefront scaffold — all in one binary.
Install
The CLI ships inside the @carrierllc/mcp npm package and installs two binaries: carrier (the CLI) and carrier-mcp (the stdio MCP server). Node 22+ required for the npm paths.
Homebrew (macOS / Linux)
brew tap Lifecycle-Innovations-Limited/carrier
brew trust --tap Lifecycle-Innovations-Limited/carrier # Homebrew 5+ requires trusting third-party taps
brew install carrier
carrier --versionnpm (global)
npm i -g @carrierllc/mcp
carrier --versionnpx (no install)
npx -y -p @carrierllc/mcp carrier-mcpUpgrading: brew update && brew upgrade carrier or npm i -g @carrierllc/mcp@latest.
Authentication
Two modes. Interactive use needs no credentials at all; headless use takes an API key from the environment.
- 01OAuth on first use (interactive).
carrier plugin installregisters the zero-credential MCP URLhttps://mcp.carrier.llc/mcpin Claude Code. The first tool call opens Clerk sign-in / sign-up in your browser (Google, GitHub, or email). No token to paste. Stuck?claude mcp auth carrier. - 02API key (headless / CI). The fleet commands and
carrier askcall the remote MCP directly and read a bearer credential from the environment, in this order:CARRIER_API_KEY,CARRIER_ORG_API_KEY,ESIMVAULT_API_TOKEN,CARRIER_OCS_API_TOKEN.
Headless setup
# Console → Settings → API Keys (keys start with ak_)
export CARRIER_API_KEY=ak_...
carrier ask "show fleet health"
carrier subscribers list --account-id 123 --jsonCore commands
carrierInteractive home: status, plugin + MCP install, optional storefront scaffold.
carrier init [--dir <path>] [--yes] [--full]Guided setup. --yes uses Carrier defaults with no prompts (plugin + scaffold + build); --full runs the classic plugin + storefront wizard.
carrier statusMCP / plugin / auth status with concrete next steps.
carrier plugin installInstall the Carrier Claude Code plugin and register the zero-cred MCP (OAuth on first use).
carrier plugin statusPlugin + MCP registration state and auth next steps.
carrier open <signup|signin|console|onboarding|mcp>Open Carrier account and product URLs in your browser.
carrier examplesNatural-language fleet prompts for Claude, plus the full domain command map.
carrier ask "<intent>"Natural-language fallback for anything the discrete commands miss. Needs CARRIER_API_KEY or an OCS token.
carrier --version / --helpVersion and help. Every subcommand also accepts --help.
Fleet commands
Every capability is a discrete command, grouped by the same domains the Console uses. Each one calls a single MCP tool with the exact same argument shapes — CLI, Console and MCP stay in lockstep.
--json— raw tool response on stdout, ready forjq; diagnostics go to stderr.--commit— write commands run as a dry run by default. Nothing changes until you re-run with--commit.- Usage windows (
--start/--end) are clamped to 7 days — OCS rejects wider windows. Omit both for the last 7 days.
carrier subscribers
Look up, inspect and change subscribers.carrier subscribers list [--account-id --iccid --msisdn --imsi --status --limit --offset]List subscribers. OCS needs at least one of account / iccid / msisdn / imsi.
carrier subscribers get [--iccid | --msisdn] [--gz-counter]Full record for one subscriber.
carrier subscribers location --iccid <iccid>Last-known location from the most recent cell tower usage.
carrier subscribers usage --iccid <iccid> [--start --end]Daily data, voice and SMS usage over a window of up to 7 days (defaults to the last 7).
carrier subscribers events --iccid <iccid> [--start --end]Network attach/detach events over a window of up to 7 days.
carrier subscribers active-period --iccid <iccid>First and last usage dates for one subscriber.
carrier subscribers esim-status [--account-id --reseller-id]eSIM state counts per account: active, suspended, inventory.
carrier subscribers set-status --iccid <iccid> --status <status>Change a subscriber's status (e.g. ACTIVE, SUSPENDED).
carrier subscribers set-balance --iccid <iccid> --amount <n> --mode <adapt|set>Add to or replace a subscriber's balance.
carrier packages
Packages assigned to a subscriber.carrier packages list --iccid <iccid>Packages on one subscriber, with allowance and expiry.
carrier packages assign --template-id <id> [--iccid | --account-id]Assign a one-time package from a template. --account-id auto-picks a free eSIM.
carrier packages set-status --iccid <iccid> --package-id <id> --status <status>Activate or deactivate one package without deleting it.
carrier packages set-expiry --iccid <iccid> --package-id <id> [--expires <date> | --validity-days <n>]Move a package's expiry date.
carrier packages set-limits --iccid <iccid> --package-id <id> --limits <json>Change data, voice or SMS ceilings on an assigned package.
carrier packages delete --iccid <iccid> --package-id <id>Permanently remove one package from a subscriber.
carrier templates
The package template catalog.carrier templates list [--account-id]Browse package templates available for assignment.
carrier templates create --template <json>Create a package template from a JSON configuration.
carrier templates set-core --template-id <id> --changes <json>Change name, limits, price, validity or zone on a template.
carrier templates set-recurring --template-id <id> --changes <json>Change auto-renewal settings on a template.
carrier templates set-throttling --template-id <id> --changes <json>Change throttling thresholds. Applies to existing packages too.
carrier zones
Location zones and destination lists.carrier zones list [--reseller-id]Location zones with countries and operators (preferred over elements).
carrier zones elements [--zone-id]Raw zone elements. Upstream OCS returns malformed rows for some zones.
carrier zones create --zone <json>Create a location zone from a JSON configuration.
carrier zones destinations [--reseller-id]Destination list catalog for voice and SMS packages.
carrier zones prefixes [--destination-list-id]Dialling prefixes inside one destination list.
carrier steering
Network steering lists and operator preference.carrier steering list [--reseller-id]Steering lists configured for this reseller.
carrier steering assign --iccid <iccid> --list-id <id>Assign a steering list to a subscriber. Follow with push.
carrier steering push --iccid <iccid>Push the assigned operator preference list to the device now.
carrier intelligence
Composite reports over the fleet.carrier intelligence fleet-health [--account-id]eSIM counts, low-balance accounts and what needs attention.
carrier intelligence diagnose --iccid <iccid>Why one subscriber is offline, throttled or failing to attach.
carrier intelligence anomalies --iccid <iccid>Usage spikes and burn rates that exhaust the package early.
carrier intelligence churn --iccid <iccid>Churn risk score with contributing factors.
carrier intelligence optimize --iccid <iccid>Better-fitting package for one subscriber, with the saving.
carrier intelligence coverage [--account-id --limit]Networks subscribers actually attach to, against your steering lists.
carrier intelligence high-cost [--account-id --limit --threshold-pct]Subscribers whose consumption erodes the margin.
carrier intelligence marketing [--account-id]Where subscribers and revenue concentrate, and which markets grow.
carrier intelligence country-entry --iccid <iccid> [--expected-country <iso2>]Country a subscriber is in now, optionally diffed against the last known one.
Examples
# Read: fleet overview, one subscriber, usage
carrier intelligence fleet-health
carrier subscribers get --iccid 8944500000000000000
carrier subscribers usage --iccid 8944500000000000000 --start 2026-08-10 --end 2026-08-17
# Pipe JSON into jq
carrier subscribers list --account-id 123 --json | jq '.[].iccid'
# Write: always previews first, then --commit applies
carrier subscribers set-status --iccid 8944500000000000000 --status SUSPENDED
carrier subscribers set-status --iccid 8944500000000000000 --status SUSPENDED --commit
# Anything the commands miss, in plain words
carrier ask "which subscribers in account 123 are close to their data limit?"White-label storefront
Scaffold a fully branded eSIM storefront (Next.js, from the Mango template), preview it locally, and deploy it to Cloudflare Workers — three commands.
carrier site create [dir] [--name --domain --accent --yes]Scaffold a white-labeled eSIM storefront from the Mango template, with brand config and generated logo.
carrier site deploy [dir] [--name <worker>]Install deps, build, and deploy the storefront to Cloudflare Workers (needs wrangler login).
carrier site logo [dir]Regenerate the storefront logo — SVG always; PNG when an image key is available.
End to end
carrier site create ./my-storefront --name "Nomad Mobile" --accent "#ff5a1f"
cd my-storefront && pnpm install && pnpm dev # local preview
carrier site deploy ./my-storefront # build + deploy (npx wrangler login first)Re-brand anytime by editing src/brand.config.ts in the scaffolded project.
MCP stdio mode
The same package ships carrier-mcp, a local stdio MCP server for Claude Desktop, Cursor, Windsurf and any MCP-compatible client. Your OCS token stays on your machine — no outbound auth call to Carrier.
Run directly
ESIMVAULT_API_TOKEN=<your-token> npx -y -p @carrierllc/mcp carrier-mcpClaude Desktop / Cursor / Windsurf — mcp.json
{
"mcpServers": {
"carrier": {
"command": "npx",
"args": ["-y", "-p", "@carrierllc/mcp", "carrier-mcp"],
"env": { "ESIMVAULT_API_TOKEN": "<your-token>" }
}
}
}Prefer the hosted server? (zero-cred, OAuth on first use)
claude mcp add --transport http carrier https://mcp.carrier.llc/mcpFull tool reference: API Reference · MCP Server architecture
Troubleshooting
“No headless token in the environment”
Fleet commands and carrier ask need a credential. Export CARRIER_API_KEY=ak_… (Console → Settings → API Keys), or use the interactive Claude path where OAuth runs on first use.
MCP returns 401 / 403
The key was rejected. Confirm it is a valid org key from app.carrier.llc, and that OCS onboarding is complete (carrier open onboarding).
brew install fails on a pre-release macOS
If Homebrew reports Xcode as outdated, fall back to npm i -g @carrierllc/mcp. Also make sure you ran brew trust --tap Lifecycle-Innovations-Limited/carrier — Homebrew 5+ refuses untrusted third-party formulae.
`claude` CLI not on PATH during plugin install
The plugin files are still copied; finish wiring manually: claude mcp add --transport http carrier https://mcp.carrier.llc/mcp.
A write command did nothing
By design. Write commands preview as a dry run; add --commit to apply the change.
Usage window rejected
OCS caps usage queries at 7 days. The CLI clamps wider windows and tells you when it moved the start date.