Provider authentication
Feature docs index · Repository README
Connect a provider
Run /login in Mission Control. Choose OpenAI Codex for ChatGPT OAuth, OpenAI for API-key access, Anthropic for Messages API access billed through Anthropic API credits, or Custom Provider for an OpenAI-compatible service.
Never commit credentials, copied tokens, account ids, terminal auth output, or transcripts containing secrets. Settings contain non-secret options only; credentials belong in the provider's environment variable or private auth.json under ~/.magi-code (or $MC_HOME).
OpenAI Codex
/login openai-codex
Complete the ChatGPT browser OAuth flow, then check access:
magi-code --provider openai-codex --model gpt-5.5 --prompt "Reply with only: ok"
openai-codex requires provider-keyed OAuth credentials and a ChatGPT account id. It calls https://chatgpt.com/backend-api/codex/responses. Inference and model discovery do not use --api-key, MC_API_KEY, OPENAI_API_KEY, or custom-provider keys. Do not pass OAuth tokens through those options: runtime-token/API-key auth is refused for Codex.
Login displays an authorization URL and binds 127.0.0.1:1455 for the registered redirect URI http://localhost:1455/auth/callback. Credentials are saved in auth.json. The visible URL is transient and redacted from logs/debug output. Manual redirect/code input is visually redacted, never stored in settings or sessions or sent to the model, and goes to the token exchange only when explicitly submitted.
At 80×24, custom setup shows the active field; Tab and Shift-Tab move between fields. OAuth keeps browser, copy, and redirect-input controls visible. URLs that exceed the available space show a page count: Page Up and Page Down cycle through every URL page. Copy URL always copies the complete URL.
/logout openai-codex
Logout removes the local OAuth record only. It does not revoke remote tokens or sign out browser sessions.
OpenAI API
Export OPENAI_API_KEY before launching magi-code, then choose OpenAI in /login or run /login openai. Review the prefilled custom-provider form and press Enter to save:
- Label/id:
OpenAI/openai - API root:
https://api.openai.com/v1 - API-key variable:
OPENAI_API_KEY - models.dev provider:
openai
This uses the existing custom-provider Responses transport, not ChatGPT OAuth. Setup stores only metadata and asks before replacing an existing openai configuration. Refresh the catalog in /settings → Models, then select /model openai/<model-name>. /logout openai removes the custom-provider configuration; it does not unset the environment variable.
Anthropic
export ANTHROPIC_API_KEY="<ANTHROPIC_API_KEY>"
magi-code --provider anthropic --model claude-sonnet-4-5-20250929 --prompt "Reply with only: ok"
Auth checks ANTHROPIC_API_KEY first, then the provider-keyed anthropic API-key record in auth.json. OAuth and no-auth configurations are rejected. Anthropic ignores --api-key, MC_API_KEY, and OpenAI keys such as OPENAI_API_KEY.
To save the model selection without storing a key:
{
"agent": { "model": {
"provider": "anthropic",
"model": "claude-sonnet-4-5-20250929"
}
} }
Use /settings → Models → Refresh catalog, then /model anthropic/<model-name> to select a cached model. Missing Anthropic auth does not block Codex or custom-provider catalogs. /logout anthropic removes only the local API-key record; it cannot unset or override ANTHROPIC_API_KEY.
Custom OpenAI-compatible providers
Use /login custom-provider to enter a label, API-root base URL, and optional API-key environment-variable name. Setup saves non-secret metadata, never a key value. Provider ids use lowercase slugs such as local-provider; openai-codex is reserved. An id such as openai can use the custom-provider workflow.
If you configure an API-key variable, only that named variable is read and it must be non-empty for the provider to be ready. Without one, you can use a no-auth local provider:
# No-auth local provider:
magi-code --provider local-provider --model model-name --prompt "Reply with only: ok"
# Env-var-backed provider:
export HOSTED_PROVIDER_API_KEY="<CUSTOM_PROVIDER_API_KEY>"
magi-code --provider hosted-provider --model model-name --prompt "Reply with only: ok"
Custom requests use {base_url}/responses by default. The URL is a normalized API root, not a request endpoint. Model discovery uses {base_url}/models. Edit providers.custom.<id> in settings.json for options not prompted by login:
| Option | Behavior |
|---|---|
use_responses_endpoint: false | Opts out of the default Responses endpoint and uses {base_url}/chat/completions; discovery stays on /models. There is no automatic endpoint detection. Codex is unaffected. |
supports_text_verbosity: true | Declares Responses text.verbosity support; defaults false. Emission also requires Responses mode and shared providers.openai_responses.text_verbosity. |
fast_mode | Explicit service tier and exact model ids, or sole "*" entry. No capability inference from names. See Fast mode. |
extra_models | Adds provider-local model ids omitted by /models; dedupes against discovered ids and does not change the endpoint. |
models_dev_provider | Exact models.dev namespace for matching context/reasoning/output-token metadata, not auth. Defaults to the provider id. |
For a Z.ai Coding Plan model omitted by /models:
{
"providers": { "custom": {
"zai": {
"label": "Z.ai",
"base_url": "https://api.z.ai/api/coding/paas/v4",
"api_key_env_var": "ZAI_API_KEY",
"extra_models": ["glm-5.2"]
}
}
} }
Use glm-5.2, not zai/glm-5.2, in extra_models. Catalog enrichment requires an exact namespace and model id match, never a label, host, prefix, or base-URL guess. For example, id openai uses namespace openai; id custom-openai needs models_dev_provider: "openai" to use that metadata. An explicit namespace always wins.
/logout <custom-provider-id> removes custom-provider metadata only from global settings. Project provider definitions and environment credentials remain, as do sessions, unrelated settings, and other providers.
Mission Control login controls
/login opens the staged Connect Provider modal with provider status. Use Up/Down and Enter to choose.
- Codex: click Open Browser (
Alt-O) or Copy URL (Ctrl-Y).Tab/Shift-Tabfocuses the buttons or redacted fallback field;Enteractivates the button or submits the pasted redirect URL/code.Esccancels active OAuth. - API keys: the modal shows environment setup instructions, not a key-entry field.
- Custom providers: Details contains label, base URL, optional API-key environment-variable name, and optional
models.devprovider override.Tab/Shift-Tabmoves fields. Blank override uses the provider ID and clears any previous override. Reusing an id requires confirmation:Enterreplaces;Escreturns to the form. - Success:
EnterorEsccloses. Errors:Enterretries,BackspaceorLeftgoes back, andEsccloses.
Cancelling before Saving preserves existing credentials and settings. Once durable custom-provider saving begins, it cannot be cancelled; the modal stays open until completion is reconciled.
Fast mode
Use /fast on or set global agent.fast.enabled: true. It defaults off, ignores project overrides, and applies to eligible primary turns, subagents, and manual or automatic blocking compaction, not session titles.
Codex selects the exact catalog-advertised Fast tier id, matching Fast display/name case-insensitively. Explicit tier metadata without Fast keeps the request Standard. When tier metadata or the catalog entry is missing, strictly normalized Codex GPT versions >=5.4 use the fast fallback. Unsupported models/providers request no Fast tier.
Codex OAuth Responses requests include a Codex-only x-codex-routing-hint: model=<normalized-model>, even with Fast off, unless it is invalid as an HTTP header value. With a selected Fast tier, it adds ;tier=<service-tier-id> and the body includes the exact service_tier. The hint is not sent to catalogs or custom providers.
Custom providers require explicit providers.custom.<id>.fast_mode, for example {"service_tier":"priority","models":["model-name"]}. The tier is trimmed; model ids are preserved exactly. Ids must contain 1 to 200 Unicode characters without whitespace, control characters, or secret-like values. "*" must be the sole entry. See Configuration for schema validation rules.
Fast is not an entitlement check or speed guarantee. The provider controls access, routing, speed, and billing/credits. A ChatGPT-auth response may report a different tier such as default; the reported tier does not prove faster execution. In Mission Control, an unacknowledged Fast persistence-worker failure without an event blocks retry until restart; a delivered failure is cleared when its matching event is handled.
Response detail
providers.openai_responses.text_verbosity accepts low, medium, or high. Codex uses it directly. Custom Responses providers require this value plus use_responses_endpoint: true and supports_text_verbosity: true; otherwise they omit the field.
Verbosity affects visible detail, output size, latency, and cost. It does not control reasoning effort, expose hidden/encrypted reasoning, control tool calls, or impose a hard output-token limit or exact answer length.
Credential storage and refresh
auth.json is private and owner-only on Unix. Provider records may sit alongside internal non-secret revision and provider_generations metadata; do not edit that metadata. Writes preserve unrelated provider records.
Before Codex use, including applicable auxiliary work such as model discovery, near-expired or expired credentials refresh if a refresh token is available. Network exchange runs outside auth locks. Saving reacquires the in-process lock, then the cross-process file lock, and requires the same provider generation and full source record to still match. Stale/competing responses cannot overwrite newer auth; stale errors are checked against current state so newer usable credentials can win. Generations survive logout, protecting removed and recreated records from delayed refreshes.
See Configuration for file limits, paths, and credential boundaries.