The official Opper CLI — authenticate, route AI agent inference through Opper, and manage the Opper platform from your terminal.
# Global (recommended)
npm i -g @opperai/cli
opper --help
# Or one-shot via npx
npx @opperai/cli loginThe package installs an opper binary on PATH. Once installed, every command is just opper <…>.
Starting with the first release containing standalone bundles, GitHub releases carry opper-<os>-<arch>.tar.gz for Linux and macOS and opper-windows-<arch>.zip for Windows, on x64 and arm64. Each includes its own Node runtime. Unpack one anywhere and run bin/opper (bin\opper.cmd on Windows), or let mise track releases for you:
mise use -g github:opper-ai/cli
opper --helpThe Linux bundles support Omarchy's mise installation flow. Update a mise installation with mise up; for a manual installation, download and unpack a newer release. Bundles provide the runtime for the Opper CLI itself. Agents that use npm or npx, including opper launch <agent> --install for npm-distributed agents, still require a separate Node.js/npm installation.
When a bundle configures Codex Desktop, it retains a private copy of Node and its license in that Codex home's opper-desktop directory. Credential refresh continues working when an old CLI bundle is removed. Reconfiguring from a newer bundle refreshes the retained runtime; removing the desktop integration removes it.
Heads up: if you previously installed the legacy Go CLI (
brew install opper-ai/oppercli/opper), uninstall it first — both ship theopperbinary and PATH order decides which one runs:brew uninstall opperThe interactive menu also surfaces a warning when both are detected.
opper login # OAuth device flow
opper whoami # confirm the active slot
opper agents list # see which agents you can launch
opper launch claude # route Claude Code through OpperRun opper with no arguments for an interactive menu (Account · Ask · Agents · Skills · Opper). The menu also offers quick-launch shortcuts for any agent that's already installed and configured.
Runtime auth state lives in ~/.opper/config.json as a list of "slots", each holding an API key, a base URL, and the user metadata returned by the device flow. Use --key <slot> on runtime commands to pick which slot to read from (defaults to default). Private key creation below uses its own browser authorization instead.
| Command | Description |
|---|---|
opper login [--force] [--renew] [--base-url <url>] |
OAuth device flow; stores into the active slot. --renew requests a replacement key after fresh browser approval. |
opper logout [--all] [--yes] |
Clear credentials for the active slot, or every slot. |
opper whoami |
Show the authenticated user for the active slot. |
opper config add <name> <api-key> [--base-url <url>] |
Manually store an API key in a slot. |
opper config list |
List configured slots. |
opper config get <name> |
Print the raw API key (for scripting). |
opper config remove <name> |
Delete a stored slot. |
opper config project <name> [uuid] |
Set a default resource project for a slot; omit the UUID to clear it. |
Key resolution at request time: OPPER_API_KEY env var > the slot named by --key (or default).
An environment key uses OPPER_BASE_URL or the production API root; it does not
borrow a stored slot's host, expiry, organization, or resource project.
Organization personal agent credentials have no project binding. Inference,
models, project discovery, and usage work at organization scope without a target.
Pass the global --project-uuid <uuid> flag to target a project explicitly. Indexes,
named calls, and SDK ask require an explicit project or a resource default.
Traces without a target use the organization's projectless trace group; a
configured resource default also applies to trace commands. Resource defaults
never apply implicitly to inference or agent launches.
opper projects list # names and UUIDs in this organization
opper projects list research # filter by name or UUID
opper --project-uuid <uuid> traces list
opper config project work <uuid>
opper --key work traces list
opper --key work launch opencode # organization inference
opper --key work --project-uuid <uuid> launch opencodeprojects list uses the selected key's organization and ignores resource defaults
and --project-uuid; listing projects does not change the active resource target.
Renewal replaces server credential metadata. The resource default is retained
only when the renewed credential has the same verified organization and API host.
launch --project still selects local agent configuration; keys create --project
still chooses the project for a manually created application key.
Claude Desktop and the VS Code Copilot setup cannot send the project header and
reject explicit targets. Codex Desktop supports targets, but requires a stored
slot so Finder launches can refresh it; unset OPPER_API_KEY before setup.
Copilot uses a saved key slot for in-session renewal; unset OPPER_API_KEY
and launch with --key <slot>. An explicit --project-uuid remains the
request target through renewal.
The browser flow also stores the server-issued credential ID, organization ID,
and expiry when available. opper whoami shows that expiry. An expired slot
starts renewal on the next opper login or opper launch; opper login --renew
requests renewal early. --force repeats authentication but is not a rotation
command. Renewal requires an Opper server that supports agent-login renewal and
a client registered for that policy. Failed renewal leaves the old local slot
untouched. Keys without an expiry keep their current behavior.
opper launch <agent> starts a supported AI agent with its model traffic transparently routed through Opper. Pass-through args after the agent name go straight to the agent's CLI. Terminal agents run inside a fresh Opper session so every call the agent makes is grouped together for tracing and cost — see Routing through a session without the CLI to wire that up by hand. After the session, the CLI prints a summary with duration, model, and a traces link. The usage summary uses the same key and API host as the launched session. If the usage request fails, it reports “Usage unavailable”; the rollup-delay hint is reserved for successful requests with no usage rows. Summary failures do not change the agent’s exit code. Desktop integrations use persistent gateway configuration.
opper agents list # NAME / DISPLAY / KIND / STATE / CONFIG / COMMAND
opper launch claude # Anthropic Messages shape → /v3/session/<id>/v1/messages
opper launch claude-desktop # rewire Claude Desktop (GUI) → /v3/compat (persistent GUI profile)
opper --key prod launch codex-desktop --model claude-sonnet-5
opper launch copilot # native picker, /opper-login, /opper-usage
opper launch opencode # OpenAI Chat Completions shape → /v3/session/<id>/chat/completions
opper launch codex # OpenAI Responses shape → /v3/session/<id>/responses
opper launch hermes # OpenAI Chat Completions shape → /v3/session/<id>/chat/completions
opper launch openclaw # OpenAI Chat Completions shape → /v3/session/<id>/chat/completions (background gateway)
opper launch pi # OpenAI Chat Completions shape → /v3/session/<id>/chat/completions
# Anything after the agent name is forwarded to its CLI — handy for
# scripting / cron with non-interactive flags.
opper launch pi -p "summarise this PR"
opper launch claude --resume| Agent | Slug | How Opper plugs in |
|---|---|---|
| Claude Code | claude |
ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN env vars |
| Claude Desktop | claude-desktop |
writes a third-party-inference (deploymentMode: "3p") profile into ~/Library/Application Support/Claude-3p/ (macOS) / %LOCALAPPDATA%\Claude-3p\ (Windows); quits and reopens the GUI app to apply |
| GitHub Copilot CLI | copilot |
temporary provider registry and local bridge; no global configuration |
| OpenCode | opencode |
provider block in ~/.config/opencode/opencode.json |
| Codex CLI | codex |
per-invocation Responses provider and model overrides; preserves shared configuration and supports current native profile files |
| Codex / ChatGPT desktop | codex-desktop |
configures local Codex tasks on macOS with a persistent Responses provider, selected-key credential helper, and live Opper model catalog |
| Conductor (Codex, macOS) | conductor |
configures CLI mode and a custom Codex executable in Conductor's user settings, using the selected CLI login and Opper pool/route catalog |
| Hermes | hermes |
isolated HERMES_HOME=~/.opper/hermes-home/ so your real ~/.hermes/ is never touched; OPENAI_API_KEY env var |
| OpenClaw | openclaw |
opper provider entry in ~/.openclaw/agents/main/agent/models.json; opper launch openclaw defaults to gateway start (background daemon) |
| Pi | pi |
temporary extension registers Opper in memory; the CLI leaves models.json and installed extensions unchanged |
opper launch <agent> --install runs the upstream agent's installer if it's missing (where supported). Claude Desktop is GUI-only on macOS/Windows and has no scripted installer — install it from https://claude.ai/download first.
The CLI also offers a per-agent submenu (opper → Agents → agent → Launch with model…) that lets you pick a specific Opper model from the catalog instead of the default. Claude Desktop's picker is restricted to supported Claude models and pools because its third-party gateway rejects other models. Supported versions use native discovery once the server's Claude-only response is verified; older versions, older servers and customized model lists retain the explicit-list fallback.
For OpenCode, each launch fetches /v3/compat/models using the same key and API host as the launched session, including when you select a different slot with --key. The generated model map and whitelist limit Opper's picker entries to the returned models supported by the CLI. These settings also apply at runtime so an older project configuration cannot restore removed entries or override the launch URL. Unrelated inline OPENCODE_CONFIG_CONTENT settings are preserved. Inherited inline authorization headers are removed. Before updating the Opper provider, launch checks OpenCode's merged settings and stops if provider or allowed-model authorization headers could override the selected key. Existing JSONC configuration files are edited narrowly so unrelated settings and comments survive setup and launch; malformed files are left unchanged with an error.
OpenCode reasoning variants use the catalog's supported effort levels and validated default. Pools expose only the levels advertised for their permitted members; dynamic routes and models without effort metadata have no managed effort variants. Unsupported inferred levels, including MiniMax's thinking variant, are disabled. Refresh preserves compatible model options, custom variant settings and user-disabled levels. Custom variants carrying an unsupported effort are disabled until support returns; a generated marker distinguishes those disables from user preferences. Launch refreshes existing inline model settings and stops before inference if another config layer still supplies an unsupported effort or a custom thinking option. Provider-specific thinking budgets cannot be validated from effort metadata; remove that option or replace it with an advertised effort. Unrelated compatible settings remain preserved.
After upgrading the CLI, rerun opper agents configure opencode or opper editors opencode --overwrite; launch refreshes automatically. Reinstall the persistent bridge with opper editors opencode --login-bridge, then restart OpenCode. When the updated bridge is loaded, its request hook removes unsupported outgoing effort values, including OpenCode's inferred defaults, and uses the launch's scoped catalog without changing session authentication. A manually requested unsupported variant does not always raise an error: OpenCode may fall back to a supported default, and the bridge may omit an unsupported effort value. Plain OpenCode without the updated bridge, or --pure which skips plugins, can still infer a medium request default from GPT-5 IDs even when the catalog declares no effort default. The CLI does not invent a default to suppress this upstream behavior; use the updated bridge or explicitly select an advertised variant. Select a variant in OpenCode or with opencode run --variant max when the selected model advertises it.
For Pi, configure and launch refresh the allowed tool-capable models, supported reasoning efforts, and published token prices from /v3/compat/models. Unsupported thinking levels are hidden; a thinking capability alone does not imply selectable reasoning efforts. opper launch pi loads an explicit extension and catalog from a private temporary directory and supplies the selected Opper credential through the environment. It does not rewrite models.json or add files to your Pi extensions directory. Temporary files remain available for /reload and are removed when Pi exits. /new, /resume, and /fork retain session tracing; child agents should use their own opper launch pi invocation.
For a configure-once setup, opper agents configure pi updates the managed opper provider in models.json, preserving unrelated JSONC settings and comments. It honors PI_CODING_AGENT_DIR (default ~/.pi/agent) and refuses malformed configuration without overwriting it. It saves an environment reference instead of your API key: plain pi requires OPPER_API_KEY in its environment. Run configure again to refresh its model catalog; withdrawn IDs are removed with a notice, while custom options on retained models are preserved. Plain Pi does not load the launcher's session extension. Pi's explicit modelOverrides continue to apply to model metadata. Saved authentication, project, or trace headers that conflict with launch routing cause an error before Pi starts; remove those overrides or use a separate provider name for custom routing. Pi's cost display estimates token cost from published rates; pool prices and extra charges can differ from the billed usage reported by Opper.
If the allowed list is empty, OpenCode has no Opper models to select. If the authenticated catalog request fails, launch stops before changing configuration; it does not substitute the bundled catalog. opper editors opencode also writes a whitelist when it fetches models; use --overwrite to refresh an existing Opper provider block.
The CLI preserves centrally configured opper.display_name labels from model discovery, including capitalization and spaces. OpenCode and Pi retain deployment IDs and pool badges beside those labels; dynamic routes show Variable pricing because their price depends on the model selected for each request. OpenCode route configuration omits fixed costs: OpenCode 2 preserves unknown pricing and avoids a false Free badge. OpenCode 1 and Pi still use zero for unknown rates in session accounting, so their totals can under-count route usage. Use Opper usage reporting for actual spend. The persistent login bridge below targets OpenCode 1; OpenCode 2 has a different plugin API. Its generated editor configuration can be refreshed with opper editors opencode --overwrite; the old login bridge is not a 2.x plugin.
After upgrading the CLI, opper launch opencode refreshes the generated catalog automatically. For an existing editor configuration, run opper editors opencode --overwrite. For the persistent login bridge, rerun opper editors opencode --login-bridge (with the same --key and project selection used during setup) to replace its managed installed copy, then restart OpenCode or the OpenWork runtime. Updating the npm package alone does not update that copied plugin. The bridge refreshes names and removes withdrawn routes on startup; opening the model picker alone does not refresh Opper discovery. These labels require a CLI version that consumes the metadata and a backend that publishes it; legacy discovery falls back to ID-derived names.
To verify label refresh locally without inference, build the CLI and run OPENCODE_BIN=/path/to/opencode node test/integration/catalog-display.mjs. The fixture uses temporary configuration directories and a loopback synthetic catalog, exercising editor setup and the installed bridge through real OpenCode.
For Claude Code, use version 2.1.257 or later. opper launch claude starts on Opus 5 and enables gateway model discovery, adding the Claude models available to your Opper key to Claude Code's /model picker. Claude Code keeps its built-in choices and filters discovered IDs to those containing claude or anthropic; Opper enforces model access on each request. Discovery refreshes at startup, so restart after changing your Opper model rules. If discovery fails, Claude Code can fall back to its cached or built-in list. Nonessential traffic stays disabled, which also disables Claude Code's automatic updates during these launches; update Claude Code separately before a demo.
opper launch claude --model claude-sonnet-5
opper launch claude --model claude-fable-5-1
# Request the full context window supported by these models:
opper launch claude --model 'claude-opus-5[1m]'The Opper routing and credential apply only to the launched process. Claude Code can still save model selections and its discovery cache; use the picker's session-only selection to keep your existing default. See Claude Code's gateway compatibility guide for discovery and client-version behavior.
To remove an agent's Opper integration without uninstalling the agent itself:
opper agents remove claude-desktop # works for any registered adapterThis is the non-interactive equivalent of the menu's "Remove Opper integration" action. It clears Opper-owned config (e.g., flips Claude Desktop's deploymentMode back to "1p", removes the opper provider block from OpenCode / Pi / OpenClaw, etc.) without touching anything you put there yourself.
On macOS, install the app with local Codex support from ChatGPT downloads. On Windows, install the Codex app from the Microsoft Store; the CLI discovers its registered MSIX package and bundled runtime. The bundled Codex runtime must be version 0.153.4 or later. The separate ChatGPT Classic app is not supported.
# Configure and open the app with the selected stored key and model
opper --key prod launch codex-desktop --model claude-sonnet-5
# Configure without launching (also available in the Agents menu)
opper --key prod agents configure codex-desktop --model claude-sonnet-5
# Restore the previous provider, model and catalog
opper agents remove codex-desktopIf the app is already running, the CLI saves the configuration and reports that a restart is required. Quit and reopen the app, then create a new local Codex task. Existing tasks keep their provider. This integration covers local Codex tasks; ordinary ChatGPT conversations and cloud tasks are separate.
Setup verifies the selected key's authorized, tool-capable Opper catalog using the same API root and project as inference. Supported runtimes and servers use a native model_catalog_url, which Codex refreshes directly. Older runtimes/servers retain the local catalog fallback. Run launch or configure again to change keys/models or refresh fallback catalogs. Models without confirmed tool support are excluded.
The effort slider uses each model's advertised reasoning levels. Pools offer only levels supported by every permitted member; models or pools without confirmed effort metadata keep the slider disabled. Rerun configure and restart the app to refresh an existing installation's effort choices.
Codex's built-in web search is disabled while this integration is enabled: its default cached-only search relies on an OpenAI service that Opper cannot reproduce across model providers. The previous search setting is restored when removing the integration. File tools and sub-agents remain enabled.
With the default ~/.codex home, the app reads the selected slot through a local credential helper, so it also works when opened from Finder. The API key stays in the Opper credential store. Rotating that slot's key is picked up when Codex refreshes credentials; deleting the slot stops future credential retrieval. If the slot's API host changes, rerun setup before using it.
Configuration is stored in ~/.codex/config.toml (or CODEX_HOME) and helper/catalog/backup files in CODEX_HOME/opper-desktop/. Because Codex CLI and the desktop app share this configuration, plain codex also sees these defaults. opper launch codex supplies its own provider/model and disables built-in web search per invocation, without changing saved settings. Explicit native --model or --profile choices take precedence over the launcher's default model; current profiles are separate NAME.config.toml files.
Use --codex-home <path> on desktop configure, launch, and removal to select a separate Codex home. The option takes precedence over CODEX_HOME, which remains supported; otherwise the default is ~/.codex. Setup changes only the selected directory. Ordinary Finder launches still use ~/.codex; they do not inherit the shell environment. Configure prints a launch command preserving your custom home, key, model, and API root. Use that command for subsequent launches (and after quitting an already-running app). Opper does not change global macOS launch settings.
opper --key prod agents configure codex-desktop --codex-home "$HOME/.codex-opper-test"
opper --key prod launch codex-desktop --codex-home "$HOME/.codex-opper-test"
opper agents remove codex-desktop --codex-home "$HOME/.codex-opper-test"A separate Codex home isolates Codex settings and task data. It does not by itself start a second desktop app instance or isolate the app's Electron profile.
Removal restores previous defaults and preserves unrelated settings, comments, and deliberate model changes made afterward. If the generated provider was edited independently, removal reports a conflict and retains the backup. Symlinked config files are refused before writing; use --codex-home <path> to keep a dotfile-managed configuration intact. Restart the app after removal.
Install Conductor and let it install its managed Codex runtime (0.153.4 or later). Then configure the integration using a stored CLI login:
opper login
opper --key default agents configure conductor --model claude-sonnet-5The command selects CLI mode and the generated Codex executable (normally
~/.opper/conductor/codex) in Conductor's user settings automatically. Restart
Conductor. In a workspace, create a new chat with +, open the
model picker, and choose Add models. In Default models, enable the wanted
Opper model in the Codex column. Go back to the new chat and select it in the
picker before sending a message. This integration covers Conductor's Codex agent.
Repository settings can override the user defaults; if a repository still uses
another executable or provider, check its Conductor settings.
Conductor may still show CLI not authenticated in settings: that badge checks
the normal Codex account, while this integration retrieves credentials from the
Opper CLI login. You do not need to run codex login for the Opper connection.
Setup updates only codex_provider and codex_executable_path in
~/.conductor/settings.toml, preserving unrelated settings and recording the
previous values for removal. If an earlier manual setup already selected this
generated executable, removal clears that path to return to Conductor's bundled
Codex. The executable uses invocation-specific provider and catalog settings;
ordinary Codex settings in ~/.codex/config.toml remain unchanged.
Setup records the selected CODEX_HOME (default ~/.codex) so GUI launches use
the same verified catalog and feature settings. Refresh retains that home when
the environment variable is absent. To select another home, rerun your configure
command with CODEX_HOME=/absolute/path and the same key/project options. If a launch supplies
a different CODEX_HOME, the wrapper stops with guidance instead of overriding
that workspace setting. Removal preserves both homes' personal files.
The API key stays in the CLI credential store and is
read from the selected slot when Codex refreshes credentials. Renewing that slot
within the same organization and API host works without copying another key
into Conductor. Deleting or expiring the slot stops credential retrieval;
changing its organization or API host requires running setup again. An
environment-only OPPER_API_KEY cannot configure this persistent integration.
Setup fetches the selected key's authorized, tool-capable catalog. By default,
Conductor lists model pools (such as gpt-5-mini) and dynamic/... routes,
so each provider deployment does not crowd the picker. An exact model selected
with --model is also retained, including a provider-specific ID; it is never
rewritten to a pool. Pools and providers have distinct labels.
To include every eligible provider-specific model, opt into the full catalog:
opper --key default agents configure conductor --model-kinds allSupported runtimes and servers use authenticated native discovery. Older
runtimes/servers retain the generated catalog. Existing local catalogs migrate
to native all so saved provider selections cannot disappear; broad native
policy stays broad during refresh. Fresh native setups use the compact default.
Run the same configure command again to refresh models or change the selected login, model, or project. Built-in Codex web search is disabled for this connection, as with the Codex desktop integration. Existing Conductor chats keep their selected model; start a new chat after reconfiguring.
To remove the generated integration:
opper agents remove conductorRemoval restores the saved Conductor selections where they are still owned; restart the app before starting another session. It preserves independent settings edits. Conflicting managed settings or changed generated files are reported for manual resolution.
opper proxy opens a local session picker in your browser. Create a named
session with a project label, or select a saved session to continue it. One
session is active at a time, across every desktop app configured to use the
local bridge. Selecting a saved session keeps its attribution ID.
Running opper with no arguments also offers a Proxy submenu: start or
open the session picker, inspect status, end the active session, or stop the
proxy. Starting from the menu runs the service in the background and returns
you to the menu. These controls use the default local state directory.
Archive sessions you no longer need in the main list. The Archived view lets you restore them with the same attribution ID. Archiving the current session pauses new inference until you select another session; restoring a session does not select it automatically. Archiving only changes the local list, so Opper usage and traces remain available.
Names, project tags, session IDs and archive state are stored in
~/.opper/desktop-bridge/desktop-sessions.json (or
$OPPER_HOME/desktop-bridge/desktop-sessions.json). A custom --state-dir keeps
its own desktop-sessions.json. The file is private to your user and contains
no prompts or API keys.
On Windows, the proxy creates private state with Windows ACLs for the current
user and verifies ownership, access rules and reparse points before reading
credentials. Existing unsafe state is rejected rather than made private
automatically. The default path is %USERPROFILE%\.opper\desktop-bridge\.
The bridge starts when needed and continues running after the browser page or
launching terminal closes. Running opper proxy again opens the same picker.
Session names and tags are saved locally; inference uses the existing tagged
Opper session endpoints. This does not switch your actual Opper project or its
access policies. Finish or stop ongoing agent work before switching sessions;
an in-flight request keeps its original tags, but later steps use the active
session. Ending the session blocks new inference until another session is
selected.
Local proxy routing is optional. Normal desktop configuration and launch use
Opper directly; choose --proxy to use the session picker instead:
opper launch --proxy codex-desktop
opper launch --proxy claude-desktop
# Configure without launching the desktop app:
opper agents configure --proxy codex-desktop
opper agents configure --proxy claude-desktopThese commands start or reuse the local background bridge, save the app's provider configuration, and open the picker. Configuration alone does not launch the app. Quit and reopen the app when changing routing mode; selecting a session afterward does not require restarting it. The saved routing continues to apply to future app launches. Existing Codex tasks may retain their previous provider.
Run the same command without --proxy to restore direct Opper routing, preserving
the same key, model, explicit Opper project and Codex home options. Use
opper agents remove <agent> to remove the integration. Direct routing does not
require the local bridge. Switching an app back does not stop the bridge, since
another app may still be using it; use opper proxy stop when it is no longer
needed.
--state-dir <path> selects a separate bridge; --no-open prints its picker link
instead of opening a browser. Both require --proxy. Proxy sessions are selected
in the picker, so --proxy cannot be combined with per-launch --tag flags.
Proxy mode requires a stored CLI credential slot, not OPPER_API_KEY.
For a Windows trial, sign in and opt the installed app into the proxy from
PowerShell (unset any OPPER_API_KEY first):
opper login
opper launch --proxy codex-desktop
# Or:
opper launch --proxy claude-desktopIf the app is already running, quit it and rerun the launch command. Create a
new local Codex chat after changing its provider. Choose a session in the
browser, send a message, switch sessions and send another message in the same
chat. opper proxy status shows the selected project label and attribution ID;
check Opper usage records to confirm attribution. Running opper and choosing
Proxy reopens the picker and offers status, end and stop controls. To return
to direct routing, run the launch command without --proxy and reopen the app.
For an isolated macOS Codex trial from this checkout, build the CLI and start the bridge:
npm run build
node dist/index.js proxy start --state-dir /private/tmp/opper-desktop-trialIn another terminal, prepare a fresh test profile and open its session picker:
node scripts/desktop-tags-demo.mjs --state-dir /private/tmp/opper-desktop-trial --output /private/tmp/opper-codex-trial
node dist/index.js proxy --state-dir /private/tmp/opper-desktop-trial
zsh /private/tmp/opper-codex-trial/open.zshThe test profile uses a separate Codex home and Electron profile. It leaves the
normal desktop instance running. These directories must be fresh. The local
helper reads the bridge's local credential; the real Opper API key stays in the
selected CLI slot. Use --key <slot> when starting the bridge to choose one.
For operator debugging, proxy status, proxy tag --tag project=acme, and
proxy clear use the same --state-dir. proxy stop stops the bridge;
desktop inference is unavailable while it is stopped. proxy start stays in
the foreground for development; Ctrl-C stops that instance. The current browser
UI is local HTTP, and inference forwarding supports HTTP/SSE, not WebSockets.
This prototype assumes trusted local processes and OS users. HTTP does not
authenticate the local listener: if the bridge stops or crashes, another local
user could bind its port and receive a configured desktop app's next prompt and
local credential. Use it only on trusted single-user machines; authenticated
local transport still needs verified certificate support in both desktop apps.
Native Windows proxy lifecycle and access controls are exercised in Windows CI.
Actual Windows desktop launch and inference, and live Claude Desktop inference,
still need verification on machines with those apps installed.
For terminal agents, opper launch mints a session id and points the agent's inference base URL at a session-scoped Opper endpoint, then lets the agent's own SDK speak its native protocol on top. You can wire this up by hand with any OpenAI-, Responses-, or Anthropic-shaped client — no CLI required. Desktop integrations use persistent /v3/compat configuration and do not get a per-launch session.
https://api.opper.ai/v3/session/<session-id>[/<tag>:<value>…]/<native-path>
<session-id>— a stable id of the formsess_<uuid>(e.g.sess_3c0a79fd-e8e1-49c5-bc19-62ddd85f00c7). Reuse the same id for every call in one logical run to group them into a single session. The server validates the format — an id that doesn't start withsess_is rejected with400 {"error":"invalid session id"}.<tag>:<value>— optional attribution tags, added as extra path segments (e.g./team:growth/env:prod). URL-encode values; keep keys to[A-Za-z][A-Za-z0-9_.-]*and avoid the reservedopper.prefix.<native-path>— whatever path your client's SDK already appends. It also selects the compatibility shape:
| Client speaks | SDK appends | Full session URL |
|---|---|---|
| OpenAI Chat Completions | /chat/completions |
…/v3/session/<id>/chat/completions |
| OpenAI Responses | /responses |
…/v3/session/<id>/responses |
| Anthropic Messages | /v1/messages |
…/v3/session/<id>/v1/messages |
It's the same behaviour as the /v3/compat/... endpoints, just scoped to a session: the /v3/session/<id> prefix takes the place of /v3/compat, and the native tail still picks the wire shape.
Standard Opper bearer token, identical on every shape:
Authorization: Bearer $OPPER_API_KEY
(Anthropic SDKs default to x-api-key — set Authorization explicitly, or use ANTHROPIC_AUTH_TOKEN.)
SID="sess_$(uuidgen | tr '[:upper:]' '[:lower:]')"
curl -s "https://api.opper.ai/v3/session/$SID/chat/completions" \
-H "Authorization: Bearer $OPPER_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello"}]
}'The response is an ordinary chat completion, with cost, usage, and a meta.trace_uuid for the call. Every request you send to the same $SID — any model, any wire shape — lands in that one session.
Set the client's base URL to the session endpoint (without the native path — the SDK adds that) and use your Opper key. How you set it depends on the client:
Env-var clients — any OpenAI-compatible SDK, and env-var-driven agents like Claude Code, read the base URL from the environment:
SID="sess_$(uuidgen | tr '[:upper:]' '[:lower:]')"
# OpenAI-compatible SDKs / clients
export OPENAI_BASE_URL="https://api.opper.ai/v3/session/$SID"
export OPENAI_API_KEY="$OPPER_API_KEY"
# Claude Code (Anthropic-shaped)
export ANTHROPIC_BASE_URL="https://api.opper.ai/v3/session/$SID"
export ANTHROPIC_AUTH_TOKEN="$OPPER_API_KEY"Config-file agents — OpenCode, Hermes, Pi, and OpenClaw don't read those env vars; they take the base URL from their own provider config (opencode.json, Hermes' base_url, ~/.pi/agent/models.json, …). Point that provider's base URL at https://api.opper.ai/v3/session/<id> and use your Opper key.
Either way, that is exactly what opper launch does for you — plus a fresh id per run and an end-of-session cost summary.
opper ask "<question>" runs an Opper agent grounded on the locally-installed Opper skills (see below). Useful for "how do I…" questions about the platform, SDKs, or the CLI itself.
opper ask "how do I create an index?"
opper ask --model claude-opus-5 "compare the v2 and v3 APIs"The answer streams in, then prints a token / request count. Requires Opper skills to be installed first (opper skills install).
It uses a named SDK function. With an organization personal key, select a
resource project using --project-uuid or opper config project.
Opper skills are markdown documentation packs the CLI uses for grounding opper ask and that you can install for any compatible code agent. The CLI delegates to the upstream skills tool, which fetches from opper-ai/opper-skills and symlinks into your agents' skill paths (~/.claude/skills/, etc.).
opper skills install # `npx skills add opper-ai/opper-skills` — interactive picker
opper skills update # refetch the latest from the source repo
opper skills list # per-target install matrix
opper skills uninstall # remove + clean up legacy bundled-copy installsopper editors list
opper editors opencode [--global|--local] [--overwrite] # configure inference without launching
opper editors opencode --login-bridge # one-time setup for plain opencode
opper editors opencode --remove-login-bridge # remove only the managed pluginOpenCode is a coding agent; its inference setup remains under editors for
compatibility. Use opper launch opencode to run it with inference through Opper.
For a plain opencode command that works after the CLI exits, sign in once and
install the optional global login bridge:
opper login
opper editors opencode --login-bridge
opencodeIf you already use Opper in another organization, choose a separate CLI slot while signing in and installing the bridge:
opper --key work login
opper --key work editors opencode --login-bridge
opencodeSelect your work organization in the browser approval screen, then use
opper --key work whoami to confirm it before starting OpenCode. Renew that
slot with opper --key work login --renew.
The bridge is a local OpenCode startup plugin at
~/.config/opencode/plugins/opper-login.js. It reads the CLI's selected key
from ~/.opper/config.json, fetches that key's /v3/compat/models catalog on
each OpenCode startup, and injects the Opper provider and allowed models in
memory. It does not copy the key into opencode.json or rewrite other provider
settings. Setup binds the selected CLI slot to plain OpenCode; reinstall with
another --key to switch it, or set OPPER_KEY_SLOT for one OpenCode process.
OPPER_API_KEY overrides the slot with an independent credential; its host is
OPPER_BASE_URL or the production API root. An explicit target supplied during
bridge setup is persisted without a secret. For one plain OpenCode process,
OPPER_PROJECT_UUID supplies an explicit target. An environment key uses only
that environment target, and never borrows the bridge's stored target. If the stored key is expired or the
catalog cannot be fetched, Opper is unavailable in that OpenCode process;
other providers stay available. Renew the selected slot (for example,
opper --key work login --renew) and restart
OpenCode to load the replacement key. Plain OpenCode uses the normal compat
endpoint, so it does not get the per-launch session grouping of
opper launch opencode. OpenCode's debug config output can contain the
resolved key; do not share that output.
opper mcp add opencode # account MCP only, no inference changes
opper mcp add opencode --local --url http://localhost:8080/mcpopper mcp add currently supports OpenCode only. This configures the agent's
access to Opper account tools; opper launch <agent> separately runs an agent
with model inference through Opper. Setup helpers for other MCP clients are not
implemented yet.
The command adds the remote https://api.opper.ai/mcp server as opper. It leaves
your inference provider, model, tool permissions, and other MCP servers alone.
It needs no API key and does not log in, launch OpenCode, or approve consent.
The default connection contains only the server URL and connection settings:
{
"mcp": {
"opper": {
"type": "remote",
"url": "https://api.opper.ai/mcp",
"enabled": true
}
}
}Reopen OpenCode, connect the server, and choose your organization and permissions
in Opper in your browser. Available permissions are discovered from Opper; only
the permissions you approve are granted. If the
client requires manual authentication, use opencode mcp auth opper, then
reopen OpenCode to load the authenticated tools.
For names that need shell quoting or conflict with command options, setup
suggests opencode mcp auth so you can select the server in OpenCode's picker.
Availability of the endpoint depends on the Opper MCP deployment.
OpenCode 1.18.29 cannot automatically complete a permission upgrade after a tool reports insufficient scope. Start its native authentication flow again and approve the additional permissions in Opper. With the default URL-only setup, this does not require editing the MCP config. An agent can guide the workflow; the account owner approves access in the browser.
For an advanced client-side restriction, use --scopes to limit the
permissions that can be offered during consent:
# Restrict this client to account and project inspection.
opper mcp add opencode --scopes 'account:read projects:read'--scopes replaces only the matched server's requested scope setting. It
never adds unselected permissions, grants access, or changes existing tokens.
Reopen OpenCode after changing this restriction and use its native authentication
flow to review and approve permissions in the browser. Consent cannot exceed
the explicit restriction. To return an existing connection to normal discovery,
remove its oauth.scope property from the effective OpenCode config, preserving
any other OAuth settings, then reopen OpenCode and authenticate again. Plain
opper mcp add opencode preserves existing restrictions, including those from
earlier CLI versions.
To revoke an existing grant, disconnect it in the Opper app. Config changes alone
do not revoke grants.
The setup preserves JSONC comments and reads both opencode.json and
opencode.jsonc (plus global config.json) in OpenCode's merge order. New MCP
settings go into the existing JSONC file when present, otherwise the JSON file.
Explicit scope updates edit the highest-precedence file containing the matched
server's complete remote definition. Other preference layers remain untouched;
private headers and OAuth settings are not copied between files.
An existing server with the same URL keeps its current name, auth settings,
and enabled/disabled preference; an explicit --scopes updates only its
OAuth scope. If OAuth is disabled, an explicit --scopes change asks you to
review that setting instead of enabling it; plain setup preserves it and
explains how to enable browser consent. Remove the matched server's
oauth: false setting from the effective config, then reopen OpenCode.
A conflicting opper entry, malformed config,
or duplicate JSON keys produces an error without changing the files. --url accepts
HTTPS endpoints or HTTP loopback addresses, without credentials, query parameters,
or fragments.
When setup updates an existing regular config, it retains the original file in
a private .opper-mcp-* backup directory beside it and prints that backup path.
The backup directory excludes its contents from ordinary Git staging.
It captures and checks the current file before installing the update without
replacing a competing save. A detected conflict stops setup and preserves both
versions for review. Backups also retain late saves through an editor's already
open file; compare them if you edited the config during setup. Repeated setup
that makes no change creates no backup. Symlinked target files require a manual
merge. New files are created exclusively, so setup never replaces a file that
appeared after inspection.
Use --global or --local to select where the MCP configuration is written.
For a native OpenCode setup instead, run opencode mcp add and choose a remote
server with the same URL. That is also suitable for demonstrating server setup
before asking the agent to connect.
The previous syntax remains a compatibility alias:
opper editors opencode --mcp
opper editors opencode --mcp --local --mcp-url http://localhost:8080/mcp
opper editors opencode --mcp --mcp-scopes 'account:read projects:read'Its --mcp-url and --mcp-scopes flags correspond to --url and --scopes on
opper mcp add opencode. The alias still configures only MCP; --overwrite
remains an inference setup option.
To use Opper for both account tools and model inference, run
opper mcp add opencode, then opper launch opencode. Inference authentication
(opper login / OPPER_API_KEY) is independent of MCP browser authorization.
Direct access to the platform endpoints:
| Command | Description |
|---|---|
opper call <name> <instructions> [input] [--model <id>] [--stream] |
Run an Opper function. Reads input from stdin when the positional arg is omitted. |
opper keys create --project <uuid> --name <name> --output <path> [--mcp-url <url>] |
Approve key creation in the browser and save the secret into a new private env file. Prints only metadata. |
opper models list [filter] [--inference-location] [--storage-location] [--training] [--logging] [--moderation] [--json] |
List available models (built-in + custom) with where they run and their training, logging and moderation stances. The flags filter the way a model access rule on the Rules page does, e.g. --inference-location EU --storage-location EU --training no --logging none --moderation none. Values are comma-separated alternatives. |
opper models create <name> <identifier> <apiKey> [--extra <json>] |
Register a custom model. |
opper models get <name> / delete <name> |
Inspect / remove a custom model. |
opper indexes list [--limit] [--offset] |
List knowledge-base indexes. |
opper indexes get <name> / create <name> [--embedding-model <id>] / delete <name> |
Manage indexes. |
opper indexes add <name> <content> [--key <id>] [--metadata <json>] |
Add a document (<content> accepts - for stdin). |
opper indexes query <name> <query> [--top-k <n>] [--filters <json>] |
Semantic search. |
opper traces list [--limit] [--offset] [--name <substring>] |
List traces. |
opper traces get <id> / delete <id> |
Inspect / remove a trace. |
opper usage list [--from-date] [--to-date] [--granularity] [--fields] [--group-by] [--out csv] |
Token / cost analytics. |
opper image generate <prompt> [-o <file>] [--base64] [-m <model>] [--size] [--quality] [--image] [--param k=v] |
Generate or edit an image. |
opper video generate <prompt> [-o <file>] [-m <model>] [--seconds] [--resolution] [--aspect-ratio] [--image] [--video] [--audio] [--no-audio] |
Generate a video: submits, waits, downloads. |
opper keys create --project <project-uuid> --name 'My app' --output .env.opperThe command opens Opper consent for project read access and API key creation.
Choose the organization containing that project and explicitly select API key
creation. The CLI checks the project, creates one runtime key through the
delegated API, then writes OPPER_API_KEY=... into the new file with POSIX mode
0600. The parent directory must already exist. Existing files and symlinks are
never replaced, including when another process creates the destination during
browser approval. Stdout contains only the key ID, name, project UUID, and saved
path as JSON; progress and the browser URL go to stderr. Load the env file in
your application without printing or pasting it into an agent conversation.
This authorization is independent of opper login, --key, OPPER_API_KEY,
and OpenCode's credentials. It uses the maintained MCP SDK for discovery, public
client registration, and PKCE. Only the public client registration is retained
under ~/.opper/mcp-clients (or $OPPER_HOME/mcp-clients), keyed by MCP URL and
issuer; OAuth tokens stay in memory. The temporary OAuth connection is revoked
when the operation finishes, including on errors. The application key remains
usable after that connection is revoked.
For local development, append --mcp-url http://localhost:8080/mcp. A production
server must have the delegated MCP/OAuth endpoints deployed before this command
can authorize. Ordinary API errors and SDK errors are sanitized, including with
--debug.
The CLI retries an uncertain create once with the same idempotency UUID. If the
outcome is still unknown, its error includes --idempotency-key <uuid>: reuse
that value only with the same project, name, MCP URL, account, organization, and
retained public client registration. Never generate another operation ID to
resolve an unknown outcome. A replay identifies the existing key but cannot
return its secret again; the CLI revokes that key and reports that a fresh
creation is needed. A failed file installation also attempts to revoke only
the newly created key. If key or connection cleanup fails, the CLI reports the
remaining action and exits with an error; an already installed env file is kept.
If a server reset or client deletion leaves the browser reporting invalid_client,
use --reset-client with a fresh key creation to replace only that MCP URL
and issuer's retained public registration. The next authorization needs fresh
browser consent. A token endpoint rejection also removes the rejected registration
and asks you to restart; the CLI never exchanges an old authorization code under a
new client identity. Existing OAuth grants are not revoked by resetting local
registration; manage those in Agent connections.
Do not reset a client while a previous key creation is uncertain. --reset-client
cannot be combined with --idempotency-key; recovery also refuses to register a
new identity if the original cache is missing or invalid. Restore the original
registration or reconcile the earlier key in Opper before starting a fresh create.
# Inline arguments
opper call myfunction "respond in kind" "what is 2+2?"
# Stream the response token-by-token
opper call --stream myfunction "respond in kind" "what is 2+2?"
# Pipe input from stdin (any text)
echo "what is 2+2?" | opper call myfunction "respond in kind"
# Pipe structured JSON in
echo '{"name":"Johnny","age":41}' | opper call myfunction "only print age"
# Override the model for one call
opper call --model claude-sonnet-5 myfunction "summarise" "long text…"Bring your own model deployment under any provider Opper supports — Azure, AWS, GCP, custom OpenAI-compatible endpoints, etc. Pass any provider-specific config through --extra as a JSON object.
# Azure OpenAI deployment
opper models create my-gpt4 azure/my-gpt4-deployment my-api-key \
--extra '{"api_base": "https://my-gpt4-endpoint.openai.azure.com/", "api_version": "2024-06-01"}'
# Inspect / delete
opper models get my-gpt4
opper models delete my-gpt4# Create an index
opper indexes create support-docs
# Add documents (inline or from stdin)
opper indexes add support-docs "How to reset your password: …" --key reset-password
cat refunds.md | opper indexes add support-docs - --key refunds --metadata '{"category":"billing"}'
# Search
opper indexes query support-docs "how do I get a refund?" --top-k 5
opper indexes query support-docs "billing question" --filters '{"category":"billing"}'If your application tags calls with arbitrary metadata (e.g. customer_id), opper usage list can group cost / count / tokens by that tag. Tagging happens at call time via the SDK:
# Python SDK
result, _ = await opper.call(
name="respond",
input="What is the capital of Sweden?",
tags={"customer_id": "acme"},
)# Then attribute spend per tag
opper usage list --from-date=2026-04-01 --to-date=2026-04-30 \
--fields=total_tokens,cost --group-by=customer_id
# Pipe to CSV for billing systems
opper usage list --from-date=2026-04-01 --group-by=customer_id --out=csv > april.csvRuns against POST /v3/images, so any model from opper models list image
works — including dedicated image models like openai/gpt-image-2. The
default is gemini/gemini-3.1-flash-lite-image (fast, ~$0.03/image).
# Save to image_<ts>.<ext> in cwd — the extension follows the bytes the
# model returned (gemini emits JPEG, gpt-image emits PNG)
opper image generate "a serene mountain lake at dawn"
# Specific output, specific model
opper image generate "logo concept" -o ./out/logo.png \
-m openai/gpt-image-2
# Print raw base64 (for piping)
opper image generate "icon" --base64 | base64 -d > icon.png
# Edit a local image at 2K (sizes and qualities: the model's params.image)
opper image generate "put it on a marble shelf" --image ./product.png \
-m openai/gpt-image-2.5-flare --size 2048x2048 --quality highGenerated images are not persisted to /v3/files: you get the bytes and
nothing counts against the org's storage quota.
Runs against POST /v3/videos: it submits the job, polls until the clip is
ready and saves it. Any model from opper models list video works; ids name
the provider (bytedance:ap/seedance-2.5, fal/kling-3.0-pro). The default is
gemini/gemini-omni-1.1-flash. Inputs take a local path, a URL or a
file_<id>.
# 5 s vertical clip, silent (a silent clip bills less where audio is priced)
opper video generate "a serum bottle turning on a marble shelf" \
-m bytedance:ap/seedance-2.5 --seconds 5 --resolution 720p --aspect-ratio 9:16 --no-audio
# Animate a still
opper video generate "she smiles and holds up the bottle" --image ./still.png \
-m fal/kling-3.0-pro-i2v --seconds 5
# Edit a clip
opper video generate "change her shirt to a red sweater" --video ./clip.mp4 \
-m bytedance:ap/seedance-2.5A model refuses an input or value it does not take with a 400 naming what it
accepts; opper models list video shows each model's capabilities.
# Pi in non-interactive mode for cron / CI
opper launch pi -p "summarise the latest PR title and body"
# Claude Code with a specific model and resumed session
opper launch claude --model claude-opus-5 --resume
# Codex with Sonnet for a single ask
opper launch codex --model claude-sonnet-5 -- "implement this feature"| Flag | Description |
|---|---|
--key <slot> |
API key slot to use (default: default). |
--project-uuid <uuid> |
Explicit project target sent as X-Opper-Project. |
--debug |
Verbose diagnostic output. |
--no-telemetry |
Disable anonymous telemetry. |
--no-color |
Disable ANSI colors. |
-v, --version |
Print CLI version. |
-h, --help |
Show help (grouped by domain). |
- Node.js ≥20.12 (for
util.styleText, used by interactive prompts). - macOS, Linux, or WSL. Native Windows has automated package and launch checks (see Testing); interactive Windows login remains unverified, and OAuth approval URLs must be opened manually there.
npm ci
npm run typecheck
npm test
npm run build
npm run test:smokeThe package smoke test packs the built CLI and installs the tarball into a
temporary npm prefix whose path contains spaces. It runs the generated opper
command through PowerShell and CMD on Windows, or /bin/sh on macOS/Linux,
checking version, help, the agent list, and failure exit codes. Home directories,
Opper credentials, npm configuration, and caches are isolated; the temporary
installation is removed afterward. The launch checks install local fixture
programs for Claude Code, Codex, OpenCode, and Pi, then exercise the real CLI's
argument forwarding (including multiline and long prompts), routing environment,
working directory, exit codes, configuration restoration, and denied-catalog/
missing-agent errors against a local HTTP fixture. The same compiled installer
used by --install installs the local fixture package into an isolated prefix.
Windows checks also verify that executables in the current checkout cannot
replace the installed agents. They use synthetic credentials and make no
inference calls.
Windows requires PowerShell 7 (pwsh) for this test, as provided by GitHub's
Windows runners.
PR CI runs the automated suite and package smoke test on Linux and Windows. These checks cover package installation and process launching; interactive Windows browser login, actual agent inference, and Ctrl-C behavior still need separate Windows verification.
On a Mac with Conductor and its managed Codex installed, the optional integration test runs the built CLI through Conductor's actual runtime against a local fake gateway:
npm run build
CONDUCTOR_INTEGRATION=1 node test/integration/conductor.mjsIt uses isolated settings and synthetic credentials to check automatic executable selection, pool/route discovery, provider opt-in, credential renewal, and restoring previous settings on removal. It does not make paid inference calls or change the normal Conductor/Codex settings. GUI model selection and live gateway inference are separate acceptance checks.
Releases are driven by a tag. Nothing publishes on a merge to main.
# 1. bump the version on a branch, and open a PR
npm version patch --no-git-tag-version # or minor / major
# 2. merge it
# 3. tag the merge commit
git checkout main && git pull
git tag v0.1.30 && git push origin v0.1.30Pushing the tag runs .github/workflows/release.yml, which builds, tests,
publishes to npm and cuts the GitHub release.
The tag and package.json must name the same version; the workflow checks this
before building and fails if they disagree. Both the npm publish and the GitHub
release are idempotent, so re-running a half-finished release completes it
rather than erroring.
Two things not to change without care: the workflow's filename, which npm's
trusted-publishing config pins alongside the org and repo, and the fact that it
never pushes to main — the require-pr-main ruleset has no bypass list, and a
workflow that pushes a commit there is rejected before it reaches npm.
Requires Node.js 22+ and npm on macOS/Linux. Copilot 1.0.88 is run through npx;
no global Copilot installation is required. The standard CLI sign-in, selected
--key slot, expiry checks and credential lock are shared with other agents.
opper launch copilot
opper --key work launch copilot --kinds pools,routes
opper launch copilot --list --kinds all
npx @opperai/cli@latest launch copilotInside Copilot, /model selects from the credential's current allowed catalog.
/opper-usage displays account, project, key expiry, personal/role allowance and
shared project usage. Organization billing requires explicit server permission.
/opper-login opens browser renewal and continues the same conversation after
validation of the same user, organization, project and endpoint. It does not
replay failed requests. The terminal warns within 24 hours of known expiry. Commands use Copilot's experimental extension support; --no-extension
disables them. Opper allowance is available in the native footer through its
Custom item by default. Use /footer to toggle Custom and context window
visibility independently. --no-budget disables the custom allowance command;
--budget-footer remains supported for compatibility. Use /opper-usage for
allowance details and Copilot’s /context for context usage.
The last model and type filter are remembered. A fresh isolated Copilot profile is created per launch; existing Copilot settings are untouched. Restart/resume of prior conversations is not supported yet. GitHub-connected features are not part of this BYOK integration. Private run tokens and provider references are removed on normal exit. API keys are never written to the provider registry.
One-time setup for plain copilot is not implemented. OpenCode already has
opper editors opencode --login-bridge; Copilot needs separate validation of
provider initialization versus extension/hook startup before offering equivalent
automatic credential and model refresh. No shell aliases or background services
are installed by opper launch copilot.
Pi fetches the credential-scoped catalog at setup and launch, including pools and
dynamic routes with tool support and valid context limits. An explicit
--project-uuid is used for both discovery and inference. Empty or failed catalog
lookups stop setup without installing a static fallback list. Other Pi providers
remain available.
OpenCode deployment labels include the full model ID to distinguish providers. Pools and dynamic routes are marked separately. Existing one-time OpenCode login bridges need setup rerun to receive the updated labels.
Fresh native and generated catalogs default to pools and account dynamic routes. Add
--model-kinds all to supported launch/setup commands to include provider
specific deployments. Explicit model IDs and previously configured authorized
entries remain available during refresh; narrowing never silently removes an
older selection. Existing native endpoint discovery remains in use where its
response contract is compatible. See agent model discovery
for adapter support, compatibility boundaries and runtime validation.