CLI
Store a key and set up coding agents from the command line.
The RouterPlus CLI connects your coding tools to the gateway. You approve a key in the browser once. The CLI stores the key and writes it into each tool's settings. The CLI also has a coding agent of its own.
The CLI needs Node 24 or later. It has no other dependencies. Run it from a checkout of the RouterPlus repository:
node tools/routerplus-cli/main.ts <command> [options]Commands
| Command | What it does |
|---|---|
login | Opens the consent page, receives the approved key and stores it. login --key-from-env stores a key that you made in the console. |
setup <tool> | Writes a tool's settings to use RouterPlus with the stored key. Tools: claude-code, codex, cursor, opencode, cline. |
status | Shows the key's prefix, the gateway, its usage and limit (where the gateway reports them), and the tools that use RouterPlus. |
logout | Deletes the stored key. With a management key, it also revokes the key. |
code [prompt] | Starts a coding agent in the current directory. See Coding agent. |
Log in
Make a key in the console, under Access > API keys, and store it:
ROUTERPLUS_API_KEY=tm_vk_... node tools/routerplus-cli/main.ts login --key-from-envThe CLI reads the key from the environment, never from its command line, where other users of the computer can see it in the process list.
Log in from the browser
node tools/routerplus-cli/main.ts loginThis needs the console's key approval page and POST /v1/auth/keys, which are not on every gateway yet. When the gateway does not have them, use --key-from-env.
- 01The CLI starts a server on
127.0.0.1, on a random port, to receive the approval. - 02The CLI opens the consent page in your browser and prints its URL. If the browser does not open, copy the URL.
- 03Sign in, select a workspace and click Approve. You can set a spending limit on the same page.
- 04The browser returns to the CLI. The CLI exchanges the one-time code for a key with OAuth PKCE (S256).
- 05The CLI stores the key in
~/.config/routerplus/credentials.jsonwith mode0600.
The approval must arrive within 5 minutes. The CLI never prints the key. It shows only the first 12 characters.
| Option | Meaning |
|---|---|
--no-browser | Print the URL and do not open a browser. Use this on a remote machine with port forwarding. |
--limit USD | Ask for a spending limit, for example 25. You can change it on the consent page. |
--key-from-env | Store the key in ROUTERPLUS_API_KEY instead of opening the consent page. |
Set up a tool
node tools/routerplus-cli/main.ts setup claude-code --dry-run
node tools/routerplus-cli/main.ts setup claude-code--dry-run shows the lines that would change and writes nothing. Without --dry-run, the CLI does these steps for each file it changes:
- 01It copies the file to
<file>.bak. - 02It writes the new file with mode
0600. - 03It shows the lines it changed. The key shows as its prefix.
A second setup for the same tool changes nothing. The settings are the same as in Coding agents:
| Tool | What setup writes |
|---|---|
claude-code | ~/.claude/settings.json: env.ANTHROPIC_BASE_URL (https://api.routerplus.com, without /v1) and env.ANTHROPIC_AUTH_TOKEN. It removes env.ANTHROPIC_API_KEY, because that variable makes Claude Code open its login screen. Other settings stay. |
codex | ~/.codex/config.toml: model_provider = "routerplus" and a [model_providers.routerplus] table with base_url https://api.routerplus.com/v1, wire_api = "responses" and the key in experimental_bearer_token. It sets model = "gpt-6-luna" only when the file has no model. Other tables stay. |
opencode | ~/.config/opencode/opencode.json: provider.routerplus with @ai-sdk/openai-compatible, baseURL https://api.routerplus.com/v1, the key in apiKey, and claude-sonnet-5-5, claude-opus-5-5 and gpt-6-luna with image input. It sets model only when the file has none. |
cline | Writes no file and runs nothing. Cline keeps the key in its own settings, and its CLI takes the key only on its command line (cline auth --apikey), where other users of the computer can see it. So the CLI shows the steps for Cline's settings screen and the cline auth command without the key. --copy-key puts the key on the clipboard for you to paste. |
cursor | Writes no file. Cursor keeps the key in its settings screen, so the CLI shows the steps. --copy-key puts the key on the clipboard for you to paste. |
After setup, the Codex and OpenCode files hold your key. Do not commit or share them.
Status
node tools/routerplus-cli/main.ts statusKey: tm_vk_1a2b3c... (approved by [email protected])
Stored in: /Users/you/.config/routerplus/credentials.json
Gateway: https://api.routerplus.com
Usage: $1.50 (limit $25.00, $23.50 left)
Rate limit: 300 requests per 1m
Tools:
claude-code configured
codex not configured
cursor set by hand
opencode configured with another key
cline not configured- Usage and the limit come from
GET https://api.routerplus.com/v1/key. A gateway without that endpoint shows "Usage: unavailable". - "configured with another key" means that the tool uses RouterPlus with a different key. Run
setupfor that tool to use the stored key.
Log out
node tools/routerplus-cli/main.ts logoutlogout deletes the stored key. The key still works until you disable it in the console, under Access > API keys.
To revoke the key from the CLI, give a management key. Use --management-key tm_mk_... or the ROUTERPLUS_MANAGEMENT_KEY variable. The CLI finds the key by its prefix in GET /v1/keys and calls DELETE /v1/keys/<id>. This needs a gateway with the management API.
The tools that you set up keep the key in their own settings. Run setup again after the next login, or remove the settings.
Coding agent
code starts a coding agent in your terminal. The agent reads, searches and changes the files in the current directory, and runs commands there. It uses the key in ROUTERPLUS_API_KEY when that variable is set. Otherwise it uses the stored key.
cd my-project
node /path/to/routerplus/tools/routerplus-cli/main.ts code
node /path/to/routerplus/tools/routerplus-cli/main.ts code --model claude-sonnet-5-5 --max-cost 2Type a task at the > prompt. The agent streams its answer and asks you before each change. It keeps the conversation until you type /clear or /exit.
| Command | What it does |
|---|---|
/cost | Shows the cost of the session in USD. |
/clear | Starts a new conversation. |
/exit | Quits and shows the session cost. |
One-shot mode
Give the task as an argument and pipe stdin. The agent does the task, prints the cost and exits.
node tools/routerplus-cli/main.ts code --yes "Add a test for parseDate" < /dev/nullWith no argument, the agent reads the task from stdin. In this mode the agent cannot ask you for approval:
- Without
--yes, it refuses writes and edits. - Without
--yes-commands, it refuses commands. - Without
--auto-approve-readsor--yes, it also refuses reads. - It always refuses to send a file that may hold secrets, and a command that names one.
The exit code is 0 when the agent finishes and 1 when it stops early.
Tools
| Tool | What it does | Asks you |
|---|---|---|
read_file | Reads a text file, with line numbers. Takes offset and limit in lines. | Unless --auto-approve-reads or --yes |
list_dir | Lists a directory. | Unless --auto-approve-reads or --yes |
search | Searches file contents for a regular expression. Skips .git, node_modules, binary files and files over 1 MB. Returns at most 100 matches. | Unless --auto-approve-reads or --yes |
write_file | Creates or replaces a file. Shows a diff first. | Unless --yes |
edit_file | Replaces one string in a file. The string must occur once. Shows a diff first. | Unless --yes |
run | Runs a shell command. Stops the command after 120 s and keeps the first 20,000 characters of output. | Unless --yes-commands |
Safety
- Every path must be inside the current directory. The agent resolves every symbolic link and refuses a path that leads outside, and a link whose target does not exist. It checks the path again after you approve a write, and writes without following a link.
- Before each write or edit, the agent shows a unified diff.
- These files can hold secrets:
.env,.env.*,credentials.json,*.pemand names that containkey. The agent checks both the name it is given and the file a link points to. It sends their contents only when you typey, also with--yes.searchdoes not look in these files. --yesdoes not cover commands: a command can read any file, secrets included, and its output goes to the model.--yes-commandsruns commands without asking, except a command that names a file that may hold secrets, which always asks. Use--yes-commandsonly in a directory you can restore, for example a clean git checkout.- Commands run without the CLI's own keys in their environment (
ROUTERPLUS_API_KEY,ROUTERPLUS_MANAGEMENT_KEY,TM_API_KEY,TM_ADMIN_TOKEN). - Text from the model and from files is printed with control characters shown as
\u{...}, so it cannot move the cursor, clear the screen or change an approval question.
Options
| Option | Default | Meaning |
|---|---|---|
--model ID | claude-sonnet-5-5 | The model: any model id from Models. |
--yes, -y | off | Read, write and edit files without asking. |
--yes-commands | off | Run commands without asking (not those that name a secrets file). |
--auto-approve-reads | off | Read, list and search without asking. |
--max-cost USD | none | Stop when the session cost reaches this amount. The cost is the sum of usage.cost in the answers. |
Each request sends these headers:
x-session-id, with one id for the conversation./clearstarts a new id.x-tm-labels: client=routerplus-code, a label for the agent's requests.
Options
| Option | Default | Meaning |
|---|---|---|
--api URL | https://api.routerplus.com | The gateway. login stores it, and later commands use the stored value. code also reads ROUTERPLUS_API_URL. |
--console URL | https://app.routerplus.com | The console with the consent page. |
Both URLs must use https. Plain http works only on localhost, 127.0.0.1 and [::1].
The CLI has no dependencies beyond Node and no package to install yet: it runs from a checkout of the repository.
For agents: /docs/cli.md and /llms.txt