Claude Code源码配置文件settings.json

Claude源码泄露:普通人视角理解配置文件

上一篇我们聊了 Claude Code 的"指令文件"(CLAUDE.md),这篇接着讲它的另一半——"配置文件"(settings.json)。如果说指令文件是用大白话告诉 AI"该怎么干活",那配置文件就是用结构化的开关告诉它"用哪个模型、有什么权限、能调哪些工具"。本文以普通人视角,带你看懂三个配置文件分别是什么、它们之间怎么配合、放在哪、以及日常使用时真正需要注意的几点。

接着源码泄露系列往下讲。上一篇说的是指令文件 CLAUDE.md——你用自然语言写给 AI 看的"工作须知"。这一篇讲的是配置文件 settings.json——一份结构化的"参数表"。两者最大的区别:指令文件是写给 AI 读的"软约定",配置文件是写给程序读的"硬开关"。普通用户不需要会写代码也能用好它,关键是搞清楚有几个文件、谁管谁、放哪里。

一、什么是配置文件

简单说,配置文件就是一份 JSON 格式的"参数表",告诉 Claude Code 几件事:

  • 默认用哪个模型(model,比如 Opus / Sonnet)
  • 给 AI 多大的权限(permissionMode,能不能改文件、能不能跑命令)
  • 注入哪些环境变量(env,比如数据库地址、API Key)
  • 工具调用前后自动执行什么命令(hooks,生命周期钩子)
  • 给 AI 装哪些"插件"(mcpServers,外部工具服务器)
  • 是否开启沙箱隔离(sandbox,限制 AI 的系统访问范围)
  • 以及认证(oauth)等

它和指令文件的分工可以这样记:

| | 指令文件 CLAUDE.md | 配置文件 settings.json | |---|---|---| | 写给谁看 | 写给 AI 读的自然语言 | 写给程序读的结构化字段 | | 内容 | "该怎么干活"的约定 | "用什么、能做什么"的开关 | | 格式 | Markdown 大白话 | 标准 JSON |

二、3个配置文件分别是什么

Claude Code 源码里其实定义了 5 个配置文件的加载位置,但其中 2 个是旧格式兼容文件(~/.claude.json 和 <project>/.claude.json),新用户根本不需要创建,可以直接忽略。

配置文件加载顺序(优先级从低到高):
1. ~/.claude.json                          ← ⚠️ 旧格式兼容,新用户无需创建
2. ~/.claude/settings.json                 ← ✅ 全局默认设置(所有项目通用)
3. <project>/.claude.json                  ← ⚠️ 旧格式兼容,新用户无需创建
4. <project>/.claude/settings.json         ← ✅ 当前项目专属设置
5. <project>/.claude/settings.local.json   ← ✅ 个人本地覆盖(最高优先级,不进 Git)

普通用户只需关注 3 个文件: ~/.claude/settings.json(全局)、<project>/.claude/settings.json(项目)、<project>/.claude/settings.local.json(个人覆盖)。标注 ⚠️ 的旧格式文件可忽略。

1. 全局配置 ~/.claude/settings.json

  • 位置:你的用户主目录下(Windows 是 C:\Users\<你的用户名>\.claude\)
  • 作用范围:这台电脑上、你这个账户的所有项目都生效
  • 适合放:你个人长期不变的默认偏好,比如默认模型、全局权限白名单、状态栏设置

2. 项目级配置 <项目>/.claude/settings.json

  • 位置:某个具体项目文件夹里的 .claude/ 目录下
  • 作用范围:只对这一个项目生效,但对所有打开这个项目的人都生效
  • 这个文件会进 Git——也就是说,团队成员 clone 下来就能直接用同一套设置
  • 适合放:项目专属的东西,比如这个项目该用哪个模型、专属的 MCP 工具、自动跑 lint 的钩子
  • 重要:绝对不要在这里写密码、API Key,因为它会被提交到 Git 仓库里

3. 个人本地覆盖 <项目>/.claude/settings.local.json

  • 位置:和项目级配置同一个 .claude/ 目录,只是文件名多了 .local
  • 作用范围:这一个项目 × 这台机器 × 你这个用户——最小、最私人
  • 这个文件不进 Git(.local.json 后缀会被自动忽略),只存在于你本地
  • 适合放:你的私人 token、个人偏好(比如团队用 Sonnet 但你想用 Opus)、本机专属的绝对路径
  • 它的优先级最高——存在时会覆盖项目级和全局的同名字段

