Vectrum
Sign In

README: Claude Code's servers, settings and CLAUDE.md

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Jjonicommitted 1 parent eff8c42commite750ed4

Showing 1 changed file with 201 additions and 3 deletions.

+201−3README.mdView File
@@ -55,7 +55,7 @@ would break your Claude Code login.
5555 Useful flags: `-model`, `-effort low|medium|high|xhigh|max`, `-max-turns`,
5656 `-resume latest`, `-no-stream`, `-no-cache`, `-no-auto-compact`, `-v`, `-yolo`,
5757 `-no-tui`, `-no-skills`, `-no-agents`, `-no-web`, `-no-hooks`,
58- `-no-diagnostics`, `-no-mcp`, `-no-claude-code-auth`.
58+ `-no-diagnostics`, `-no-mcp`, `-no-claude-code-auth`, `-trust-project`.
5959
6060 ### Flags and thresholds
6161
@@ -884,6 +884,7 @@ rather than the project's.
884884 | Path | What |
885885 | --- | --- |
886886 | `~/.config/codey/config.json` | the answers, written by the wizard and `/settings`; [hooks](#hooks) go here by hand |
887+ | `~/.config/codey/trust.json` | which checkouts' [Claude Code files](#trusting-a-project) you trusted, and which version of them |
887888 | `<repo>/.codey/sessions/` | saved conversations, which is what `-resume` and `/resume` read |
888889 | `<repo>/.codey/events.jsonl` | the event log METRICS.md is built from |
889890 | `<repo>/.codey/history` | what has been typed at the prompt here, which `↑` walks back through |
@@ -942,6 +943,114 @@ The whole thing is `↑↓` and `enter`, `esc` to go back. Animations collapse t
942943 their final frame under `NO_COLOR`, a `dumb` terminal, or a window under 60×20,
943944 and any key skips the one playing.
944945
946+ ### Claude Code's settings
947+
948+ If you already use Claude Code, a project set up for it should not need setting
949+ up a second time. Codey reads three kinds of thing from Claude Code's files —
950+ [its MCP servers](#claude-codes-servers), its permission rules, and its
951+ CLAUDE.md files — and none of it is copied anywhere or written back: change it
952+ in Claude Code and the next start here sees the change.
953+
954+ **Permissions.** The `permissions` block of three settings files, in the order
955+ Claude Code reads them:
956+
957+ | File | Whose | `deny` / `ask` | `allow` | `defaultMode` |
958+ | --- | --- | --- | --- | --- |
959+ | `~/.claude/settings.json` | yours, every project | honoured | honoured | `acceptEdits` only |
960+ | `.claude/settings.json` | the repository's, committed | honoured | only once [trusted](#trusting-a-project) | ignored |
961+ | `.claude/settings.local.json` | yours, this project, git-ignored | honoured | honoured | `acceptEdits` only |
962+
963+ The rule underneath that table is who wrote the file. A deny or an ask rule can
964+ only make the agent do less or ask more, and nobody comes to harm from that, so
965+ a repository may add as many as it likes. An allow rule is the opposite: it is
966+ a decision that something runs without you being asked, and a decision written
967+ into a repository was made by whoever wrote the repository. The shared file's
968+ allow rules therefore wait for the same trust question as its `.mcp.json`, and
969+ until you answer it they are listed and ignored. A `settings.local.json` that
970+ git turns out to be tracking arrived with the clone, whatever its name says,
971+ and is treated as shared.
972+
973+ The rules act before anything else in the approval policy. A deny holds in
974+ every mode, `-yolo` included — that is what writing it down is for — and it
975+ holds for the read-only tools too, since `Read(.env)` is a rule about reading.
976+ An ask rule puts the call to you even when the mode would have let it through,
977+ and even when you said "always this tool" earlier in the session. An allow rule
978+ lets a call through without a prompt. Between them deny beats ask beats allow,
979+ as in Claude Code, so no allow rule anywhere argues a call past a deny. The
980+ denial the model reads names the rule and the file, so it can tell you which
981+ line to change instead of retrying. `/allowed` lists every rule under the file
982+ it came from, and says which are in force and why the others are not.
983+
984+ Claude Code's names map onto Codey's: `Bash` is `bash`, `Read` is `read_file`
985+ (and, as best it can, `glob` and `grep`), `Edit` is both `edit_file` and
986+ `write_file`, `MultiEdit` is `edit_file`, `Write` is `write_file`, `Glob`,
987+ `Grep`, `WebFetch`, `WebSearch` and `TodoWrite` are the obvious ones, and
988+ `mcp__server` and `mcp__server__tool` are unchanged. A rule naming a tool Codey
989+ does not have, or written in a form it does not understand, is reported at
990+ startup and takes no part. Paths follow Claude Code's conventions: `//path` is
991+ absolute, `~/path` is under your home, `/path` is under the project root, and
992+ anything else is relative to it, with a bare name such as `.env` matching at
993+ any depth the way `.gitignore` would. Links are followed, so a rule about
994+ `.env` also catches a symlink to it.
995+
996+ `Bash(npm run test:*)` is matched one simple command at a time, using the same
997+ parser as the approval prompt. An allow rule covers `npm run test && rm -rf ~`
998+ only if something also allows `rm`; a deny rule catches the line if it catches
999+ any part of it. A command the parser cannot see through — `$(...)`, backticks,
1000+ `bash -c`, a variable in command position — never matches an allow rule, and
1001+ where a deny rule cannot be ruled out for it, the call is asked about rather
1002+ than run. So is anything that does more than its words say: `PATH=. git
1003+ status`, or `echo hi > ~/.bashrc`, is not covered by an allow rule for `git` or
1004+ `echo`. None of this makes shell allowlisting a security boundary — see
1005+ [Safety](#safety) — but it does stop the commonest way a prefix rule says yes to
1006+ something nobody wrote down.
1007+
1008+ `defaultMode: "acceptEdits"` in a file of yours lets file edits through, as
1009+ Claude Code's mode of that name does. `default` is the default. The other modes
1010+ are ignored with a notice, from every file: `bypassPermissions` in particular,
1011+ because in Codey the way to stop being asked is `-yolo`, typed on the command
1012+ line for one run, and neither a file of yours nor a repository's gets to say it
1013+ for you.
1014+
1015+ **CLAUDE.md.** The files Claude Code loads into every conversation are loaded
1016+ into this one's system prompt, at startup, in Claude Code's order:
1017+ `~/.claude/CLAUDE.md`, then — from the top of the project down to the working
1018+ root — each directory's `CLAUDE.md`, `.claude/CLAUDE.md` and `CLAUDE.local.md`.
1019+ The top is the nearest directory with a `.git` in it, or your home directory if
1020+ there is none on the way; a root that is in neither is a project of one
1021+ directory, because walking up to `/` would read whatever happened to be lying
1022+ in `/tmp`. Later files are more specific and the prompt says they win.
1023+ `@path/to/file` imports are followed, relative to the file they appear in and up
1024+ to five deep, skipping anything in a code block. A project's files may import
1025+ only from the project, and that is checked where symlinks lead: a repository's
1026+ CLAUDE.md that could import `@~/.aws/credentials` would be a repository reading
1027+ your credentials into a conversation that is then sent to the model. Your own
1028+ `~/.claude/CLAUDE.md` and `CLAUDE.local.md` may import from your home
1029+ directory. The whole thing is read once per session, so the cached prompt
1030+ prefix stays the same from request to request; restart to pick up an edit.
1031+ `AGENTS.md` is not loaded this way, but the agent is still told to read one if
1032+ the repository has it, as before, and a CLAUDE.md that says `@AGENTS.md` brings
1033+ it in.
1034+
1035+ **What is not carried over**, so nobody has to find out the hard way:
1036+
1037+ - Hooks in Claude Code's format (`PreToolUse`, `PostToolUse` and the rest).
1038+ Codey's [hooks](#hooks) are a different thing — they watch, they cannot
1039+ veto — and a script written to block a tool call would silently block
1040+ nothing here.
1041+ - `env`, `model`, `apiKeyHelper`, `statusLine`, `outputStyle`, `cleanupPeriodDays`
1042+ and the other non-permission settings. Codey has its own config for the ones
1043+ it has an equivalent of.
1044+ - `permissions.additionalDirectories`: the file tools keep the working root as
1045+ their only root.
1046+ - Claude Code's own record of which `.mcp.json` servers you approved
1047+ (`enabledMcpjsonServers`, `enableAllProjectMcpServers`). It approves by name,
1048+ so a server whose command changed under the same name would still count;
1049+ Codey asks its own question about the exact definitions instead.
1050+ - Managed (enterprise) settings, subdirectory CLAUDE.md files loaded on demand,
1051+ and `.claude/rules/`.
1052+ - Remote MCP servers, which Codey's client does not speak.
1053+
9451054 ## Tools
9461055
9471056 | Tool | Approval | Notes |
@@ -1191,7 +1300,85 @@ Only tools are used: not resources, prompts or sampling, and no HTTP
11911300 transport. Pictures a tool returns are described to the model rather than
11921301 shown. A server's directory is fixed when it starts, so after `/worktree` it
11931302 is still serving the root the session began in. `-no-mcp` starts none of them
1194- for one run.
1303+ for one run — Codey's own and Claude Code's alike.
1304+
1305+ ### Claude Code's servers
1306+
1307+ The servers Claude Code already knows about are started as well, read from
1308+ where Claude Code keeps them rather than copied into Codey's config:
1309+
1310+ | Where | Whose | Started |
1311+ | --- | --- | --- |
1312+ | `~/.claude.json`, under `projects["<root>"].mcpServers` | yours, for this project — what `claude mcp add` writes | always |
1313+ | `.mcp.json` at the working root | the repository's, committed | once you [trust it](#trusting-a-project) |
1314+ | `~/.claude.json`, top-level `mcpServers` | yours, for every project — `claude mcp add -s user` | always |
1315+
1316+ The shape is the one already shown above, `{"mcpServers": {name: {command,
1317+ args, env}}}`, with `"type": "stdio"` accepted and meaning the same thing. A
1318+ server with `"type": "http"` or `"sse"`, or with a `url`, is a remote server;
1319+ Codey's client speaks only stdio, so it is reported at startup and skipped.
1320+ `${VAR}` and `${VAR:-default}` are expanded in the command, the arguments and
1321+ the env values, as Claude Code expands them — so a `.mcp.json` can say
1322+ `"${DB_URL}"` and leave the secret in your environment. A variable that is
1323+ unset and has no default skips that server with a notice naming it, rather
1324+ than starting it with a hole in its command line.
1325+
1326+ When two places define a server of the same name, Codey's own `mcp_servers`
1327+ win, and after that the table is read top to bottom: your per-project servers,
1328+ then the repository's, then your global ones. That is Claude Code's own order,
1329+ so a name means the same program in both. Each clash is reported once, naming
1330+ the one that won, because a server that quietly turned out to be a different
1331+ program is not something anyone thinks to debug.
1332+
1333+ #### Trusting a project
1334+
1335+ A `.mcp.json` comes from the repository. Starting a server listed there means
1336+ running a command — with your environment, your credentials, your network —
1337+ that whoever wrote the repository chose, before the agent has done anything
1338+ and outside every approval prompt. So, like Claude Code, Codey asks first. The
1339+ first interactive start in a checkout whose `.mcp.json` or shared
1340+ `.claude/settings.json` [allow rules](#claude-codes-settings) would grant
1341+ something prints, before the TUI opens:
1342+
1343+ ```
1344+ Claude Code's configuration for /home/you/src/thing would:
1345+
1346+ start these MCP servers, from .mcp.json:
1347+ db: npx -y @acme/db-mcp --url ${DB_URL} (env: DB_TOKEN)
1348+ run these without asking, from .claude/settings.json:
1349+ Bash(make:*)
1350+
1351+ These files come from the repository, not from you: trusting them lets it
1352+ choose commands this machine runs. Your answer is remembered until they change.
1353+ Trust them for this checkout? [y/N]
1354+ ```
1355+
1356+ One question covers both files, because it is one question: do you trust what
1357+ this repository says about itself. The full command line is shown because that
1358+ is the thing being agreed to. The answer — yes or no — is remembered for this
1359+ checkout against a fingerprint of exactly those definitions, as written, before
1360+ any `${VAR}` is expanded. A new server, a changed argument or one more allow
1361+ rule is a different fingerprint, and the question comes back; nothing else
1362+ does. A refusal is remembered too, so saying no once is not a question at every
1363+ start.
1364+
1365+ The record is kept in `~/.config/codey/trust.json`, not in the project's
1366+ `.codey/` directory with the rest of the per-repository state. That is the
1367+ point of it: anything inside the working tree can arrive with a clone, and a
1368+ repository that shipped its own record of being trusted would be approving its
1369+ own servers. The fingerprint would be no defence there — whoever wrote the
1370+ `.mcp.json` can compute it. Only a file the repository cannot reach can say what
1371+ you decided.
1372+
1373+ Where nobody can be asked — `-p`, `codey agent stdio`, a piped stdin — an
1374+ undecided project's servers are not started and its allow rules are ignored,
1375+ with a line on stderr saying so. A checkout you have already trusted needs
1376+ nothing more. `-trust-project` says yes for one run without asking and without
1377+ recording anything, which is what a CI job against a repository you control
1378+ wants. Servers in `~/.claude.json` never ask: you put them there, as you put
1379+ Codey's own in its config. Once started, every server's tool calls go through
1380+ the approval prompts like any other, unless an allow rule such as `mcp__db`
1381+ says otherwise.
11951382
11961383 ## Hooks
11971384
@@ -1441,6 +1628,14 @@ interpreter with `-c` cannot be analysed at all, so it is marked opaque and
14411628 allowlists for shell commands do not work; this exists to make the prompt
14421629 specific, not to make the decision for you.
14431630
1631+ [Claude Code's permission rules](#claude-codes-settings) sit in front of all
1632+ of that. Its deny rules hold in every mode, `-yolo` included, which makes them
1633+ the one part of this layer you can lean on: a call they refuse does not run.
1634+ Its allow rules are matched with the same parser, one simple command at a
1635+ time, and an opaque command matches none of them — but the warning above
1636+ applies to them with full force. `Bash(find:*)` allows `find . -exec rm {} +`,
1637+ and no parser will tell you otherwise.
1638+
14441639 Hooks sit outside all three layers, deliberately: a command in `"hooks"` runs
14451640 on every event it is attached to, without a prompt, because you put it in your
14461641 own config rather than the agent asking for it. The path jail is what keeps the
@@ -1449,7 +1644,9 @@ working root you would sensibly point Codey at — but the flip side is that
14491644 anything able to write that file has arranged to run commands here. `-no-hooks`
14501645 is the switch that says no for one run. MCP servers are the same bargain: each
14511646 is a program started with your environment when the session opens, and only
1452- its tool calls go through the prompts. `-no-mcp` is theirs.
1647+ its tool calls go through the prompts. `-no-mcp` is theirs. The one kind of
1648+ server that does not come from a file you wrote — a repository's `.mcp.json` —
1649+ waits for you to [trust it](#trusting-a-project) first.
14531650
14541651 **A sandbox.** This is the layer that actually contains a mistake, and the
14551652 Codey cannot provide it for you. The honest recipe on Linux:
@@ -1489,6 +1686,7 @@ internal/websearch the search command, the URL jail, HTML to text
14891686 internal/mcp MCP client: starts the configured servers, offers their tools
14901687 internal/config saved defaults: model, effort, approvals, web search, theme, diagnostics
14911688 internal/approval allow / deny / ask, with shell analysis
1689+ internal/ccsettings Claude Code's MCP servers, permission rules and CLAUDE.md, and who may grant what
14921690 internal/ask questions the agent puts to you mid-task, and the tool for it
14931691 internal/hooks the lifecycle, published: fan-out, and the config's commands
14941692 internal/herdr reporting agent state to the herdr pane Codey is running in