跳转到内容

Claude Code 的四层配置:settings.json 放什么、.claude.json 放什么、谁覆盖谁

约 15 分钟 难度:进阶 动手章

配置文件有四个作用域,加上命令行参数一共五级。从高到低:managed(企业管理策略)、命令行参数、.claude/settings.local.json.claude/settings.json~/.claude/settings.json。managed 层压过一切,包括命令行参数。

标量值(字符串、布尔、数字)按这个顺序覆盖;数组值(如 permissions.allow)跨层拼接去重,不覆盖。这个区别是配置调试里最容易踩的一处:以为项目层的 deny 规则会替换用户层的,实际是两边的规则都在生效。

settings.json.claude.json 是两个不同的文件,职责不重叠。往错的那个文件里写 key,Claude Code 启动时静默忽略,不报错。

五级优先级,以及为什么 managed 压过命令行

Section titled “五级优先级,以及为什么 managed 压过命令行”

优先级从高到低:

级别位置谁能改
managed服务端下发 / MDM 策略 / 系统目录下的 managed-settings.jsonIT 管理员
命令行参数--settings <file-or-json>--permission-mode当前这次会话
local仓库根的 .claude/settings.local.json你自己,仅这个仓库
project.claude/settings.json提交进 git,全团队共享
user~/.claude/settings.json你自己,所有项目

命令行参数通常是优先级最高的,这里不是。managed 层的定位是「组织策略不可绕过」,所以它必须压过 --settings,否则任何人加一个命令行参数就能解掉安全策略。

managed 层在不同平台的落地位置不同:

  • macOS:/Library/Application Support/ClaudeCode/managed-settings.json
  • Linux 和 WSL:/etc/claude-code/managed-settings.json
  • Windows:C:\Program Files\ClaudeCode\managed-settings.json

Windows 上的旧路径 C:\ProgramData\ClaudeCode\managed-settings.json 自 v2.1.75 起不再被读取。如果之前部署在那里,需要迁移。

这是配置调试里最常被误解的一条。

标量值按优先级覆盖。用户设置里 spinnerTipsEnabledtrue、项目设置里是 false,最终生效的是 false(项目层优先级更高)。

数组值跨层拼接去重。managed 层把 sandbox.filesystem.allowWrite 设成 ["/opt/company-tools"],你在用户层加了 ["~/.kube"],最终两个路径都在。低优先级的层可以往数组里添加条目,不会被高优先级层清空。

权限规则也走合并这条路。所以「项目层写了 permissions.deny,就能覆盖掉用户层的 deny」这个预期是错的:两边的 deny 规则都在生效,实际拦截范围是并集。

两个数组字段是例外,不参与合并:

  • fallbackModel:这是一条有顺序含义的链,位置本身携带信息。定义它的最高优先级文件提供整条链的值。
  • availableModels:最高优先级的 managed 源定义它时,那份列表原样生效,用户 / 项目 / local 层的条目无法扩展它。非 managed 的几层之间照常合并。

settings.json 是行为配置文件:envpermissionshooksmodelstatusLine 这些都写在这里。

~/.claude.json 是 CLI 自身维护的状态文件,内容包括:

  • OAuth 会话(登录态)
  • MCP 服务器的 local scope 和 user scope 配置
  • 每个项目的状态:已批准的工具、workspace 信任记录
  • 各类缓存

project scope 的 MCP 服务器不在这里,单独放在项目根的 .mcp.json

有一组 key 只认 ~/.claude.json,写进 settings.json 会被静默忽略:

key作用
autoConnectIde从外部终端启动时是否自动连接正在运行的 IDE
autoInstallIdeExtension在 VS Code 终端里运行时是否自动装 IDE 扩展
diffTool连了 IDE 时 diff 显示在哪:auto 走 IDE 的 diff 视图,terminal 留在终端
externalEditorContext用 Ctrl+G 打开外部编辑器时,是否把上一条回复作为 # 注释带进去
permissionExplainerEnabledBash 权限提示上按 Ctrl+E 时是否给出命令解释
teammateDefaultModelagent team 里 teammate 的默认模型

