config

A command for reading and changing cctally’s saved preferences in a local JSON configuration file. JSON is a plain-text format for storing settings.

In plain words
What is it for?
Use it to get, set, or remove individual configuration values, including settings that the dashboard can change.
Why use it?
It provides one place to control options such as time zone and other supported behavior, without editing the file by hand.

Command

Install

Getting it into your agent

One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.

agentmods
npx agentmods add commands/omrikais/cctally/config
Clone the repo
git clone --depth 1 https://github.com/omrikais/cctally
Per session 0 Only the description is in the session, so the agent can decide to use it. The body loads when it is invoked.
When invoked 6,311 The whole file, excluding the scripts and references it only reads on demand.
Security scan A 0 findings. Scan, not verified.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5 $0.00000 $0.06311
Opus 5 $0.00000 $0.03155
Sonnet 5 $0.00000 $0.01262
Haiku 4.5 $0.00000 $0.00631

Measured 3d ago against content hash 7432fc3da20b, method: parsed. Prices are Anthropic first-party input rates as of 2026-08-30, from the pricing page.

Security

Grade A, and why

config scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 3d ago.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Nothing flagged

None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.

docs/commands/config.md · 321 lines

How it starts

The opening of the file, as written. The whole thing — 321 lines — stays where its author put it; the contents beside it link to each section on GitHub.

cctally config

Manage cctally user preferences in ~/.local/share/cctally/config.json.

Subcommands

cctally config get [<key>] [--json]
cctally config set <key> <value> [--json]
cctally config unset <key>

Allowed keys

Every key cctally config set accepts, in the order the CLI's own allowlist declares them. cctally config get with no key prints the same set.

The Dashboard writable column says what POST /api/settings does with the key, and it has three states rather than two:

  • Yes — the dashboard Settings overlay writes it, and a direct POST persists it.
  • Ignored — the endpoint accepts the key, does not persist it, and now reports it back in the response's ignored_fields array. Use cctally config set to change it for real.
  • No — the endpoint rejects it with HTTP 400 and a field pointer. Some of these are CLI-only because they hold secrets or arm destructive behavior; others apply only at server startup.
