9.2 Configuring the CLI

Two kinds of settings:

9.2.1 Default config file location

If you do not pass --config PATH and do not set $OWNSONA_CONFIG, the CLI looks at an OS-specific default:

OSDefault config path
Linux / BSD~/.config/ownsona/config.ini
macOS~/Library/Application Support/ownsona/config.ini
Windows%LOCALAPPDATA%\ownsona\config.ini

Create the parent directory if it doesn’t exist (mkdir -p ~/.config/ownsona on Linux, etc.).

9.2.2 Resolution order

For every setting, highest priority wins:

  1. CLI flag (--config, --server, --token, ...).
  2. Environment variable (OWNSONA_SERVER, OWNSONA_TOKEN, OWNSONA_LLM_API_KEY, etc.).
  3. Config file at $OWNSONA_CONFIG or the OS-specific default.
  4. Built-in defaults (only for LLM-side keys).

9.2.3 Authenticating to the server

The CLI talks to OwnSona over OAuth 2.1, just like every other MCP client. The first time you point it at a server, run:

ownsona auth login

That subcommand discovers your server’s authorization server, registers the CLI dynamically (RFC 7591), opens a browser tab to https://your-host/oauth/authorize, and waits for the redirect. You enter your OWNSONA_LOGIN_USERNAME / OWNSONA_LOGIN_PASSWORD (from the server’s application.ini), click Allow, and the CLI stores the resulting access + refresh tokens in its config file. From then on every subcommand transparently refreshes the access token as needed.

Inspect status with ownsona auth status; it prints the auth mode, the refresh token’s TTL, and how much time is left on the current access token.

9.2.4 Config file format

INI-style. # and ; start comments. [sections] are parsed but ignored. A template ships at cli/config.ini.example:

# --- MCP server (required for every subcommand) ---
server_url = https://your-host/mcp

# --- OAuth credentials (populated by `ownsona auth login`) ---
# Edit these directly only if you know what you're doing.
oauth_client_id                  = <generated-by-dynamic-registration>
oauth_refresh_token              = <stored-by-auth-login>
oauth_access_token               = <stored-by-auth-login>
oauth_access_token_expires_at    = <unix-epoch-seconds>

# --- LLM (used only by `teach`) ---
llm_api_key  = sk-...
llm_model    = gpt-4o
llm_base_url = https://api.openai.com/v1
subject_name = Blake

# --- Legacy / external-IdP path ---
# If your OwnSona instance is fronted by a different IdP (Cloudflare
# Access, oauth2-proxy, ...) that hands you a static bearer token,
# put it here.  Mutually exclusive with the OAuth fields above.
# token = <static-bearer-from-external-idp>

The default mode is OAuth. The token = field exists only as a legacy escape hatch for users fronting OwnSona with an external identity provider that issues static bearer tokens — it is not the path against a vanilla OwnSona install, and the embedded AS does not accept it. See Re-authenticating in Connecting OpenAI for cases when an existing OAuth session stops working.