CLI Reference
One CLI for auth, tool discovery, syncing, and component installation. Works with any Node ≥ 18 project.
npm i -D betteragent-clibetteragent login
Authenticate the CLI with a project secret key.
betteragent login [OPTIONS]| Option | Description |
|---|---|
--key <secret> | Secret key (ba_secret_…). Prompted if omitted. |
--api-url <url> | Override the API URL (or set BETTERAGENT_API_URL). |
$ betteragent login --key ba_secret_abc123
✓ Signed in to acme-app (FREE).
Credentials saved to ~/.betteragent/credentials.jsonbetteragent init
First-time setup wizard — installs a chat component, scaffolds tool files,
generates AgentProvider, writes .env.local.
betteragent init [OPTIONS]| Option | Description |
|---|---|
--cwd <dir> | Working directory (default: current). |
--yes | Accept all defaults without prompting. |
$ betteragent init
✓ Signed in as acme-app (http://localhost:3000)
? Which chat variant? › sidebar
→ Installing sidebar...
✓ components/chat/sidebar.tsx
✓ components/chat/pieces/...
? Scan your project for tools? › yes
→ Found 8 routes · 4 server actions
✓ components/betteragent-provider.tsx (AgentProvider)
✓ Done. Run betteragent sync to push.betteragent discover
Scan your codebase for route handlers and server actions, then generate tool
files. Counts are higher than init’s scan because discover inspects
exports at the file level (every handler/export), while init only counts
at the route/action level.
betteragent discover [OPTIONS]| Option | Description |
|---|---|
--cwd <dir> | Working directory (default: current). |
--dry-run | Preview generated files without writing. |
--yes | Skip confirmation prompts. |
$ betteragent discover
✓ Found 11 route handlers · 9 server action exports
? Select routes to expose as tools › (multiselect)
? Select server actions to expose › (multiselect)
? Generate actions.betteragent.ts template? › yes
✓ routes.betteragent.ts (3 routes)
✓ server-actions.betteragent.ts (4 actions)
✓ actions.betteragent.ts (template)What discover looks for
Route handlers. Files named route.ts / route.tsx under app/api/, with
an export function or export async function named GET, POST, PUT,
PATCH, or DELETE. One candidate per exported method, so a file exporting
both GET and POST yields two. node_modules, .next, dist, out, and
dot-directories are skipped.
The URL path is derived from the folder structure:
| File | Tool path |
|---|---|
app/api/v1/chat/route.ts | /api/v1/chat |
app/api/projects/(list)/route.ts | /api/projects — route groups are dropped |
app/api/surveys/[surveyId]/route.ts | /api/surveys/{surveyId} — dynamic segments become path parameters, seeded into the generated schema |
app/api/files/[...path]/route.ts | skipped — a catch-all matches any number of segments, which a single tool parameter can’t express |
Skipped routes are reported so you know they were found and why they weren’t included.
Server actions. Exported async functions in files with a "use server"
directive. Exports beginning with _ are found but unselected by default.
Generated files are a starting point: every route gets schema: z.object({})
(plus any path parameters) and an empty description, both of which you’re
meant to fill in. The agent’s tool selection is only as good as those
descriptions.
betteragent sync
Push your local tool definitions to the BetterAgent backend.
betteragent sync [OPTIONS]| Option | Description |
|---|---|
--cwd <dir> | Working directory (default: current). |
--dry-run | Validate without uploading. |
$ betteragent sync
Using betteragent.config.json
→ Loading tool files from .
✓ routes.betteragent.ts (3 tools)
✓ server-actions.betteragent.ts (4 tools)
→ Prepared 7 tools for sync.
✓ Synced. +7 added · ~0 updated · -0 removed · =0 unchanged.betteragent add
Install a BetterAgent chat component into your project from the registry.
betteragent add [NAME] [OPTIONS]| Option | Description |
|---|---|
NAME | Component: sidebar | chat-popup | cmd-k | inline-bar | drawer. Omit for interactive picker. |
--cwd <dir> | Working directory (default: current). |
--overwrite | Overwrite existing files without prompting. |
--dry-run | Show what would be installed without writing. |
$ betteragent add
? Which components do you want to install? (multiselect)
◉ sidebar Right-side panel, always visible ✓
◯ chat-popup Floating bottom-right button
◯ cmd-k ⌘K overlay, tap to open on mobile
◯ inline-bar Embedded input bar in the page
◯ drawer Slide-out panel from the right edge
→ Installing sidebar...
✓ components/chat/sidebar.tsx
✓ components/chat/pieces/ (10 files)
✓ sidebar installed.betteragent remove
Remove installed BetterAgent chat components from your project.
betteragent remove [NAME] [OPTIONS]| Option | Description |
|---|---|
NAME | Component name. Omit for interactive picker of installed components. |
--cwd <dir> | Working directory (default: current). |
--yes | Skip confirmation prompt. |
$ betteragent remove
? Which components do you want to remove? (multiselect)
◉ sidebar 10 files · installed 2026-05-22
? Remove sidebar (10 files)? › yes
✓ components/chat/sidebar.tsx
✓ sidebar removed. 10 files deleted.betteragent whoami
Show the currently authenticated project and re-verify credentials.
betteragent whoami$ betteragent whoami
acme-app
project: cmpbilv2g00002rck...
client key: ba_client_abc123...
plan: FREE
api: https://www.betteragent.devbetteragent logout
Remove stored credentials from ~/.betteragent/credentials.json.
betteragent logout$ betteragent logout
✓ Removed credentials at ~/.betteragent/credentials.jsonConfiguration — betteragent.config.json
Optional per-project config. Place it alongside your tool files. All fields are optional — the CLI falls back to credentials and defaults.
{
// API URL — overrides BETTERAGENT_API_URL and the URL stored in
// credentials. This points at the BetterAgent backend the CLI talks to
// (production default: https://www.betteragent.dev) — only override it
// if you're running a local/self-hosted BetterAgent backend instance,
// not your own app's URL.
"apiUrl": "http://localhost:3000",
// Project ID — override for monorepos
// where you sync to a specific project.
"projectId": "cmpbilv2g00002rck...",
// Extra env files loaded before tool files are imported, on top of the
// app's own .env* cascade (which `sync` always loads, mirroring
// `next dev`). Useful when .env lives at the monorepo root.
"env": ["../../.env"],
// Custom tool file paths
"files": {
"routes": "./routes.betteragent.ts",
"serverActions": "./server-actions.betteragent.ts",
"actions": "./actions.betteragent.ts",
"provider": "./components/betteragent-provider.tsx"
},
// Installed components (managed by CLI)
"installed": {
"sidebar": {
"files": ["components/chat/sidebar.tsx", "..."],
"installedAt": "2026-05-22T10:00:00.000Z"
}
}
}Env var override. BETTERAGENT_API_URL overrides apiUrl from config and
credentials. Useful in CI/CD.
Resolution order:
- CLI flag (
--api-url) - Env var (
BETTERAGENT_API_URL) betteragent.config.jsonapiUrl- Production default (
https://www.betteragent.dev)
Base URL
baseUrl is not a CLI setting — it lives on the project, in dashboard
settings. It’s where the chat engine sends route-tool requests, so it points at
your deployed app (or a tunnel, in development), not at BetterAgent.
Each tool’s path is resolved against it as an absolute URL:
baseUrl | path | Request |
|---|---|---|
https://app.example.com | /api/surveys | https://app.example.com/api/surveys |
https://app.example.com/base | /api/surveys | https://app.example.com/api/surveys |
Note the second row: because path starts with /, it replaces any path prefix
on baseUrl rather than appending to it. If your API lives under a prefix, put
the prefix in each tool’s path.
Requests are rejected before they’re sent if the resolved URL points at a
private or link-local address, and a route tool can never reach a different
origin than baseUrl — see how route tools authenticate for what is
and isn’t sent with them.
Tool files
Generated by betteragent discover or written by hand. betteragent sync reads
and pushes them to the backend. See the Tool Files reference for the
full schema, the parameter placement rules, and the authentication model.