aclif

Developer FAQ

Architecture and protocols

1How is access via aclif different from using an MCP server?

With an MCP server, the agent reaches an API through a process definition someone described and deployed. That server publishes a list of tools, the agent picks one, and the server executes it. With aclif, the agent reaches the API through a command it composes itself. The agent asks the command to describe its structure and provide examples. It then composes the exact command required, runs it, and gets one JSON document back. MCP is a protocol between a model and a server. aclif is a tool the agent runs directly.

For many agent use cases, using MCP imposes unnecessary operational and economic costs. aclif was designed to eliminate these costs. The economic cost is context. Every tool an MCP server lists occupies the agent's context and consumes tokens on every turn. The server's author therefore chooses between coverage and cost. Many tools keep the whole API reachable. A few broad operations stay cheap but cannot express everything the API can do. A host can lower the cost with tool filtering or deferred loading, or a server could publish a generic call tool. Each of those is a design-time decision, made per server by whoever builds or configures it, and it sets which operations the agent can ever reach. Each deployed server has an operational cost as well. Each is its own process to deploy, secure, and keep current, with its own grammar, login, error format, and names for the same things. An agent that works across several platforms needs a server for each.

aclif resolves the trade-off. A command's definition loads only when the agent asks for it with --schema or --examples, so the full API surface of every provider is reachable at no standing cost in context. Every provider shares one grammar, one JSON envelope, one error vocabulary, and declared safety metadata. Canonical names let an agent call a record customer whether the provider stores it as Account or core_company. A protocol does not supply any of this on its own.

The larger difference is when the command is chosen. An MCP tool call is decided by the model at run time, on every run. For many agentic workflows, the aclif command can be determined once, at design time: a person or an authoring tool discovers the provider, introspects the command, and writes the exact command string into the workflow. At run time that command executes as ordinary code, with no model in the loop. Execution is deterministic, and the inference cost is zero. 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.

2How is it deployed?

aclif can run in three ways. Any agent framework, or a hand-written loop, can use any of them, since every result is just a JSON document.

  • 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. 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.

Details, including the minimal host code, are on the Embedding page.

3What are the runtime requirements?

aclif needs Node.js 22 or later and nothing else. @aclif/core is an npm package with a binary attached, written in TypeScript and built on oclif. Its continuous integration runs on Linux and Windows under Node 22 and 24.

Safety, security, and context

4How does a gateway handle credentials?

A gateway is meant to sit inside an enterprise that already has an identity provider and a secrets vault. The agents that call it hold no SaaS credentials. Each request to the gateway includes the agent source and the user's SSO identity token. The gateway verifies it and attaches that identity and the token's claims to the aclif invocation, where every command, hook, and audit event can read them.

Credentials come from the vault. aclif defines a one-method CredentialResolver interface and includes resolvers for static values, environment variables, and config-file profiles. A vault resolver is not included, since every vault has its own API. The gateway author needs to write one: a small class with that single method, which looks up the entry for the current request in the enterprise vault and returns it. The framework calls it before each command and hands the secret to the provider client and nowhere else. The secret never reaches the agent, the response, or any log.

The identity stays with the call, so policy is checked against the user before a command runs and the audit record names who ran it.

5How does a gateway handle shared service accounts?

A shared service account is one credential for a provider instance that many users and agents act through, such as an integration user in a CRM. It lives in the vault as one entry per organization, provider, and instance. The gateway's credential resolver returns it when the calling agent is entitled to it, and the provider client authenticates with it the same way it would with any other credential. Nothing in the framework treats it as a special case.

A gateway can still attribute each call to a person and limit what the shared account may do. The user's identity travels with every call, so the gateway can produce a record that names the person who ran the command even though the target system sees only the service account.

6How does aclif save tokens in the context window?

The token cost aclif targets is tool definitions. A tool server publishes its tools up front, and each definition sits in the agent's context on every turn whether or not the task needs it. For a full enterprise API that could be hundreds of definitions. An agent that accesses several platforms multiplies the count, because each platform brings its own tool set, its own grammar and namespace, and the agent has to hold all of them at once.

aclif inverts the loading. One tool describes the grammar for them all. The agent asks for a command's definition at the moment it needs it and pays nothing for the rest. Because the grammar and the envelope are the same for every provider, adding a platform adds no new grammar to learn, and canonical names mean one vocabulary across all of them, so the context an agent holds stays about the same size whether it reaches one platform or five.

An agent that executes a defined workflow can remove the model from the call altogether by fixing the command at design time, as described in question 1.

Supported providers

7Do I need a provider for every external service an agent accesses via aclif?

Yes. A provider is what maps a platform's API onto the command surface. The provider supplies the client, the credential schema, the error classifier, and the commands with their safety metadata and examples. The framework derives everything else from those declarations: auth flags, environment variables, profiles, etc.

