Where Gemini CLI reads settings.json and which file wins
Find where Gemini CLI reads settings.json, which of the user, project and system files overrides which, and why a project's settings can be ignored entirely.
You edited a project's .gemini/settings.json and nothing changed, or values from two files look mixed. Check which file wins.
[1] Check the version. Keys and behavior can change between releases; everything below is for this one.
$ gemini --version0.64.0[2] Learn the locations and order. The installed package ships its docs (same content as the official reference). A higher number overrides a lower one.
| Order | File | Location (Linux) |
|---|---|---|
| 1 | Defaults | built into the program |
| 2 | System defaults | /etc/gemini-cli/system-defaults.json |
| 3 | User | ~/.gemini/settings.json |
| 4 | Project | <project>/.gemini/settings.json |
| 5 | System overrides | /etc/gemini-cli/settings.json |
| 6 | Environment variables | shell, .env |
| 7 | Command-line flags | gemini -m … and so on |
Entries 2 and 5 can be moved with GEMINI_CLI_SYSTEM_DEFAULTS_PATH and GEMINI_CLI_SYSTEM_SETTINGS_PATH. System overrides beat project settings, so a value set by an administrator cannot be undone from a project.
[3] Put an MCP server with the same name in both the user and the project file. gemini mcp list prints the merged list without logging in, which makes it a handy probe.
{ "mcpServers": { "shared": { "command": "echo", "args": ["user"], "env": { "A": "1" } }, "user-only": { "command": "echo" } }}{ "mcpServers": { "shared": { "command": "printf" }, "proj-only": { "command": "ls" } }}[4] List the servers from /srv/app.
$ cd /srv/app$ gemini mcp listConfigured MCP servers: ✗ shared: printf (stdio) - Disconnected✗ user-only: echo (stdio) - Disconnected✗ proj-only: ls (stdio) - DisconnectedmcpServers merges by server name. All three servers show up, and for the clashing shared the project definition won. The user's args and env did not survive: the whole entry is replaced, not merged field by field. (Disconnected only means the test commands are not MCP servers.)
[5] Arrays differ per setting. The settings definitions in the installed bundle split like this:
| Strategy | Settings |
|---|---|
concat (appended) | context.includeDirectories · the per-event lists under hooks (BeforeTool, …) |
union (merged, no duplicates) | context.fileFiltering.customIgnoreFilePaths · tools.exclude · disabled extension and skill lists, and others |
replace (overwritten) | everything else |
The official enterprise doc agrees: includeDirectories is concatenated in the order System Defaults, User, Workspace, System Overrides. Array merging was not observed on screen in this test; it rests on the docs and the source definitions.
[6] Know when the project file is skipped entirely. In an untrusted folder, .gemini/settings.json is not loaded. In this version security.folderTrust.enabled defaults to true, so a folder you have not trusted gives:
Warning: MCP servers are configured but disabled because this folder is untrusted.User-level servers are also suppressed in untrusted folders to prevent accidental side-effects.Trust is stored in ~/.gemini/trustedFolders.json when you pick a folder in the interactive dialog. For this test the file was written by hand with {"/srv/app":"TRUST_FOLDER"}. In non-interactive runs (CI), use --skip-trust or GEMINI_CLI_TRUST_WORKSPACE=true (trusted folders doc).
[7] A JSON syntax error stops startup and names the file.
Error in /srv/app/.gemini/settings.json: Expected property name or '}' in JSON at position 16 (line 2 column 1)Please fix the configuration file(s) and try again.[8] The key for context file names in settings.json is context.fileName (a string or an array).
{ "context": { "fileName": ["GEMINI.md", "CONTEXT.md"] }}contextFileName is the key in an extension's gemini-extension.json. A guide that tells you to put contextFileName in settings.json is using a key this version's docs do not list. If the memory file is not loaded, see Gemini CLI does not load GEMINI.md.