The .claude directory
Every file Claude Code reads from your project's .claude folder and from ~/.claude, what each is for, when it loads, and how local session data is kept and cleared.
Claude Code reads configuration from two places: a .claude/ folder (plus a few files) inside each project, and a .claude/ folder in your home directory that applies everywhere. It also writes a fair amount of its own data into ~/.claude as you work.
In practice most people only ever touch two files: CLAUDE.md and settings.json. Everything else is optional and worth adding only when you need it. This page is the map.
The project tree
A fully loaded project might look like this. You will rarely have all of it.
my-app/
├── CLAUDE.md # instructions loaded every session (committed)
├── CLAUDE.local.md # your private project notes (gitignored, optional)
├── .mcp.json # team-shared MCP servers (committed)
├── .worktreeinclude # gitignored files to copy into new worktrees (committed)
└── .claude/
├── settings.json # permissions, hooks, env, model (committed)
├── settings.local.json # your personal overrides (gitignored)
├── rules/ # topic instructions, optionally path-scoped
│ ├── migrations.md
│ └── frontend/forms.md
├── skills/
│ └── release-notes/
│ ├── SKILL.md
│ └── template.md
├── commands/ # older single-file form of skills
├── agents/ # subagent definitions
├── workflows/ # saved dynamic workflow scripts (.js)
├── output-styles/ # team-shared output styles
└── agent-memory/ # memory written by subagents with memory: project
CLAUDE.md
Project instructions that Claude reads at the start of every session: commands, architecture, conventions. Commit it so the whole team shares the same baseline. Some practical points:
- Aim for under 200 lines. Longer files still load in full, but adherence drops.
- Anything that only matters for certain tasks should move to a skill or a path-scoped rule so it only loads when relevant.
- List the commands you run constantly (build, test, lint, format) so Claude never has to guess.
- Run
/memoryto open it from inside a session. - It can live at
.claude/CLAUDE.mdinstead if you like a tidy root. - If the repo already has an
AGENTS.mdfor other agents, Claude Code can read that instead.
An example from a Django project I maintain:
# Bookings service
## Commands
- Run tests: `uv run pytest -q`
- Lint and format: `uv run ruff check --fix . && uv run ruff format .`
- Local server: `uv run python manage.py runserver 8010`
## Conventions
- Business logic lives in `services/`, never in views or serialisers
- Every new model field needs a migration and a factory update in `tests/factories.py`
- Money is stored as integer pence; never use floats for currency
Full guidance is in memory.
.mcp.json
Project-scoped MCP servers that everyone on the team gets. It sits at the repository root, not inside .claude/. Reference secrets through environment variables rather than pasting them in; Claude Code expands ${VAR} from your shell when it launches the server.
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "linear-mcp-server"],
"env": { "LINEAR_API_KEY": "${LINEAR_API_KEY}" }
}
}
}
Servers connect when the session starts, but their full tool schemas are deferred and fetched through tool search when needed. Servers only you need belong in ~/.claude.json instead; claude mcp add --scope user writes there. See MCP.
.worktreeinclude
When Claude creates a git worktree (via --worktree, the EnterWorktree tool, or a subagent with isolation: worktree), the new checkout has no untracked files, so your .env is missing. List the gitignored files to copy across, using .gitignore syntax. Only files that both match a pattern and are gitignored get copied, so tracked files are never duplicated.
# secrets and local config
.env.development.local
certs/localhost-key.pem
It lives at the repository root, also applies to parallel sessions in the desktop app, and is ignored if you replace worktree creation with a WorktreeCreate hook for another version control system (copy files in your hook instead). See worktrees.
.claude/settings.json
Configuration that Claude Code enforces, as opposed to guidance Claude reads. Common keys:
| Key | Purpose |
|---|---|
permissions | Allow, deny or ask before particular tools or commands |
hooks | Run your scripts at lifecycle events |
statusLine | Customise the status line at the bottom of the terminal |
model | Default model for this project |
env | Environment variables set in every session |
outputStyle | Select an output style |
{
"permissions": {
"allow": ["Bash(make test *)", "Bash(make lint)"],
"deny": ["Read(./secrets/**)", "Bash(terraform apply *)"]
},
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs -I{} gofmt -w {}" }
]
}
]
}
}
Bash rules accept wildcards, so Bash(make test *) covers any command starting with make test. Array settings such as permissions.allow combine across every scope, while single-value settings such as model take the most specific value. Project settings override your global ones; local settings, CLI flags and managed policy override project settings. See settings and permissions.
.claude/settings.local.json
Your personal overrides for this project, in exactly the same format. It is the highest-priority file you edit yourself (CLI flags and managed settings still beat it). When Claude Code first saves a setting here in a repository that does not already ignore it, it adds **/.claude/settings.local.json to your global git excludes file: the core.excludesFile path from your global git config if that is absolute or starts with ~, otherwise $XDG_CONFIG_HOME/git/ignore or ~/.config/git/ignore. Add the same line to the project .gitignore if you want teammates protected too.
Permission rules you approve during a session are written here.
.claude/rules/
Instructions split into topic files. A rule with no frontmatter loads at session start like CLAUDE.md. A rule with paths: loads only when Claude reads, writes or edits a matching file. Subfolders are discovered automatically.
---
paths:
- "db/migrations/**/*.sql"
---
# Migration rules
- Every migration must be reversible; include the down step
- Never rename a column in one step: add, backfill, then drop in a later release
- Lock-heavy operations need a comment explaining the expected table size
Like CLAUDE.md, rules are guidance, not enforcement. Use hooks or permissions for anything that must hold. When CLAUDE.md approaches 200 lines, splitting into rules is the natural next step.
.claude/skills/
Each skill is a folder containing SKILL.md and any supporting files. By default both you and Claude can invoke a skill. Frontmatter controls that: disable-model-invocation: true makes it user-only (good for /deploy), and user-invocable: false hides it from the / menu while still letting Claude use it.
---
description: Drafts release notes for the current tag from merged pull requests
disable-model-invocation: true
argument-hint: <previous-tag>
---
## Merged since $ARGUMENTS
!`git log $ARGUMENTS..HEAD --merges --pretty=format:'%s'`
Group the changes above into Features, Fixes and Internal.
Follow the tone and layout in template.md from this skill's folder.
Leave out anything labelled chore unless it affects users.
Things to know:
- Arguments typed after the name arrive as
$ARGUMENTS; use$0,$1and so on for positional values. - A line in the form
!`command`runs in your shell first and its output is injected into the prompt. - The
descriptiondecides when Claude picks the skill automatically. - Claude is told the skill's folder path, so it can open bundled files you mention. In shell injection lines, use
${CLAUDE_SKILL_DIR}to reference bundled scripts.
See skills.
.claude/commands/
The older, single-file form. commands/triage.md creates /triage exactly as skills/triage/SKILL.md would, and both can be invoked by Claude. Commands still work and accept $ARGUMENTS, but new work should use skills because a folder lets you bundle templates and scripts. If a command and a skill share a name, the skill wins.
.claude/agents/
Each Markdown file defines a subagent: frontmatter for its name, description, tools and optional model, and a body that becomes its system prompt. Every subagent runs in its own fresh context window.
---
name: migration-checker
description: Reviews database migrations for locking, reversibility and data loss risks
tools: Read, Grep, Glob
---
You review SQL and ORM migrations before they ship.
For each migration report: tables touched, lock level, whether it is reversible,
and any step that could lose data. Suggest a safer sequence when needed.
Restrict tools with tools:. Type @ in the prompt and pick an agent to delegate to it directly.
.claude/workflows/
Each .js file is a saved dynamic workflow, a script that spawns and coordinates many subagents. You do not write these by hand: Claude writes them, and you save a run from /workflows by pressing s. Each file becomes a /<name> command. A project workflow beats a personal one of the same name.
.claude/output-styles/
Output styles are usually personal and live in ~/.claude/output-styles/. Put one here when the whole team shares it, such as a review mode.
.claude/agent-memory/
Created automatically for subagents whose frontmatter sets memory: project. Each such subagent gets agent-memory/<agent-name>/MEMORY.md, which it writes and maintains itself; the first 200 lines (capped at 25 KB) are loaded into its system prompt when it runs. This is separate from your main session's auto memory. Use memory: local to write to .claude/agent-memory-local/ instead and keep it out of git, or memory: user for ~/.claude/agent-memory/ across projects.
The home directory tree
~/
├── .claude.json # app state, OAuth, trust decisions, personal MCP servers
└── .claude/
├── CLAUDE.md # personal instructions for every project
├── settings.json # your default settings everywhere
├── keybindings.json # custom shortcuts
├── themes/ # custom colour themes
├── rules/ # personal rules for every project
├── skills/ # personal skills
├── commands/ # personal single-file commands
├── output-styles/ # personal output styles
├── agents/ # personal subagents
├── workflows/ # personal saved workflows
├── agent-memory/ # memory for subagents with memory: user
└── projects/ # transcripts and auto memory, per project
~/.claude.json
State that does not belong in settings: your OAuth session, per-project trust decisions, personal MCP servers and UI toggles such as autoConnectIde and externalEditorContext. The projects key holds per-project state like trust acceptance and last-session metrics. You normally change it through /config rather than by hand. MCP servers here are yours alone: user scope applies to every project, local scope to one project without being committed.
~/.claude/CLAUDE.md
Personal instructions loaded alongside each project's CLAUDE.md. When they conflict, the project wins. Keep it short because it loads everywhere. Mine covers commit style, a preference for showing the verification command after a change, and UK spelling.
~/.claude/settings.json
The same keys as project settings, applied to every project: permissions you always allow, a preferred model, a desktop notification hook. Unlike CLAUDE.md files, which are all loaded together, settings are merged key by key and the project value wins where both set it.
~/.claude/keybindings.json
Rebinds shortcuts in the interactive terminal. Run /keybindings to create or open it with a schema reference. It hot-reloads when you save. Ctrl+C, Ctrl+D, Ctrl+M and Caps Lock are reserved.
{
"bindings": [
{
"context": "Chat",
"bindings": { "ctrl+g": "chat:externalEditor", "ctrl+s": null }
}
]
}
Setting an action to null unbinds it, and context limits the binding to one part of the interface. See keybindings.
~/.claude/themes/
Each .json file is a custom theme: a built-in base plus an overrides map of colour tokens. Create one interactively with /theme or by hand; choosing it stores custom:<slug> as your theme. Files hot-reload. See terminal configuration.
{ "name": "Harbour", "base": "dark", "overrides": { "claude": "#7cc4fa", "error": "#ff6b6b" } }
~/.claude/projects/ and auto memory
Each project gets a folder keyed by its path. Inside, memory/MEMORY.md is an index Claude writes for itself; the first 200 lines or 25 KB (whichever comes first) load at session start. Detail lives in separate topic files alongside it (such as feedback_testing.md), which Claude reads only when a related task comes up. Auto memory is on by default; toggle it with /memory or the autoMemoryEnabled setting. The files are plain Markdown, so edit or delete them freely. See memory.
~/.claude/output-styles/
Custom styles available in every project. By default a style replaces Claude Code's built-in software engineering instructions; set keep-coding-instructions: true in its frontmatter to keep them. Built-in styles are Default, Proactive, Concise, Explanatory and Learning. Select one with /output-style, /config or the outputStyle setting, using the filename without .md or the name field. A project style with the same name takes precedence. Switching applies from your next message; a style file you create or edit mid-session is picked up in the terminal after a restart.
Other personal folders
rules/, skills/, commands/, agents/ and workflows/ in ~/.claude work exactly like their project equivalents but apply everywhere. agent-memory/ holds memory for subagents set to memory: user.
Files that live elsewhere
| File | Where | Purpose |
|---|---|---|
managed-settings.json | A system path that depends on the OS | Organisation-enforced settings that your own files and --settings cannot override, with narrow exceptions. See managed settings |
CLAUDE.local.md | Project root | Your private notes for this project, loaded with CLAUDE.md. Create it yourself and add it to .gitignore |
AGENTS.md | Project root, .claude/ or any folder | Agent instructions that Claude Code can load instead of CLAUDE.md |
| Installed plugins | ~/.claude/plugins | Cloned marketplaces, installed versions, the installed_plugins.json record and per-plugin data, managed by claude plugin commands. Plugins synced from claude.ai land in ~/.claude/plugins/synced/ |
A couple of plugin edge cases: a plugin installed from a marketplace command source in link mode is stored as a link, with its files staying wherever the command put them (this needs Claude Code v2.1.229 or later), and a plugin referenced by relative path in a marketplace added from a local folder loads in place from its source. See plugin loading.
Which file do I edit?
| Goal | File | Scope |
|---|---|---|
| Tell Claude about the project and its conventions | CLAUDE.md | Project or global |
| Allow or block a tool or command | settings.json (permissions, or a hooks guard) | Project or global |
| Run a script around tool calls | settings.json (hooks) | Project or global |
| Set session environment variables | settings.json (env) | Project or global |
| Keep a personal tweak out of git | settings.local.json | Project |
Add a /name workflow | skills/<name>/SKILL.md | Project or global |
| Define a specialist subagent | agents/*.md | Project or global |
| Orchestrate many subagents | workflows/*.js | Project or global |
| Connect an MCP server for the team | .mcp.json | Project |
| Change how responses are written | output-styles/*.md | Project or global |
Remember that some things outrank these files: managed settings from your organisation (bar the documented exceptions), CLI flags like --permission-mode and --settings for that session, and certain environment variables (check each one in environment variables). Settings gives the full precedence order.
Frontmatter at a glance
| File | Fields it understands |
|---|---|
skills/<name>/SKILL.md | name, description, when_to_use, argument-hint, arguments, disable-model-invocation, user-invocable, allowed-tools, disallowed-tools, model, effort, context, agent, background, hooks, paths, shell, metadata, license, compatibility |
commands/*.md | All of the skill fields except name and paths |
agents/*.md | name, description, tools, disallowedTools, model, permissionMode, maxTurns, skills, mcpServers, hooks, memory, background, effort, isolation, color, initialPrompt, omitClaudeMd, experimental |
output-styles/*.md | name, description, keep-coding-instructions, force-for-plugin |
rules/*.md | paths |
Agents shipped inside a plugin honour only a subset of the subagent fields; see plugin components. If something you configured is not taking effect, debug your configuration has a symptom-first checklist.
Data Claude Code writes
Besides your configuration, ~/.claude collects data as you work. All of it is plain text and not encrypted at rest. Anything that passes through a tool, including file contents, command output and pasted text, ends up in a transcript.
Swept automatically
Files under these paths are deleted once they are older than cleanupPeriodDays (default 30, minimum 1; 0 is rejected as invalid). The same cut-off removes orphaned worktrees.
Path under ~/.claude/ | What is in it |
|---|---|
projects/<project>/<session>.jsonl | The full transcript: messages, tool calls, tool results |
projects/<project>/<session>.orphaned-<timestamp>-<suffix>.jsonl and <session>.jsonl.superseded-<timestamp> | Earlier transcripts set aside rather than overwritten; hidden from the session picker |
projects/<project>/<session>/subagents/ | Subagent transcripts, removed with their parent |
projects/<project>/<session>/tool-results/ | Large tool outputs spilled to disk, and full-size images returned by MCP tools |
file-history/<session>/ | Pre-edit snapshots for checkpoint restore, covering the 100 most recent checkpoints (each file's first snapshot is always kept) |
plans/ | Plan files from plan mode |
debug/ | Debug logs, written when you start with --debug or run /debug |
paste-cache/ | Large pastes |
image-cache/<session>/ | Images attached in v2.1.274 and earlier. Newer versions store images in a per-session images/ folder under the temp directory set by CLAUDE_CODE_TMPDIR. Leftover directories here are swept regardless of age |
uploads/<session>/ | Files and photos attached from the web or mobile app to a Remote Control session. Cloud session attachments stay in the cloud environment |
dev-mods/<session>/ | Mods Claude wrote during the session |
session-env/ | Per-session environment metadata |
tasks/ | Task lists from the task tools |
shell-snapshots/ | Aliases, functions and shell options captured at startup for the Bash tool. Removed on clean exit; swept after a crash |
backups/ | The five most recent earlier versions of ~/.claude.json, plus any copy that failed to parse |
feedback-bundles/ | Redacted transcript archives from /feedback on third-party providers or without Anthropic credentials |
feedback/drafts/ | Feedback Claude has drafted for your review in /feedback; capped at 10, swept after cleanupPeriodDays or 30 days, whichever is shorter |
usage-data/ | /insights reports and the cached analysis behind them |
skills/.trash/, plugins/.trash/ | Skills and plugins removed by claude.ai sync, recoverable until swept |
plugins/installed_plugins.set-aside.<date>.<hash>.json, plugins/installed_plugins.unreadable.<date>.<hash>.kept | Copies made before rewriting the plugin install record |
todos/, statsig/, logs/ | Legacy folders no longer written; emptied and removed |
Some data follows its own rules:
sessions/holds one small file per running session to detect concurrency and crashes. Each file is removed when its session exits, and crash leftovers are cleared at the next launch.- Auto memory in
projects/<project>/memory/is never swept file by file; the folder is removed only after sitting empty for the whole retention period. (Before v2.1.228, subfolders inside it could be swept as if they were session data.) - Desktop and Cowork transcripts for sessions you started or last continued there are kept indefinitely unless you set
desktopSessionCleanupPeriodDays(v2.1.248 or later). They fall back tocleanupPeriodDayswhen managed settings set that value or when the HIPAA configuration applies to you.
The sweep does not run in claude -p --bare sessions. It also pauses itself when it cannot safely work out the retention period (the retention_sweep telemetry event lists the causes); if the cause is an unreadable settings file, or a settings error while cleanupPeriodDays or desktopSessionCleanupPeriodDays is explicitly set, /status shows a warning until it is fixed. When managed settings supply cleanupPeriodDays, the sweep runs at that value regardless. See monitoring usage for checking this across a fleet.
The session scratchpad
Each session gets a scratch folder for temporary files: intermediate results, helper scripts, drafts. Claude uses it instead of /tmp and can read and write there without prompting you. It lives under the temp directory, not ~/.claude:
| OS | Path |
|---|---|
| macOS | /private/tmp/claude-<uid>/<project>/<session-id>/scratchpad/ |
| Linux | /tmp/claude-<uid>/<project>/<session-id>/scratchpad/ (or under $TMPDIR if set) |
| Windows | %TEMP%\claude\<project>\<session-id>\scratchpad\ |
<project> is the working directory with every non-alphanumeric character replaced by -. CLAUDE_CODE_TMPDIR moves the whole tree. Hooks receive the path as scratchpad_dir. The scratchpad lives as long as the transcript, but the OS may clear it on restart, so ask Claude to move anything worth keeping into the project.
A scratchpad exists only when you are signed in with a claude.ai account (not an API key), using the Anthropic API rather than Bedrock, Google Cloud or Foundry, and enableArtifact is not false.
Kept until you delete them
Path under ~/.claude/ | Contents |
|---|---|
history.jsonl | Every prompt you typed, with timestamp and project, powering up-arrow recall, Ctrl+R search and ! completion. Trimmed to cleanupPeriodDays only under the HIPAA configuration |
stats-cache.json | Aggregated token and cost totals for /usage |
remote-settings.json | Cached server-managed settings (or {}), checked at startup and hourly, deleted on logout |
cache/changelog.md | Cached changelog for /release-notes |
policy-limits.json | Cached organisation feature policy, with a .stamp.json sidecar; deleted on logout |
Do not delete .credentials.json (your login), agent-memory/ (subagent memory) or jobs/ and daemon/ (background session state). Other caches and lock files are safe to remove.
Reducing exposure
- Lower
cleanupPeriodDays, and setdesktopSessionCleanupPeriodDaysfor desktop transcripts. - Set
CLAUDE_CODE_SKIP_PROMPT_HISTORYto stop writing transcripts and prompt history in any mode. For one-off scripts,claude -p --no-session-persistencedoes the same, as doespersistSession: falsein the TypeScript Agent SDK (the Python SDK has no equivalent). - Deny reads of credential files with permission rules.
Clearing a project's data
claude purge removes what Claude Code holds for one project: transcripts and auto memory under projects/, the session tasks/, debug/ and file-history/ entries, matching lines in history.jsonl, and the project's entry in ~/.claude.json. It shows the plan and asks before deleting. (Before v2.1.288 the command was claude project purge.)
claude purge ~/code/bookings --dry-run # show the plan only
claude purge ~/code/bookings # confirm, then delete
claude purge ~/code/bookings --yes # no prompt, for scripts
claude purge --all # every project; deletes history.jsonl entirely
claude purge -i # step through items one by one
Leave out the path to pick a project from a list. If nothing matches, it exits with status 1. It does not touch shell-snapshots/ or backups/ (not project-scoped), nor images and scratchpads in the temp directory. If anyone ran /heapdump, delete the .heapsnapshot files by hand: they contain the full conversation and any credentials in memory.
Deleting by hand
| Delete | You lose |
|---|---|
projects/ | Resume, continue and rewind for past sessions, plus auto memory everywhere |
history.jsonl | Prompt recall, history search and ! completion |
paste-cache/ | Pasted text inside recalled prompts |
uploads/ | Attachments past Remote Control sessions refer to |
file-history/ | Checkpoint restore for past sessions |
stats-cache.json | Historical /usage totals |
usage-data/ | Past /insights reports |
feedback-bundles/, feedback/drafts/ | Unsent feedback |
tasks/ | Task lists a resumed session would reload |
skills/.trash/, plugins/.trash/ | The chance to recover synced items |
remote-settings.json, cache/changelog.md, policy-limits.json | Nothing; they are refetched |
debug/, plans/, session-env/, shell-snapshots/, backups/, legacy folders | Nothing you will notice |
Never delete ~/.claude.json, ~/.claude/settings.json or ~/.claude/plugins/: they hold your login, preferences and installed plugins.