Configuration
September 18, 2026 · View on GitHub
Configuration
Most people only need the examples on this page. The full option list is at the bottom.
Where settings live
OpenCode Quota normally keeps its settings in one separate file:
- Project install:
<your-repo>/opencode-quota/quota-toast.jsonc - Global install: usually
~/.config/opencode/opencode-quota/quota-toast.jsonc - Custom config directory:
$OPENCODE_CONFIG_DIR/opencode-quota/quota-toast.jsonc
Strict .json files also work. Run /quota_status if you are unsure which file is active.
opencode.jsonc loads the main plugin. tui.jsonc loads TUI features. Put the settings below in quota-toast.jsonc, not tui.jsonc.
Common changes
| You want | Setting |
|---|---|
| Find providers automatically | enabledProviders: "auto" |
| Show every reset period | formatStyle: "allWindows" |
| Show one quota window per provider | formatStyle: "singleWindow" |
| Show quota used instead of left | percentDisplayMode: "used" |
| Estimate when eligible fixed quota runs out | quotaProjection: "runway" |
Show percentages without left or used | percentLabelStyle: "bare" |
| Use dense reset countdown units | resetTimeSpaced: false |
| Show supplementary accounting facts | accountingDetail: "detailed" |
| Show slash results with messages | tuiCommandDisplay: "inline" |
| Show slash results in a TUI popup | tuiCommandDisplay: "dialog" |
| Turn the TUI sidebar on or off | tuiSidebarPanel.enabled |
| Prefer an OpenCode Go collapsed row | tuiSidebarPanel.opencodeGoPreferredWindow |
| Turn popup quota notifications on or off | enableToast |
| Notify when weekly quota resets | resetNotifications.enabled |
| Turn the compact quota line on or off | tuiCompactStatus.enabled |
| Show a quota progress bar under the prompt | tuiPromptBar.enabled |
| Show or hide session input/output tokens | showSessionTokens |
| Include descendant/subagent session tokens | sessionTokenScope: "tree" |
The installer chooses allWindows by default. If the setting is absent, the built-in default is singleWindow.
Example
{
// Find providers from OpenCode configuration and authentication.
"enabledProviders": "auto",
// Show every quota reset period as percentage remaining.
"formatStyle": "allWindows",
"percentDisplayMode": "remaining",
// Optional linear estimate for supported fixed windows. Off when omitted.
"quotaProjection": "runway",
"percentLabelStyle": "bare",
// Use dense compound reset countdowns instead of the spaced default.
"resetTimeSpaced": false,
"accountingDetail": "summary",
// Keep TUI slash-command results with normal messages.
"tuiCommandDisplay": "inline",
// Show the sidebar and prefer OpenCode Go's Five-hour row while collapsed.
"tuiSidebarPanel": {
"enabled": true,
"opencodeGoPreferredWindow": "rolling",
},
"enableToast": false,
"resetNotifications": { "enabled": false, "windows": ["weekly"] },
"tuiCompactStatus": { "enabled": false },
// Show a quota progress bar under the prompt.
"tuiPromptBar": { "enabled": true },
}
Restart OpenCode after changing the file.
Show accounting detail
accountingDetail is a root setting with two values:
"summary"(default) keeps primary accounting rows and shows at most one supporting basis expression per percentage row."detailed"also admits supplementary rows and, on wide output, can show separateUsed,Limit, andRemainingfacts.
It applies to human output from /quota, terminal show, popup toasts, the TUI sidebar, Compact status, and the prompt bar below the input. Narrow, tiny, 36-column sidebar, and compact layouts can omit basis or supplementary detail rather than truncate a financial value. The prompt bar always keeps one primary row and omits supplementary rows and basis details.
This setting is independent of formatStyle, which selects quota windows, and percentDisplayMode, which selects used or remaining percentage direction. Those display settings do not change provider input or cache identity. Changing only accountingDetail reprojects an available snapshot immediately; later collection still follows normal cache expiry, disabled-cache, and refresh rules. The words Used, Limit, and Remaining always keep their literal meanings in either percentage mode.
Estimate when fixed quota runs out
quotaProjection: "runway" is optional and off by default. It adds a Runs out estimate to eligible percentage rows on shared Web/Desktop and TUI /quota, terminal show, popup toasts, the expanded Sidebar, Compact status, and the prompt bar.
{
"quotaProjection": "runway",
}
The estimate is a straight-line average since the confirmed fixed window began: used percentage divided by elapsed time, then remaining percentage divided by that average rate. It is not a recent-rate forecast, trend, alert, budget, or prediction model. Changing percentDisplayMode between remaining and used does not change the calculation.
The provider's exact reset countdown stays separate from the estimate. If the calculated exhaustion is before reset, full displays use Runs out ≈ 1h 50m; Compact status and the prompt bar use r/o ≈ 1h 50m, where r/o means “runs out.” The approximation marker always has one following space, duration units are spaced, and partial minutes round up. If current use would last through the reset, displays say lasts past reset.
Availability is deliberately narrow. A row needs a finite percentage, its original observation time, a nonzero elapsed interval, and explicit fixed-window start, end/reset, and full-reset evidence. OpenAI's known API rate-limit windows, xAI periods with explicit currentPeriod.start and currentPeriod.end, Cursor cycles with cursorBillingCycleStartDay, Qwen's maintained UTC-day window, and configured local-estimate utc-day windows can qualify. Rolling windows, RPM rows, balance/status/unlimited rows, Cursor's calendar-month fallback, and windows inferred only from labels do not. Unsupported rows are simply unchanged.
This option changes human presentation only. It reuses cached provider snapshots without another provider request, preserves the provider observation time, and does not add fields to JSON export v2.
Notify when quota becomes available again
Reset notifications are opt-in. They reuse provider snapshots already collected by OpenCode Quota, so enabling them does not add provider requests.
{
"resetNotifications": {
"enabled": true,
"windows": ["weekly"],
},
}
The first observation establishes a baseline. A success toast appears only after OpenCode Quota observes the advertised reset boundary, a newer reset timestamp, and an increase in remaining quota. A local acknowledgment prevents the same reset from being announced again after restart. The state file stores pseudonymous SHA-256 identity keys plus remaining percentages and reset, observation, and acknowledgment timestamps. Literal account source identifiers, display labels, and credentials are not written to it.
Reset notifications use the server popup-toast surface. They do not appear in slash-command or CLI
output, Sidebar, Compact status, status collection, telemetry, or JSON exports, and require a host
that supports tui.showToast. Supported window names are fiveHour, hourly, daily, weekly,
monthly, and yearly.
Include subagent session tokens
Session totals use only the current session by default. To include the current session and every descendant or subagent session once:
{
"showSessionTokens": true,
"sessionTokenScope": "tree",
}
This scope applies to the embedded session-token output in /quota on Web and TUI, popup toasts, the TUI sidebar, and the compact line below the message input. It does not change /tokens_session or /tokens_session_all; those commands keep their explicit current-session and session-tree meanings.
Custom providers
A custom provider connects OpenCode Quota to a provider that is not built in, or lets you tune a maintained local estimate.
Use the guided command:
npx @slkiser/opencode-quota@latest provider add
It asks what kind of provider you have, previews the complete canonical merged global config, and asks before writing. It never asks for a response body, credential, or secret value. For json-v1, it guides you through the optional rows path and each mapping one field at a time. The same schema validator used at startup checks the constructed adapter before the preview.
The command updates the active global quota config. If a global quota-toast.jsonc or .json exists, it uses that file. Otherwise it uses the global opencode.jsonc or .json. Project custom-provider definitions are not allowed.
How custom providers work
- Remote API: reads real quota data from a supported HTTPS endpoint.
- Local estimate: counts matching OpenCode requests and can estimate spend.
- OpenCode Quota tries models.dev pricing automatically.
- Add
pricingModelMaponly when automatic matching cannot find one clear model. - Generated counters live under
~/.local/state/opencode/opencode-quota/.
A custom model provider still needs its normal OpenCode provider block. That block tells OpenCode how to use the model; quotaProviders tells OpenCode Quota how to measure it.
Complete fallback example
When no separate quota settings file exists, the guided command uses the global OpenCode config.
The command writes the experimental.quotaToast.quotaProviders section. Configure the normal OpenCode provider block separately:
{
"$schema": "https://opencode.ai/config.json",
"experimental": {
"quotaToast": {
"enabledProviders": "auto",
"quotaProviders": [
{
"id": "openrouter-primary",
"providerId": "openrouter",
"label": "OpenRouter Primary",
"mode": "remote-api",
"url": "https://openrouter.ai/api/v1/key",
"format": "openrouter-key-v1",
"apiKeyEnv": "OPENROUTER_API_KEY",
},
{
"id": "private-gateway",
"label": "Private Gateway Estimate",
"mode": "local-estimate",
"modelIds": ["model-a"],
"windows": [
{
"id": "daily",
"label": "Daily",
"type": "utc-day",
"requestLimit": 1000,
"usdBudget": 25,
},
],
},
],
},
},
"provider": {
"private-gateway": {
"models": {
"model-a": {},
},
},
},
}
Custom-provider rules
quotaProvidersis global-only and keeps file order.idis the stable identity. AddproviderIdonly when it differs.modelIdsaffects onlyonlyCurrentModel. Use exact, case-sensitive model IDs without the outer provider prefix, or omit it to cover every model for that provider.- Remote APIs use a fixed authenticated
GET. Supported formats arequota-v1,json-v1, andopenrouter-key-v1. json-v1requires anadapterwith 1–16 mappings. Paths are literal own-property segment arrays, not JSONPath.- Local estimates support 1–16 UTC-day or rolling request windows.
- Automatic models.dev matching runs first.
pricingModelMapcannot override a successful automatic match. - If any request cannot be priced, request counts stay visible and the budget percentage is reported unavailable.
- Credentials resolve from
apiKeyEnv, trusted globalprovider.<providerId>.options.apiKey, then API-key entries in OpenCodeauth.json. - Definitions run automatically with
enabledProviders: "auto". A manual list must includequota-providersand every built-in provider you still want. - To tune maintained estimates, use the reserved
qwen-codeoralibaba-coding-planID and its maintained window shape. Do not add a duplicate normal provider block. - Project secrets, scripts, custom headers, executable mappings, regular expressions, and JSONPath are not accepted.
Run /quota_status to see the exact state path and safe authentication source without exposing secrets.
See Providers for response formats and setup details.
More recipes
Choose providers yourself
{
"enabledProviders": ["copilot", "openai", "google-agy"],
}
Show used percentages
{
"percentDisplayMode": "used",
}
Keep compact status on Home only
{
"tuiCompactStatus": {
"enabled": true,
"homeBottom": true,
"sessionPrompt": false,
},
}
Choose decimal reset countdowns
By default, popup toasts, the Sidebar, terminal show, and the prompt bar show exact remaining days, hours, and minutes with spaces between compound units, such as 6d 1h 17m, 2h 14m, or 37m. Partial minutes round up. Set resetTimeDecimals to an integer from 0 to 4 to instead show the largest unit as a decimal value, such as 5.7d or 1.4h.
{
"resetTimeDecimals": 1,
}
Leave it unset to use the default exact-to-minute display.
Choose reset spacing and shorten percent labels
Exact compound countdowns use spaces by default. Set resetTimeSpaced to false when a dense layout is more important. For example, 2d 5h 14m becomes 2d5h14m, and 3h 45m becomes 3h45m. Minute-only values such as 14m, expired values shown as reset, and partial-minute rounding stay unchanged. This setting applies to /quota in Web, Desktop, and the TUI, popup toasts, terminal show, the expanded and collapsed Sidebar, Compact status, and the prompt bar.
resetTimeDecimals keeps its existing largest-unit decimal format and takes precedence over spacing on the displays where decimal countdowns apply.
Set percentLabelStyle to "bare" to show 81% instead of 81% left, or 19% instead of 19% used. Full reports identify the mode as Quota [Remaining] or Quota [Used]. The Sidebar uses the same heading, keeps its collapse icon, and gives the freed columns to its bars. Compact status and prompt percentages remain bare.
{
"resetTimeSpaced": false,
"percentLabelStyle": "bare",
}
Both settings are optional. Leave resetTimeSpaced unset to keep spaced countdowns, and leave percentLabelStyle unset to keep full percent labels.
Change maintainer notices
{
"maintainerAnnouncements": {
"enabled": true,
"home": true,
},
}
Set enabled to false to turn automatic notices off.
Allow more time for provider requests
{
"requestTimeoutMs": 12000,
}
Advanced: also write the older OpenCode settings block
npx @slkiser/opencode-quota init --sync-legacy-config
Use this only if another tool needs experimental.quotaToast mirrored into opencode.jsonc or .json.
Full configuration reference
Most settings go in the same opencode-quota/quota-toast.jsonc or .json sidecar described above. The guided editor maintains quotaProviders in that authoritative sidecar when one exists; otherwise it uses the global OpenCode experimental.quotaToast section; do not duplicate it in a second file.
Existing experimental.quotaToast settings remain supported. Quota settings do not live in tui.json.
All settings
Core/shared settings
| Option | Default | Meaning |
|---|---|---|
enabled | true | Master switch for quota collection and handled slash commands. When false, /quota, /quota_status, /pricing_refresh, and /tokens_* are handled as no-ops. |
resetNotifications.enabled | false | Emit a one-shot success toast when an observed configured quota window resets. Requires popup toasts to be enabled and adds no provider requests. |
resetNotifications.windows | ["weekly"] | Window classes eligible for reset notifications: fiveHour, hourly, daily, weekly, monthly, or yearly. |
enabledProviders | "auto" | Auto-detect providers, or set an explicit provider list. Use the aggregate ID quota-providers for configured definitions. |
quotaProviders | [] | Ordered global-only remote-api or local-estimate definitions maintained in global OpenCode JSONC/JSON. Each item has a stable id; providerId is only needed when different. |
minIntervalMs | 300000 | Minimum fetch interval between provider updates. |
requestTimeoutMs | 5000 | Remote provider request timeout in milliseconds. |
formatStyle | singleWindow | Shared quota reset-period display for TUI popup toasts, the Sidebar panel, and Compact status line unless a TUI surface override is set: singleWindow shows one reset period per provider; allWindows shows all reset periods per provider. Legacy classic/grouped aliases are still accepted. |
percentDisplayMode | remaining | Percentage/bar direction across human surfaces: remaining shows the percentage left; used shows the percentage consumed. It does not rename literal basis facts. |
quotaProjection | unset | Set to "runway" for a linear Runs out estimate on explicitly supported fixed, full-reset percentage windows. Off when unset; unsupported rows remain unchanged; JSON export v2 is unchanged. |
percentLabelStyle | unset | Set to bare to remove left or used from full-report percentage labels. Full reports and the Sidebar name the direction in a Quota [Remaining] or Quota [Used] heading. full is also accepted. Unset keeps full labels. |
accountingDetail | summary | Provider-neutral accounting detail across human surfaces: summary keeps primary rows; detailed also admits supplementary rows and fuller basis detail when width allows. Independent of formatStyle and percentDisplayMode. |
resetTimeDecimals | unset | Decimal places for a largest-unit reset countdown override in popup toasts, the Sidebar panel, terminal show, and the prompt bar. Accepts integers 0–4; when unset, the default shows exact remaining days, hours, and minutes. |
resetTimeSpaced | true | Exact compound countdowns use spaces, such as 2d 5h 14m, on /quota, popup toasts, terminal show, the Sidebar, Compact status, and the prompt bar. Set to false for dense spelling such as 2d5h14m. resetTimeDecimals keeps its legacy decimal format where it applies. |
onlyCurrentModel | false | Filter quota rows to the current model/provider when that session selection can be resolved. |
showSessionTokens | true | Show the Session input/output tokens section when session token data is available. When cached input is present, the section keeps the legacy in/out layout and appends cached input in parentheses next to the input amount. |
sessionTokenScope | "current" | Choose current for the active session only or tree for the active session plus recursive descendants/subagents, counted once. Applies to /quota, popup toasts, the Sidebar panel, and the compact input line when showSessionTokens is enabled. Does not change /tokens_session or /tokens_session_all. |
pricingSnapshot.source | "auto" | Token pricing snapshot selection for /tokens_*: auto, bundled, or runtime. |
pricingSnapshot.autoRefresh | 7 | Refresh stale local pricing data after this many days. |
TUI toast settings
| Option | Default | Meaning |
|---|---|---|
enableToast | true | Show TUI popup toasts. OpenCode 1.17.20 Web does not surface these events. Disabling this does not disable terminal checks, other UI surfaces, or /quota. |
toastDurationMs | 9000 | Toast duration in milliseconds. |
showOnIdle | true | Show a toast on the idle trigger. |
showOnQuestion | true | Show a toast after a question/assistant response. |
showOnCompact | true | Show a toast after session compaction. |
showOnBothFail | true | Show a fallback toast when providers attempted quota reads and all failed. |
layout.maxWidth | 50 | Toast formatting width target. |
layout.narrowAt | 42 | Toast compact-layout breakpoint. |
layout.tinyAt | 32 | Toast tiny-layout breakpoint. |
debug | false | Append toast debug context when troubleshooting. |
TUI settings
| Option | Default | Meaning |
|---|---|---|
tuiCommandDisplay | "inline" | Choose where deterministic native TUI command output appears. inline adds an ignored/no-reply plain-text message to the active transcript and uses a dialog on Home; dialog always opens the local popup. |
tuiSidebarPanel.enabled | true | Show the Sidebar Quota panel when the TUI plugin is installed. Click the panel header to toggle its collapsed/expanded window layout; OpenCode remembers the last state. This is not an accountingDetail override. |
tuiSidebarPanel.formatStyle | (root formatStyle) | Override formatStyle for the Sidebar panel only. Useful when you want allWindows detail in the sidebar but a different style elsewhere. |
tuiSidebarPanel.opencodeGoPreferredWindow | unset | Prefer rolling (Five-hour), weekly, or monthly for OpenCode Go only while the sidebar is collapsed. If unset or unavailable, the lowest-remaining window is used. Expanded rows still follow opencodeGoWindows. |
tuiCompactStatus.enabled | false | Opt in to Compact status line UI surfaces. |
tuiCompactStatus.homeBottom | true | Show the Compact status line at the home bottom location. |
tuiCompactStatus.sessionPrompt | true | Show the Compact status line by wrapping the TUI session prompt. Disable this if you only want the home-bottom line. |
tuiCompactStatus.suppressWhenNativeProviderQuota | true | Hide the Compact status line when OpenCode exposes native provider-quota support. |
tuiCompactStatus.maxWidth | 96 | Maximum Compact status line text width. |
tuiCompactStatus.formatStyle | (root formatStyle) | Override formatStyle for the Compact status line only. Useful when you want singleWindow on the compact line while the sidebar shows allWindows. |
tuiPromptBar.enabled | false | Show one opt-in primary quota/accounting result below the TUI prompt and replace the Compact line there. Rich results use the first projected primary row; legacy-only results keep the existing 5h percentage preference. Basis and supplementary rows are omitted. |
Maintainer announcement settings
| Option | Default | Meaning |
|---|---|---|
maintainerAnnouncements.enabled | true | Enable bundled maintainer announcements. |
maintainerAnnouncements.home | true | Show the count-only notice on TUI home when the quota TUI plugin is configured, or as a one-shot toast fallback after a visible quota toast when it is not. |
Provider-specific settings
| Option | Default | Meaning |
|---|---|---|
anthropicBinaryPath | "claude" | Command/path used for local Claude CLI probing. |
googleModels | ["CLAUDE"] | Google model keys to query: CLAUDE, G3PRO, G3FLASH, G3IMAGE, GPTOSS. |
opencodeGoWindows | ["rolling", "weekly", "monthly"] | Choose which validated OpenCode Go API results are available across surfaces and in the expanded sidebar: Five-hour, Weekly, and Monthly. |
opencodeMonthlyLimit | unset | Override the OpenCode Zen monthly budget in USD. |
cursorPlan | "none" | Cursor included API budget preset: none, pro, pro-plus, ultra. |
cursorIncludedApiUsd | unset | Override Cursor monthly included API budget in USD. |
cursorBillingCycleStartDay | unset | Local billing-cycle anchor day 1..28; when unset, Cursor usage resets on the local calendar month. |
Kilo Gateway has no quota-toast.json credential setting. Use KILO_API_KEY, trusted user/global provider.kilo.options.apiKey, or a strict kilo API-key entry in OpenCode auth.json; project-local OpenCode config is not read for this secret. See Kilo Gateway setup.
Ollama Cloud has no quota-toast.json credential setting. Use OLLAMA_API_KEY, trusted user/global provider.ollama-cloud.options.apiKey, or a strict ollama-cloud API-key entry in OpenCode auth.json; project-local OpenCode config is not read for this secret. See Ollama Cloud setup.
OpenCode Go has no quota-toast.json workspace ID, cookie, endpoint, credential, or token setting. It automatically uses OPENCODE_API_KEY, trusted user/global provider.opencode-go.options.apiKey, trusted user/global fallback provider.opencode.options.apiKey, a strict opencode-go API-key entry in OpenCode auth.json, or a strict legacy opencode auth entry as the final fallback. opencodeGoWindows filters the Five-hour, Weekly, and Monthly rows returned by the official usage API, including the expanded sidebar. Use tuiSidebarPanel.opencodeGoPreferredWindow to prefer one available row only while the sidebar is collapsed. See OpenCode Go setup.
Xiaomi MiMo has no quota-toast.json credential or endpoint setting. Use MIMO_USAGE_COOKIE or trusted user/global opencode-quota/mimo.json; see Xiaomi MiMo setup.
Removed Zen setting: opencodeZenDisplay is no longer supported. Runtime loading stays diagnostic-only: if a file-backed, SDK, or legacy config source contains the key, /quota_status reports a nonfatal migration issue and does not translate it. The explicit update command migrates recognized file-backed "default" to root accountingDetail: "summary" and "detailed" to "detailed". If a valid accountingDetail already exists, it stays authoritative and the ignored old key is removed. Unknown or invalid values, invalid replacements, duplicate keys, ambiguous structures, and SDK-only sources remain unchanged for manual review. See Updating safely.
Export settings
| Option | Default | Meaning |
|---|---|---|
export.enabled | false | Write a JSON export file after each TUI background refresh. |
export.path | "" | Export file path. Empty string uses the XDG default: $XDG_CACHE_HOME/opencode/quota-export.json. Supports ~/ expansion. |
Telemetry settings
| Option | Default | Meaning |
|---|---|---|
telemetry.enabled | false | Publish quota consumption and cache-age gauges through the host's global OpenTelemetry MeterProvider; adds no provider calls. |
See External integration for metric names, attributes, setup, and privacy behavior.