Listen to the brief:
A few weeks ago, Justin Poehnelt published a sharp take — You Need to Rewrite Your CLI for AI Agents. The core argument is that human-first and agent-first CLIs have fundamentally different requirements, and retrofitting one for the other doesn't work. Human DX optimizes for discoverability and forgiveness. Agent DX optimizes for predictability and defense-in-depth.
We read it and recognized ourselves. The Algolia CLI was built for humans. Helpful output formatting, interactive prompts, guided flows. All the right things for a developer at a terminal — and all the wrong defaults for an LLM trying to automate Algolia operations.
So with v1.8.1, we set out to fix that. Here's what we built, mapped directly to Justin's recommendations.
Justin's first structural recommendation is to expose commands that return machine-readable signatures, parameters, and required scopes. This makes the CLI itself the documentation, queryable at runtime.
We shipped this as algolia describe / algolia schema:
# Describe the root command tree $ algolia describe # Describe a specific command $ algolia describe search # Describe a subcommand $ algolia describe objects browse
Every command emits a structured JSON response with its full argument list, flags, subcommands, and usage. The response is versioned (schemaVersion: "v1"), so agents can parse it reliably across CLI versions.
An agent no longer needs to parse --help text or rely on static documentation. It queries the CLI at runtime, discovers what flags are available, and constructs valid invocations from the schema — exactly the capability Justin describes as making the CLI self-documenting in a way agents can consume programmatically.
Agents can't parse human-friendly tables and color-coded terminal output. But the deeper concern is context window consumption — pulling a 10,000-record index response into an agent's working context will blow its token budget.
In v1.8.1, we extended --output json and --output ndjson across the commands agents are most likely to call — algolia apikeys get, algolia apikeys list, algolia objects browse, algolia objects operations, algolia search, and more.
NDJSON matters here specifically because of what Justin calls context window discipline. Newline-delimited JSON lets an agent process a stream of records one at a time — it doesn't have to buffer a full API response before acting on it. Combined with field selection to trim unnecessary data, it's the difference between a command that fits in context and one that doesn't.
Field masks that let agents explicitly limit returned fields are still on our roadmap, but the streaming output foundation is in place.
Justin makes the case plainly — --dry-run validates requests locally before API calls, preventing data loss from hallucinated parameters. The agent is not a trusted operator. It can confidently pass a hallucinated object ID or a malformed JSON body, and without a dry-run path, that becomes a live API call.
In v1.8.1, we added --dry-run broadly across the mutation surface of the CLI.
Crawler operations — crawler create, crawler run, crawler reindex, crawler pause, crawler unblock, crawler test
$ algolia crawler run <crawler-id> --dry-run Would run crawler abc123 (dry run)
Index mutations — objects update, rules import, synonyms import, dictionary entries import
$ algolia objects update myIndex -F records.ndjson --dry-run
In dry-run mode, the CLI validates the request, prints a structured summary of what would happen, and exits cleanly — no API call, no side effects. It also surfaces validation errors that would otherwise only appear after data has been modified. For agents, the right pattern is to run with --dry-run first, confirm the summary matches intent, then execute. This is now supported consistently across the mutation surface.
Justin's section on input hardening identifies the failure modes that agents introduce and humans typically don't — path traversals like ../../.ssh, embedded query parameters in IDs, double-encoded strings, and control characters embedded in otherwise valid-looking values. His prescription is to reject all of it and assume adversarial input.
We added ValidateNoControlChars, applied to identifier-like inputs throughout the CLI:
// ValidateNoControlChars rejects identifier-like inputs containing control
// characters, which are easy to miss in automation and should never be valid.
func ValidateNoControlChars(field, value string) error {
for _, r := range value {
if unicode.IsControl(r) {
return FlagErrorf("%s must not contain control characters", field)
}
}
return nil
}
Control characters are invisible in terminal output but trivially generated by a language model — embedded \r, \n, or null bytes in what looks like a valid index name or object ID. The CLI now fails fast with a clear error rather than silently forwarding malformed data to the Algolia API.
This is the beginning of a defensive input validation layer, not the end of it. Path traversal detection and embedded query parameter rejection are still ahead. But treating agent-generated input as potentially adversarial — rather than assuming it's well-formed — is the right posture, and this establishes that baseline.
There's a principle that gets at why the old API key model is wrong for agentic workflows: an agent should act on behalf of the user, inheriting their identity and permissions — not operate as a separate privileged account.
With admin API keys, an agent holds credentials that are more powerful than any individual user. They carry full account permissions, never expire, and can't be scoped to a specific task. If an agent misbehaves or gets compromised, it has the keys to everything. Worse, there's no meaningful audit trail — actions are attributed to a key, not a person.
OAuth PKCE, shipped in v1.8.1 as algolia auth login, inverts this.
$ algolia auth login # Opens browser → authenticates → stores token # CLI is now authenticated with scoped, expiring credentials
The user authenticates once against the Algolia Dashboard. The CLI stores a short-lived, scoped OAuth token tied to that user's identity. When an agent invokes the CLI using that token, it acts with exactly the permissions that user has — no more. If the user can't delete an index, neither can the agent.
This is the on-behalf-of pattern: the agent's authority is derived from and bounded by the user's. It's the right security posture for agentic systems, and it's now the default authentication path for the Algolia CLI.
For fully non-interactive environments like CI pipelines, environment variable injection remains available as well:
export ALGOLIA_APPLICATION_ID=your_app_id export ALGOLIA_API_KEY=your_api_key algolia search myIndex --query "shoes"
Justin's point here cuts against a comfortable assumption — that --help is sufficient context for an agent. It isn't. --help is text designed for humans scanning a terminal. What agents need are structured documents they can load before acting, covering when to use --dry-run, when to confirm with users, what operations are destructive, and what the right invocation patterns are for common workflows.
We ship AGENTS.md at the repository root. It covers repo structure, build and test commands, architecture patterns, naming conventions, and change guidance — everything a coding agent needs to work in this codebase without having to explore it first.
We also ship CLAUDE.md for Claude Code users, following the same principle for a specific agent surface.
This isn't documentation for humans who might read it someday. It's structured context that gets injected into an agent's working memory before it writes its first line of code.
Justin's implementation checklist maps directly to where we are.
--output json / --output ndjson for machine-readable outputalgolia describe / algolia schema for runtime introspection--dry-run for mutations across crawler and index operationsAGENTS.md for agent-specific contextStill ahead:
--sanitize for response filtering against prompt injectionThe Algolia CLI is open source at github.com/algolia/cli. If you're building agents that work with Algolia — or if you have thoughts on what we should tackle next — we'd love to hear from you.
And, check our documentation for more ways to use AI assistants and agents to build, integrate, and maintain Algolia in your applications.
Chuck Meyer
Senior Manager, Developer Relations