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",
"subagent_main_model": null,
"warned_about_architect": true,
"preset": "flash",
"telemetry_opted_out": false
}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, grouped by purpose.
Auth.
| Variable | Use |
|---|---|
FRED_API_KEY | API key for the Fred proxy. Skips the credentials file entirely. Preferred for CI. |
FRED_BASE_URL | Override the proxy URL. Default: https://api.fredcode.net/v1 |
FRED_AUTH_URL | Override the auth host used by fred login. Default: https://app.fredcode.net |
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. |
FRED_EDITOR_MODEL | Pin the editor (str_replace) slot. Defaults to the main model. |
FRED_WEAK_MODEL | Pin the weak slot used for cheap classifier passes. Defaults to deepseek-v4-flash. |
FRED_SUBAGENT_MAIN_MODEL | Pin the main model for spawned subagents (Task tool). Defaults to the main slot. |
API behavior.
| Variable | Use |
|---|---|
FRED_API_RETRIES | Max retries on a transient HTTP error before giving up. Default: 3. |
FRED_API_BACKOFF_BASE_MS | Initial backoff in ms; doubles per retry with a small jitter. Default: 100. |
Feature toggles.
| Variable | Use |
|---|---|
FRED_REPOMAP | Set to 0 to disable the repo-map context primer. Useful in monorepos where the map is too noisy. |
FRED_RULES | Set to 0 to disable project rules loading from .fred/rules/. |
FRED_CHECKPOINTS | Shadow-git checkpoints. 1 (default) keeps the last 20 turns recoverable via /restore. Set to 0 to skip. |
FRED_APPROVAL_MODE | Default approval mode: untrusted | on_request | never. CLI --approval and /sandbox approval m override per session. |
FRED_SANDBOX_MODE | Default macOS sandbox mode: ro | workspace-write | full. CLI --sandbox overrides per session. |
FRED_MCP_SCHEMAS | Set to eager to load every MCP server's tool schemas at startup. Default is lazy (load on first call). |
FRED_MCP_CALL_TIMEOUT | Per-call timeout for MCP tool invocations, in seconds. Default: 30. |
Telemetry.
| Variable | Use |
|---|---|
FRED_TELEMETRY_DB_URL | Opt in to self-hosted telemetry by pointing this at a Postgres URL. When unset, the CLI sends to the proxy at api.fredcode.net. |
FRED_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. |
FRED_NO_RATE_CARD_REFRESH | Skip the startup refresh of the cached rate card. Useful in CI where you don't want any network on cold-start. |
Prompt.
| Variable | Use |
|---|---|
FRED_NO_CONFIRM_PRO | Set to 1 to skip the once-per-account confirmation prompt when switching to deepseek-v4-pro. |
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 .fred/rules/ so they only attach when relevant.
Project rules: .fred/rules/*.md
Rules are Markdown files inside .fred/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: .fred/settings.json
Per-project hooks (commands the harness runs on lifecycle events) and MCP servers (extra tools Fred can call) both live in .fred/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 ~/.fred/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.