The Pilot CLI
Connect Pilot MCP from the terminal with the pilot command. Sign-in, setup in your assistants, stdio bridge, skills, tool calls and diagnostics.
The Pilot CLI (@braike/pilot, command pilot) connects Pilot MCP from your terminal, without copying any configuration by hand. It signs you in through your browser, registers the Pilot server in your assistants, bridges clients that only start local programs, installs the skills, and queries Pilot from a script.
Install
You need Node.js 20 or later. Without installing anything, npx downloads the CLI and runs it:
npx @braike/pilot setupTo keep the pilot command at hand, install it once and for all:
npm install -g @braike/pilot
pilot --versionThe examples on this page write pilot; with npx, replace pilot with npx @braike/pilot.
In two commands
npx @braike/pilot login
npx @braike/pilot setuplogin opens Pilot's authorization screen in your browser; setup finds the assistants installed on your computer and registers Pilot in them. Then restart your assistant and ask it a question.
Commands
pilot login
Opens the Pilot sign-in in your browser (OAuth 2.1). You choose the workspace to share and keep the Read level, as for an assistant (see the authorization screen). The CLI then keeps the token it receives on your computer.
pilot login
pilot login --workspace <workspace id>
pilot login --no-browser--workspace locks the authorization to one workspace, like a workspace address. --no-browser prints the address to open instead of opening the browser, for example on a server.
pilot logout
Revokes the CLI's access with Pilot, then deletes the tokens kept on this computer. Without --workspace, every sign-in for the address.
pilot logout
pilot logout --workspace <workspace id>When Pilot cannot answer (unavailable, network), the sign-in is kept and the command fails, to be run again. --force forgets it on this computer anyway.
pilot status
Tells whether the CLI is signed in, to which address, for which workspace, at which level, until when, and whether it can renew the token by itself. It never shows a token, and returns exit code 1 when no sign-in is usable.
pilot statuspilot setup
Registers the Pilot server in the assistants found on your computer. Without --client, the CLI registers it in each of them; --all says so explicitly.
pilot setup
pilot setup --client cursor
pilot setup --client claude-code --client vscode
pilot setup --client cursor --dry-run
pilot setup --client generic| Option | Effect |
|---|---|
--client <name> | Registers Pilot in this assistant only; can be repeated. |
--all | Registers Pilot in every assistant found. |
--workspace <id> | Registers a workspace address, https://app.pilot.braike.com/mcp/<id>. |
--transport remote or stdio | Remote address, or the local pilot mcp bridge for every assistant. |
--name <name> | Names the entry something other than pilot, for example one entry per workspace. |
--dry-run | Shows the change without writing anything, and the real file when a link leads to it. |
--force | Writes anyway in the three cases left to you (see below). |
Supported assistants, the name to give --client, and what the CLI writes:
| Assistant | --client | What the CLI writes |
|---|---|---|
| Claude Desktop | claude-desktop | the local bridge, in claude_desktop_config.json |
| Claude Code | claude-code | claude mcp add --transport http --scope user when the claude command is installed, otherwise ~/.claude.json |
| Cursor | cursor | ~/.cursor/mcp.json |
| VS Code | vscode | the mcp.json file of your user profile |
| VS Code Insiders | vscode-insiders | the same, in the Code - Insiders folder |
| Windsurf (Devin Desktop) | windsurf | ~/.config/devin/mcp_config.json, and ~/.codeium/windsurf/mcp_config.json for an install from before the rename |
| Codex and the ChatGPT desktop app | codex | ~/.codex/config.toml |
| Gemini CLI | gemini | ~/.gemini/settings.json |
| Any other MCP client | generic | nothing: the CLI prints the configuration to copy |
An assistant that speaks remote MCP gets Pilot's address and signs in by itself on first use, through the same authorization screen: Claude Code with /mcp (or claude mcp login pilot), Codex with codex mcp login pilot, Gemini CLI with /mcp auth pilot; Cursor, VS Code and Windsurf open the authorization page on first use. Claude Desktop's configuration only holds local servers: it gets the pilot mcp bridge, signed in by pilot login. Claude on claude.ai and ChatGPT in the browser connect from their own interface: see Connect your assistant.
Before changing a file, the CLI keeps a dated copy of it in ~/.config/pilot/backups/; run again, it creates no duplicate. Only the Pilot entry changes: a JSON file is written again with its own indentation, and in Codex's TOML only the Pilot table changes. Three cases are left to you, unless --force:
- a file whose real path, links followed, leads outside your home folder and the configuration folders (
XDG_CONFIG_HOME,APPDATA,LOCALAPPDATA,CODEX_HOME,CLAUDE_CONFIG_DIR); - an entry with the same name that is not Pilot's: choose another name with
--name; - a JSON file with comments, which
--forcewrites again without them.
pilot remove
Removes the Pilot entry from the assistants' configuration, leaving the rest untouched. An entry with the same name that is not Pilot's stays, unless --force.
pilot remove --client cursor
pilot remove --all --dry-runOptions: --client <name>, --all, --name <name>, --dry-run, --force.
pilot mcp
Starts a local stdio MCP server that relays Pilot's remote server: the bridge for assistants that can only start a local program. In such an assistant's configuration:
{
"mcpServers": {
"pilot": {
"command": "npx",
"args": ["-y", "@braike/pilot", "mcp"]
}
}
}- Credential: the access key in the
PILOT_API_KEYvariable when it is set, otherwise thepilot loginsign-in, read again at every request: a sign-in made elsewhere serves at once. The bridge renews the token before it expires. - Without a sign-in, the bridge opens the Pilot sign-in in your browser by itself and answers the assistant with an error while you sign in; then try again. When no browser can open (a server,
PILOT_NO_BROWSER), each request gets an error that says to runnpx @braike/pilot login. - A specific workspace:
--workspace <id>, or thePILOT_WORKSPACEvariable.
pilot tools
Lists the tools Pilot serves you, one per line.
pilot tools
pilot tools --json | jq '.[].name'pilot call
Calls a tool and prints its response. A tool in error returns exit code 1, for scripts.
pilot call pilot_data_freshness
pilot call google_get_campaign_performance --arg customer_id=1234567890 --arg date_range=LAST_7_DAYS
pilot call google_analytics_run_report --json-args '{"dateRanges":[{"startDate":"28daysAgo","endDate":"yesterday"}],"dimensions":["sessionDefaultChannelGroup"],"metrics":["sessions"]}'--arg key=value can be repeated and follows the type the tool's schema declares: a number, a boolean, an array or an object are read as such, anything else stays text. --arg key:=<json> passes a JSON value as is. --json-args passes an object, which --arg values complete or override. The tools and their parameters are on Ad platforms and their tools.
pilot skills list and pilot skills install
Lists the skills catalogue and installs them where your assistant reads them.
pilot skills list
pilot skills install
pilot skills install google-ads-account-audit --target claude-code
pilot skills install --target claude --out ./archives
pilot skills install --target ./.github/skills--target | Where |
|---|---|
claude-code | ~/.claude/skills/<skill>/ |
codex | ~/.agents/skills/<skill>/, read by Codex and the ChatGPT desktop app |
cursor | ~/.cursor/skills/<skill>/ |
claude | a <skill>.zip archive in --out (the current folder by default), to upload in Claude: Customize, Skills, +, + Create skill, Upload a skill |
| a path | that folder, for example ./.github/skills for VS Code |
Without a skill name, the CLI installs the whole catalogue; without --target, it installs in every assistant found among Claude Code, Codex and Cursor. It replaces a skill's folder as a whole; a folder edited by hand since its installation is left as is, unless --force. --dry-run shows what would be installed.
The CLI reads the catalogue this documentation publishes, https://pilot.braike.com/skills/index.json, and checks each file's size and SHA-256 fingerprint before writing: one mismatch refuses the whole skill.
pilot doctor
Checks your setup: Node.js version, the CLI version against the latest published, network access, discovery of Pilot's sign-in, your credential, and the configured assistants. A newer version is only a warning, with the update command. A failed check returns exit code 1. See Troubleshooting.
pilot doctorpilot open
Opens your workspace console, the Claude & ChatGPT page, in your browser; without a known workspace, the list of your workspaces. --no-browser prints the address.
pilot open
pilot open --workspace <workspace id>pilot --version gives the version, pilot help <command> the help for a command.
Common options
| Option | Effect |
|---|---|
--base-url <address> | Pilot's address (default https://app.pilot.braike.com). The CLI refuses any address that is not Pilot's. |
--allow-local | Accepts a local address (http://localhost:3000), for development only. |
--json | JSON output, for scripts. |
--lang fr or en | Language of the messages; otherwise PILOT_LANG, then your system's language. |
--verbose | Details what the CLI does, without ever showing a token, a key or a secret. |
-h, --help | Help for the command. |
Environment variables
| Variable | Use |
|---|---|
PILOT_API_KEY | An access key (ulys_...), used by mcp, tools, call and doctor instead of the sign-in. |
PILOT_WORKSPACE | The workspace, when --workspace is not given. |
PILOT_BASE_URL | Pilot's address, when --base-url is not given. |
PILOT_CONFIG_DIR | The CLI's folder instead of ~/.config/pilot. |
PILOT_LANG | fr or en. |
PILOT_NO_BROWSER | 1: never opens a browser (also the case on a Linux machine without a display). |
PILOT_LOGIN_TIMEOUT_MS | How long a sign-in waits for the browser, in milliseconds (5 minutes by default). |
npm_config_registry | The registry doctor asks for the latest version (npm's by default). |
Exit codes
| Code | Meaning |
|---|---|
0 | Success. |
1 | Failure: a tool in error, no usable sign-in for status, a sign-in kept by logout because Pilot could not answer, a file left to you by setup or remove, a failed doctor check. |
2 | Usage error: unknown command or option, missing value. |
Security
- Your tokens stay with you, in
~/.config/pilot/credentials.json: a folder only you can read (permissions 0700, file 0600), written in one go. Loosened permissions are tightened again; on Windows, the protection of your user profile applies. - A token only goes to the address that issued it. The authorization server's metadata must name the address you chose, and each of its endpoints must belong to it, or the sign-in is refused. Redirections are never followed.
- Only Pilot's addresses, over HTTPS; a local address only with
--allow-local. - OAuth 2.1 sign-in: PKCE
S256and a checkedstate, return tohttp://127.0.0.1on a random port, a client registered once then reused, resource indicator.pilot logoutrevokes the tokens, and a new sign-in revokes, when it can, the token it replaces. - Nothing shown: no token, no key, no code or secret, even with
--verbose. Control sequences in text that comes from a server are removed. - Your configurations protected: a dated copy before any change, only the Pilot entry changes, no write outside your folders or over someone else's entry without
--force, and--dry-runto see first. - No dependency: the package relies on Node.js alone, with no other npm package: no third-party package touches your tokens.
Troubleshooting
Run pilot doctor first: each failed check says where to look.