Autessa CLI
autessa is a model-driven command line interface over the Autessa SDK. The builder UI and the CLI are two front ends over one platform: everything you would normally click together — tools, agents, tables, triggers, scheduled jobs, webhooks, custom apps — can be built entirely from a terminal, with no browser in the loop. And because it is the same SDK writing the same records, anything you build this way is in the web app the instant it is written: same ids, same versions, same history, same permissions.
What it's for
- Reproducible builds. A shell script that creates a table, a tool, an agent and a schedule is a deployable artifact. Clicking through a UI is not.
- Agent-built systems. A coding agent can read the CLI's own help and assemble a working Autessa workflow without a human driving a mouse, either from its shell or through the hosted Autessa connector in any AI app that supports MCP. See Coding agents.
- Environment promotion. The same script, run against a different profile, builds the same thing in a different company.
- Scripting and automation. Every command reads and writes JSON, so the CLI composes with
jq, shell scripts, and CI steps. - Review and handoff. Build from the terminal, then send a teammate a link to the resource in the builder. They see exactly what you made, in the UI they already know.
Key concepts
The surface is generated, not written
The CLI ships as a single zero-dependency Node file that contains no command list. On first use it fetches the SDK manifest from your server and caches it at ~/.autessa/manifest.json. Command names, argument names and types, help text, response shapes and grouping all come from that manifest.
Two consequences worth internalizing:
- When the platform gains a command, your CLI gains it too — no upgrade needed, just
--refresh. - When a command name changes, your cached list goes stale. The CLI detects this (
SDK_UNKNOWN_ENDPOINT), refreshes automatically, and tells you to re-run. That is not a missing command; it is an out-of-date cache.
Namespace, command, flags
Every invocation is autessa <namespace> <command> [--flags], with names in hyphen-case:
autessa agents all
autessa tools publish --toolId gPdJwp5jbr9eN
autessa autessadb tables create --tableName todos --schema '{"columnDefinitions":[...]}'
Namespaces nest where the SDK nests them — autessa autessadb query insert, autessa tools history list, autessa app domains status.
You discover, you don't memorize
Three commands get you anywhere:
autessa help # every namespace
autessa <namespace> help # a namespace's commands
autessa <namespace> <command> help # a command's arguments, types and response
Running a command that still needs required arguments prints its help instead of failing — the drill-down is the interface. See Discovering commands.
One SDK, two front ends
There is no "CLI API" separate from the platform. Every command posts a {methodId, args} envelope to a single dispatcher, which invokes the same SDK method the web builder invokes, behind the same guard chain: company scope, permission checks, read-only policy, argument validation, call budget.
your terminal the browser
│ │
│ autessa <ns> <cmd> │ clicks
▼ ▼
┌────────────────────────────────────────┐
│ the Autessa SDK │
│ scope · permissions · validation · │
│ budget · versioning · audit │
└────────────────────────────────────────┘
│
▼
one set of records, one history
The practical guarantee: the CLI cannot do anything your account could not do in the browser, and the browser cannot see anything the CLI did not really do. There is no shadow state and no sync step.
Immediately auditable
"Auditable in the web app" is not a promise about eventual replication — it is a consequence of there being one store. A tool you create from the terminal has a toolId you can paste into a builder URL right away. An agent you publish from a script shows up in the agent list at version 1. A row you insert lands in the table grid.
The reverse holds too. Runs you trigger from the CLI are recorded in the same execution history the UI reads, tagged with where they came from:
autessa tools history list --toolId gPdJwp5jbr9eN
{
"executions": [
{
"eventId": "a02e8438-9032-46f3-a875-41d051f2c013",
"toolId": "gPdJwp5jbr9eN",
"toolName": "docs_scratch_summarize",
"invocationId": "df4fd983-9021-43c8-b42c-cb02c8f0105c",
"source": "API",
"success": true,
"durationMs": 3001,
"createdAt": "2026-09-10T09:24:45Z",
"requestVariables": "{\"text\":\"...\"}",
"result": "{\"success\":true,\"content\":\"...\"}",
"requestTruncated": false,
"resultTruncated": false
}
],
"totalElements": 1,
"hasNext": false
}
The source field distinguishes API, TRIGGER, WORK_ITEM, AGENT, SCHEDULED, WEBHOOK and SCRIPT — so a terminal-driven run is auditable as a terminal-driven run, not disguised as something else.
The audit surfaces
Every one of these is readable from the CLI and viewable in the web app:
| What | Command | In the web app |
|---|---|---|
| Tool executions, with decrypted inputs and outputs | autessa tools history list / history detail | Tool history |
| Closed agent conversations, with full message and tool logs | autessa agents conversations history / conversation | Agent history |
| Manager conversations and evaluations | autessa managers conversations | Manager history |
| Table trigger firings, with event input and response | autessa trigger-history list / detail | Triggers |
| Row-level data access | autessa autessadb access-log list | AutessaDB access log |
| Scheduled job runs | autessa scheduled-events history | Scheduled jobs |
| Inbound webhook calls | autessa custom-webhooks get-execution-history | Webhook handlers |
Payloads are capped in list responses — requestTruncated and resultTruncated tell you when — and the matching detail command returns the full, uncapped value.
conversations history may lag a moment behind execute-close.Jumping from a terminal to the page
Ids are the bridge. Any resource you create prints an opaque id you can hand straight to the web app. For custom apps the CLI composes the URLs for you:
autessa app visible-urls --appId GTBhswTJ6a9r
{
"editorUrl": "https://builder.autessa.com/app-builder/editor/GTBhswTJ6a9r",
"publishedUrl": "https://builder.autessa.com/customappsv2/view/GTBhswTJ6a9r"
}
editorUrl is where a human opens what you built; publishedUrl is where end users reach it once you publish. A build script that ends by printing editorUrl gives whoever runs it a one-click path into the UI.
What stays in the browser
Working from a terminal does not make the browser obsolete. A number of operations are deliberately web-app-only, and they fall into recognizable groups:
- OAuth connector setup. Connecting Gmail, HubSpot, QuickBooks, Notion and the rest requires a human granting consent to a third party. The CLI lists, reads, shares, uses and deletes connectors — it just cannot create the ones that need a consent screen. A few that authenticate with an API key rather than OAuth (beehiiv, Ghost, Bluesky) can be connected without a browser.
- Money. Paying an invoice, prepaying, changing a plan commitment and managing payment methods are UI-only. Reading your balance, ledger, budgets, invoices and per-task usage is not.
- Identity and org. SSO configuration, ownership transfer, and poweruser API-key management are administered in the browser.
- Human-confirmation flows. Sending and voiding e-signature envelopes, dispatching meeting recorder bots, publishing marketplace templates, and recording SMS consent.
- App source editing in the visual builder. You can pull, edit and push an app's files from the CLI — see Custom apps — but the vibecode/workspace editing experience itself is a browser feature.
These commands still appear in the help tree, and running one tells you where to go:
autessa payments add-bank-account
Payout bank accounts are linked from your Autessa Payments settings in the web app.
That is a design decision rather than an omission: discovery should tell you a capability exists and where it lives, instead of leaving you unsure whether you mistyped.
How to build a workflow end to end
A complete, reproducible build — table, tool, agent — with no browser:
#!/usr/bin/env bash
set -euo pipefail
# 1. A table to work against
TABLE_ID=$(autessa autessadb tables create \
--tableName support_tickets \
--schema '{"columnDefinitions":[
{"columnName":"subject","columnType":"SHORT_TEXT","required":true},
{"columnName":"body","columnType":"LONG_TEXT"},
{"columnName":"status","columnType":"SINGLE_SELECT","allowedValues":["open","triaged","closed"]}
]}' | jq -r '.tableId')
# 2. A tool the agent can call
TOOL_ID=$(autessa tools create \
--toolName triage_ticket \
--toolDescription "Classify a support ticket's urgency in one word." \
| jq -r '.tool.toolId')
autessa tools update --toolId "$TOOL_ID" --updatedTool "$(jq -n --arg id "$TOOL_ID" '{
toolId: $id,
name: "triage_ticket",
description: "Classify a support ticket'"'"'s urgency in one word.",
toolConfig: {
toolType: "LLM_CALL",
config: {
promptTemplate: "Reply with exactly one of: low, medium, high.\n\n@@{body}",
model: "SMALL_INSTRUCTION_FOLLOWING"
}
},
arguments: { body: { description: "The ticket body.", isRequired: true, argumentSchema: { type: "string" } } }
}')"
autessa tools publish --toolId "$TOOL_ID"
# 3. An agent that uses it
AGENT_ID=$(autessa agents create \
--agentType SIMPLE \
--agentName "Ticket Triage" \
--agentDescription "Triages inbound support tickets." \
| jq -r '.agent.agentId')
autessa agents update --agentId "$AGENT_ID" --updatedAgent "$(jq -n --arg id "$AGENT_ID" --arg tool "$TOOL_ID" '{
agentId: $id,
agentType: "SIMPLE",
name: "Ticket Triage",
agentInstructions: "Triage the ticket with the triage_ticket tool and reply with just the urgency.",
model: "SMALL_INSTRUCTION_FOLLOWING",
maxIterations: 10,
tools: [{ toolId: $tool }]
}')"
autessa agents publish --agentId "$AGENT_ID"
echo "table $TABLE_ID"
echo "tool $TOOL_ID"
echo "agent $AGENT_ID"
Run it and every id it prints is live in the builder before the script exits. Delete everything just as reproducibly:
autessa agents delete --agentId "$AGENT_ID"
autessa tools delete --toolId "$TOOL_ID"
autessa autessadb tables cli-delete --tableId "$TABLE_ID"
autessa autessadb tables list-deleted shows your trash and restore brings a table back. Agent and tool deletion is permanent.How to run unattended
autessa login needs a browser once, and the credential it mints is tenant-scoped and self-expiring with no silent refresh. That is a security property, not an oversight — there is no long-lived CLI token to leak from a build machine.
For work that must run without a human present:
-
Long-running or scheduled work belongs on the platform, not on a build box. Scheduled jobs, table triggers and inbound webhooks run server-side with no session to expire. Use the CLI to create them, and let the platform run them.
-
For genuinely unattended HTTP automation, use a poweruser key — the Poweruser API covers the same operations the CLI exposes, and every CLI command has a poweruser equivalent.
-
Keep environments in separate profiles and select per-invocation, so a promotion script never has to guess which tenant it is pointed at:
AUTESSA_PROFILE=staging ./build-workflow.shAUTESSA_PROFILE=prod ./build-workflow.sh
Where to go next
| If you want to… | Read |
|---|---|
| Install, sign in, manage several tenants | Install and sign in |
| Learn the help tree, flags, output formats, errors | Discovering commands |
| Sync a custom app's source to disk | Custom apps |
| Create tables and read/write rows | AutessaDB |
| Build a capability an agent can call | Tools |
| Create, configure and run an agent | Agents |
| Orchestrate several agents | Managers |
| Run work on a cron, interval or timer | Scheduled jobs |
| Point a coding agent at Autessa | Coding agents |
| See every namespace and command | All commands |
Related
- Discovering commands
- Coding agents
- Command surface
- Poweruser API — the same operations over HTTP
- Platform concepts