---
title: "ThunderPhone CLI"
description: "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:

```bash
npm install -g thunderphone
thunderphone --help
```

## Log in

```bash
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.

```bash
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.

| Command | Purpose |
| --- | --- |
| `login [--no-browser] [--scope "scopes"]` | Authorize through a device code |
| `logout`, `whoami` | Remove local credentials; list accessible organizations |
| `agents list`, `agents get ID` | Read agents |
| `agents create --file agent.json` | Create an agent |
| `agents update ID --file agent.json` | Save an agent draft |
| `agents deploy ID`, `agents delete ID` | Deploy the draft; delete an agent |
| `numbers list` | Read phone numbers |
| `numbers provision --country US --area-code 415` | Provision a US inbound number |
| `numbers assign NUMBER_ID --agent ID` | Assign 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 ID` | Read one call or its transcript |
| `test run AGENT_ID [--scenario ID] --consent-to-charge` | Run 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.json` | Prepare a vendor JSON import for review |
| `imports get UUID`, `imports commit UUID` | Inspect an import; commit selected agents after review |
| `mcp setup`, `mcp serve` | Configure 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](/guides/import-agents).

## MCP setup

```bash
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:

```json
{
  "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

```bash
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.
