12k
All articles

What Lives in Your .claude Folder

What lives in your .claude folder: CLAUDE.md, settings.json, rules, skills, agents, MCP servers, precedence, and what to commit or ignore.

OpenReplay Team
OpenReplay Team
What Lives in Your .claude Folder

Your .claude folder holds two different kinds of thing: instructions that get loaded into Claude’s context at the start of every session (CLAUDE.md, rules/, skills/, agents/), and configuration that governs how the tool behaves (settings.json, hooks, MCP servers). Both kinds are split across a project directory you commit and a ~/.claude directory in your home folder that you never commit.

The folder also tends to grow on its own. Approving a permission prompt writes a file you didn’t create, /init drops a CLAUDE.md, and a pull request can end up carrying a .claude/settings.local.json full of one developer’s allow rules.

This is a file-by-file tour: what each path does, which file wins when two of them set the same thing, and a per-file verdict on whether it belongs in the repository.

Key Takeaways

  • Claude Code resolves configuration three different ways: settings.json values follow a five-level precedence order where the highest scope wins, CLAUDE.md files stack from the filesystem root downward instead of replacing one another, and permission rules merge so every rule from every scope stays in force.
  • The five settings scopes, highest precedence first, are managed settings, command-line flags, .claude/settings.local.json, .claude/settings.json, and ~/.claude/settings.json.
  • Commit CLAUDE.md, .claude/settings.json, .claude/rules/, .claude/skills/, .claude/agents/ and .mcp.json; keep .claude/settings.local.json, CLAUDE.local.md and everything under ~/.claude out of the repository.
  • Claude Code adds .claude/settings.local.json to your global git excludes the first time it writes to that file in a repository that doesn’t already ignore it, so a copy you created by hand still needs its own .gitignore entry.

Where Are the Two .claude Locations?

Claude Code reads two .claude roots. One sits in the project, travels with the repository and is meant for the whole team; the other, ~/.claude in your home folder, is yours alone and follows you into every project on the machine. That split is the single most useful thing to internalise. The Claude Code directory reference draws the same line: commit the project files, leave the home-folder ones where they are. Windows puts the home root at %USERPROFILE%\.claude, and pointing CLAUDE_CONFIG_DIR somewhere else moves all of it.

my-project/
├── CLAUDE.md                    # instructions loaded every session
├── CLAUDE.local.md              # private preferences, gitignored
├── .mcp.json                    # team-shared MCP servers
└── .claude/
    ├── settings.json            # permissions, hooks, env, model defaults
    ├── settings.local.json      # your personal overrides, gitignored
    ├── rules/*.md               # topic-scoped instructions, optionally path-gated
    ├── skills/<name>/SKILL.md   # reusable prompts invoked with /name
    ├── commands/*.md            # single-file prompts, same mechanism as skills
    ├── agents/*.md              # subagent definitions with their own prompt and tools
    ├── workflows/*.js           # workflow scripts saved from /workflows
    ├── output-styles/*.md       # instruction sets that adjust how Claude works
    └── agent-memory/<name>/     # persistent memory for subagents
~/.claude.json                   # app state, OAuth, personal MCP servers
~/.claude/
├── CLAUDE.md                    # your instructions, across every project
├── settings.json                # personal defaults
├── rules/*.md                   # user-level rules, applied to every project
├── keybindings.json             # custom keyboard shortcuts
├── themes/*.json                # custom colour themes
├── plugins/                     # cloned marketplaces and per-plugin data
├── projects/<project>/memory/   # auto memory Claude writes itself
└── .credentials.json            # login credentials

In practice, two files absorb nearly all the editing: CLAUDE.md and settings.json. Everything else is optional.

CLAUDE.md, Imports, and Path-Gated Rules

CLAUDE.md is the file Claude Code loads into context at the start of every session, and it is read from four locations: managed policy, ~/.claude/CLAUDE.md, the project (./CLAUDE.md or ./.claude/CLAUDE.md), and ./CLAUDE.local.md for personal notes. The memory documentation is clear that these stack rather than compete: each file Claude Code finds is added to context in sequence, starting at the filesystem root and working down to your working directory, and inside a single directory the CLAUDE.local.md goes in after the CLAUDE.md. A file in a parent directory is loaded at launch; one in a subdirectory waits until Claude opens a file there.

The @path/to/file syntax pulls in another file, resolved relative to the importing file, up to four hops deep. Breaking a long file into imports tidies it up without buying back any context, since everything it imports is expanded at launch too. Import parsing ignores anything inside backticks or a fenced block, which is how you name a path in your instructions without pulling the file in.

Two limits matter. The 200-line figure is a target rather than a cap: past it, a file eats more context and Claude follows it less reliably. The real ceiling is 4 MiB. Claude Code loads a CLAUDE.md up to that size in full and skips one that goes over.

.claude/rules/*.md is the modular alternative. Rule files are discovered recursively, one topic each. Give a rule no frontmatter and it loads at launch, ranking alongside .claude/CLAUDE.md; give it a paths field and it stays out of context until Claude touches a file matching the glob.

---
paths:
  - "src/components/**/*.tsx"
