best is the command line for every Behavioral State Protocol service: one binary, no
configuration, driven by the service's own manifest and catalogues. You sign in by approving a code in your own
browser, and the credential goes where your agent's @behavioralstate/best-mcp keeps its own, so a person and their
agent share sign-ins. Nothing in it is written for one service: what best can do on a service is what that service
publishes.
The plan is the epic behavioralstate/spec#52 on the Behavioralstate board; the board is the plan, no plan file lives here. How the work is made and shipped is SDLC.md.
1. Install. One line, on Linux and macOS:
curl -fsSL https://raw.githubusercontent.com/behavioralstate/best-cli/main/install.sh | shIt takes the newest release's archive for your machine, checks it against SHA256SUMS, and puts best in
~/.local/bin (BEST_INSTALL_DIR chooses another place). On Windows, in PowerShell:
irm https://raw.githubusercontent.com/behavioralstate/best-cli/main/install.ps1 | iexOr take an archive from the releases page by hand
(best-x86_64-unknown-linux-musl.tar.gz, best-aarch64-unknown-linux-musl.tar.gz, best-aarch64-apple-darwin.tar.gz,
best-x86_64-pc-windows-msvc.zip, each with SHA256SUMS and a build provenance attestation:
gh attestation verify <archive> --repo behavioralstate/best-cli), or build it with
cargo install --git https://github.com/behavioralstate/best-cli. best --version says which it is.
2. Sign in. Name the connection and give the manifest address, or just the host:
best login lab-peer --manifest https://peer.example.com:7777/.well-known/best
best login dotquant --manifest baas.dotquant.ioResolved baas.dotquant.io to https://baas.dotquant.io/.well-known/best
Open this link in your own browser, sign in and approve:
https://dotquant.io/activate?user_code=8BB9-CB44
The code is 8BB9-CB44. Waiting for your approval (the code expires in 15 minutes)…
Signed in as 'dotquant' (tenant 67e04942-…) at baas.dotquant.io; the credential is durable until revoked.
The credential is in /home/ada/.best-mcp/credentials.json, where best-mcp finds it too. It is printed only when asked, by `best credential`.
io.dotquant.trading https://baas.dotquant.io/api/best/tenants/67e04942-…
Next: `best queries dotquant` and `best commands dotquant`.
The service's own sign-in guidance (the note of its manifest's authentication block, and of its device answer) is
printed under the code exactly as the service wrote it, and nothing when it published none: it is what says whether
approving opens an account for you or admits you to a machine someone else runs.
best never opens the link itself: approving is yours. A device code you already hold (a registration started on another device, or at an authorization URL this machine
cannot reach) is redeemed with best login <name> --manifest <address> --device-code -, the code typed or piped on stdin
(--device-code <code> works too, but leaves the code in your shell history and the process list); a service that declares no token endpoint is refused at once. A name that is already signed in signs in
again at the same manifest, its credential replaced once you approve (what to do when the service answers its key
401); at another manifest it is left as it is (best logout <name> forgets one). Plain http:// is accepted only on this machine; --ca-file <pem> trusts a
certificate the service's operator sent you (a best-peer makes its own).
3. Read the service. Everything comes from its catalogues:
best connections # what you are signed in to
best queries dotquant # the queries, with their descriptions
best commands dotquant # the commands; IMPACT marks the ones that ask first
best schema dotquant list-brokers # a command's, a query's or an event's JSON Schema
best workflows dotquant # the service's published recipes
best query dotquant list-brokers # a table for a list, JSON otherwise
best query dotquant get-broker-cash --param brokerId=0735cfd1-…
best events dotquant --limit 20 # the event log
best events dotquant --follow --type OrderFilled # what happened, then what happens next, one line per event
best watch lab-peer get-hardware-state get-workloads # the answers, the events as they come, an answer again when it movedA service with several tenants may let one credential open more than one, such as a workspace you work in. --tenant
works on another with the same connection, for that run: best --tenant 0735cfd1-… query dotquant list-brokers
The address comes from the manifest you signed in at, and the credential goes to no other
host. Leave it out and you are on the tenant you signed in as. login, logout, connections, credential and manifest
are about a whole connection, so they refuse it.
best credential <name> prints a connection's credential alone, for a tool that takes it from a pipe, so nothing has to
read the credentials file: best credential work | docker login registry.example.com --username <id> --password-stdin. On
a terminal it refuses unless --force.
best watch keeps a service in view until Ctrl-C: each query's answer once, under its name; then the live stream, one
line per event; and a query's answer again whenever it moved. The answers are read again shortly after each event
and every five seconds (--every), since some readings change with no event, such as a card its owner is using.
Nothing is redrawn: each update is printed after the last, so it reads the same in a terminal, a file or a pipe;
--json gives one line per answer ({"query", "time", "answer"}) or event ({"event"}), and --limit stops after so
many updates. A service that restarts or fails for a moment is said on stderr and the watch goes on; its refusal ends
the watch with the service's words and its exit code.
4. Send a command. The envelope is built from the catalogue (type, dataschema), the payload is yours:
best send lab-peer deploy-model --data '{"model": "qwen2.5:0.5b", "engine": "ollama", "memory_bytes": 1073741824}'Accepted DeployModel: id 2a6f…, correlation 2a6f….
Follow it with `best events lab-peer --correlation-id 2a6f… --follow`.
A command whose catalogue entry carries the impact annotation shows its warning and asks before sending; --yes
answers for a script, and without a terminal the command is not sent without it. --dry-run prints the envelope and
sends nothing; --file payload.json and --data - (stdin) carry the payload; --correlation-id joins an existing
process.
5. When something goes wrong, the answer is the service's own: a BEST refusal prints its code, message and
details (a 400 names the field and the fix); the sign-in endpoints' errors likewise. --json on any command prints the
service's JSON on stdout, and errors as JSON on stderr. Exit codes:
| Code | Meaning |
|---|---|
| 0 | done |
| 1 | failed |
| 2 | the command line was wrong |
| 3 | not signed in, the sign-in was refused, or the credential was |
| 4 | a high-impact command was not confirmed |
| 5 | the service refused the request |
| 6 | the service could not be reached, or failed |
6. Stay current. best update installs the newest release over the binary you ran, on Linux, macOS and Windows. It
takes the archive the install scripts take and checks it against the same SHA256SUMS:
Downloading https://github.com/behavioralstate/best-cli/releases/latest/download/best-x86_64-unknown-linux-musl.tar.gz
Updated best 0.1.2 to 0.3.0: /home/ada/.local/bin/best
best update --check changes nothing and says the running version and the newest, on stdout. With --json, --check
answers {"running", "newest", "updateAvailable", "update"} and best update answers
{"running", "newest", "updated", "path"}. When the newest cannot be read the exit code is 6; any other failure is 1.
Already on the newest, it says so and changes nothing. The old binary stays until the new one is written beside it and
has said its version, so a failed download or a bad archive leaves the install as it was. On Windows, where a running
binary cannot be overwritten, the old one is moved aside and a later run of best removes it. A build of cargo's (cargo install, or a target directory) is left as it is, and you are told to run
cargo install --git https://github.com/behavioralstate/best-cli --force. best update trusts only the system's
certificates, whatever --ca-file says. Running the install script again also upgrades.
A command this best does not know is when an older install finds out. After the usual error, on stderr and with the
usual exit code 2, it says:
no such command; this is best 0.1.2, the newest is 0.3.0: `best update` installs it
It waits at most three seconds for the newest; if it cannot be read in that time it says so and still names
best update. A build of cargo's is told the cargo install above instead. With --json the same is one JSON error on
stderr, with running, newest and update in its details.
No other command reads a release: nothing checks on the way.
~/.best-mcp/credentials.json (BEST_MCP_CREDENTIALS_FILE moves it, for best and best-mcp alike), one entry per
connection name: tenantId, apiKey, authType, authHeader, issuedAt, manifest (the address signed in at) and
endpoints (service id → endpoint). best reads and writes it entry for entry: what another program wrote, members it
does not know included, comes out as it went in; the file is backed up beside itself (credentials.json.bak) before
every write and is readable by its owner only. A connection whose manifest names several services is name for the
first and name/<service id> for any other.
cargo build && cargo test
cargo clippy --all-targets -- -D warningsThe tests run the binary against a fake of the BEST surface (tests/cli.rs) and a directory standing for the newest release (tests/update.rs), and need no service and no release. The run against real ones, best-peer and the DotQuant BaaS, is kept as acceptance/best-peer-and-dotquant.md.