aclif

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

FieldHolds
successtrue or false
resultthe records or the provider's response
_context.paginationreturned, total, hasMore, and nextCommand, a complete command string for the next page
_context.relatedCommandscomplete command strings worth running next
erroron 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.