Configuration
Fred reads from three places: your shell environment, your home config, and the project you're in. None of it is required — defaults work on a fresh machine — but every knob is here when you need to pin a model in CI, add a project rule, or wire up an MCP server.
Home directory layout (~/.config/fred/)
After fred login runs once, your home config looks like this:
~/.config/fred/
├── credentials.json # mode 0600 — auth state
├── preferences.json # mode 0644 — model + UI prefs
└── rate-card.json # cached pricing, refreshed from /api/pricingcredentials.json is written by fred login and read on every CLI invocation. Schema:
{
"version": 1,
"api_key": "sk-fred-…", // empty if stored in keychain
"email": "you@example.com",
"base_url": "https://api.fredcode.net/v1",
"fetched_at": "2026-04-30T17:22:11Z"
}On macOS, if you installed with the [keychain] extra, the API key is mirrored into the system keychain and the api_key field stays empty. The keychain copy wins on read.
preferences.json is written by /model, /flash, /pro, and the once-per-account pro confirmation. Schema:
{
"version": 1,
"main_model": "deepseek-v4-flash",
"editor_model": "deepseek-v4-flash",
"weak_model": "deepseek-v4-flash",
"warned_about_pro": true,
"preset": "flash"
}rate-card.json is a runtime cache of the pricing JSON served by /api/pricing. Fred refreshes it on startup if it's missing or older than 24 hours. If the cache is more than 7 days old and the network refresh fails, you'll see a one-line staleness warning at session start — billing still works (pricing is computed server-side), but the local cost line may drift.
Environment variables
Every env var the CLI reads. Anything prefixed DSC_ is a legacy alias that predates the rename — both forms still work, the FRED_ form wins on conflict.
Auth.
| Variable | Use |
|---|---|
FRED_API_KEY | API key for the Fred proxy. Skips the credentials file entirely. Preferred for CI. |
DSC_API_KEY | Legacy alias of FRED_API_KEY. Still honored, but FRED_API_KEY wins on conflict. |
FRED_BASE_URL | Override the proxy URL. Default: https://api.fredcode.net/v1 |
DSC_BASE_URL | Legacy alias of FRED_BASE_URL. |
FRED_AUTH_URL | Override the auth host used by fred login. Default: https://app.fredcode.net |
DSC_AUTH_URL | Legacy alias of FRED_AUTH_URL. |
DEEPSEEK_API_KEY | Bypass the Fred proxy and talk to DeepSeek directly. Skips metering, balance, and rate-card pricing — diagnostic use only. |
Models.
| Variable | Use |
|---|---|
FRED_MAIN_MODEL | Pin the main slot at startup. One of deepseek-v4-flash or deepseek-v4-pro. |
DSC_MAIN_MODEL | Legacy alias of FRED_MAIN_MODEL. |
FRED_EDITOR_MODEL | Pin the editor (str_replace) slot. Defaults to the main model. |
DSC_EDITOR_MODEL | Legacy alias of FRED_EDITOR_MODEL. |
FRED_WEAK_MODEL | Pin the weak slot used for cheap classifier passes. Defaults to deepseek-v4-flash. |
DSC_WEAK_MODEL | Legacy alias of FRED_WEAK_MODEL. |
API behavior.
| Variable | Use |
|---|---|
DSC_API_RETRIES | Max retries on a transient HTTP error before giving up. Default: 3. |
DSC_API_BACKOFF_BASE_MS | Initial backoff in ms; doubles per retry with a small jitter. Default: 100. |
Feature toggles.
| Variable | Use |
|---|---|
DSC_REPOMAP | Set to 0 to disable the repo-map context primer. Useful in monorepos where the map is too noisy. |
DSC_RULES | Set to 0 to disable project rules loading from .dsc/rules/. |
DSC_CHECKPOINTS | Shadow-git checkpoints. 1 (default) keeps the last 20 turns recoverable via /restore. Set to 0 to skip. |
DSC_AUTO_SEED_TODOS | Set to 1 to have Fred propose an initial todo list on the first turn of a new session. |
FRED_APPROVAL_MODE | Default approval mode: untrusted | on_request | never. CLI --approval and /sandbox approval m override per session. |
Telemetry.
| Variable | Use |
|---|---|
DSC_TELEMETRY_DB_URL | Opt in to local telemetry by pointing this at a SQLite or Postgres URL. Off by default; nothing leaves your machine unless you set this. |
DSC_TELEMETRY_NO_TEXT | Set to 1 to record turn metadata (timings, tokens, tool calls) without storing prompt or response bodies. |
UI.
| Variable | Use |
|---|---|
NO_COLOR | Industry-standard. Set anything truthy to disable ANSI color output. |
FRED_NO_BANNER | Skip the banner block on REPL start. |
FRED_REDUCED_MOTION | Set to 1 to disable spinners and progress animations. |
FRED_NO_UPDATE_CHECK | Skip the once-per-day PyPI version poll on startup. |
Prompt.
| Variable | Use |
|---|---|
FRED_NO_CONFIRM_PRO | Set to 1 to skip the once-per-account confirmation prompt when switching to deepseek-v4-pro. |
FRED_* always wins over DSC_* (the legacy prefix). DSC_*aliases will stay supported for a long time so existing CI configs don't break.
Project memory: AGENTS.md / CLAUDE.md
At startup, Fred looks for AGENTS.md in the current working directory (and falls back to CLAUDE.mdif it's missing). The contents are injected as a system-prompt addendum every turn, so it's the right place for repo conventions, sharp edges, and things every session should know without you having to repeat yourself.
Good things to put in there:
- House style — "use Drizzle, not raw SQL", "tabs not spaces".
- Sharp edges — "the worker can't import from src/, mirror with sync-pricing.ts".
- Where things live — a one-paragraph map of the package layout.
- What not to touch — "migrations 0001 and 0002 are already in prod".
If both AGENTS.md and CLAUDE.md are present, AGENTS.md wins. Pick one and stick with it.
AGENTS.md gets re-tokenized every turn. A 200-line file is fine; a 2,000-line file will eat into your context window for no benefit. Move long-form rules into .dsc/rules/ so they only attach when relevant.
Project rules: .dsc/rules/*.md
Rules are Markdown files inside .dsc/rules/ with optional YAML front-matter. They split into three categories based on how they attach:
- Always-on — no front-matter, or
alwaysApply: true. Loaded every turn, like an extension of AGENTS.md. - Glob-triggered — front-matter sets a
globpattern. Auto-attaches the moment a matching file shows up in the turn (read, edited, or grepped). - Request-only — front-matter has a
descriptionbut no glob andalwaysApply: false. The model sees the title and description in its tool list and pulls the rule in via therequest_ruletool when it decides it's relevant.
Example front-matter:
---
description: Conventions for Drizzle migrations
glob: src/db/migrations/*.sql
alwaysApply: false
---
# Migration rules
- New migrations are numbered 0NNN_<slug>.sql.
- Never edit a migration that has run in prod — write a new one instead.
- ...See project rules for the full schema and authoring tips.
Hooks and MCP: .dsc/settings.json
Per-project hooks (commands the harness runs on lifecycle events) and MCP servers (extra tools Fred can call) both live in .dsc/settings.json. Same file, two top-level keys:
{
"hooks": {
"PreToolUse": [
{ "matcher": "bash", "command": "./scripts/audit.sh" }
],
"Stop": [
{ "command": "npm run lint --silent" }
]
},
"mcp": {
"servers": {
"linear": {
"command": "npx",
"args": ["-y", "@linear/mcp-server"],
"env": { "LINEAR_API_KEY": "lin_api_…" }
}
}
}
}Hooks let you run lint, audit, or telemetry shell scripts at well-defined points in the loop. MCP gives Fred access to tools beyond the built-ins (issue trackers, databases, your own scripts). Both are loaded once per session — restart the REPL after editing the file.
Drill-down docs: hooks · MCP servers.
Permission rules
Permission rules — "always allow git status", "always deny rm -rf" — live in ~/.dsc/settings.local.json. They're per-user, not per-project, because they encode trust decisions you've already made.
Edit them via slash command rather than by hand: /perms add bash "git status", /perms remove bash "git status", or just /permsto list. The in-prompt "Always allow this command?" option writes to the same file.
Full details on the gating model: permissions & yolo.
Most users never touch any of this. The defaults are fine. Drop down to env vars when you need CI predictability or want to pin a model across machines; reach for AGENTS.md and rules when a session keeps making the same wrong assumption.