Configuration
ctxfile works with zero configuration. To tune it, put a .ctxfile.json at your project root. Every field is optional; unknown fields are rejected.
Full example
{
"tokenBudget": 50000,
"maxFileTokens": 4000,
"cacheDir": "~/.ctxfile",
"cacheMaxAgeMs": 30000,
"include": ["src/**", "docs/plan.md"],
"exclude": ["fixtures/", "*.snap"],
"notion": {
"pageIds": ["1a2b3c4d-…"]
},
"ollama": {
"baseUrl": "http://localhost:11434",
"model": "qwen3:4b",
"summarize": false
},
"consult": {
"providers": [
{
"type": "anthropic",
"model": "claude-sonnet-5",
"apiKeyEnv": "ANTHROPIC_API_KEY"
},
{
"type": "openai-compatible",
"model": "gpt-5.2",
"baseUrl": "https://api.openai.com/v1",
"apiKeyEnv": "OPENAI_API_KEY"
},
{ "type": "ollama", "model": "qwen3:4b" }
]
},
"voice": {
"whisperPath": "/opt/homebrew/bin/whisper-cli",
"modelPath": "~/models/ggml-base.en.bin",
"audioDir": "~/voice-notes"
},
"export": {
"profile": "repo-safe",
"include": ["plan", "gitState", "keyFiles"]
},
"telemetry": { "enabled": false }
}Fields
| Field | Default | What it does |
|---|---|---|
| tokenBudget | 50000 | Total token budget for the whole snapshot. Files are greedily fitted to it. |
| maxFileTokens | 4000 | Per-file cap. Larger files get head+tail truncation. |
| cacheDir | ~/.ctxfile | Where the local SQLite snapshot cache lives. |
| cacheMaxAgeMs | 30000 | A cached snapshot younger than this is served without rebuilding. |
| include | [] | Allowlist patterns for the file connector. Empty means rank-based selection. |
| exclude | [] | Extra gitignore-style excludes, on top of .gitignore and denied paths. |
| notion.pageIds | [] | Explicit Notion page IDs to ingest. Only active when NOTION_TOKEN is also set. |
| ollama.baseUrl | http://localhost:11434 | Your local Ollama endpoint. |
| ollama.model | None | Model used for the session summary. |
| ollama.summarize | false | Opt-in switch for the local summarizer. |
| consult.providers | [] | Providers for the Pro consult tool. Each entry: type (anthropic | openai-compatible | ollama), model, baseUrl, apiKeyEnv: the name of the env var holding the key, never the key itself. |
| voice.whisperPath | None | Path to your whisper.cpp binary (Pro voice notes). |
| voice.modelPath | None | Path to the whisper model file. |
| voice.audioDir | None | Extra directory (besides root) that transcription may read audio from. |
| telemetry.enabled | false | Opt-in anonymous install ping. Off by default, stays off until you set it. |
| export.profile | repo-safe | Default profile for ctxfile export: repo-safe | full | custom. See Cloud agents. |
| export.include | None | Section allowlist used by the custom profile: plan, gitState, keyFiles, keyFileContent, notionPages, sessions, sessionSummary. |
| serve.tokens | [] | Reserved for the upcoming ctxfile serve: named tokens (name, tokenEnv, scopes). Validated today, used by nothing yet; tokens are env-var names, never literal secrets. |
Environment variables
| Variable | Role |
|---|---|
| NOTION_TOKEN | Notion integration token. The Notion connector activates only when this is set and notion.pageIds is non-empty. |
| OLLAMA_BASE_URL | Overrides ollama.baseUrl. |
Secrets never live in config. apiKeyEnv naming is deliberate. See Privacy for what each opt-in actually enables.
CLI flags
ctxfile --root <dir> # project root (default: cwd)
ctxfile --config <path> # explicit config file
ctxfile ui # local dashboard on 127.0.0.1
ctxfile export # write .ctxfile/context.{json,md}
ctxfile hooks install # pre-commit export refresh
ctxfile activate <key> # activate a Pro license
ctxfile --versionEvery command and flag, including export --profile/--stdout and ui --port, is documented on the CLI reference.