8What providers are available today?

Five, all included in the aclif binary.

  • Salesforce (native): SOQL and SOSL queries, aggregates, DML, object and field metadata, permissions, Apex classes and triggers, and debug logs.
  • ServiceNow (native): table queries, aggregates, DML, table and field metadata, full-text search, and server-side scripts.
  • DocuSign (native): envelopes, from creating and sending to listing, downloading, and deleting.
  • Agentforce (native): listing agents, and starting, messaging, and ending sessions with them.
  • Google Workspace (contributed): Gmail (query, read, send, reply, attachments) and Google Calendar.

Native providers are maintained by the project and are included in every release, with live smoke tests against real instances. Contributed providers are maintained by the people who wrote them and are packaged with the aclif release. Private providers are kept by one deployment and never ship upstream. All three tiers run through the same conformance suite.

More native providers are planned for future releases, and contributed providers are welcome. See CONTRIBUTING.md.

9Can an agent work with two instances of the same provider?

Yes. An instance is one deployment of a platform, such as a single Salesforce org, with its own credentials and its own customizations. Two Salesforce orgs are two instances of the Salesforce provider.

Each instance has its own tenant catalog, captured with introspect --bootstrap, so learn and --schema describe that instance's own custom objects and fields.

Canonical names span instances the same way they span providers: an alias set can map customer to Account in one org and to a custom object in the other, and --canonical resolves it for whichever instance the command names.

10How much effort is it to write a new provider?

The effort is small if a coding agent writes it. Most of a provider is a direct translation of the platform's API specification: each operation becomes a command, its parameters become flags, its enumerations become flag options, and its method and path decide the safety metadata. That translation is tedious for a person but trivial for Claude Code, Codex, or a similar tool.

The aclif repository provides a sample generation prompt in PROVIDER_AUTHORING.md, an AGENTS.md for coding agents, and an add-provider skill for Claude Code. The agent generates the provider, runs the conformance suite, and fixes what fails. You review the result. Details are in the repository.

Aliases, canonical names, and semantic data

11How does aclif handle canonical names across providers?

With alias sets. An alias set is a JSON or YAML file that maps a canonical entity name, and the field names under it, to the native name each provider and instance uses. One set can say that customer is Account in one Salesforce instance, Customer__c in a second Salesforce instance, and core_company in ServiceNow. A starter vocabulary is included with the framework, covering customers, contacts, people, opportunities, incidents, email, calendar events, and envelopes across the built-in providers.

An organization writes its own alias set from the material the CLI gives it, and the framework resolves it. introspect --bootstrap captures each instance's catalog of objects, fields, and enumerations, one catalog per instance, and comparing two catalogs is how a person or an authoring agent decides that this instance's Account and that one's Customer__c are both customer. The result is a file. aliases validate checks its structure and that every provider it names is one the CLI has, and aliases import puts it in use, layered above the starter vocabulary so an organization's own mapping wins where the two overlap.

A command resolves the names when it runs with --canonical. The CLI looks up each entity and field for the command's provider and instance through the sets in use, and sends the native names to the API.

The native names stay reachable. An agent that knows an instance's real object and field names can use them directly, and an agent that only knows the canonical vocabulary can work across every provider and instance the organization has mapped. Inside a gateway the host supplies the alias store, so the mappings live with the organization's other configuration.

12Canonical mapping is a notoriously hard problem. Whole product lines exist to solve it with a semantic data layer. What makes you think aclif can solve it?

It does not try to. General-purpose data unification, the problem a semantic layer or a data warehouse takes on, is a large engineering effort, and aclif does not attempt to solve that problem. It works on a much narrower, tightly constrained subset: naming the entities and fields an agent acts on, so that a command an agent composes once runs against whichever provider and instance it names. That is action execution, and the constraints are what make it practical.

  • The mapping is a data file. No provider is written to understand every enterprise customization natively. Each instance's custom objects and fields are captured into a tenant catalog at deploy time, and an alias set is a plain file that maps a canonical name such as customer onto that instance's own object, such as Account_Custom_v2. The framework resolves the file at run time and sends the native names to the API.
  • The work happens at design time. Nothing is inferred by a model during an automated run. A person or an authoring agent compares two catalogs, decides that this instance's Account and that one's Customer__c are both customer, and records that decision once. When the schema changes, the operator recaptures the catalog and edits the alias set. The framework and the agent's own commands stay as they are.
  • Every miss is a structured error. A canonical name the alias set does not know fails locally, before any request leaves the machine, with CANONICAL_NOT_FOUND and the nearest matches. A native field the platform rejects comes back as INVALID_FIELD with the corrected value and a working example. In both cases the agent gets one JSON document that names the failure and the fix, and it can correct the command in one turn instead of guessing. --schema and --flags-for let it check the command before running it at all.

