Claude Code 的设置文件:四个文件各管什么、谁盖过谁、怎么确认生效
改了设置没反应,多半是写错了文件,或者被更高一层盖住了。本站实测了项目共享、项目本地和命令行三层的先后,权限规则跨文件合并,哪些值写在项目文件里不生效,以及设置写坏时的表现:多一个逗号整份文件作废,键名拼错则一声不吭。附 ~/.claude 目录里它自己存了哪些数据。
本站已实测,测试日期:2026-10-12。
本页目录(13 节)
这篇教程解决一个问题:Claude Code 的设置散在好几个文件里。改了一处没反应时,要知道该查哪个文件;团队想统一配置、个人又想留点自己的习惯时,要知道各写在哪。
本站前面的教程里,权限规则、hooks、状态栏、接入中转站用的环境变量,写的都是 settings.json。这篇把这个文件本身讲清楚。
| 实测环境 | |
|---|---|
| 日期 | 2026-10-12 |
| 版本 | Claude Code 2.1.296 |
| 系统 | Ubuntu 24.04 |
| 连接方式 | 通过酷站AI 中转站,不是直连官方 |
这篇的实测只看启动和界面,没有向模型发过一句话,所以没有花费。
四个文件,各管一个范围
| 范围 | 文件 | 影响谁 | 适合放什么 |
|---|---|---|---|
| 用户 | ~/.claude/settings.json |
你,这台机器上的所有项目 | 个人偏好:主题、默认模型、你自己的权限规则 |
| 项目共享 | 项目里的 .claude/settings.json |
在这个目录里干活的所有人。提交进 git,同事克隆下来就有 | 团队的权限规则、hooks、插件、项目要用的环境变量 |
| 项目本地 | 项目里的 .claude/settings.local.json |
你,只在这一个项目里 | 个人在这个项目里的例外;想先自己试、还没打算分享的配置 |
| 托管 | 组织统一下发的 managed-settings.json 等 |
组织部署到的每一台机器 | 安全策略 |
个人和小团队只会碰到前三个。
装好 Claude Code 时,这些文件一个都不存在,都是后来建的:你自己建,或者 Claude Code 在你第一次改某个选项时替你建。
另外还有一个 ~/.claude.json(在家目录下,不在 .claude 文件夹里)。它是 Claude Code 写给自己用的:你信任过哪些目录、个人的 MCP 服务器、各种界面状态。文档说不需要手动编辑它。
三种改法
一、/config 菜单。 会话里运行 /config,改主题、编辑模式这类个人选项。它列的只是一小部分常用项,不是全部设置。大多数选项存进用户设置。
二、直接编辑文件。 设置文件是严格的 JSON,不能写注释,最后一项后面不能有逗号。文档建议在开头加一行 $schema,支持 JSON Schema 的编辑器(VS Code、Cursor 等)就会给补全和校验:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": ["Bash(npm run lint)", "Bash(npm run test *)"],
"deny": ["Read(./.env)", "Read(./.env.*)"]
}
}
三、只对这一次会话。 想试一个值又不想存下来:
claude --settings '{"model": "claude-opus-5-5"}'
--settings 后面可以是一段 JSON,也可以是一个文件的路径。有些键还有专门的参数(--model)或环境变量(ANTHROPIC_MODEL)。
实测一:同一个键写在三处,谁生效
要看清谁盖过谁,得找一个一眼能看出来的设置。本站用的是状态栏:让它直接显示自己是哪个文件配的。
项目共享设置里写:
{
"statusLine": { "type": "command", "command": "echo 状态栏来自:项目共享设置" }
}
项目本地设置和命令行里各写一份,只改那几个字。然后依次看输入框下面那一行:
| 这时有哪几处设置 | 状态栏显示 |
|---|---|
| 只有项目共享 | 状态栏来自:项目共享设置 |
| 项目共享 + 项目本地 | 状态栏来自:项目本地设置 |
项目共享 + 项目本地 + 启动时带 --settings |
状态栏来自:命令行 |
删掉项目本地,不带 --settings |
状态栏来自:项目共享设置 |
和文档给的顺序一致。从高到低:
- 托管设置
- 命令行的
--settings - 项目本地(
.claude/settings.local.json) - 项目共享(
.claude/settings.json) - 用户(
~/.claude/settings.json)
规律是:越具体的越优先。项目的盖过个人全局的,个人在这个项目里的例外又盖过项目的。
环境变量不在这个顺序里。 文档特别说明,一个行为同时有环境变量和设置键时,谁优先是一对一对单独定的。比如 shell 里导出的 ANTHROPIC_MODEL 会盖过任何文件里的 model。拿不准时查那个键在设置参考里的条目。
实测二:改了要不要重启
上表第二行是在会话开着的时候做的:新建了 .claude/settings.local.json,几秒后状态栏就变了,没有重启。
文档的说法:Claude Code 盯着这几个设置文件,一变就重新加载,权限规则和 hooks 的修改都能立刻用上。
例外是少数只在启动时读一次的键,最常碰到的两个:
| 键 | 会话中途想改,用什么 |
|---|---|
model |
/model |
effortLevel、modelSettings |
/effort |
实测三:列表是合并的,不是覆盖
项目共享设置里写一条允许规则,项目本地设置里写另一条:
{ "permissions": { "allow": ["Bash(npm run lint)"], "deny": ["Read(./.env)"] } }
{ "permissions": { "allow": ["Bash(npm run test *)"] } }
启动后运行 /permissions,Allow 页签下两条都在:
Permissions Recently denied Allow Ask Deny Auto mode Workspace
Claude Code won't ask before using allowed tools.
1. Add a new rule…
2. Bash(npm run lint)
3. Bash(npm run test *)
permissions.allow 这样的列表,各个文件写的会合在一起,每个文件都可以往里加,不会把别的文件写的顶掉。
这也意味着:你没法在本地设置里“取消”项目共享设置里的一条允许规则。 要拦住它,得加一条拒绝规则。规则之间怎么排先后,权限模式那篇有讲。
实测四:有些值,写在项目文件里不生效
在项目共享设置里写默认的权限模式,换三个值各启动一次,看界面底部:
permissions.defaultMode 的值 |
启动后的模式 |
|---|---|
plan |
plan mode on |
acceptEdits |
accept edits on |
bypassPermissions |
manual mode on,没有生效 |
前两个照办了。bypassPermissions(跳过所有确认)被忽略,退回到了手动确认。
文档里有这一条:auto 和 bypassPermissions 这两个值,写在项目共享或项目本地设置里都不生效,要写在用户设置里,或者启动时用 --permission-mode。道理不难想:一个克隆下来的仓库,不应该能替你把确认关掉。
同一类的限制文档还列了几种:
- 有些键只认用户设置。 设置参考的索引里,范围一栏标着
User、User or managed的键,写进项目共享设置不起作用。 - 有些内容要等信任。 项目共享设置里的允许规则、额外目录、插件市场、大部分环境变量,要等每个人信任了这个目录才生效。拒绝规则和询问规则不用等,立刻生效。
所以把设置提交进仓库之后,同事那边“没生效”,先看是不是这两种情况。
实测五:怎么确认加载了哪些文件
会话里运行 /status。本站的输出(去掉了会话 ID):
Settings Status Config Usage Stats
Version: 2.1.296
cwd: /home/ccdemo/demo/h3-settings
Anthropic base URL: https://api.koozhan.com
Model: Default (claude-opus-5-5)
Setting sources: User settings, Shared project settings, Project local settings
Managed settings (remote): not fetched — not available with a custom ANTHROPIC_BASE_URL
看 Setting sources 那一行:三个文件都读到了。
它只告诉你读了哪些文件,不告诉你每个键最后是哪个文件给的。要查后者,只能按上面的顺序自己从高到低看一遍。
顺带看到两处和中转站有关的:接口地址显示的是中转站的域名;远程下发的托管设置没有去取,原因写着“用了自定义的接口地址”。
实测六:设置写坏了会怎样
三种写坏的方式,表现完全不同。
多一个逗号:整份文件作废
{
"permissions": { "allow": ["Bash(npm run lint)"], },
}
启动时弹出:
Settings Error
/home/ccdemo/demo/h3-settings/.claude/settings.json
└ Invalid or malformed JSON
Files with errors are skipped entirely, not just the invalid settings.
❯ 1. Fix with Claude
2. Exit and fix manually
3. Continue without these settings
注意中间那句:出错的文件是整份跳过,不是只跳过出错的那一行。如果你的拒绝规则写在这个文件里,选了“继续”之后它们就都不在了。
取值不合法:告诉你是哪一项
规则少写一个括号,再加一个不允许的取值:
{
"permissions": { "allow": ["Bash(npm run lint"] },
"cleanupPeriodDays": 0
}
Settings Error
/home/ccdemo/demo/h3-settings/.claude/settings.json
├ cleanupPeriodDays: Number must be greater than or equal to 0
└ permissions.allow: Invalid permission rule "Bash(npm run lint" was skipped: Malformed Tool(content)
rule. Rules take the form Tool or Tool(content) and must end at the closing ")"
cleanupPeriodDays must be at least 1. To keep transcripts for a long time, set a large number …
每一项都指出来了,还给了改法。
键名拼错:一声不吭
把 statusLine 写成全小写的 statusline:
{
"statusline": { "type": "command", "command": "echo hi" }
}
启动正常,没有任何提示,状态栏也没有出现。不认识的键被直接忽略了。
这是三种里最难查的。设置不生效、又没有报错时,先核对键名的大小写。开头那行 $schema 的用处就在这里:编辑器会当场标出不认识的键。
用 claude doctor 列出被拒绝的项
在终端里(不是会话里)运行 claude doctor,它会把被拒绝的设置项列出来:
Invalid settings
- /home/ccdemo/demo/h3-settings/.claude/settings.json › permissions.allow: Invalid permission rule "Bash(npm run lint" was skipped: …
- /home/ccdemo/demo/h3-settings/.claude/settings.json › cleanupPeriodDays: Number must be greater than or equal to 0
拼错的 statusline 它也没有列。它只报“认识但不合法”的,不报“不认识”的。
文档还说明:用 claude -p 非交互运行时没有对话框,坏掉的文件或设置项被跳过,程序照常继续。脚本里跑出来的行为不对,记得用 claude doctor 看一眼。
.claude 目录里还有什么
设置文件只是其中一种。按“想做什么”找文件:
| 想做的事 | 文件 | 本站的教程 |
|---|---|---|
| 告诉 Claude 项目的背景和约定 | CLAUDE.md、.claude/rules/*.md |
CLAUDE.md 怎么写 |
| 允许或拦住某些操作 | settings.json 里的 permissions |
权限模式怎么选 |
| 在工具运行前后执行脚本 | settings.json 里的 hooks |
Hooks 实战 |
| 给会话设环境变量 | settings.json 里的 env |
接入中转站 |
加一个用 /名字 调用的能力 |
.claude/skills/<名字>/SKILL.md |
skills 怎么写 |
| 定义一个有自己工具的子代理 | .claude/agents/*.md |
子代理实战 |
| 接外部工具 | 项目根目录的 .mcp.json |
接 MCP 服务器 |
| 改回答的风格 | .claude/output-styles/*.md |
把终端调顺手 |
| 改快捷键 | ~/.claude/keybindings.json(只有全局的) |
同上 |
除了最后一行,这些文件都既可以放在项目里(随仓库分享),也可以放在 ~/.claude/ 下(只给自己,所有项目通用)。
~/.claude 里它自己存了什么
~/.claude 不只放你写的配置,Claude Code 干活时产生的数据也在这里。下面是本站测试账号用了两天之后的实际情况(只列了一部分):
| 路径 | 实际大小 | 里面是什么 |
|---|---|---|
projects/ |
23 MB,32 个项目目录,182 份会话记录 | 每个会话的完整记录:每条消息、每次工具调用和结果 |
history.jsonl |
44 KB,183 行 | 你输入过的每一条提示词,带时间和项目路径 |
file-history/ |
364 KB | Claude 改文件之前的快照,回退时用 |
plans/ |
16 KB | plan 模式下写的计划 |
debug/ |
96 KB | 用 --debug 启动时的调试日志 |
backups/ |
200 KB,5 份 | ~/.claude.json 的旧版本 |
plugins/ |
19 MB | 装过的插件和插件市场 |
有两点值得知道。
这些都是明文。 文档的原话:凡是经过工具的东西都会写进磁盘上的会话记录,包括文件内容、命令输出、粘贴的文字。也就是说,Claude 读过一个带密码的配置文件,那个密码就躺在 projects/ 下的某个 .jsonl 里。
不是永久保存,也不是都会清。 会话记录、文件快照、计划、调试日志这些,超过 cleanupPeriodDays(默认 30 天)会自动删除。history.jsonl 不在自动清理的范围里,会一直留到你自己删。
~/.claude.json 里按项目记着一些状态,其中有一项 hasTrustDialogAccepted:你对哪些目录点过“信任”,就记在这里。
设了不生效,按这个顺序查
/status看文件读到了没有。Setting sources里没有那一层,说明文件不在该在的位置,或者整份坏了被跳过。claude doctor看有没有被拒绝的项。- 核对键名的大小写。 拼错的键不会有任何提示。
- 更高一层有没有设同一个键。 从命令行参数、项目本地、项目共享、用户,一层层看。再看有没有对应的环境变量。
- 这个值是不是不能写在这个文件里。 比如项目文件里的
bypassPermissions。 - 是不是只在启动时读的键。
model和 effort 相关的,重开一个会话。
通过中转站用,有什么不一样
设置文件的规则和接入方式无关。有关系的只有两处:
- 中转站的地址和 key 本身就写在设置里,通常是用户设置的
env里那两个变量,见接入中转站。 - 从 claude.ai 控制台远程下发的托管设置取不到,
/status里会写明原因。这只和用组织账号的人有关。
这次实测没有覆盖到的
- 用户设置这一层没有动手改。 测试账号的用户设置文件里放着接入配置,我们不碰它。它排在最低一层是文档的说法,实测只验证了上面三层。
- 托管设置没有测。
/config菜单没有逐项试,它把每个选项存到哪个文件是文档的说法。- “只有个别设置项出错、文件其余部分照常生效”的情况没有单独复现。 文档把它叫 Settings Warning。本站第二个例子里因为有一项被整体校验拒绝,弹的是 Settings Error。
- Claude Code 自己创建
settings.local.json时会把它排除在 git 之外,这一点没有验证。手工建的不会,要自己加进.gitignore。 - Windows 上的路径没有测,文档说
~/.claude对应%USERPROFILE%\.claude。