---

Prefer function components with explicitly typed props.
Co-locate the test file beside the component it covers.

Contradictory instructions across files get resolved arbitrarily, so there is no rule to memorise there. Run /context or /memory to see what actually loaded, and if an instruction genuinely must run at a fixed point, write it as a PreToolUse hook instead. A hook runs as a shell command at a fixed point in the session, whether or not Claude would have chosen to.

Where Does AGENTS.md Fit?

A repository that already carries AGENTS.md for other coding agents needs nothing extra: Claude Code reads those files itself, on their own or beside CLAUDE.md. Where the working directory and its parents hold no CLAUDE.md, AGENTS.md is what loads. Which files load is set by “Project instructions” in /config, and that setting only appears in sessions that can fetch Anthropic’s feature flags, so it is absent on Bedrock, Vertex and Foundry.

For a session that cannot load AGENTS.md, or when you want to keep an existing CLAUDE.md, add a CLAUDE.md next to AGENTS.md that imports it:

@AGENTS.md

## Claude Code

Run `pnpm typecheck` before proposing any change under `packages/api/`.

A symlink also works when you need no Claude-specific content: ln -s AGENTS.md CLAUDE.md. Windows will not create one without Administrator privileges or Developer Mode, so the import is the safer route there. A directly-read AGENTS.md does not appear under Memory files in /context or /memory. The session prints an “AGENTS.md loaded” line instead.

Do not confuse AGENTS.md with CLAUDE.local.md. The latter is the personal, gitignored companion to CLAUDE.md and has nothing to do with cross-tool interop.

What Is the Difference Between skills/, commands/ and agents/?

Commands and skills run on the same mechanism and both answer to /name. The directory reference points new work at skills/<name>/SKILL.md, because a skill directory can bundle supporting files alongside the instructions while a command is a single markdown file. An existing commands/*.md directory keeps working. For how to structure a skill for frontend work, see our guide to Claude Code skills for frontend workflows.

agents/*.md holds subagent definitions, each with its own prompt and tool list. Both directories exist at project scope and under ~/.claude, and both are picked up by their location rather than by registration in a settings file.

Claude Code Configuration Precedence: settings.json Against settings.local.json

settings.json is the shared project file and settings.local.json is your personal per-project override, and when both set the same key the local file wins. The settings reference gives five precedence levels, highest first: managed settings, command-line arguments, .claude/settings.local.json, .claude/settings.json, and ~/.claude/settings.json. JSON you hand to --settings slots in just under managed settings and above all three of your own files.

The part that catches people out is that not every key follows that stack. List keys such as permissions.allow, permissions.ask and permissions.deny combine across scopes rather than replace each other, so a deny rule in a teammate’s shared settings.json still bites even when your local file allows the same tool. Four model keys are the exception to that merge. fallbackModel is an ordered chain, so the highest-precedence file that sets it supplies the whole value. modelPicker works the same way, except that it reads only managed settings, --settings and user settings, and ignores the key in project and local files (Claude Code v2.1.242 and later). A managed availableModels list applies as it stands and your own additions are dropped, though across user, project and local files those arrays still merge. modelSettings is resolved one model at a time.

Shared file:

{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "cleanupPeriodDays": 30,
  "permissions": {
    "deny": ["Read(./.env)"]
  }
}

Local file:

{
  "cleanupPeriodDays": 7,
  "permissions": {
    "allow": ["Bash(npm run lint)"]
  }
}

The resolved session uses cleanupPeriodDays: 7, because the local file outranks the shared one on a scalar key. Both permission rules stay active: npm run lint runs without a prompt and reading .env is still blocked. Settings files are strict JSON: add a // comment or a trailing comma and the file fails to parse. The $schema line gives you editor autocomplete, and because the published schema sometimes trails the newest CLI releases, a warning on a key documented last week says more about the schema than about your file. Run /status to confirm which settings files loaded.

Where Do Hooks and MCP Servers Live?

Hooks are not separate files. They live under the hooks key in settings.json, at whichever scope you want them to apply, and an edit takes effect without restarting the session. MCP servers split by audience: .mcp.json sits at the project root, ships with the repository, and is the team-shared list. Personal MCP servers live in ~/.claude.json, which also stores app state, OAuth data and local-scope servers keyed by project path, so treat it as machine state rather than as a configuration file you edit by hand.

What to Commit and What to gitignore

PathWhat it isVerdict
CLAUDE.mdInstructions loaded every sessionCommit
.claude/settings.jsonTeam permissions, hooks, envCommit
.claude/rules/*.mdTopic-scoped, optionally path-gated instructionsCommit
.claude/skills/, .claude/commands//name promptsCommit
.claude/agents/*.mdSubagent definitionsCommit
.mcp.jsonTeam-shared MCP serversCommit
.claude/settings.local.jsonYour personal overridesIgnore
CLAUDE.local.mdYour private preferencesIgnore
~/.claude/*, ~/.claude.jsonPersonal and machine stateNever in a repo

The first time Claude Code writes that local file in a repository that does not already ignore it, it appends **/.claude/settings.local.json to your global git excludes. That write is what happens when you answer “Yes, and don’t ask again” to a permission prompt. Create the file by hand and nothing is added for you, so make the entry explicit:

