Skip to content

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 /memory to open it from inside a session.
  • It can live at .claude/CLAUDE.md instead if you like a tidy root.
  • If the repo already has an AGENTS.md for 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:

KeyPurpose
permissionsAllow, deny or ask before particular tools or commands
hooksRun your scripts at lifecycle events
statusLineCustomise the status line at the bottom of the terminal
modelDefault model for this project
envEnvironment variables set in every session
outputStyleSelect 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, $1 and 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 description decides 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

FileWherePurpose
managed-settings.jsonA system path that depends on the OSOrganisation-enforced settings that your own files and --settings cannot override, with narrow exceptions. See managed settings
CLAUDE.local.mdProject rootYour private notes for this project, loaded with CLAUDE.md. Create it yourself and add it to .gitignore
AGENTS.mdProject root, .claude/ or any folderAgent instructions that Claude Code can load instead of CLAUDE.md
Installed plugins~/.claude/pluginsCloned 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?

GoalFileScope
Tell Claude about the project and its conventionsCLAUDE.mdProject or global
Allow or block a tool or commandsettings.json (permissions, or a hooks guard)Project or global
Run a script around tool callssettings.json (hooks)Project or global
Set session environment variablessettings.json (env)Project or global
Keep a personal tweak out of gitsettings.local.jsonProject
Add a /name workflowskills/<name>/SKILL.mdProject or global
Define a specialist subagentagents/*.mdProject or global
Orchestrate many subagentsworkflows/*.jsProject or global
Connect an MCP server for the team.mcp.jsonProject
Change how responses are writtenoutput-styles/*.mdProject 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

FileFields it understands
skills/<name>/SKILL.mdname, 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/*.mdAll of the skill fields except name and paths
agents/*.mdname, description, tools, disallowedTools, model, permissionMode, maxTurns, skills, mcpServers, hooks, memory, background, effort, isolation, color, initialPrompt, omitClaudeMd, experimental
output-styles/*.mdname, description, keep-coding-instructions, force-for-plugin
rules/*.mdpaths

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>.jsonlThe 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>.keptCopies 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 to cleanupPeriodDays when 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:

OSPath
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.jsonlEvery 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.jsonAggregated token and cost totals for /usage
remote-settings.jsonCached server-managed settings (or {}), checked at startup and hourly, deleted on logout
cache/changelog.mdCached changelog for /release-notes
policy-limits.jsonCached 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 set desktopSessionCleanupPeriodDays for desktop transcripts.
  • Set CLAUDE_CODE_SKIP_PROMPT_HISTORY to stop writing transcripts and prompt history in any mode. For one-off scripts, claude -p --no-session-persistence does the same, as does persistSession: false in 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

DeleteYou lose
projects/Resume, continue and rewind for past sessions, plus auto memory everywhere
history.jsonlPrompt 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.jsonHistorical /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.jsonNothing; they are refetched
debug/, plans/, session-env/, shell-snapshots/, backups/, legacy foldersNothing you will notice

Never delete ~/.claude.json, ~/.claude/settings.json or ~/.claude/plugins/: they hold your login, preferences and installed plugins.