v2.1.119 之前,一批 /config 偏好项也存在 ~/.claude.json 而非 settings.json 里,包括 themeverboseeditorModeautoCompactEnabledpreferredNotifChannel。跨版本抄配置片段时这是一个容易踩的差异点。

配置改完不要靠「行为看起来对了」来判断,因为同一个行为可能由别的层决定。跑一次会话后执行:

/status

Status 标签页里有一行 Setting sources,列出当前会话加载的每一层来源,例如 User settingsProject local settings。managed 层会额外标出下发渠道,形如 Enterprise managed settings (remote)(plist)(HKLM)(HKCU)(file)

这一行有两个限制要知道:

  • 只有「已加载且至少含一个 key」的来源才会出现。JSON 语法坏掉的文件不出现在列表里,即使它有内容。所以某一层没出现,第一件事是查那个文件的 JSON 是否合法。
  • 它只告诉你哪些来源被读了,不告诉你某一个具体 key 最终由哪一层提供。

要看每一条错误的细节,用:

Terminal window
claude doctor

大多数 key 改完立即生效,两个例外

Section titled “大多数 key 改完立即生效,两个例外”

Claude Code 监听设置文件,改动后会重载,多数 key 不需要重启会话。permissionshooksapiKeyHelper 这些都在重载范围内,user / project / local / managed 四层都监听。每检测到一次改动,ConfigChange hook 会触发一次。

两个 key 是启动时读一次的:

  • model:会话中途要换模型用 /model
  • outputStyle:它属于系统提示的一部分,系统提示只在 /clear 或重启时重建

一个容易误判的场景:defaultMode: auto 不生效

Section titled “一个容易误判的场景:defaultMode: auto 不生效”

.claude/settings.json.claude/settings.local.json 里写 "permissions": {"defaultMode": "auto"},会话仍然以 default 模式启动,而且不报错。

这不是 bug。Claude Code v2.1.142 及以后版本会忽略来自项目层和 local 层的 auto 值,避免一个仓库通过提交配置文件的方式给自己授予 auto mode。要让它生效,把这一项移到 ~/.claude/settings.json

同类的「按来源忽略」规则还有几处,都是同一个防御思路,防止克隆下来的仓库通过自带配置提权:

字段忽略哪些来源
permissions.defaultMode: "auto"项目、local
autoMode(分类器规则)项目、local
pluginConfigs项目、local
footerLinksRegexes项目、local
vimInsertModeRemaps项目、local
skipDangerousModePermissionPrompt项目
enableArtifact项目、local

判断方法一致:这个字段一旦被仓库自带的配置控制,会不会让仓库获得它本不该有的权限或对你的输入 / 凭据的影响力。会,就只从用户层和 managed 层读。

settings.json 顶部加一行 $schema,VS Code、Cursor 这类支持 JSON schema 的编辑器就能给出补全和内联校验:

{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": ["Bash(npm run lint)"],
"deny": ["Read(./.env)", "Read(./secrets/**)"]
}
}

这份公开 schema 是定期更新的,可能不包含最近几个版本新加的字段。所以一个刚出现在文档里的字段被编辑器标黄,不代表配置真的无效,对照官方文档确认即可。

  • 在用户层和项目层各写一条 permissions.deny,然后跑 /permissions 看列表里是不是两条都在。这能直接验证「数组合并」而不是覆盖。
  • 故意把 .claude/settings.json 的 JSON 写坏(少一个逗号),看 /statusSetting sources 里这一层会不会消失,再用 claude doctor 看它报的是什么。
  • ~/.claude.json 的完整字段结构。官方文档说明了它的角色和几个 key,没有逐条列出全部字段。本文列的 key 来自官方 settings 文档的 Global config settings 一节,不代表这就是全部。
  • 配置文件的自动备份机制。文档提到 Claude Code 会创建带时间戳的备份并保留最近五份,具体的备份文件命名和位置没有查到明确说明。
  • 各版本之间 key 归属的迁移细节。只核实到 v2.1.119 这一次变化,更早的版本没有跟踪。
这一节有错或讲不清? 提个 Issue 直接改文档 请作者催更