一句话记忆:全局管所有项目,项目级管一个项目所有人,本地覆盖只管你自己这台机器。范围越小,优先级越高。

三、3个配置文件之间的关系

这是最容易绕晕、也最关键的一节。三个文件不是"三选一",而是同时存在、层层叠加。

3.1 它们是怎么合并的:深度合并

Claude Code 有一套多层级配置合并系统。三个文件按优先级从低到高排列:

1. ~/.claude/settings.json          ← 全局默认(优先级最低)
2. <项目>/.claude/settings.json      ← 项目级
3. <项目>/.claude/settings.local.json ← 个人本地覆盖(优先级最高)

合并用的是深度合并(源码里叫 deep_merge_objects)——意思是嵌套的内容会递归地合在一起,而不是简单地整个替换掉。

举个最直观的例子:假设你在全局配了 1 个 MCP 工具,又在项目级配了 1 个,再在本地配了 1 个。最终结果不是"只剩最后那 1 个",而是3 个工具都能用(合并叠加)。

3.2 三类字段,三种合并规则

不同类型的字段,合并方式不一样,记住这三条就够了:

| 字段类型 | 例子 | 合并规则 | |---|---|---| | 标量字段(单个值) | model、permissionMode、sandbox.enabled | 后者覆盖前者(本地 > 项目 > 全局),最后只生效一个 | | 对象字段(带子项) | env、mcpServers | 递归合并——不同的子项全部保留,相同的子项再按规则继续合并 | | 数组字段(列表) | permissions.allow、permissions.deny | 设计意图是取并集(许可叠加),多个文件里的项会累加到一起 |

深度合并(deep merge)VS 递归合并(recursive merge):

深度合并:用作整个三层配置合并机制的名字——它是个统称,里面其实包含三套子规则:标量覆盖、数组取并集、对象递归合并。合并会"深入"到嵌套的内层,与"浅合并(shallow merge,只合最外层)"相对

递归合并:专门用来描述其中对象字段那一档(env / mcpServers)的行为

  • 不同的 key → 全部保留(这一点确实像并集)
  • 相同的 key → 仍然按优先级覆盖(这一点不是并集)
  • 真正发生"递归"动作的只有对象字段。标量字段(model)是直接覆盖、不往下钻;数组字段(hooks)是整体取并集、也不往下钻。只有对象字段才会"进入内层 、对相同 key 继续合并"——这一步才是字面意义上的递归

3.3 用"作用域"理解:一层套一层

如果你读过上一篇的指令文件,会发现配置文件其实是同一个套娃结构:

┌──────────────────────────────────┐
│  全局 / 所有项目                  │  优先级最低
│   ┌──────────────────────────┐   │
│   │  项目级 / 一个项目        │   │
│   │   ┌──────────────────┐   │   │
│   │   │ 本地 / 你这台机器 │   │   │  优先级最高
│   │   └──────────────────┘   │   │
│   └──────────────────────────┘   │
└──────────────────────────────────┘
        局部覆盖全局,从外向内优先级递增

本质上就是"用户 / 项目 / 机器"三个维度被层层收窄。范围越小越靠内、优先级越高——更具体的设置会覆盖更通用的设置。

⚠️ 这里有一个和指令文件不同的细节,值得普通用户特别注意:

指令文件(CLAUDE.md)因为是塞进 Prompt 给大模型读的,存在"中间层最容易被忽略"的注意力特性。但配置文件完全没有这个问题——它的合并是确定性的程序代码逻辑,三层优先级严格线性递增,全局 → 项目 → 本地,不存在"中间塌陷"。

所以"局部覆盖全局"这个宏观结论两类文件都成立;但"越中间越弱"只是指令文件的事,别套到配置文件上。

3.4 和电脑环境变量的类比

如果你用过 Windows 的"系统变量 / 用户变量 / 进程变量",会觉得很眼熟——都是层级配置 + 局部覆盖全局。可进行关联理解:

  • 更具体的覆盖更通用的
  • 全局放共性,局部放差异
  • 敏感的个人配置走最局部的那一层
  • 同名设置不生效时,从最局部往外排查

