CLI
Install the agw CLI to sign in, add providers, create and check apps, and read usage from a terminal or a coding agent.
Install Node.js 22.19 or later, then install the CLI:
npm install -g @maxceem/agw
agw --help
agw deployment status --jsonA fresh CLI uses the hosted API. If you already have an account, run
agw account login before creating resources; otherwise a creation can start a
separate account. A saved connection remains active across commands, so check
the URL from deployment status and the account from agw account status.
Use agw deployment connect --cloud to sign in to the hosted service again.
It starts browser login unless you supply a management key.
If you want a new hosted account, your first provider, provider-gateway or app
creation initializes one and saves its credential privately. For example, run
agw provider add --type openai --browser --no-open. Help, status, lists,
validation and dry runs never create accounts. New unclaimed accounts are
temporary; check agw account status and use agw account claim to keep yours.
Self-hosting
Connect to an existing gateway with agw deployment connect --url URL.
To create one on your Cloudflare account, use agw deployment setup --name my-gateway --no-domain. No source checkout is needed. See
Deploy to Cloudflare for deployment and
offline archive options.
Sign in
agw account login signs the CLI in through your browser. It prints a pairing
code, opens the console's approval page and waits:
Pairing code: ABCD-EFGH
Check that your browser shows this same code before you approve.
Approve at: https://console.appaigateway.com/cli/approve/…Check that the page shows the same code before you approve: that is what tells you the request on the page is the one your terminal made. Sign in if you are not signed in already, pick the account if you belong to several, and approve. The browser comes back to the CLI, which receives a management key of its own, stores it privately and prints your account status. The tab can then be closed. Declining on the page ends the command with an error. The CLI waits up to five minutes, and the approval page stays valid for 15.
To sign in to your own deployment, run agw deployment connect --url https://ai.example.com, which runs the same login against that URL.
- No browser on this machine: over SSH, on Linux with no display, or when
no one is at the terminal, the CLI does not try to open one. It prints the URL
and the pairing code, as
--no-opendoes anywhere, and the same happens if a browser fails to open. Open the URL on any device, or go to/clion your console, for examplehttps://console.appaigateway.com/cli, and type the code; then approve. The CLI collects its key once you have. - An agent or a script: with
--jsonor--no-inputthe command returns at once withstate: "pending", theurland theuserCode. Give the URL to a person, then runagw operation wait <id>to finish the login once they have approved it.
Each key a login creates is listed on the console's Access page
with a CLI tag and the label the CLI sent, such as CLI on mac-studio, so
you can tell which machine holds which key. Revoke one there to end that
machine's access.
agw account logout revokes the saved key on the deployment and removes it from
this machine. If the deployment cannot be reached, the key is still removed
here, the command says it could not be revoked, and revoked is false in its
--json result; revoke it on the Access page instead.
Keys for agents and CI
A machine that cannot approve anything in a browser uses an existing management key. Create one on the console's Access page, then either:
- set
AGW_MANAGEMENT_KEYin the environment. When it is set, it is the credential for every command and takes precedence over any saved login, and the environment key is not saved to disk. Commands can still save operation state and application-key files.agw account loginrefuses to run while it is set, andagw account logoutonly clears the saved login and reminds you the variable is still in charge. Useagw deployment connect --url URLto choose which deployment the key is sent to; it stores the URL, not the key. - or pipe it once with
--key-stdin, which saves it like a browser login:
agw account login --key-stdin < /private/path/management-key
agw deployment connect --url https://ai.example.com --key-stdin < /private/path/management-key--key-prompt asks for the key in a hidden prompt instead. Never pass a key as
a command argument.
Human handoffs
Run agw account claim to establish human ownership. The CLI prints a browser
URL. Open it in a browser outside the agent's visible session, compare the
account shown with the terminal, and create your sign-in on that page. This
account must be claimed by a new person, so if the browser is already signed in
as someone with an account, the page asks you to sign out first. The page shows
the account being claimed and the person approving, and one button completes
it. The CLI stays connected afterwards, so an interrupted command can
simply continue; to end that access later, run agw account logout or revoke
its key on the console's Access page.
Provider commands offer a browser handoff for write-only secrets. Share the URL with the person supplying the credential. The page shows the provider, destination and proposed changes. Secrets never appear in CLI output or later reads. Poll with the operation command shown by the CLI; handoffs last 15 minutes.
Daily workflow
agw account status --json
agw provider list --json
agw app list --json
agw usage show --month 2026-09 --json
agw app --help
agw provider --helpUse the command's --help for its exact flags. Read an app before editing it.
Application updates carry the revision read when the command starts and reject
a competing write during that command. A --file exported earlier can still
replace more recent settings: reread and merge before using it. Add and update
with --file preserve the complete validated configuration, including native endpoint
parameters. They do not transfer credentials or usage
to another deployment. Build that file from agw app show <app-id> --json,
keeping name, config and status from result.app.
agw app snippet <app-id> prints a request that app can send: curl for a
server app, Swift for an iOS one. Creating an app prints it too. It is built
from that app's own providers, allowed endpoints and priced models, and stands
named placeholders in — PROVIDER_SLUG, MODEL — for anything not set up yet,
so you always get something to run and can see what is still missing.
For file changes, validate a new app with agw app validate --file app.json --json. For an existing app, use agw app update <app-id> --file app.json --dry-run --json, which validates it as an update. Check the returned
validation.remote: without a login, draft validation checks only the local
schema and cannot verify provider references or pricing.
After saving, run agw app check <app-id> --json. It reads configuration
without sending inference; it does not verify upstream keys, App Attest on a
device, sign-in or entitlements. Generate the matching client example with
app snippet and address any placeholder notes before using it.
agw app show and agw app check print an app's warnings.
Flag-based agw app add --type ios enables both production and development
App Attest environments. Use --attest-environments production for a shipped
app, and a separate development app when needed. The console and an API body
that omits environments default to production only.
--verify-on every_request or --verify-on token_exchange, on agw app add --type ios or agw app update, sets when the app verifies App Attest. A new
app verifies every request, which needs clients on the AppAIGateway Swift
package 1.4 or later; token_exchange checks the assertion once per hourly
token. Apps created before this setting was added were set to
token_exchange, so switch one to every_request only once every build in
use is on 1.4 or later.
Application keys are written only to a private file. Select a path with
--key-output, or use the default managed private file.
Use the browser login, AGW_MANAGEMENT_KEY or --key-stdin to authenticate;
see Sign in. Never put secrets in command arguments, source control, chat or logs.
The CLI does not make inference requests as a setup check. Provider inference
must be requested explicitly.
Human support
Where your deployment offers human support, agw support send emails it for
you, and the reply comes to your account's email address:
agw support send --type bug --message "Streaming responses stop after 30 seconds" --context app_id=my-app--type is bug, support or feedback. Pipe a longer message in with
--message-stdin, and add facts with repeated --context name=value. In a
terminal the CLI shows the message and asks before sending; without one it
sends only with --yes, so an agent has to have shown you the message first.
A message that looks like it contains a key, token or password is refused, and
the same message sent twice within ten minutes is sent once. The answer
carries a reference such as SUP-7F3K2Q to quote when you follow up.
Output and recovery
--json writes one JSON document to stdout with schemaVersion, ok and either
result or error. Progress goes to stderr. Without --json the same result is
printed as plain text to read, and a failure is printed to stderr instead of
stdout. A successful result with state: "pending" still needs its browser
step and operation wait; it does not mean the change finished. Exit codes are
0 for success, 2 for input errors, 3 for remote failures,
4 for state or authentication recovery, and 5 for a wait timeout. A timeout
leaves the operation pending.
A request refused by a limit says which one: error.message names the limit, its
ceiling and what the count is shared across, and error.details carries scope,
limit, windowSeconds, retryAfterSeconds and resetAt. Wait
retryAfterSeconds and repeat the same command.
The CLI keeps one active connection. Its private state lives in
$XDG_STATE_HOME/agw or ~/.local/state/agw, and %LOCALAPPDATA%/agw on Windows.
It saves initiation proofs before requests and credentials before reporting
success. Repeat a failed command with the same state to recover a lost response;
do not delete state or invent a new request proof. A recovered application key
can finish writing to a new unused output file without issuing another key.
A short lock guards each write to that state rather than the command around it,
so other commands still run beside an agw operation wait that is polling. A
deployment installed with agw deployment setup keeps its vault key in a file
of its own under vault-keys/ in the same directory, and keeps nothing else
from the install. Back that directory up privately: losing the vault key makes
stored provider credentials unreadable.
Remote key replay lasts 15 minutes. After it expires, recovery identifies the existing resource; inspect it and replace its key intentionally. Each creation is saved as an operation before it is sent, so running the same command again after a lost response never creates a duplicate. Account usage includes retained records from deleted apps.
agw deployment update --dry-run and agw deployment domain --hostname ai.example.com --dry-run inspect changes without deploying. Updating a mobile
app's embedded gateway URL remains a separate application release.