Skip to main content

CLI reference

ambit starts a local Ambit on kind, checks an install, validates Ambit objects in files, and connects coding tools to Ambit. To install it, see Quick start. This page describes release 0.2.0.

Global flags​

FlagDefaultMeaning
--kubeconfig <file>$KUBECONFIG, else ~/.kube/configkubeconfig file
--context <name>the current contextkubeconfig context
-n, --namespace <name>ambit-systemnamespace of the Ambit releases
--yesoffdo not ask for confirmation. Required without a terminal.
--output text|jsontextjson only for ambit check and ambit version. Then stdout holds only the JSON; other lines go to stderr.
--no-coloroffno colour. Colour is used only on a terminal, and never when NO_COLOR is set.
--verboseoffalso print the logs of the Helm and kind libraries

Exit codes​

CodeMeaning
0The command did what it says. For ambit check: no check failed (warnings and unknown results are allowed).
1A step failed, or (for ambit check) at least one check failed.
2Usage error: a bad flag, a missing file, a --context or --kubeconfig that you named and that does not exist (also for ambit check), or no --yes where the command must ask but there is no terminal.

Every failure of ambit local up and the other commands prints a line ✗ <what> — <why> and, on the next line, next: with the command to run or a page to read. If Docker is not running, ambit local up stops before it changes anything: the line reads ✗ Docker is not running — <why>, and next: says start Docker Desktop (macOS and Windows) or start Docker: sudo systemctl start docker (Linux).

Secrets in the output​

The CLI never prints the OpenRouter key, the admin password or tokens: one output layer replaces them with [redacted] in text, JSON and --verbose output, also inside error messages from the libraries it uses. Keys are read from a hidden prompt (the question is written to stderr, so it stays on the terminal when you redirect stdout, for example ambit local up > log), an environment variable or a file, never from a flag value, so they do not end up in your shell history. The local admin password is printed by ambit local up only on a terminal (--no-password hides it there too), and by ambit local password, whose purpose is to print it.

ambit local up​

Creates a local Ambit on a kind cluster, or repairs one that ambit local up created. Press Ctrl+C once to stop (the command says how to remove a cluster it created); press it a second time to end the process at once. Steps: preflight (the L checks below), cluster, the third-party CRDs, the charts ambit-crds and ambit (with progress every 10 seconds), a model, the access rule everyone-local, a test call, and a summary. See What ambit local up does for each object.

FlagDefaultMeaning
--name <name>ambitname of the kind cluster; the kubectl context is kind-<name>. ambit local down and ambit local password take it too.
--port <port>8080port on 127.0.0.1 for the console and the gateway
--https-port <port>8443port on 127.0.0.1 for HTTPS
--openrouter-key-file <file>file with an OpenRouter API key (one line). OPENROUTER_API_KEY works too.
--no-keyoffuse the test model that repeats your message; do not ask for a key
--model <id>automaticOpenRouter model id, instead of the first free model that answers
--no-passwordoffdo not print the admin password in the summary
--timeout <duration>15mhow long to wait for the pods
--skip-checksoffturn the memory failure of preflight into a warning
--chart-dir <dir>install the charts from charts/ of a checkout. Required for a build from source (ambit version says dev).
--chart-repo <repository>oci://ghcr.io/craftsman-apps/chartsa mirror of the chart registry
--registry-config <file>Helm'sHelm registry login file, for a private registry

The CLI uses only the kubectl context kind-<name> and gives back your previous current context after kind creates the cluster. It keeps an existing OpenRouter Secret on a repair unless you give a new key. Proxies: the CLI and the kind node use HTTPS_PROXY and NO_PROXY from the environment.

ambit local down​

Deletes the kind cluster that ambit local up created, after it asks (--yes skips the question). Flag: --name. It changes nothing else.

ambit local password​

Prints the password of admin@ambit.local of the local cluster. Flag: --name.

