Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

CLI

The amodal CLI runs your agent's runtime locally — the same HTTP runtime and chat UI that Amodal hosts in the cloud, pointed at an agent bundle on disk. Use it to develop and test an agent before deploying.

It's a self-contained native binary (the JS runtime is embedded), so it needs no system Node, npm, or other runtime — just curl/tar to install.

Install

curl -fsSL https://releases.amodalai.com/install.sh | bash

This installs amodal into ~/.amodal and adds it to your PATH (macOS and Linux). Restart your shell, then check:

amodal --version

Upgrade any time:

amodal upgrade

amodal login

Sign in so amodal dev can route model calls through Amodal's managed gateway — no BYO provider key, no rate-limit juggling. It opens your browser for a WorkOS sign-in, captures the result on a local loopback, and stores the session in ~/.amodal/credentials.json (owner-only).

amodal login

Once signed in, amodal dev mints a model key scoped to your organization (with that org's quota and billing), so you can run an agent without setting any *_API_KEY. If you belong to more than one organization you'll choose one at login — see amodal org. Login also selects the active agent for trace export (auto-selecting a single agent, prompting when there are several, and creating one when the org has none) — see amodal agent.

Headless / CI — skip the browser and sign in with a platform API key:

amodal login --token <platform-api-key>

Sign out (removes the stored session):

amodal logout

Revoking your WorkOS session (in the dashboard) also invalidates the CLI, since it refreshes through WorkOS.

amodal org

Choose which organization amodal dev mints its gateway key against — a user can belong to several. amodal login sets this the first time (auto-selecting when you have one org, prompting when you have several). Switch or inspect it any time:

amodal org           # pick from a list
amodal org --list    # show your orgs and which is active

Override for a single run with amodal dev --org <org-id>. The active org is shown in the amodal dev startup banner. Switching orgs also reselects the active agent, since agents are org-scoped.

amodal agent

Choose which agent local amodal dev runs attribute their traces to — that's where they appear in the dashboard. amodal login sets this the first time (auto-selecting when the org has one agent, prompting when it has several, creating one when it has none). Switch or inspect it any time:

amodal agent           # pick from a list (or create a new agent)
amodal agent --list    # show the org's agents and which is active

amodal dev

Run the runtime against an on-disk agent bundle (any directory containing an amodal.json):

amodal dev ./path/to/agent    # point at a bundle directory
amodal dev                    # …or run from inside one (defaults to ".")

amodal dev serves two things at the same URL (default http://localhost:3847):

  • the HTTP runtime API — chat, tools, sessions
  • the chat UI, at the same URL (pass --open to launch it in your browser automatically)

It uses an in-memory session store, so no database is required.

Hot reload

amodal dev watches the agent bundle and applies edits without a restart (pass --no-watch to disable):

  • Prompts, tools, skills, hooks, config — saving a file under agents/, tools/, skills/, hooks/, connections/, knowledge/, stores/, evals/, or amodal.json reloads the bundle. Open chat sessions keep their history; the next message runs against the updated agent.
  • .env files — edits re-apply on save and the model is re-resolved, so API keys, MODEL, and LLM_PROVIDER changes take effect immediately. Variables exported in your shell still win over .env.
  • Broken edits fail soft — an invalid amodal.json or tool config keeps the previous bundle serving and logs the error ([reload] failed: …); fixing the file recovers on the next save.
  • The chat UI refreshes itself over the runtime's event stream — no manual browser reload needed.

Build output (.build/), node_modules/, and dotfiles other than .env are ignored and never trigger a reload.

Choosing the model

amodal dev resolves the model in two steps: what runs (provider + model) and where calls route (the managed gateway or your own keys). The two are independent — you can pick any model and still ride the gateway.

What runs. Name a model with --model (or MODEL in .env); the provider is inferred from the name (claude-*anthropic, gemini-*google, everything else OpenAI-compatible) or set explicitly with --provider / LLM_PROVIDER. If you name nothing, you get the platform default (signed in) or google/gemini-2.5-flash.

Managed gateway (default when signed in). Calls route through Amodal's platform gateway using an org-scoped key — no provider key needed, with the org's quota and billing. Any gateway-synced model works, across providers:

amodal dev                             # platform default model
amodal dev --model claude-sonnet-5     # Anthropic, via the gateway
amodal dev --model gpt-5.2             # OpenAI, via the gateway

The banner shows the routing:

  Model:   anthropic/claude-sonnet-5
  Gateway: https://…/anthropic/v1 (platform — via amodal login)
  Org:     Acme

Bring your own key (BYO). Setting the chosen provider's API key routes calls with your own credentials instead — no flag needed, the key is the signal. Configure it in a .env (loaded from the agent directory and the current directory; your shell environment wins over both):

# .env
MODEL=claude-sonnet-5
ANTHROPIC_API_KEY=sk-ant-...   # ← this makes it BYO
ProviderAPI key env var(s)
googleGEMINI_API_KEY / GOOGLE_API_KEY
anthropicANTHROPIC_API_KEY
openaiOPENAI_API_KEY
Routing rules:
  1. An API key matching the chosen provider, an explicit base URL (--base-url / LLM_BASE_URL / OPENAI_BASE_URL), or --no-gatewayBYO (your keys, your routing).
  2. Otherwise, signed in → managed gateway, with your named model or the platform default.
  3. Otherwise → local defaults (google / gemini-2.5-flash), which need a GEMINI_API_KEY.

--gateway forces the gateway even when a matching local key is set.

The trigger is the key, not the model name: signed in, --model claude-sonnet-5 with no ANTHROPIC_API_KEY rides the gateway; with the key set, it runs on your key. Keys are matched per provider — a stray GEMINI_API_KEY never pulls a claude-* run off the gateway. And if the gateway is ever unavailable, amodal dev falls back to your local env.

Scope

The bundled chat UI sends no scope_id, so agents with scope.requireScope: true (see amodal.json) would otherwise reject every request. In local dev the runtime injects a default scope of local. Override it with --scope:

amodal dev ./agent --scope mission-42

A request's own scope_id still takes precedence.

Tracing

Local runs can export OpenTelemetry traces to the platform, so they show up on the same Traces page in Amodal as your hosted deploys, and count toward the agent's Cost & Usage dashboard.

Tracing follows where your model calls go. When you're signed in and routed through the platform gateway, trace export is on by default (those requests already pass through the platform); disable it with --no-traces. When you bring your own provider keys or base URL, tracing is opt-in: without the --traces flag, amodal dev makes no trace export calls to the platform.

amodal dev               # gateway run: traces on
amodal dev --no-traces   # gateway run, export disabled
amodal dev --traces      # BYO-key run, export enabled

Exports authenticate with your login session; no key setup needed. Traces are attributed to the active agent selected at login (switch it with amodal agent), and amodal dev verifies the whole setup at startup, telling you immediately if anything is off.

The startup banner confirms tracing is active (Traces: exporting to …, and a ✓ next to traces in the Environment section). The URL in that line is the platform's ingest endpoint, not a page to open; view the traces at app.amodalai.com under Traces.

Each turn appears on the agent's Traces page, tagged with a local badge to distinguish it from hosted runs: the full span timeline (turn, tool calls, model calls), token usage, and cost, with all of the page's search, filtering, annotation, and save-as-eval features.

The Traces page shows deployed runs by default, so production metrics aren't skewed by local experiments. To see your amodal dev runs, switch the source toggle (next to the Runs / Threads / Monitoring tabs) to Local, or All to mix both. The choice applies to the whole page: the runs list, threads, and monitoring charts.

Session sync

Alongside traces, amodal dev can replicate local sessions to the platform's session history, so they appear on the agent's Sessions page with the full transcript (and links to them from Cost & Usage resolve). It follows the same default as tracing: on for gateway runs (--no-sync-sessions disables), opt-in via --sync-sessions when you bring your own keys.

The local in-memory store stays the source of truth; the platform copy is a best-effort replica, so being offline or logged out just means the session stays local. Synced sessions are pinned to the local deploy: the Sessions page shows deployed sessions by default, with a Local / All toggle to bring them in. amodal eval runs never sync; their sessions are throwaway by design and are already captured as traces.

Startup preflight

On start, amodal dev inspects the agent repo and reports what it needs, so you know what's missing before you chat:

  Agent:   ./spectrum-agent
  Env:     ./spectrum-agent/.env, ./.env
  Model:   google/gemini-2.5-flash  (LLM_PROVIDER, MODEL not set — using defaults)
  Scope:   local
  Runtime: http://localhost:3847
  Chat UI: http://localhost:3847
 
  Environment:
    ✓ GEMINI_API_KEY          LLM key (google)
    ✗ BRIGHTRF_API_URL        connection brightrf — Base URL
    ✓ SPECTRUMOS_AGENT_TOKEN  connection spectrumos — Auth token
    ✗ traces                  trace export to Amodal (off — amodal dev --traces)
    ...
  1 not set — add them to a .env (agent dir or current directory) or your shell.
 
  Press Ctrl+C to stop.

The Environment section lists every variable the agent declares a need for, with a ✓/✗ for whether it's set:

  • the LLM API key for the resolved provider — or a gateway row (LLM via platform gateway) when you're signed in, since no key is needed then
  • connection secrets and URLs — the env: / $VAR references in connections/*/spec.json
  • custom tool requirements — the env array in tools/*/tool.json
  • a traces row for trace export (informational; never counted as missing)

amodal dev also warns when the agent's npm packages aren't installed — the dependencies in package.json and connection-driver packages in amodal.json:

  ⚠ 2 npm package(s) the agent needs are not installed (no node_modules).
    Run `npm install` in ./spectrum-agent
    Missing: @this-npm-test-org/s3-connection-driver, pdf-parse

And it tells you when a newer CLI is available:

  ⬆ amodal 0.1.8 is available (you have 0.1.7). Run: amodal upgrade

Options

OptionDescription
[path]Agent bundle directory (default .)
--portPort to listen on (default 3847)
--hostHost to bind to (default 0.0.0.0)
--providerLLM provider override (google, anthropic, openai); composes with the gateway when signed in
--modelModel name override — any gateway-synced model when signed in (provider inferred from the name)
--base-urlOpenAI-compatible gateway base URL (e.g. your own LiteLLM proxy); implies BYO keys
--gateway / --no-gatewayForce routing through the platform gateway / your local keys (default: gateway when signed in, unless a matching key or base URL is set)
--orgOrg to mint the gateway key against (one-off; default from amodal login / amodal org)
--scopeDefault scope id for requests without one (default local)
--no-watchDisable hot reload of bundle + .env changes
--openOpen the chat UI in a browser on start (default off)
-V, --verboseIncrease log verbosity
-q, --quietOnly show errors

amodal eval

Run the agent's evals and exit non-zero if any fail.

amodal eval                     # every eval in evals/
amodal eval refund              # ids containing "refund"
amodal eval journeys/           # a directory prefix, nested any depth
amodal eval '/^l[23]\//'        # a regex — slashes make it one
amodal eval --tag safety        # by manifest tag (repeatable, OR'd)
amodal eval --json              # machine-readable results
amodal eval --record-dir out/   # write training records as JSONL
amodal eval --url https://…     # target a deployed runtime
amodal eval --model gemini-3.5-flash

Without --url it boots the same local runtime amodal dev uses, on an ephemeral port, and shuts it down afterwards.

Exits non-zero if any eval fails or if zero evals ran — a filter that matches nothing is a mistake, not a pass. That makes it usable as a CI gate directly.

A suite that exceeds --timeout (default 5 minutes) keeps the results it already produced and reports how many of how many finished, rather than discarding the whole run.

See Evals for the file format.

amodal upgrade

Update the CLI to the latest published version:

amodal upgrade              # update to latest
amodal upgrade --to 0.1.7   # install a specific version
amodal upgrade --force      # reinstall even if already current