# Claude Code personal config
# settings.local.json is usually auto-excluded already; this covers hand-created files
.claude/settings.local.json
CLAUDE.local.md

Shared settings are also what cloud sessions see, since those run against a fresh clone. User and local files stay on your machine and never reach them.

Everything Under ~/.claude Is Plaintext

Session transcripts, tool output, pasted text and the history.jsonl prompt log all land on disk as plain text, with file permissions the only thing standing in front of them. If a command printed a token during a session, that token is sitting in a transcript. .credentials.json holds your login credentials and survives the retention cleanup, which otherwise clears eligible files once they pass cleanupPeriodDays: 30 days by default, 1 at the lowest, and 0 refused as an invalid value.

The folder is smaller than it looks once you sort it: instructions concatenate, settings take precedence, permissions merge, and the home directory never enters version control. Open your own .claude/ against the tree above, delete the files nobody wrote on purpose, and add the two-line .gitignore block before the next pull request does it for you.

FAQs

Do I have to approve MCP servers that arrive in a teammate's committed .mcp.json?

Yes. In an interactive session Claude Code asks before it uses any project-scoped server that a .mcp.json declares, and each developer answers for themselves rather than once for the whole repository. Run claude mcp reset-project-choices to clear those answers. Non-interactive contexts cannot show the prompt: claude -p runs, Agent SDK sessions and cloud sessions load project-scoped servers without asking, so use disabledMcpjsonServers to block a server in every permission mode.

How do I override a Claude Code setting for one session without editing a file?

Pass --settings with either a path to a JSON file or an inline JSON string. It sits below managed settings and above your user, project and local files. Some keys also have their own flag or environment variable, and which of those wins is decided key by key: --model and /model beat ANTHROPIC_MODEL, while CLAUDE_CODE_EFFORT_LEVEL beats /effort.

Does editing settings.json mid-session take effect immediately?

Some keys reload in place and some are read once at session start, so an edit can look ignored until the next launch. Permissions and hooks reload without a restart, while model, effortLevel and modelSettings are read once at start. An outputStyle change applies from your next message as of v2.1.251, though in the terminal a style file you create or edit mid-session is picked up only after a restart. If a value still looks wrong after restarting, run /status and check precedence: a higher-scope file such as .claude/settings.local.json may set the same key.

What do I lose if I delete the projects folder under ~/.claude?

Deleting projects/ removes retained transcripts and can stop you resuming past sessions, though new sessions are unaffected. The command claude project purge is the targeted alternative: it deletes the transcripts, auto memory, tasks and file-history entries for one project, the matching prompt lines in history.jsonl, and that project entry in ~/.claude.json. Both shell-snapshots/ and backups/ are left where they are. Pass -i to step through the deletion plan.

Understand every bug

Uncover frustrations, understand bugs and fix slowdowns like never before with OpenReplay — self-hosted, with full data ownership.

Star on GitHub

We use cookies to improve your experience. By using our site, you accept cookies.