local up repair, local down and local password act only on a cluster with both marks of ambit local up, a state file and a node label; see A cluster that ambit did not create.

ambit connect​

ambit connect <claude-code|codex|opencode|cursor> --url <llm address> --model <model id> [flags]

Adds Ambit's entries to the user-level config file of a coding tool, stores the key in the keychain of your computer, and ends with one test call in the tool's own request format. It never writes the key to a config file, and it never changes a project file. For what it writes for each tool, see Connect Claude Code and Cursor and Connect Codex, opencode and Hermes Agent. For cursor it prints the steps and writes nothing.

Steps: read and parse the files (a file that does not parse stops the command, nothing is changed), find conflicts, get the key, print the diff of every file, ask Write these changes? [y/N], store the key, write the files (each existing file is first copied to <file>.ambit.bak, mode 0600, only the latest copy is kept), write the state file, make the test call. If a write fails after another file was written, the written files are put back.

FlagMeaning
--url <address>Required. The LLM gateway address, for example https://llm.example.com. It is normalised: scheme and host in lower case, no trailing / and no trailing /v1. Must be http or https.
--model <id>Required except for cursor. The model ID that clients send (the provider's ID).
--console-url <address>The console address. It is saved so that ambit disconnect can print the page where you revoke the key.
--key-file <path>Read the key from this file. Without it: AMBIT_API_KEY, then a hidden prompt. A key is never a flag value.
--replace-keyA key is stored for this address: ask for a new one and replace it. Without the flag the stored key is reused and nothing is asked.
--key-store keychain|fileForce a store. Default: the keychain, and a 0600 file only on Linux or BSD without a Secret Service (with a warning).
--shell bash|zsh|fish|powershell|noneopencode only: the shell that gets the function. Default: detected. none prints the function and writes nothing.
--dry-runPrint the diff of every file and the key action. Write nothing, store nothing, delete nothing, ask for no key and make no test call. Exit 1 when the real run would stop (a conflict, a file that does not parse, an opencode v2 file), else 0.
--forceReplace a conflicting entry that Ambit did not write. The old value is saved for ambit disconnect, except these, which stay only in the backup file and are not put back: ANTHROPIC_AUTH_TOKEN, ANTHROPIC_API_KEY, CLAUDE_CODE_USE_BEDROCK, CLAUDE_CODE_USE_VERTEX, CLAUDE_CODE_USE_FOUNDRY and an old provider.ambit of opencode.
--no-testSkip the test call.

On Windows, ambit connect opencode asks PowerShell for its execution policy. Windows PowerShell 5.1 starts with the policy Restricted, and under Restricted or AllSigned it does not load the profile that holds the function. Then connect still writes the function, prints a warn line, and prints next: Set-ExecutionPolicy -Scope CurrentUser RemoteSigned. Ambit never changes the policy: run that command yourself, or use --shell none.

The key is checked for the format ambit_ and 43 letters and digits. If the same command ran before and nothing changed, it prints ✓ <tool> is already connected to <url> and makes only the test call. If the test call fails, the config stays; the output says what failed and ends with to undo: ambit disconnect <tool>.

ambit disconnect​

ambit disconnect <claude-code|codex|opencode|cursor> [flags]
ambit disconnect --all [flags]

Removes exactly what ambit connect added, and keeps every other byte of the file when nothing changed in between. For Codex and opencode this needs the state file connect.json: without it, the blank line that connect added before a block stays. An entry that you changed after connect stays, with a ! line. A tool that is not recorded in the state file prints ✓ <tool> is not connected (nothing recorded); for Codex and opencode, a marked block that is found is still removed. When no other tool uses the key, the stored key is deleted. That does not revoke it: the last line says to revoke it in the console.

FlagMeaning
--allEvery tool recorded in the state file. It cannot be used with a tool name (exit 2).
--console-url <address>Overrides the console address saved at connect, for the last line.
--keep-keyDo not delete the stored key, even when no tool uses it.
--dry-runPrint the diffs and change nothing.

ambit key print​

ambit key print --url <llm address> [--reveal]

Prints the key that ambit connect stored for the address to standard output, with a line end and nothing else. The tools that ambit connect configures run this command each time they start. It reads the keychain or the key file only: no network and no cluster. On a terminal it refuses (exit 2) unless you add --reveal. If no key is stored, it exits with 1 and writes the reason to standard error. It prints the key whenever its output is not a terminal (that is how the tools read it), so do not run it where its output is logged. It is the only command that prints a key as it is. See Where the Ambit CLI keeps the key for what the keychain protects and what it does not.

connect, disconnect and key print print text only: --output json is a usage error (exit 2). They use the exit codes 0, 1 and 2, and never 3. A failure, including an error text from the operating system, goes through the same redaction as the other commands.

CaseExit
Done, including "already connected", warnings, and a --dry-run that finds no problem0
Unknown tool, missing --url or --model, --all with a tool name, a bad --url, a key that is not in the Ambit format, --output json, an unknown flag such as --revoke; no terminal and no --yes2
A config file that does not parse, both opencode.json and opencode.jsonc, an opencode v2 config1
A conflict without --force, also under --dry-run1
A keychain error on macOS or Windows, a locked Secret Service1
A write that failed (permission, file held open, file changed while ambit worked)1
ambit runs from a temporary npx copy1
The test call failed1
ambit key print: no key stored1

ambit check​

Reads the cluster and prints one line per check: ✓ pass, ! warning, ✗ failed, ? unknown (the CLI could not look: a missing permission or an endpoint that does not answer; the line names the permission), - n/a (the check does not apply). It changes no object. Two checks are active and say so: the health probes open a port-forward to a pod, and --deep sends one test call per model.

Without flags it runs the checks that apply: the pre-install group when Ambit is not installed; else the health group, and the production group unless console.url is under localtest.me.

FlagMeaning
--prethe pre-install group
--localalso the local group (Docker and ports, as ambit local up checks them); with --name, --port, --https-port
-f, --values <file>values file for the pre-install checks R4 and R5
--production / --no-productionrun or skip the production group
--deepone test call per Ready model (a few tokens each) and an audit-record check (the OpenTelemetry Collector's count of records sent to ClickHouse must grow within 60 s of a test call). Reads a gateway token from AMBIT_TOKEN.
--fail-on-unknownexit 1 when a check could not look, for CI that must prove every check ran

--output json prints a list of {"id", "group", "status", "message", "next", "source"}.

In CI and scripts, run ambit check --fail-on-unknown. Without it, a check that could not look is ? and the exit code stays 0. If KUBECONFIG points to a file that does not exist, every check is ? and the command exits 0. With --fail-on-unknown the same run exits 1. A --kubeconfig or --context that you pass on the command line and that cannot be used exits 2 in both cases.

IDGroupCheckSource
R1preKubernetes 1.30 or laterlive objects
R2preyou can create CRDs, namespaces and ClusterRoleslive objects
R3prewhich of the releases ambit-crds and ambit are installed, and their versionslive objects
R4prea default StorageClass when the chart's own ClickHouse is onvalues (-f), live objects
R5prethe TLS Secret named in gateway.tls.certificateSecret existsvalues (-f), live objects
R6prethird-party CRDs installed by another tool are not older than this version needslive objects
L1localDocker is runningdocker
L2localthe container runtime is supported (not rootless Docker, not Podman)docker
L3localmemory for Docker: warning below 6 GB, failure below 4 GBdocker
L4localthe two ports are freehost
L5localno kind cluster with the name, or one that ambit local up createddocker
H1healthboth releases are deployed, at the same versionlive objects
H2healththe third-party and Ambit CRDs are Establishedlive objects
H3healthevery pod is Ready, else the reasonlive objects
H4healththe gateway answers its readiness endpoint (active: port-forward)live objects
H5healthDex answers its discovery document (active: port-forward)live objects
H6healththe chart's ClickHouse answers a ping when evidence is on (active: port-forward)values, live objects
H7healthevery Model, Server and AccessRule is Readylive objects
H8healthwith --deep: each Ready model answers a test calllive objects
P1productiongateway.replicas is 2 or more, with a PodDisruptionBudget and 2 Ready replicasvalues, PDB, Deployment
P2productionbootstrapAdmin.enabled is falsevalues
P3productionHTTPS: console.url uses HTTPS, gateway.tls is set, the certificate covers the hosts and is valid for 14 more daysvalues, Secret (certificate only)
P4productionevidence is on and its pods are Ready; with --deep, the collector sends a test call's audit record to ClickHousevalues, pods; with --deep, collector metrics
P5productionlimits are on and limits.failureMode is set by youvalues you supplied
P6productionbudgets use an external Valkey (warning only)values
P7productionprotection is on when any MCP Server existsvalues, objects
P8productionalerts are on when the Prometheus Operator is installedvalues, CRDs
P9productionone console replica, Readyvalues, Deployment
P10productionevery Model's credentials are in an existing Secret, or in the gateway's cloud identityobjects, Secret existence, values
P11productionaccess.mode is enforce (audit-only mode is a warning, with the days since modeSince); with --deep in audit mode, it fails when a test call's audit record does not reach the store. A line under it counts the audit-mode call records of the last 24 hours with a missing or failed mark (a warning above 0). While a mode switch or rules change is not active, another line (a warning) names the object agentgateway rejected, the gateway's reason and the next stepvalues, ambit-access-mode, collector metrics; the line reads ClickHouse

Permissions​

ambit check needs read access (get, list) to the Ambit objects (Models, Servers, AccessRules), Deployments, Pods, PodDisruptionBudgets and StorageClasses in the namespace, to CustomResourceDefinitions, and get on Secrets in the namespace: Helm keeps the release values in Secrets, P3 reads the TLS certificate, and P10 checks that each credentials Secret exists (without reading its values). The active checks need create on pods/portforward: the health probes, and P4 and P11 with --deep, which read the collector's metrics on port 8888 (one test call serves both). The mark-missing line under P11 needs create on pods/exec in the ClickHouse pod: it runs one SELECT there with the pod's own credentials, so the CLI never reads the ClickHouse password. With an external ClickHouse, or without that permission, the line is ?; the Audit page shows the same count. R2 uses SelfSubjectAccessReviews, which every signed-in user may create. Without a permission, the check is ? and names what is missing, for example cannot get secrets in ambit-system.

ambit validate​

ambit validate <file or directory>...

Checks every Ambit object (apiVersion: ambitproject.dev/...) in the YAML files the way the cluster would on apply: defaults, unknown fields, the schema and its CEL rules. Other objects are skipped. Exit 1 if any object would be refused. In GitHub Actions it also prints ::error annotations. For CI, the binary is also at /ambit in the image ghcr.io/craftsman-apps/ambit-console.

ambit version​

Prints the CLI version, the chart version it installs, and, when the cluster answers within 3 seconds, the installed versions of ambit-crds and ambit. --output json prints {"cli", "charts", "chartRepo", "installed", "cluster"}.

Files the CLI writes​

  • A state file per local cluster: ~/Library/Application Support/ambit/local/<name>.json (macOS), ~/.config/ambit/local/<name>.json (Linux), %AppData%\ambit\local\<name>.json (Windows). ambit local down deletes it.
  • ambit connect records what it wrote in connect.json in the ambit folder of your user config folder (~/Library/Application Support/ambit on macOS, ~/.config/ambit on Linux, %AppData%\ambit on Windows), mode 0600. The file never holds a key. The fallback key file is in keys/ in the same folder. Each tool's config file that ambit connect changed has a copy <file>.ambit.bak; ambit disconnect does not delete it.
  • kind adds the context kind-<name> to your kubeconfig; ambit local down removes it.