# Show HN: Aclif – Agent CLI Framework. One grammar, canonical names across SaaS

> Source: <https://www.aclif.ai/>
> Published: 2026-09-17 16:48:17+00:00

# The Agent CLI Framework

aclif builds command-line tools for AI agents. An agent gets a single tool that provides a unified abstraction across every SaaS provider: one grammar, and canonical names that reach the same record by the same name on any platform.

## Try it now

Install the binary, list the providers, and read a command's schema, examples, and safety metadata.

```
npm install -g @aclif/core

aclif discover --json
aclif learn salesforce --json
aclif learn servicenow --json
aclif salesforce data query --schema
aclif salesforce data query --examples
aclif salesforce data query --query "SELECT Id FROM Account LIMIT 3" --dry-run
aclif servicenow data query --table incident --query "active=true^priority=1" --dry-run
```

## Why agents need their own CLI

An MCP server publishes a fixed list of tools, and every tool on the list occupies the agent's context on every turn. The server's author trades coverage for cost when the server is built. Publishing every operation (a typical API has hundreds of definitions) keeps the whole API reachable and consumes tokens for all of it on every turn. Publishing a handful of broad operations keeps the token count small, and any operation the author left off the list is out of the agent's reach. An agent that spans several platforms needs a server, a login, a grammar, an error format, and a set of names for each.

aclif loads a command's definition only when the agent asks for it, so the whole API of every provider is reachable at no standing cost in context. One grammar, one envelope, and one error vocabulary cover every provider, so the agent's context stays about the same size whether it reaches one platform or five.

An agent that runs a defined workflow can leave the model out of the call altogether. A person or an authoring tool works out the exact command at design time and embeds it in the workflow as a string. At run time the agent executes that string as ordinary code, with no tool definition loaded and no inference. The command is chosen at design time, and the authority to run it, the credential, the acting identity, and the policy, is supplied at run time by whatever runs it. Neither side ever holds both.

## What every command gives you

### One grammar

One command structure, one JSON envelope, and one error vocabulary across every provider. An agent learns the tool once, and a new platform adds commands without adding grammar. A JSON manifest adds a command over one HTTP endpoint in the same grammar, with no code.

### Canonical names

Alias sets map `customer` to
    `Account` in one Salesforce instance and
    `core_company` in ServiceNow. A tenant
    catalog, captured from each instance at deploy time,
    teaches the CLI each instance's custom objects and
    fields with no change to the provider.

### Errors an agent can act on

An agent recovers in one turn. Every error names the failure, the command that fixes it, and, where the provider's classifier has a rewrite rule for the mistake, the corrected input ready to resend. The classifier is plain code with no model behind it. A command validated in a shell at design time returns the same error at run time under any host, because the same command classes run in both.

### Introspection without execution

`--schema`, `--examples`,
    `--shape`, and four more flags return before
    the command runs, need no credentials, and count against
    no API quota. An agent can discover, learn, introspect,
    and preview against a rate-limited instance and spend
    nothing.

### An embeddable runtime

The same command classes run in-process inside a host that supplies credentials, identity, and policy per request, keeps connections warm, and caches expensive logins per instance. A gateway built on it works with the enterprise's own identity provider and secrets vault.

### Declared safety

Mutability, blast radius, reversibility, and
    idempotency are declared on every command. A policy
    check
    can refuse it before its code loads. Every mutation
    accepts `--dry-run`, demands
    `--confirm` where its metadata says so, and
    writes an audit line after every run.

## The introspection-first workflow

An agent needs no documentation beyond the binary, and nothing before the last step touches the API.

```
aclif discover --json                          # every provider, its tier, whether credentials are configured
aclif learn salesforce --json                  # a briefing: topics, key fields, query syntax, auth paths
aclif salesforce data query --schema           # flags, args, safety metadata, no execution
aclif salesforce data query --examples         # runnable examples with the responses they produce
aclif salesforce data query --query "SELECT Id, Name FROM Account LIMIT 5" --dry-run
aclif salesforce data query --query "SELECT Id, Name FROM Account LIMIT 5" --json
```

