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 启动时,优先级从低到高是:
~/.config/opencode/opencode.json/home/user/projects/acme/opencode.json/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 怎么选、本地模型怎么自动发现、以及怎么把成本压下来。