ThunderPhone 2.0 is live.Self-serve, from 2¢/min.Read the announcement

Getting Started

ThunderPhone CLI

Log in, manage voice agents and calls, configure MCP clients, and scaffold projects from the terminal.

The CLI requires Node.js 18.18 or later. Run it with npx, or install it globally:

npm install -g thunderphone
thunderphone --help

Log in

npx thunderphone login
thunderphone whoami --json

Login prints a verification code, opens the browser, and waits for authorization. Use --no-browser on a headless machine and open the printed URL elsewhere. Device login requires the API's OAuth device-flow rollout. An organization API key in THUNDERPHONE_API_KEY can also authenticate commands and takes precedence over stored login credentials.

Credentials are stored by profile in ~/.config/thunderphone/credentials.json with file mode 0600. XDG_CONFIG_HOME and THUNDERPHONE_CONFIG_DIR override the directory. Access tokens refresh automatically and rotating refresh tokens are saved atomically. Tokens are never printed by login.

thunderphone login --profile work
thunderphone agents list --profile work --json
thunderphone logout --profile work

THUNDERPHONE_PROFILE sets the default profile. Logout removes local credentials; it does not revoke the server grant. The default API is https://api.thunderphone.com. Use --api-base-url or THUNDERPHONE_API_BASE_URL for another API. A profile's token cannot be sent to a different configured API URL; log into that URL with a separate profile.

Commands

Every command accepts --json. Successful data goes to stdout; errors go to stderr with a nonzero exit code. Without --json, output is a compact table or field list. JSON retains the API response structure, with credential fields redacted. MCP serving reserves stdout for the MCP protocol.

CommandPurpose
login [--no-browser] [--scope "scopes"]Authorize through a device code
logout, whoamiRemove local credentials; list accessible organizations
agents list, agents get IDRead agents
agents create --file agent.jsonCreate an agent
agents update ID --file agent.jsonSave an agent draft
agents deploy ID, agents delete IDDeploy the draft; delete an agent
numbers listRead phone numbers
numbers provision --country US --area-code 415Provision a US inbound number
numbers assign NUMBER_ID --agent IDAssign an inbound agent
call TO --agent ID --from FROM [--wait]Place an outbound call; optionally wait for its transcript
calls list [--limit N] [--agent ID]List calls (limit 1–200)
calls get ID, calls transcript IDRead one call or its transcript
test run AGENT_ID [--scenario ID] --consent-to-chargeRun billable saved scenarios using the web channel
test status RUN_ID [--agent ID]Inspect a batch, with scenario details when an agent is supplied
import VENDOR export.jsonPrepare a vendor JSON import for review
imports get UUID, imports commit UUIDInspect an import; commit selected agents after review
mcp setup, mcp serveConfigure a client; start the stdio bridge
init [directory]Scaffold a project

Outbound calls require a connected carrier number. THUNDERPHONE_FROM_NUMBER can supply --from. ThunderPhone-provisioned numbers are inbound-only. --wait defaults to a one-hour timeout; set --timeout SECONDS to change it. A timeout stops waiting without ending the call.

Imports support vapi, retell, elevenlabs, and bland. The second argument is a path to a vendor JSON export, not a remote vendor ID. The API prepares a mapping asynchronously; inspect it with imports get UUID and commit only after it is ready and you have reviewed the mapped fields and warnings. See agent imports.

MCP setup

thunderphone mcp setup --client cursor --api-key-env THUNDERPHONE_API_KEY
thunderphone mcp setup --client codex --scope user --api-key-env THUNDERPHONE_API_KEY
thunderphone mcp setup --client claude-desktop --scope user

Clients: claude-code, codex, cursor, vscode, gemini, claude-desktop, and windsurf. Project scope is the default. Desktop and Windsurf require user scope. Omit --client to detect a single client from the project; ambiguous detection prompts interactively or fails with instructions in a non-interactive session. Setup prints the file it wrote and preserves unrelated servers. Existing JSON must be valid strict JSON; Codex TOML values are preserved but comments may be reformatted.

Setup prefers direct remote HTTP. With --api-key-env, it writes a variable reference, never the key. Without that option, direct HTTP relies on the client's OAuth support; it does not use the CLI credential file. To reuse thunderphone login credentials in any stdio-capable client, use:

{
  "mcpServers": {
    "thunderphone": {
      "command": "npx",
      "args": ["-y", "@thunderphone/mcp"]
    }
  }
}

The wrapper checks THUNDERPHONE_API_KEY, then the current CLI profile (refreshing when needed), then delegates OAuth to mcp-remote. THUNDERPHONE_MCP_URL overrides the endpoint. It emits no telemetry. Standalone setup is also available through npx -y @thunderphone/mcp setup --client cursor or thunderphone-mcp setup after installing @thunderphone/mcp globally.

Create a project

npx create-thunderphone-agent my-receptionist
npx create-thunderphone-agent my-outbound --template python --agent-type outbound
# Equivalent:
thunderphone init my-receptionist --template node --agent-type receptionist

Templates are node and python; agent types are receptionist, outbound, and custom. The default agent is an English/Spanish dental receptionist with explicit demo facts. Projects include agent.json, deploy scripts, MCP configurations for Claude Code, Cursor and VS Code, agent instructions, .env.example, and a README. Scaffolding is offline and refuses to overwrite a nonempty directory.

Edit the business facts before deployment. Export the API key, connected caller number, and your test recipient as documented in the generated README. npm run deploy or python deploy.py creates or updates the agent, deploys its draft, and places a billable test call. The scripts use API-key authentication; the CLI and stdio MCP wrapper also support device login. Python scripts require Python 3.9 or later.