OpenCode 配置入门:opencode.json 与 cli.json

Posted on Fri 02 October 2026 in AI 编程 • Sucre Liu

第一件要分清的事

OpenCode 的配置分成两套,放在不同文件、管不同东西:

服务/项目配置 CLI 设置
文件 opencode.json(c) ~/.config/opencode/cli.json
管什么 模型、代理、权限、插件、MCP、命令、技能…… 主题、键位、标签、diff 视图、通知
作用域 全局 + 项目(可分层覆盖) 只有全局,没有项目级

把终端主题写进项目 opencode.json,或者指望 cli.json 影响会话行为,都属于串了台。先记住这条边界,后面的坑少一半。

opencode.json:项目配置怎么被找到

支持 JSON 和 JSONC(要写注释就用 JSONC)。加 schema 让编辑器能校验和补全:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-sonnet-4-5",
}

全局配置放这里,对所有项目生效:

~/.config/opencode/opencode.json(c)

项目配置放这两处之一:

<project>/opencode.json(c)
<project>/.opencode/opencode.json(c)

它从当前目录一路查到文件系统根,然后按顺序合并。这里有个容易被忽略的规则:

先合并所有直接的 opencode.json(c)(从最远到最近),再以同样顺序合并 .opencode/ 目录里的文件。因此每个 .opencode 配置都会覆盖所有直接配置。

用官方例子,从 packages/web 启动时,优先级从低到高是:

  1. ~/.config/opencode/opencode.json
  2. /home/user/projects/acme/opencode.json
  3. /home/user/projects/acme/packages/web/opencode.json

不冲突的设置会被保留,冲突的按优先级覆盖。建议在一个目录树里统一用同一种形式(要么都用直接文件,要么都用 .opencode/),否则"为什么这个值被盖掉了"会很难查。

值得先配的几项

不用一次配全。按需求挑:

{
  "$schema": "https://opencode.ai/config.json",
  "model": "anthropic/claude-sonnet-4-5",
  "default_agent": "build",
  "formatter": true,
  "snapshots": true,
  "permissions": [
    { "action": "shell", "resource": "*", "effect": "ask" },
    { "action": "shell", "resource": "git status *", "effect": "allow" }
  ],
  "mcp": {
    "servers": {
      "playwright": {
        "type": "local",
        "command": ["bunx", "@playwright/mcp"]
      }
    }
  }
}

各字段大概管什么:

字段 作用
model 默认模型,provider/model 格式
default_agent 会话未指定时用的主代理
permissions 有序权限规则(allow / deny / ask)
agents / commands / skills 自定义代理、命令、技能来源
plugins / mcp 插件与 MCP 服务
providers provider 与模型的请求、端点、变体配置
formatter 写入/编辑后自动格式化
snapshots 快照开关(影响撤销)
compaction 上下文压缩策略
watcher 忽略哪些目录不触发更新
tool_output 单次工具结果保留的行数/字节上限
websearch 搜索 provider 选择
shell 终端与 shell 工具用的 shell
worktree 新 worktree 的父目录
update 更新检查策略

两个容易忽略但有价值的项:

  • tool_output 默认保留 2000 行 / 51200 字节,超出会截断。如果你的工具输出常被截掉关键信息,先调这里,而不是怀疑模型。
  • update 默认 "notify";"auto" 会自动装但不重启运行中的服务(项目级设置会被忽略,只认全局)。

cli.json:只属于终端的那一份

CLI 设置只有全局一个文件:

~/.config/opencode/cli.json

设了 $XDG_CONFIG_HOME 就用 $XDG_CONFIG_HOME/opencode/cli.json。它有自己的 schema:

{
  "$schema": "https://opencode.ai/v2/cli.json"
}

未知设置会被拒绝(不是静默忽略),有效修改在 TUI 运行时热加载。也可以在启动时用环境变量注入:

OPENCODE_CLI_CONFIG_CONTENT='{"tabs":{"mode":"off"}}' opencode

内联设置会合并覆盖全局 cli.json;嵌套对象合并,数组和标量整体替换。

几个常见分组:

{
  "theme": { "name": "tokyonight", "mode": "system" },
  "mouse": true,
  "session": {
    "sidebar": "auto",
    "tps": true,
    "markdown": "rendered",
    "permissions": "prompt"
  },
  "tabs": { "mode": "auto", "scope": "cwd", "layout": "horizontal" },
  "diffs": { "source": "branch", "wrap": "word", "tree": true },
  "attention": { "notifications": true, "sound": true, "volume": 0.4 },
  "keybinds": { "leader": "ctrl+x" }
}

逐个挑两个说:

  • session.permissions 设成 autoaccept 会自动接受每个权限请求。除非在隔离环境,否则别开。 这和"随便点同意"没区别。
  • diffs.source 有 branch(分支+本地改动)、committed(只分支提交)、working(暂存+未暂存+未跟踪)。在 /diff 里按 d 可以临时改,退出即失效,不会写回文件。

键位用 keybinds.<命令ID> 覆盖,<leader> 引用 keybinds.leader,<leader> 的等待时长在 leader.timeout(毫秒)。禁用某个绑定用 "none" 或 false。

一条实践建议

把两套配置按"能不能共享"来分:

  • 项目配置进仓库:模型默认值、权限基线、MCP、formatter、agents/commands/skills——这些是团队共识,应该版本化。
  • CLI 设置留在本机:主题、键位、通知、diff 视图——这些是个人口味,不该强迫同事接受。

这也解释了为什么 cli.json 没有项目级:界面偏好本来就不该跟项目走。

小结

  • 两套配置:opencode.json(c) 管行为、可分层;cli.json 只管终端、只有全局。
  • 项目配置从当前目录查到根,先合并直接文件、再合并 .opencode,后者整体覆盖前者。统一一种形式,别混用。
  • tool_output、update、watcher 这几个"不显眼但会用得上"的字段值得先了解。
  • 界面偏好别进仓库,行为约定才进仓库。

下一篇讲模型与 provider:provider/model#variant 怎么选、本地模型怎么自动发现、以及怎么把成本压下来。