The envelope's `_context` block holds
pagination with the exact next command, the fields
available, and related commands worth running. Exit codes
are 0, 1 (API), 2 (usage), 3 (authentication). The contract
and its JSON Schemas are in
[CONTRACT.md](https://github.com/agent-cli-framework/aclif/blob/main/docs/CONTRACT.md).

## Three ways to run it

A vendor CLI is built for one deployment: installed on a machine, logged in by the person at the keyboard, one process per command. Behind a gateway that fails. Every call spawns a process and logs in again, the acting user's identity cannot be forwarded, nothing declares what a command will do, and nothing is uniform to audit. aclif's command classes run unchanged in three places, and whoever runs them decides who supplies credentials, enforces policy, and keeps the audit trail.

- **Run by the agent.** The agent process
  spawns the binary, executes the command, and reads the
  JSON it returns. Credentials come from flags, environment
  variables, or a profile in the agent's own environment.
  Use this when one agent, one operator, and one set of
  credentials share a trust boundary.
- **Run by a host application, the design-time
  case.** An application sits between the model and
  aclif and holds the credentials. The model calls a tool
  the application defines, and the application executes the
  command, in-process or by passing a command string to the
  CLI. A person or an authoring tool uses this to let a
  model discover providers, introspect commands, and
  validate the exact command it will write into an agent.
  Use this when the
  model must never hold credentials and tool definitions
  must stay out of its context.
- **Run by a gateway, the runtime case.** A
  deployed agent submits commands, and one long-lived
  process serves many such agents. The gateway resolves
  credentials from the enterprise vault per request, checks
  policy against the acting user, records every call, and
  keeps connections warm. The agents hold no provider
  credentials and cannot widen their own scope. Use this
  when many agents share providers and one place must hold
  policy and audit.

|  | Run by the agent | Run by a host application | Run by a gateway | 
|---|---|---|---|
| Credentials | flags, env, `config.yaml` | host-supplied resolver | vault-backed resolver, per request | 
| Policy | `config.yaml` | `capabilityGate` hook | `capabilityGate` plus the host's middleware | 
| Identity | `--identity-token` or env | the acting user on the invocation | the acting user and SSO claims from the request | 
| Audit | stderr line per run | reporter events | reporter events, recorded by the host | 
| Connections | file session cache | runtime pool | runtime pool, keyed per instance and identity | 

Details on the [Embedding](embedding.html)
page.

## Gateway deployments

Long-lived, embeddable deployment enables a gateway topology where additional security policy can be applied. One process the enterprise operates executes every command for every agent, and the arrangement provides:

- **Credentials in one place.** Resolved
  inside the gateway, per request, from the enterprise's
  vault. Agents hold none.
- **Enterprise-wide canonical names.** Tenant catalogs and alias sets are held by the gateway, so
  every agent uses the same names for the same records
  across every provider and instance.
- **Every call attributed to a person.** The acting user's identity travels with each call into the
  policy check and the audit record, even through a shared
  service account.
- **Policy enforced once.** Every command
  declares what it will do, and the gateway checks that
  declaration before the command's code loads. Agents cannot
  widen their own scope.
- **One audit trail.** The same event for
  every command from every agent, naming the user, the
  command, and the outcome.

## Install, or build your own

```
npm install -g @aclif/core

# Your org's My Domain URL, no trailing slash
export SF_INSTANCE_URL=https://example.my.salesforce.com

# A session token from the Salesforce CLI (sf org login web first if needed)
export SF_ACCESS_TOKEN=$(sf org auth show-access-token -o me@example.com --json | jq -r .result.accessToken)

aclif salesforce data query --query "SELECT Id, Name FROM Account LIMIT 3" --json
```

Without the Salesforce CLI, use an API user. Salesforce emails the security token when the password is set or reset:

```
export SF_INSTANCE_URL=https://example.my.salesforce.com SF_USERNAME=me@example.com SF_PASSWORD=... SF_SECURITY_TOKEN=...
aclif salesforce data query --query "SELECT Id, Name FROM Account LIMIT 3" --json
```

The `aclif` binary ships with every built-in
provider and needs Node 22 or later. The binary you ship is
yours: one scaffold command produces a CLI with its own
name, its own config directory, its own environment
variables, and only the providers it chose. See
[Getting started](getting-started.html) and
[Build a CLI](build-a-cli.html).

## Providers

Salesforce, ServiceNow, DocuSign, and Agentforce are
native and are included in every release. Google Workspace
(Gmail, Calendar) is contributed. A private tier holds
providers a fork keeps to itself, under a path upstream
never commits to. Writing a provider takes little effort: it
is a direct translation of the platform's API specification
onto the command surface, a coding agent does it from a
sample prompt in the repository, and the conformance suite
checks the result. See [Providers](providers.html).

aclif is MIT licensed. Contributions follow
[CONTRIBUTING.md](https://github.com/agent-cli-framework/aclif/blob/main/CONTRIBUTING.md);
the guide for people and coding agents changing the
framework is
[AGENTS.md](https://github.com/agent-cli-framework/aclif/blob/main/AGENTS.md).