Key Values Default Dashboard writable Notes
display.tz local, utc, or any IANA name (e.g. America/New_York). local Yes The render zone for every subcommand that prints a clock instant, and the parse zone for naive --since/--until on the date-bucketing commands. A per-call --tz flag wins for that one invocation. See How display.tz interacts with subcommands.
alerts.enabled Boolean (true/false/1/0/yes/no/on/off). false Yes The master switch for threshold alerts. See alerts.md.
alerts.projected_enabled Boolean. false Yes Opt-in for projected-pace alerts, so an upgrade fires no surprise notifications. See alerts.md.
alerts.rate_change_enabled Boolean. false Yes Opt-in for a PUSH notification when the provider changes its metering rate. Recording is unconditional, so quota, doctor, the status line and the dashboard show the state whether or not this is on; this switch decides only whether a transition also notifies, and it needs alerts.enabled as well.
alerts.notifier auto, osascript, notify-send, command, none — the OS-popup backend for threshold alerts. auto Yes See Alerts dispatch keys.
alerts.command_template JSON: a non-empty list of argv strings (e.g. ["notify-send","{title}","{body}"]) or null to clear. null No Trusted local command execution, and it routinely holds secrets, so the dashboard refuses it and redacts it from every echo as the boolean command_configured. See Alerts dispatch keys.
alerts.quota JSON object with enabled, actual_thresholds, projected_thresholds and rules. {"enabled": false, "actual_thresholds": [90, 95], "projected_thresholds": [], "rules": []} No The Codex quota alert axis. The block is absent from config.json until you write it, and disabled until enabled is true. Written as a whole object from the CLI. See codex-quota.md.
dashboard.bind loopback (= 127.0.0.1), lan (= 0.0.0.0), or any literal host string (IPv4, IPv6, hostname). Resolution order: --host flag > config > default. loopback No Applies only at server startup, so the running server keeps its bind. See dashboard.md.
dashboard.expose_transcripts Boolean (true/false/1/0/yes/no/on/off). The LAN opt-in for the conversation-viewer transcript endpoints. When false those routes are served only over loopback. false No A privacy gate, not live-mutable. Even when true an anti-DNS-rebinding Host allowlist applies — see dashboard.md.
dashboard.cache_failure_markers Boolean. Opt-out for the conversation-viewer cache-rebuild markers (the amber chip on a turn that re-created the bulk of its cached prefix). Absence is treated as ON. true Yes false hides every marker, the outline landmark/jump button, and the stats count. Also toggleable from the dashboard settings modal.
dashboard.live_tail Boolean. Opt-out for the conversation-viewer live-tail. Absence is treated as ON. true Yes true lets an open reader follow an active session within ~1s via a per-conversation SSE stream; false falls back to the 5-second snapshot tick. See dashboard.md.
dashboard.lan_auth Boolean. Requires the per-run bearer token on every /api/* request when the dashboard binds to a non-loopback address. true Yes true is fail-safe; set false only for a trusted LAN. The running server keeps its startup access mode, so a change applies only after restarting the dashboard.
update.check.enabled Boolean (a JSON boolean over the API; a string is rejected). true Yes Whether the background update check runs at all. See update.md.
update.check.ttl_hours Integer in [1, 720]. A JSON integer, not a string; a boolean is rejected because bool is an int subclass. 24 Yes How long one update-check result is reused before the next check. See update.md.
update.channel stable or beta — the release channel cctally update tracks. beta receives every release as it ships; stable only the maintainer-promoted ones. stable Yes Install-method-independent (Homebrew always tracks stable). Also toggleable from the dashboard settings modal, which mirrors it as update.configured_channel; resolve_update_channel is the single resolver every consumer reads it through. See update.md.
statusline.visual_burn_rate off, emoji, text, emoji-text. off No The segment-3 visual indicator; the -B/--visual-burn-rate flag wins per call. See statusline.md.
statusline.cost_source auto, cctally, cc, both. The legacy ccusage value is rejected with a rename hint. auto No Which session-cost source the status line renders. See statusline.md.
statusline.cctally_extensions Boolean (true/false/yes/no/on/off/1/0). true No Appends or suppresses the cctally extension segment. See statusline.md.
statusline.usage_only Boolean. false No Renders only the 5h X% · 7d Y% subscription percentages. See statusline.md.
budget.weekly_usd A finite number greater than zero, or null for no budget. null Yes The Claude equivalent-spend budget. See budget.md.
budget.alerts_enabled Boolean. true Yes On when a budget is set. See budget.md.
budget.alert_thresholds Comma-separated base-10 integers in [1,100]; values are sorted and deduplicated, and an empty string means [] (silenced). 90,100 Yes The percentages of the budget that fire an alert. See budget.md.
budget.projected_enabled Boolean. false Yes Opt-in for the projected-pace budget alert. See budget.md.
budget.period subscription-week, calendar-week, or calendar-month. subscription-week Ignored The dashboard accepts this leaf and runs the same forward-only reconcile the CLI does, but never stores it — the response discloses that in ignored_fields. Set it with cctally config set. See budget.md.
budget.projects JSON object of {canonical git-root path: usd}; each value a finite number greater than zero. {} No Per-project weekly budgets, CLI-only. See budget.md.
budget.project_alerts_enabled Boolean. false Yes Opt-in for per-project budget alerts. See budget.md.
budget.accounts JSON object of {account ref: usd}; each value a finite number greater than zero. {} No Per-account Claude budgets. Refs are resolved to immutable account keys at write time, which is why this is CLI-only. See account.md.
budget.codex Whole Codex budget object, or null for no Codex budget. null No This compatibility key remains round-trippable; the leaf keys below are preferred for partial edits. See Codex budget leaf writes.
budget.codex.amount_usd Finite decimal strictly greater than zero. null Ignored Writing it creates a missing Codex block with every default below; unsetting it removes the whole block. Amounts are never invented from a browser, so the endpoint accepts and drops this leaf. See Codex budget leaf writes.
budget.codex.period calendar-week or calendar-month; Codex never uses subscription-week. calendar-month Ignored Accepted and dropped by the dashboard, like every other CLI-only Codex leaf. See Codex budget leaf writes.
budget.codex.alerts_enabled Boolean (true/false/yes/no/on/off/1/0). false Yes Over the API this must be a JSON boolean; a string is rejected exactly as its Claude sibling is. See Codex budget leaf writes.
budget.codex.alert_thresholds Comma-separated base-10 integers in [1,100]; sorted and deduplicated, empty string means []. 90,100 Ignored Accepted and dropped by the dashboard. See Codex budget leaf writes.
budget.codex.projected_enabled Boolean controlling the Codex projected-budget alert. false Yes See Codex budget leaf writes.
budget.codex.accounts JSON object of {account ref: usd}; each value a finite number greater than zero. {} No Per-account Codex budgets. Refs are resolved to immutable account keys at write time. See account.md.
telemetry.enabled Boolean. Opt-out for the anonymous install-count telemetry; absence is treated as ON. true No Also disabled by CCTALLY_DISABLE_TELEMETRY=1, DO_NOT_TRACK=1, and dev checkouts. cctally telemetry off/on is a thin wrapper over this key. See telemetry.md and the privacy page.
conversation.retention_days Positive integer, or off / 0 to keep transcripts forever. 90 No How many days of conversation transcripts are retained in cache.db. Cost and usage history is never affected, and transcripts are re-derivable from the JSONL. A malformed persisted value resolves to the default. See cache-sync.md and db.md.
storage.artifact_retention JSON object bounding the on-disk evidence corruption recovery retains. Fields: max_age_days, max_count_per_family, max_total_mib, min_free_mib — each a positive integer or null to disable that rule — and max_shape_examples, a positive integer that is never nullable. Omitted fields inherit their default. At least one of max_age_days, max_count_per_family and max_total_mib must stay enabled. {"max_age_days": 30, "max_count_per_family": 20, "max_total_mib": 4096, "min_free_mib": 10240, "max_shape_examples": 8} No A destructive-retention policy, managed through cctally config and cctally db prune, and never browser-writable. A malformed persisted block turns automatic reclamation OFF, FAILs doctor's db.retained_artifacts leg, and makes cctally db prune exit 2 without deleting anything — cctally never falls back to a policy you did not write. Unclassified, active or referenced evidence is never deleted under any policy. See db.md.
codex.hook.ingest_budget_seconds Positive number, strictly below 20 (Codex kills a hook at 30 seconds). A value at or above the cap is rejected (exit 2) rather than clamped. 5 No The wall-clock ceiling on the native Codex hook's rollout-ingest leg: the hook stops at the deadline, records where it stopped, and resumes there next tick. Applies to the hook path ONLY — cctally cache-sync --source codex always runs to completion. A malformed persisted value resolves to the default. Surfaced by doctor's data.codex_ingest_backlog leg.

Read the full file on GitHub · 321 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. 3d ago First seen · 321 lines · 0 tokens per session scan A 7432fc3da20b

Subscribe to this mod's changes

config is a command published in the GitHub repository omrikais/cctally (5 stars, last pushed 4d ago), licensed Apache-2.0. It costs nothing until one of its globs matches a file; then it loads 6,311 tokens. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-31.