三处错位(不能直接套用):

  1. 中间层维度:Windows 用户变量 = "哪个登录账户"(身份维度);Claude 项目级 = "哪个目录树"(空间维度)。OS 不感知"项目"概念,最接近的对应物是 git config --local。
  2. 嵌套语义:Windows 三层是平铺读取顺序,系统/用户变量不构成父子集;Claude 的"作用域 3 ⊂ 2 ⊂ 1"是真子集嵌套。
  3. 第三层维度:Windows 进程变量 = 时间维度(当前会话,退出即失);Claude .local.json = 空间维度(永久落盘但不入 git)。

四、配置文件实例

光说规则太抽象,下面用一个个人作品展示网站的例子(技术栈:Next.js + Python API + SQLite)把三个文件串起来看。

4.1 全局.claude/settings.json

注意:标准 JSON 不支持注释,以下 // 注释仅用于说明,实际文件中请删除注释行。

{
  "model": "claude-opus-4-6",              // 默认使用的模型(可选 opus/sonnet 等)
  "permissionMode": "workspace-write",      // 权限模式:read-only / workspace-write / danger-full-access
  "env": { "MY_API_KEY": "..." },            // 注入到环境变量中,AI 和工具可以读取的API KEY
  "hooks": {                                 // 生命周期钩子:在工具调用前后自动执行的命令
    "PreToolUse": ["lint-check"],            //   工具调用前 → 先运行 lint 检查
    "PostToolUse": ["auto-test"]             //   工具调用后 → 自动运行测试
  },
  "mcpServers": {                            // MCP 外部工具服务器配置(给 AI 装"插件")
    "my-server": {                           //   工具名称(自定义,用于标识)
      "command": "uvx",                      //     启动命令(uvx = Python 工具运行器)
      "args": ["mcp-server-sqlite", "--db", "data.db"],  // 启动参数(SQLite MCP 服务器 + 数据库路径)
      "env": { "TOKEN": "..." }              //     传给该 MCP 服务器的环境变量
    }
  },
  "sandbox": {                               // 沙箱隔离配置(限制 AI 的系统访问范围)
    "enabled": true,                         //   是否启用沙箱
    "filesystemMode": "workspace-only",      //   文件系统限制:只能访问当前工作区
    "networkIsolation": true                 //   网络隔离:禁止 AI 发起外部网络请求
  }
}

要点:

  • 这个文件在你的用户主目录 ~/.claude/ 下,作用范围是这台机器上、你这个账户的所有项目——不属于任何单个项目,也不进 Git
  • 它是配置文件最常用、也最该先配好的一层:默认模型、全局权限白名单、状态栏这类"长期不变的个人偏好"都放这里
  • 它的优先级最低,但角色是"兜底"——项目级 / 本地没配的字段,最终都会回落到这里生效
  • 这里的 model、permissionMode 是给所有项目的默认值:设成 Opus 后所有项目默认用 Opus,某个项目想换再去项目级 / 本地单独覆盖
  • 因为是"按需覆盖"模式,很多人其实只有这一个文件就够用了——普通项目没特殊需求时,根本不必再建项目级或本地配置
  • 例子里 sandbox.enabled 设为 true,可以理解为给所有项目兜一条通用安全基线;信任的个人项目再在项目级把它关掉(见 4.2)

4.2 项目级 settings.json(会进 Git,团队共享)

{
  "model": "claude-sonnet-4-20250514",       // 用 Sonnet 模型(更快更便宜,展示网站够用)
  "permissionMode": "workspace-write",      // 日常开发标准权限
  "env": {                                   // 项目级环境变量(会进 Git,不放敏感信息)
    "DATABASE_URL": "sqlite:///data/portfolio.db",  // 数据库相对路径(团队通用)
    "NODE_ENV": "development"                // Node.js 环境标识
  },
  "hooks": {                                 // 生命周期钩子
    "PreToolUse": [],                        //   工具调用前:无额外操作
    "PostToolUse": ["npm run lint"]          //   工具调用后:自动跑 ESLint 检查代码风格
  },
  "mcpServers": {                            // 项目专属的 MCP 工具
    "portfolio-db": {                        //   作品集数据库工具
      "command": "uvx",                      //     用 uvx 启动
      "args": ["mcp-server-sqlite", "--db", "data/portfolio.db"],  // 指向项目内的 SQLite 文件
      "env": {}                              //     无额外环境变量
    }
  },
  "sandbox": {                               // 沙箱配置
    "enabled": false                         //   个人项目关闭沙箱(信任自己的代码)
  }
}

