Getting started
The reference CLI is the aclif
binary, built with every native and contributed provider.
Requires Node 22 or later.
Install
npm install -g @aclif/core
aclif discover --json
Hello providers
Before you configure anything, the binary will tell you
what it can do. Every native provider, Salesforce,
ServiceNow, DocuSign, and Agentforce among them, ships with
its standard schemas built in, and discover,
learn, --schema, and
--examples read them straight from the binary.
You can walk a provider's commands, flags, and safety
metadata from a fresh install. Nothing here needs
credentials:
npm install -g @aclif/core
aclif discover --json # every provider, its commands, whether credentials are configured
aclif learn salesforce --json # a briefing: topics, key fields, query syntax, auth paths
aclif salesforce data query --schema # flags, args, and safety metadata, without executing
aclif salesforce data query --examples # runnable examples with the responses they produce
aclif salesforce data query --query "SELECT Id, Name FROM Account LIMIT 3" --dry-run
The dry run prints what the command would do and its declared safety metadata:
{
"dryRun": true,
"wouldExecute": {"query": "SELECT Id, Name FROM Account LIMIT 3"},
"aciMetadata": {
"mutability": "read",
"idempotent": true,
"reversible": false,
"blastRadius": "filtered_set",
"apiCallsConsumed": 1,
"requiresConfirmation": false,
"prerequisites": []
}
}
Run the same command without --dry-run and,
with no credentials configured, the error names every way to
supply them, with exit code 3:
{
"success": false,
"error": {
"code": "NO_CREDENTIALS",
"message": "No Salesforce credentials provided.",
"syntaxGuide": "Use one of:\n Session token: --instance-url + --access-token (or SF_INSTANCE_URL, SF_ACCESS_TOKEN)\n Username + password (+ security token): ...\n OAuth2 client credentials: --instance-url + --client-id + --client-secret (or SF_INSTANCE_URL, SF_CLIENT_ID, SF_CLIENT_SECRET)"
}
}
To run it for real, point it at an org as described under Credentials below.
Or from a checkout:
git clone https://github.com/agent-cli-framework/aclif.git
cd aclif && npm install && npm run build
node bin/run.js discover --json
discover lists every provider, its tier, and
whether credentials are configured. It needs no credentials
itself.
Credentials
Credentials resolve in one order: command flags, then environment variables, then a named profile in the config file. Each provider declares its authentication paths once, and the flags, environment names, profile format, and error messages all follow from that declaration.
# 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
For anything longer than a session, put a profile in
~/.config/aclif/config.yaml. Secrets in a
profile can be literal, or read from the environment, a
file, or a command at credential time, so the file itself
holds no secret.
default_profile: dev
profiles:
dev:
salesforce:
instance_url: https://example.my.salesforce.com
access_token: {env: SF_ACCESS_TOKEN}
Select one with --profile dev or
ACLIF_PROFILE=dev.
aclif auth status shows which profile and
credentials are in effect without revealing a secret. The
full reference is
CONFIGURATION.md.
Learn a provider, then a command
aclif learn salesforce --json # topics, key fields, query syntax, auth paths
aclif salesforce data query --schema # flags, args, safety metadata
aclif salesforce data query --examples # runnable examples with the responses they produce
aclif salesforce data query --shape # the structure of a successful result
aclif salesforce data query --estimate # rough token cost per record
Every introspection flag returns before the command executes and works with an empty environment, so none of these calls needs credentials or counts against the instance's API quota. This is the property that lets an agent load a command's definition only at the moment it needs it and pay nothing for the rest. Because every provider shares the same grammar, an agent that has learned one command has learned the pattern for all of them.
Run, safely
aclif salesforce data query --query "SELECT Id FROM Account LIMIT 1" --dry-run
aclif salesforce data dml --operation delete --object Account --ids 001xx --confirm
Every mutation accepts --dry-run. Commands
whose declared metadata marks them as deletes, as touching
all records, or as executing code on the target require
--confirm, and the policy layer enforces that
before the command's code loads. After every run an audit
line writes to stderr naming the command, the user, and the
exit code, so every call is attributed to a person even when
it ran through a shared service account.
Read the result
| Field | Holds |
|---|---|
success | true or
false |
result | the records or the provider's response |
_context.pagination | returned,
total, hasMore, and nextCommand, a
complete command string for the next page |
_context.relatedCommands | complete command strings worth running next |
error | on failure:
code, message, a
syntaxGuide naming the command that fixes it,
and where possible a workingExample and a
correctedValue |
Exit codes are 0 for success, 1 for an API failure, 2 for a usage error, and 3 for missing or rejected credentials, so an agent can branch without parsing prose. The full contract, with the JSON Schemas that validate every envelope, is CONTRACT.md. The agent-facing skill is skills/aclif.
Give an agent the binary
An agent that reads or changes Salesforce records on a
user's behalf reaches Salesforce by running
aclif commands as a subprocess.
Install aclif on the machine where the agent
runs and put the credentials in that machine's environment.
Then install the skill. It tells the agent to start with
aclif discover --json, to read
--schema and --examples before
running a command, to dry-run mutations, and to stop on a
credential failure instead of asking for a token. The skill
is in the npm package and in the repository at
skills/aclif;
copy it where your agent loads skills:
cp -r "$(npm root -g)/@aclif/core/skills/aclif" ~/.claude/skills/aclif
For a runtime with no skill support, put the contents of
SKILL.md in the system prompt. The agent learns
each command from the binary itself, so the skill is the
only document it needs;
USING_WITH_AGENTS.md
covers the install for other runtimes and for a CLI built
from aclif. The repository
Dockerfile
builds a container with the binary and nothing else, for
agent sandboxes that cannot install Node.
The agent runs
aclif learn salesforce --json to get the query
syntax, reads aclif salesforce data query --schema,
then runs
aclif salesforce data query --query "SELECT Id, Name FROM Account WHERE Industry = 'Energy'" --json
and reads the records out of the envelope. If it tries a
delete without --confirm, the command returns
an error and nothing is changed.
For an agent that executes a defined workflow, do the discovery once. Run the introspection steps at design time, embed the exact command string in the workflow, and the agent executes it at run time as ordinary code, with no model in the loop and no inference cost for the call.
Next, build a CLI with your own name and providers or embed the runtime in a host process.