codex - 💡(How to fix) Fix Add explicit config scopes with a gitignored project-local override layer

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Root Cause

Codex currently documents two persistent user-controlled layers for local work:

  • user/global config in ~/.codex/config.toml
  • shared project overrides in .codex/config.toml

That works for simple cases, but it does not scale well for people and teams who use Codex across multiple projects, purposes, and machines:

  • A repo can commit useful defaults in .codex/config.toml, but an individual cannot make a durable per-machine/per-user override for that repo without modifying the committed file or passing -c every time.
  • User config is lower precedence than project config, so it cannot override a committed project MCP/server/sandbox/model choice for one developer.
  • Profiles are useful, but they are not a project-local file and do not replace a gitignored per-repo override for local ports, local paths, experimental MCP servers, disabled project MCP servers, or machine-specific provider settings.
  • Dotfiles users want ~/.codex/config.toml to remain stable user-authored configuration, while Codex also needs places for shared repo defaults and local mutable/private data.

This becomes especially important when a user wants several Codex setups: different computers, different usernames/paths, different MCP availability, different local services, or different project workflows. The desired model is not one giant file that every Codex surface writes into; it is a small config-scope hierarchy with clear ownership.

Code Example

~/.codex/config.toml              # user/global defaults, safe to manage with dotfiles
<repo>/.codex/config.toml         # shared project defaults, safe to commit
<repo>/.codex/config.local.toml   # local user/machine override, gitignored
~/.codex/state.toml               # Codex-owned mutable local state, separate concern

---

# <repo>/.codex/config.toml
[mcp_servers.project-tools]
command = "project-tools-mcp"
args = ["--port", "3000"]
required = true

---

# <repo>/.codex/config.local.toml
[mcp_servers.project-tools]
enabled = false

---

# <repo>/.codex/config.local.toml
[mcp_servers.project-tools]
command = "project-tools-mcp"
args = ["--port", "4317"]
required = false
RAW_BUFFERClick to expand / collapse

What variant of Codex are you using?

CLI / IDE / app configuration system

What feature would you like to see?

Please add an explicit gitignored project-local override layer for Codex configuration, for example:

~/.codex/config.toml              # user/global defaults, safe to manage with dotfiles
<repo>/.codex/config.toml         # shared project defaults, safe to commit
<repo>/.codex/config.local.toml   # local user/machine override, gitignored
~/.codex/state.toml               # Codex-owned mutable local state, separate concern

The immediate request is the third layer: a first-class .codex/config.local.toml or equivalent that overrides the committed project .codex/config.toml without requiring -c flags, profiles, wrapper scripts, or dirtying the repository.

Suggested precedence, fitting the current documented Codex model:

  1. CLI flags and --config overrides
  2. Active profile values
  3. Local project override: .codex/config.local.toml (trusted projects only, gitignored)
  4. Shared project config: .codex/config.toml from project/root/current-directory layers
  5. User config: ~/.codex/config.toml
  6. System config
  7. Built-in defaults

This local layer should also be visible in /debug-config and app-server config/read layer/origin diagnostics so users can understand why a value won.

Why this matters

Codex currently documents two persistent user-controlled layers for local work:

  • user/global config in ~/.codex/config.toml
  • shared project overrides in .codex/config.toml

That works for simple cases, but it does not scale well for people and teams who use Codex across multiple projects, purposes, and machines:

  • A repo can commit useful defaults in .codex/config.toml, but an individual cannot make a durable per-machine/per-user override for that repo without modifying the committed file or passing -c every time.
  • User config is lower precedence than project config, so it cannot override a committed project MCP/server/sandbox/model choice for one developer.
  • Profiles are useful, but they are not a project-local file and do not replace a gitignored per-repo override for local ports, local paths, experimental MCP servers, disabled project MCP servers, or machine-specific provider settings.
  • Dotfiles users want ~/.codex/config.toml to remain stable user-authored configuration, while Codex also needs places for shared repo defaults and local mutable/private data.

This becomes especially important when a user wants several Codex setups: different computers, different usernames/paths, different MCP availability, different local services, or different project workflows. The desired model is not one giant file that every Codex surface writes into; it is a small config-scope hierarchy with clear ownership.

Claude Code precedent

Claude Code has a useful precedent here:

  • ~/.claude/settings.json for user settings
  • .claude/settings.json for project settings shared through git
  • .claude/settings.local.json for local project-specific settings, not shared, and gitignored when created
  • separate handling for app state / OAuth / per-project state in ~/.claude.json
  • MCP scopes with local / project / user behavior, including project-shared .mcp.json

The important part is the scope model, not the exact filenames. Claude Code's local scope works because a repo can provide team defaults while each developer can keep private machine-specific overrides out of git. That is the missing Codex layer.

Concrete example

A repository may want to commit a shared MCP server:

# <repo>/.codex/config.toml
[mcp_servers.project-tools]
command = "project-tools-mcp"
args = ["--port", "3000"]
required = true

One developer may need a local override:

# <repo>/.codex/config.local.toml
[mcp_servers.project-tools]
enabled = false

or:

# <repo>/.codex/config.local.toml
[mcp_servers.project-tools]
command = "project-tools-mcp"
args = ["--port", "4317"]
required = false

Today, that developer either changes the committed .codex/config.toml, uses a launch wrapper / -c every time, or changes a global profile that is not scoped to the repo.

Related issues

This request is related to, but distinct from, the existing config-state pollution issues:

  • #14601 and #11061 cover Codex-owned mutable state being written into ~/.codex/config.toml and making dotfile/multi-machine setups hard.
  • #15433 was a duplicate-ish trust-state issue around separating project trust from global config.
  • #15970 is the closest previous request. It asked for config.local.toml to override project-shared config, especially MCP config, but was closed after the discussion appears to have focused on project .codex/config.toml overriding user config. The clarified need there was the reverse: override an existing project-level config without -c.
  • #13056 and #23487 cover project-scoped MCP configuration and codex mcp add --scoped; a local override layer would give those workflows a complete set of write targets: user, shared project, and local project.
  • #18334 is adjacent, but custom config search locations are not the same as a standard gitignored local override file.

Proposed acceptance criteria

  • Codex reads .codex/config.local.toml or an equivalent local project file from trusted projects.
  • The local project file overrides shared .codex/config.toml for the same project/current-directory layer.
  • Codex ensures the local file is gitignored when Codex creates it.
  • /debug-config and app-server config diagnostics show the local layer and per-key origins.
  • The same project-config denylist/safety checks apply to this local layer, or a stricter denylist is documented.
  • Future CLI writes can target this scope, for example codex mcp add --scope local ..., while --scope project targets shared .codex/config.toml and the default/global target remains ~/.codex/config.toml.

This would make Codex's configuration system much more scalable: shared team defaults, private local project overrides, stable dotfile-managed user defaults, and Codex-owned mutable state can each live in the place users expect.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING

codex - 💡(How to fix) Fix Add explicit config scopes with a gitignored project-local override layer