要点:

  • 这个文件会进 Git,团队成员(或你换电脑后)clone 下来就能直接用
  • model 用 Sonnet——更快更便宜,展示网站不需要 Opus 级别的推理能力
  • permissionMode 选 workspace-write,这是日常开发的标准选择
  • mcpServers 配了一个 SQLite 工具,让 AI 能直接查询作品集数据库
  • hooks 里配了 npm run lint,AI 每次改完代码自动跑代码风格检查
  • 这里不写任何密码、API Key,因为它会进 Git

4.3 个人本地覆盖 settings.local.json(不进 Git)

同一个项目,你的个人本地配置:

{
  "model": "claude-opus-4-6",                // 覆盖项目级的 Sonnet → 个人偏好用更强的 Opus
  "env": {                                   // 个人私密环境变量(不进 Git,只在本地生效)
    "VERCEL_TOKEN": "my-vercel-deploy-token",     // Vercel 部署令牌(用于自动部署展示网站)
    "GITHUB_TOKEN": "ghp_xxxxxxxxxxxx",           // GitHub 个人访问令牌(用于 Issues/PR 操作)
    "DATABASE_URL": "sqlite:///D:/projects/portfolio/data/portfolio.db"  // 覆盖为本机绝对路径
  },
  "mcpServers": {                            // 个人额外的 MCP 工具(会与项目级合并)
    "github-helper": {                       //   GitHub 操作工具(管理 Issues、创建 PR)
      "command": "npx",                      //     用 npx 启动
      "args": ["-y", "@modelcontextprotocol/server-github"],  // -y 自动确认安装
      "env": { "GITHUB_TOKEN": "ghp_xxxxxxxxxxxx" }           // 传入 GitHub token
    },
    "vercel-deploy": {                       //   HTTP 请求工具(用于调用 Vercel API 部署)
      "command": "npx",                      //     用 npx 启动
      "args": ["-y", "mcp-server-fetch"],    //     MCP fetch 服务器(通用 HTTP 请求能力)
      "env": {}                              //     无额外环境变量(Vercel token 已在上面的 env 中)
    }
  }
}

要点:

  • 这个文件不进 Git,只存在于你本地
  • model 覆盖成 claude-opus-4-6——你个人偏好用更强的模型,但不影响团队设置
  • env 里放了你的私人 token(Vercel 部署、GitHub),只在本地生效,安全
  • DATABASE_URL 把项目级的相对路径覆盖成你本机的绝对路径
  • 多加了一个 github-helper MCP 工具——这是你的个人需求,不是团队统一需求

4.3 三层叠加后,最终生效的是什么

把全局 + 项目级 + 本地三层合并,最终结果是:

model        = claude-opus-4-6        ← 标量字段:三层都有值,按优先级取最高 → 本地 Opus 覆盖项目级 Sonnet
permissionMode = workspace-write       ← 标量字段:本地没设,回落到「有值的最高层」→ 项目级生效(哪怕全局也设了也轮不到)
mcpServers   = { portfolio-db, github-helper, vercel-deploy }  ← 对象字段递归合并:三个 key 互不重复 → 1(项目)+2(本地)=3 个全保留
hooks        = { PostToolUse: ["npm run lint"] }  ← 数组字段:本例只有项目级配了 → 它是唯一有值的层,并未发生合并
env          = { VERCEL_TOKEN, GITHUB_TOKEN, DATABASE_URL(本地路径), NODE_ENV }  ← 对象字段递归合并:不同 key 全保留,重复 key(DATABASE_URL)由本地覆盖

看明白这张表,你就真正理解了"深度合并":

  • model 是单个值,本地的 Opus 把项目级的 Sonnet 覆盖掉了;
  • mcpServers 是对象,项目级的 1 个 + 本地的 2 个 = 最终 3 个工具全部可用;
  • env 同理,不同的 key 全保留,相同的 key(DATABASE_URL)由最高优先级的本地值胜出。

4.4 顺带说说 permissionMode(权限模式)

配置文件里有个字段叫 permissionMode,它决定了 AI 默认能干多少事,普通用户只需理解以下三个模式:

| 模式 | 含义 | 适用场景 | |---|---|---| | read-only | 只能读文件,不能改、不能跑命令 | 代码审查、不信任的代码 | | workspace-write | 能自由读写项目文件,但跑危险命令仍会弹窗确认 | 日常开发标准选择 | | danger-full-access | 所有操作直接放行,不弹窗 | 最高效也最危险,生产环境务必配合沙箱 |