So aclif is not a semantic layer. It is a uniform command grammar, with a lookup table in front of it, that an agent can use safely. The entity and field names an organization already has, whether from custom objects or an existing glossary, can be written into that table.

13Can I drive the canonical vocabulary from my existing semantic layer, business glossary, or enterprise data dictionary?

Yes, for the part of it that names things. Semantic layers and metric models are built for data warehouses and analytics platforms, where the physical side is a warehouse table, an analytical copy of the operational systems. aclif's target use case is the operational systems themselves: live SaaS instances and external service endpoints that are the source of record, reached through their own APIs. A warehouse with an API could be wrapped as a provider like any other, but that is not the case the framework is built around. An alias set's native side is an object in one of those instances, as captured in its tenant catalog.

What transfers directly is the naming half of a semantic model: its logical entities, the dimensions or attributes under them, and the synonyms a glossary attaches to each. Those map one to one onto alias-set entities and fields, with the business term as the canonical name. An alias set is a JSON or YAML file with a small published structure, so anything that can write the file can drive the vocabulary. The glossary supplies the canonical side, the tenant catalog for each instance supplies the native side, aliases validate checks the result, and aliases import puts it in use above the starter vocabulary.

Building the alias set from the semantic layer is therefore a re-target. The semantic layer's business names become the alias set's canonical names. The semantic layer's references to warehouse tables are set aside, unless the warehouse is itself one of the instances the agent acts on. In their place, each canonical name is bound to the native object in the tenant catalog of the live instance. Where the warehouse was loaded from those same source objects, its lineage usually names them.

Development and error handling

14Can I add my own internal or proprietary APIs?

Yes, in one of two ways, depending on how much of the API the agent needs.

  • One endpoint: a manifest. A JSON document declares the command id, description, safety metadata, a request template with method, path, query, and body containing {flag} placeholders, the flags, and optionally a response structure and examples. It is loaded from a profile in config.yaml or added by a host.
  • A whole API: a provider. You write a TypeScript provider in the private tier of your own CLI, to the same contract as the native providers, usually by having a coding agent generate it from the API's OpenAPI document.

See Providers, PROVIDER_AUTHORING.md, and BUILDING_A_CLI.md.

15How does aclif handle an instance's custom objects and instance-specific endpoints?

By learning them from the instance itself. A provider's commands cover the platform's API as the vendor documents it, but every instance adds custom objects, custom fields on standard objects, its own picklist values, and sometimes endpoints of its own. None of that is in any specification, so aclif captures it from the live instance at deploy time and keeps it in a tenant catalog. A new custom object added later is picked up the same way, with no change to the provider and no rebuild.

<provider> introspect --bootstrap walks the instance once, under the operator's credentials, and records each custom entity and each custom field on a standard entity, with its type, label, enumerated values, and the entities it references. The walk is read-only and the catalog holds structure only, never record values or secrets. It is cached per provider and instance, so two Salesforce orgs get two catalogs. Each entry records how it was learned: from the platform's metadata API, inferred from a sample record, or found by a probe. --refresh recaptures after the instance changes, and --all widens the walk to every entity.

Once the catalog exists, every other command reads it without a further API call. learn lists the instance's own entities in its briefing, --schema reports them as available entities on the commands that take one, and an alias set can map a canonical name onto a custom object, so an agent that knows only customer reaches Customer__c. An endpoint the instance added outside the platform's standard API is declared as a manifest, described in the previous question, and joins the same command surface.

16What is different about aclif's errors?

Every error tells the agent what went wrong so it can recover in a single turn. Each error names the failure and includes the command that fixes it.

{
  "success": false,
  "error": {
    "code": "INVALID_FIELD",
    "message": "No such column 'Cases' on entity 'Case'.",
    "correctedValue": "SELECT AccountId, COUNT(Id) Cases FROM Case GROUP BY AccountId ORDER BY COUNT(Id) DESC",
    "syntaxGuide": "Salesforce SOQL does not allow ORDER BY on aggregate aliases. ...",
    "workingExample": "SELECT AccountId, COUNT(Id) Cases FROM Case GROUP BY AccountId ORDER BY COUNT(Id) DESC LIMIT 10"
  }
}
17Does introspection consume SaaS API quota?

No. Every command accepts seven introspection flags, each of which returns before the command executes: --schema, --examples, --shape, --changelog, --discover, --flags-for <category>, and --estimate. They return static data the command declares about itself: its flags and arguments, its safety metadata, its worked examples with the responses they produce, and the structure of its result. No request leaves the machine, so no credentials are needed and no API call is counted. An agent can work through the whole discover, learn, introspect, preview loop against a rate-limited instance and spend nothing.