The .claude directory is where all the project's customization lives, and the easiest way to make sense of it is to split its contents by role. Some files are instruction that affects the model (CLAUDE.md, rules). Others are policy that sets rules and permissions (settings, permissions). Others are extension that adds executable components (commands, agents, skills, hooks, MCP). Mixing these roles is a frequent source of confusion: instruction is edited expecting a policy effect, and an executable component is taken for a harmless note.
A typical team repository lays these roles out in a familiar structure. At the root are CLAUDE.md and an uncommitted CLAUDE.local.md, .mcp.json with MCP definitions, .worktreeinclude. Inside .claude are settings.json and an uncommitted settings.local.json, and alongside them the directories rules, skills, agents, hooks, output-styles, commands and, if configured, agent-memory. It helps to see this map in full once, to understand where to put a new entity.
Not every project needs all the directories, and this is an important principle. The minimum is a short CLAUDE.md and .claude/settings.json; the rest is added when a repeatable task or a measurable control appears, not in advance. The rule of choice is simple: facts and rules needed almost always - in CLAUDE.md and rules; a procedure on demand - in a skill; a separate role with its own context - in a subagent; an event check - in a hook; an external source - in MCP; a portable set - in a plugin; enforced policy - in managed.
It helps to gather the need and the mechanism into a table once, so as not to invent a new entity for every task. Below is such a map - from project facts to enforced policy. You return to it when your hand reaches to put a procedure in CLAUDE.md or a rule in a skill: each mechanism has its own role and its own loading semantics, and choosing the right mechanism matters more than cramming one place with everything.
| Need | Mechanism |
|---|---|
| Facts and rules needed almost always | CLAUDE.md / rules |
| A procedure on demand | skill |
| A separate role and context | subagent |
| A deterministic event check |
|---|
| hook |
| An external tool / data source | MCP |
|---|
| A portable set of components | plugin |
|---|
| Enforced policy | managed settings |
|---|
A separate subtlety - the --add-dir flag gives access to additional directories but does not turn the configuration lying there into project configuration. It is about file access, not about connecting someone's policy. And in general different components - subagents, skills, rules, memory - have different discovery semantics, so for each you check its documentation rather than transfer intuition from one mechanism to another.
What to commit and what not is a matter of both convenience and security. You commit shared instructions, shared settings, reviewed hooks, skills, agents and .mcp.json without secrets. You do not commit settings.local.json and CLAUDE.local.md, OAuth and cache state, tokens, machine-specific absolute paths and persistent memory with personal or sensitive data. The line is simple: into the repository goes what should be shared and reviewed, and the personal and secret stays local.
A configuration change is worth reviewing as code, because editing .claude/settings.json, a hook or .mcp.json affects all future sessions. In a pull request you answer concrete questions: did permissions, paths or network domains expand; did an executable command appear; where does the package, plugin or server come from; is there a version pin; did a secret get in; what will the user see before trust and approval; how is this change disabled. Each point closes its class of risk.
The typical .claude failures are about mixing roles and carelessness. Putting an executable hook or MCP in as a harmless detail without reviewing it as code. Committing settings.local or CLAUDE.local, multiplying the personal across the repository. Confusing access via --add-dir with connecting someone's policy. Keep the three roles separate, commit only the shared and reviewed, and check any configuration change with the same questions as a code change.
repository/
├── CLAUDE.md
├── CLAUDE.local.md # personal, do not commit
├── .mcp.json # project MCP
├── .worktreeinclude
└── .claude/
├── settings.json # shared settings/policy
├── settings.local.json # personal, do not commit
├── rules/ # instruction (path-scoped)
├── skills/ # a procedure on demand
├── agents/ # separate roles
├── hooks/ # event checks
├── output-styles/
└── commands/