它和你平时点的弹窗按钮是配套的:

  • 点 "Allow Once":只允许这一次,不写进任何文件;
  • 点 "Always Allow":把这条命令加进白名单(写入 settings.local.json 的 permissions.allow),以后不再弹窗。

可以这样理解:permissionMode 是"默认能干什么"的天花板,permissions.allow 是"白名单",可以通过预先声明哪些具体命令跳过弹窗直接放行。

五、配置文件放在哪里

下面这棵目录树标了 ★ 的就是你真正需要关心的文件:

~/                                    ← 用户主目录(Windows: C:\Users\<name>)
└── .claude/                          ← Claude Code 用户级配置目录
    ├── settings.json                 ← ★ 全局配置(管所有项目)
    ├── CLAUDE.md                     ← 用户级指令文件
    ├── plugins/                      ← 用户级插件
    └── projects/                     ← 会话历史等运行数据(自动管理,别动)

<某个项目根目录>/
├── .claude/
│   ├── settings.json                 ← ★ 项目级配置(进 Git,团队共享)
│   ├── settings.local.json           ← ★ 本地覆盖(不进 Git,优先级最高)
│   ├── CLAUDE.md                     ← 项目级指令文件
│   └── commands/  agents/  hooks/  rules/
├── CLAUDE.md                         ← 项目级指令文件(与 .claude/CLAUDE.md 二选一)
├── CLAUDE.local.md                   ← 项目本地指令(不进 Git)
└── .gitignore                        ← 必须包含 settings.local.json

几个容易踩的点:

  • 配置文件的本地版 settings.local.json 是在 .claude/ 目录里面;而指令文件的本地版 CLAUDE.local.md 是在项目根目录——两者位置不一样,别记混。
  • 凡是带 .local 的文件都不进 Git,需要在 .gitignore 里显式写一行 .claude/settings.local.json 把它排除掉。
  • 用户级的 ~/.claude/settings.json 是配置文件最常用的一层,模型、全局白名单这类长期偏好都放这里。
  • 进阶:环境变量 CLAUDE_CONFIG_HOME 可以改掉 ~/.claude 这个默认路径,一般人用不到。

六、普通人使用时需要关注的几点建议

前面都是原理,这一节是给普通用户的实操建议——把握住这几条,基本就不会出问题。

1. 不是每个项目都要建配置文件。 Claude Code 是"按需覆盖"模式,不是"必须存在"模式。没有项目级配置,它会自动回落到用户级配置;没有本地配置,再往上回落。所以普通项目 + 用户级配置已经够用时,什么都不用加。只有在以下情况才值得新建配置文件:项目需要特定模型、项目有私密 token、项目有专属 MCP 工具、项目需要自动跑 typecheck/lint。

2. 密钥永远只放 settings.local.json。 任何 API Key、token、密码——只能写在不进 Git 的本地文件里。项目级 settings.json 会被提交到仓库,写进去等于公开泄露。这是最重要的一条安全红线。

3. 一定要配好 .gitignore。 在 .gitignore 里加上 .claude/settings.local.json(和 CLAUDE.local.md)。否则你的本地私密配置会不小心被提交上去。

4. 想临时换模型 / 权限,改 settings.local.json 最省心。 因为它优先级最高,在里面加一个字段就能临时覆盖;不想要了直接删掉那行,就自动回落到项目级或全局设置,随时可逆,不影响别人。

5. 日常开发用 workspace-write 就好。 别一上来就开 danger-full-access。workspace-write 已经能让 AI 自由读写项目文件,危险命令还会弹窗给你最后一道确认;遇到反复弹窗的常用命令,点"Always Allow"逐步攒白名单即可。

6. 全局放共性,局部放差异。 长期不变的个人偏好(默认模型、常用白名单)放全局 ~/.claude/settings.json;项目专属的东西放项目级;只属于你这台机器的东西放本地。一旦某个设置没生效,从最局部(本地)往外(全局)逐层排查同名字段被谁覆盖了。


小结:配置文件就是一份分三层的"参数表"——全局、项目、本地,范围越小优先级越高,三层会被深度合并成一份最终生效的设置。普通用户记住三件事就够了:密钥只进本地文件、本地文件别忘了写进 .gitignore、没特殊需求就不必新建配置文件。它和上一篇的指令文件一个管"硬开关"、一个管"软约定",配合起来才是完整的 Claude Code 使用姿势。