{"id":163917,"date":"2026-03-24T00:43:27","date_gmt":"2026-03-23T21:43:27","guid":{"rendered":"https:\/\/computingforgeeks.com\/?p=163917"},"modified":"2026-03-24T01:09:09","modified_gmt":"2026-03-23T22:09:09","slug":"claude-code-dot-claude-directory-guide","status":"publish","type":"post","link":"https:\/\/computingforgeeks.com\/claude-code-dot-claude-directory-guide\/","title":{"rendered":"The Complete .claude Directory Guide for Claude Code"},"content":{"rendered":"\n<p>Every Claude Code project has a <code>.claude<\/code> directory. Most people ignore it. That is a waste, because this one folder determines whether Claude remembers your coding standards, runs your workflows automatically, and stops asking you the same questions every session.<\/p>\n\n\n\n<p>This guide covers the full .claude directory structure: CLAUDE.md configuration, modular rules, custom slash commands, skills, subagents, permissions with settings.json, hooks, MCP servers, and the memory system. Each section includes working examples you can drop into your own projects. New to Claude Code? Start with our <a href=\"https:\/\/computingforgeeks.com\/claude-code-cheat-sheet\/\" target=\"_blank\" rel=\"noreferrer noopener\">Claude Code cheat sheet<\/a> first, then come back here.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Two Directories, Not One<\/h2>\n\n\n\n<p>There are actually two <code>.claude<\/code> directories in play, not one. The first lives inside your project and the second lives in your home directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>your-project\/.claude\/     # Team config - committed to git\n~\/.claude\/                # Personal config - never committed<\/code><\/pre>\n\n\n\n<p>The <strong>project-level<\/strong> folder holds team configuration. You commit it to git. Everyone on the team gets the same rules, commands, and permission policies. The <strong>user-level<\/strong> <code>~\/.claude\/<\/code> folder holds your personal preferences, session history, and auto-memory that persists across all your projects.<\/p>\n\n\n\n<p>Here is the complete structure of both directories:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>your-project\/\n\u251c\u2500\u2500 CLAUDE.md                      # Team instructions (committed)\n\u251c\u2500\u2500 CLAUDE.local.md                # Your personal overrides (gitignored)\n\u2514\u2500\u2500 .claude\/\n    \u251c\u2500\u2500 settings.json              # Permissions + config (committed)\n    \u251c\u2500\u2500 settings.local.json        # Personal permission overrides (gitignored)\n    \u251c\u2500\u2500 .mcp.json                  # MCP server configurations\n    \u251c\u2500\u2500 rules\/                     # Modular instruction files\n    \u2502   \u251c\u2500\u2500 code-style.md\n    \u2502   \u251c\u2500\u2500 testing.md\n    \u2502   \u2514\u2500\u2500 api-conventions.md\n    \u251c\u2500\u2500 commands\/                  # Custom slash commands\n    \u2502   \u251c\u2500\u2500 review.md              # becomes \/project:review\n    \u2502   \u2514\u2500\u2500 fix-issue.md           # becomes \/project:fix-issue\n    \u251c\u2500\u2500 skills\/                    # Auto-invoked workflows\n    \u2502   \u2514\u2500\u2500 deploy\/\n    \u2502       \u251c\u2500\u2500 SKILL.md\n    \u2502       \u2514\u2500\u2500 deploy-config.md\n    \u251c\u2500\u2500 agents\/                    # Specialized subagent personas\n    \u2502   \u251c\u2500\u2500 code-reviewer.md\n    \u2502   \u2514\u2500\u2500 security-auditor.md\n    \u2514\u2500\u2500 hooks\/                     # Event-driven automation scripts\n        \u2514\u2500\u2500 validate-bash.sh\n\n~\/.claude\/\n\u251c\u2500\u2500 CLAUDE.md                      # Global instructions (all projects)\n\u251c\u2500\u2500 settings.json                  # Global permissions\n\u251c\u2500\u2500 commands\/                      # Personal commands (\/user:cmd-name)\n\u251c\u2500\u2500 skills\/                        # Personal skills\n\u251c\u2500\u2500 agents\/                        # Personal agents\n\u2514\u2500\u2500 projects\/                      # Session history + auto-memory\n    \u2514\u2500\u2500 project-hash\/\n        \u2514\u2500\u2500 memory\/\n            \u2514\u2500\u2500 MEMORY.md<\/code><\/pre>\n\n\n\n<p>For git, commit <code>.claude\/settings.json<\/code>, <code>.claude\/rules\/<\/code>, <code>.claude\/commands\/<\/code>, <code>.claude\/skills\/<\/code>, and <code>.claude\/agents\/<\/code>. Add the personal and machine-local files to your <code>.gitignore<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># .gitignore - Claude Code personal files\nCLAUDE.local.md\n.claude\/settings.local.json\n.claude\/agent-memory-local\/<\/code><\/pre>\n\n\n\n<p>The full specification for every file is in the <a href=\"https:\/\/docs.anthropic.com\/en\/docs\/claude-code\/settings\" target=\"_blank\" rel=\"noreferrer noopener\">official Claude Code documentation<\/a>. The rest of this guide focuses on practical usage with real examples.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">CLAUDE.md: The Foundation<\/h2>\n\n\n\n<p>CLAUDE.md is the most important file in the entire system. Claude Code loads it into the system prompt at the start of every session and follows it for the entire conversation. Whatever you write in CLAUDE.md, Claude will follow &#8211; build commands, architecture decisions, coding conventions, and project-specific gotchas.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Loading Order and Priority<\/h3>\n\n\n\n<p>Claude Code loads instructions from multiple CLAUDE.md files and merges them. Higher priority wins when there is a conflict:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Priority (highest to lowest):\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  CLAUDE.local.md (project root)             \u2502  Highest - your personal overrides\n\u2502  \u2191 loaded on top of                         \u2502  gitignored, only you see this\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  CLAUDE.md (project root or .claude\/)       \u2502  Team instructions\n\u2502  \u2191 loaded on top of                         \u2502  committed to git\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  ~\/.claude\/CLAUDE.md                        \u2502  Your global preferences\n\u2502  \u2191 loaded on top of                         \u2502  applies to all projects\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502  Managed Policy (org-wide)                  \u2502  Lowest - IT-deployed\n\u2502  cannot be overridden                       \u2502  enforced on all users\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nAll layers combine \u2192 Claude sees everything as one system prompt<\/code><\/pre>\n\n\n\n<p>The managed policy layer is deployed by IT administrators at the OS level (<code>\/Library\/Application Support\/ClaudeCode\/CLAUDE.md<\/code> on macOS, <code>\/etc\/claude-code\/CLAUDE.md<\/code> on Linux). Most individual developers will not use this layer.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">What Belongs in CLAUDE.md<\/h3>\n\n\n\n<p>Keep CLAUDE.md under 200 lines. Files longer than that eat too much context and Claude&#8217;s instruction adherence drops. Write the things Claude cannot figure out by reading your code:<\/p>\n\n\n\n<p><strong>Include:<\/strong> Build\/test\/lint commands, architecture decisions, non-obvious gotchas, import conventions, naming patterns, error handling styles, and file structure for main modules.<\/p>\n\n\n\n<p><strong>Do not include:<\/strong> Anything that belongs in a linter or formatter config, full documentation you can link to, or long paragraphs explaining theory.<\/p>\n\n\n\n<p>Here is a real CLAUDE.md for a Node.js API project:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># Acme API\n\n## Commands\nnpm run dev          # Start dev server (port 3000)\nnpm run test         # Run tests (Vitest)\nnpm run lint         # ESLint + Prettier\nnpm run build        # TypeScript compile\nnpm run db:migrate   # Run Prisma migrations\nnpm run db:seed      # Seed test data\n\n## Architecture\n- Express REST API on Node 22 with TypeScript\n- PostgreSQL via Prisma ORM\n- Handlers in src\/handlers\/, middleware in src\/middleware\/\n- Shared types in src\/types\/\n- Tests mirror src\/ structure in tests\/\n\n## Conventions\n- Validate all request bodies with zod schemas\n- Return shape is always { data, error, meta }\n- Never expose stack traces in responses\n- Use the logger module (src\/lib\/logger.ts), not console.log\n- All database queries go through Prisma, no raw SQL\n\n## Important\n- Tests hit a real local database, not mocks. Run `npm run db:test:reset` first\n- Strict TypeScript: no unused imports, no any types\n- Every handler needs integration tests covering happy path + error cases<\/code><\/pre>\n\n\n\n<p>That is roughly 25 lines. It gives Claude everything it needs to work productively without constant clarification.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">CLAUDE.local.md for Personal Overrides<\/h3>\n\n\n\n<p>Create <code>CLAUDE.local.md<\/code> in your project root for preferences specific to you, not the team. Claude reads it alongside CLAUDE.md but it is automatically gitignored. Use it for things like your preferred editor commands, debugging shortcuts, or personal workflow tweaks.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Nested CLAUDE.md for Monorepos<\/h3>\n\n\n\n<p>In a monorepo, each package or service can have its own CLAUDE.md. These are lazy-loaded &#8211; Claude only reads them when it opens files in that directory:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>monorepo\/\n\u251c\u2500\u2500 CLAUDE.md                    # Root: shared conventions\n\u251c\u2500\u2500 packages\/\n\u2502   \u251c\u2500\u2500 frontend\/\n\u2502   \u2502   \u2514\u2500\u2500 CLAUDE.md            # React-specific rules\n\u2502   \u2514\u2500\u2500 backend\/\n\u2502       \u2514\u2500\u2500 CLAUDE.md            # API-specific rules\n\u2514\u2500\u2500 services\/\n    \u2514\u2500\u2500 auth\/\n        \u2514\u2500\u2500 CLAUDE.md            # Auth service specifics<\/code><\/pre>\n\n\n\n<p>You can also reference other files using the <code>@<\/code> import syntax: <code>@.\/docs\/architecture.md<\/code> or <code>@~\/.claude\/my-preferences.md<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The rules\/ Directory: Scaling Instructions<\/h2>\n\n\n\n<p>Once your CLAUDE.md grows past 200 lines, split it into focused rule files inside <code>.claude\/rules\/<\/code>. Every markdown file in this directory loads automatically alongside CLAUDE.md. The advantage: different team members own different rule files without stepping on each other.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.claude\/rules\/\n\u251c\u2500\u2500 code-style.md          # Loaded every session\n\u251c\u2500\u2500 testing.md             # Loaded every session\n\u251c\u2500\u2500 api-conventions.md     # Loaded only for src\/handlers\/**\n\u2514\u2500\u2500 security.md            # Loaded every session<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Path-Scoped Rules<\/h3>\n\n\n\n<p>The real power of rules is path scoping. Add a YAML frontmatter block with <code>paths:<\/code> and the rule only activates when Claude is working with matching files:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\npaths:\n  - \"src\/handlers\/**\/*.ts\"\n  - \"src\/middleware\/**\/*.ts\"\n---\n\n# API Design Rules\n\n- Every handler follows the pattern: validate -> execute -> respond\n- Use zod schemas colocated with the handler file\n- HTTP status codes: 200 (success), 201 (created), 400 (validation),\n  401 (auth), 404 (not found), 500 (server error)\n- Pagination uses cursor-based approach with { cursor, limit } params<\/code><\/pre>\n\n\n\n<p>Claude will not load this rule when editing a React component. It only loads when working inside <code>src\/handlers\/<\/code> or <code>src\/middleware\/<\/code>. Rules without a <code>paths:<\/code> field load unconditionally every session. This saves context window space by only loading relevant instructions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Custom Commands: Your Slash Commands<\/h2>\n\n\n\n<p>Every markdown file you drop into <code>.claude\/commands\/<\/code> becomes a custom slash command. The filename becomes the command name: <code>review.md<\/code> creates <code>\/project:review<\/code>, and <code>fix-issue.md<\/code> creates <code>\/project:fix-issue<\/code>.<\/p>\n\n\n\n<p>Here is a practical code review command. Create <code>.claude\/commands\/review.md<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\ndescription: Review the current branch diff for issues before merging\n---\n\n## Files Changed\n\n!`git diff --name-only main...HEAD`\n\n## Full Diff\n\n!`git diff main...HEAD`\n\nReview every changed file for:\n1. Missing input validation on new endpoints\n2. SQL injection or data exposure risks\n3. Missing or incomplete test coverage\n4. Performance issues (N+1 queries, missing indexes)\n5. Error handling gaps\n\nGive specific, actionable feedback per file. Flag blockers vs nice-to-haves.<\/code><\/pre>\n\n\n\n<p>The <code>!<\/code> backtick syntax is what makes commands powerful. It runs shell commands and injects the real output into the prompt before Claude sees it. When you type <code>\/project:review<\/code>, Claude receives the actual git diff &#8211; not a placeholder.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Passing Arguments to Commands<\/h3>\n\n\n\n<p>Use <code>$ARGUMENTS<\/code> to accept input after the command name. Here is a command that pulls a GitHub issue and fixes it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\ndescription: Investigate and fix a GitHub issue\nargument-hint: [issue-number]\n---\n\n## Issue Details\n\n!`gh issue view $ARGUMENTS --json title,body,labels,comments`\n\n## Related Code\n\nSearch the codebase for files related to this issue. Trace the bug to\nits root cause. Fix it and write a test that would have caught it.<\/code><\/pre>\n\n\n\n<p>Running <code>\/project:fix-issue 234<\/code> fetches issue #234 from GitHub and feeds it directly into the prompt. For personal commands that work across all projects, place them in <code>~\/.claude\/commands\/<\/code> &#8211; they show up as <code>\/user:command-name<\/code>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Skills: Auto-Invoked Workflows<\/h2>\n\n\n\n<p>Skills look similar to commands on the surface, but the trigger mechanism is fundamentally different:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Commands vs Skills:\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502         Commands            \u2502            Skills               \u2502\n\u251c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 You trigger manually        \u2502 Claude invokes automatically    \u2502\n\u2502 \/project:review             \u2502 based on task description       \u2502\n\u2502                             \u2502                                 \u2502\n\u2502 Always a single .md file    \u2502 A folder with SKILL.md +        \u2502\n\u2502                             \u2502 supporting files                \u2502\n\u2502                             \u2502                                 \u2502\n\u2502 Good for repeatable         \u2502 Good for context-aware          \u2502\n\u2502 manual workflows            \u2502 automatic workflows             \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n\nCommands wait for you. Skills watch the conversation and act\nwhen the moment is right.<\/code><\/pre>\n\n\n\n<p>Each skill lives in its own subdirectory with a <code>SKILL.md<\/code> file. Here is a deploy skill:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>.claude\/skills\/deploy\/\n\u251c\u2500\u2500 SKILL.md              # Required: main skill definition\n\u251c\u2500\u2500 deploy-config.md      # Supporting docs (referenced with @)\n\u2514\u2500\u2500 scripts\/\n    \u2514\u2500\u2500 deploy.sh         # Executable scripts Claude can run<\/code><\/pre>\n\n\n\n<p>The SKILL.md uses YAML frontmatter to define when and how the skill runs:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\nname: deploy\ndescription: Deploy the API to staging or production. Use when the user\n  says \"deploy\", \"ship it\", \"push to staging\", or \"release\".\nargument-hint: [staging|production]\nallowed-tools: Read, Bash, Grep\n---\n\n## Pre-deploy Checks\n\nRun these checks before deploying:\n\n!`npm run lint`\n!`npm run test`\n!`npm run build`\n\nIf any check fails, stop and report the issue. Do not deploy broken code.\n\n## Deploy\n\nTarget environment: $ARGUMENTS (default: staging)\n\nRead the deployment configuration from @deploy-config.md and execute\nthe deployment steps for the target environment.<\/code><\/pre>\n\n\n\n<p>When you say &#8220;deploy to staging&#8221;, Claude reads the description, recognizes it matches, and invokes the skill automatically. You can also call it explicitly with <code>\/deploy staging<\/code>.<\/p>\n\n\n\n<p>Key SKILL.md frontmatter fields:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Field<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>name<\/code><\/td><td>Skill identifier (lowercase, hyphens)<\/td><\/tr><tr><td><code>description<\/code><\/td><td>When to auto-invoke this skill<\/td><\/tr><tr><td><code>allowed-tools<\/code><\/td><td>Restrict which tools the skill can use<\/td><\/tr><tr><td><code>argument-hint<\/code><\/td><td>Show in autocomplete when typing \/skill-name<\/td><\/tr><tr><td><code>context: fork<\/code><\/td><td>Run in an isolated subagent context<\/td><\/tr><tr><td><code>model<\/code><\/td><td>Override the model (sonnet, haiku, opus)<\/td><\/tr><tr><td><code>user-invocable: false<\/code><\/td><td>Only Claude can invoke, not the user<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>The <code>@<\/code> reference syntax (<code>@deploy-config.md<\/code>) pulls in supporting files that live alongside SKILL.md. This is the key difference from commands: skills are packages with multiple files, commands are single files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Custom Agents: Specialized Subagents<\/h2>\n\n\n\n<p>When a task benefits from a dedicated specialist, define a subagent persona in <code>.claude\/agents\/<\/code>. Each agent runs in its own isolated context window &#8211; it does its work, compresses the findings, and reports back without cluttering your main session.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>How subagents work:\n\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502        Main Agent            \u2502  Your conversation\n\u2502  (context filling up)        \u2502\n\u2502                              \u2502\n\u2502  \"spawns subagent            \u2502\n\u2502   with task\"                 \u2502\n\u2502         \u2502                    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n          \u2502\n          \u25bc\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502  Subagent: code-reviewer     \u2502  Fresh context window\n\u2502  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510     \u2502  Fully isolated\n\u2502  \u2502 system prompt +     \u2502     \u2502\n\u2502  \u2502 this task only      \u2502     \u2502\n\u2502  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518     \u2502\n\u2502                              \u2502\n\u2502  Explores, reads, analyzes   \u2502\n\u2502  All exploration stays here  \u2502\n\u2502         \u2502                    \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n          \u2502\n          \u25bc returns compressed findings\n\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502        Main Agent            \u2502\n\u2502  Gets only the answer,       \u2502\n\u2502  not the 10k tokens of       \u2502\n\u2502  exploration                 \u2502\n\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518<\/code><\/pre>\n\n\n\n<p>Here is a code reviewer agent. Create <code>.claude\/agents\/code-reviewer.md<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\nname: code-reviewer\ndescription: Expert code reviewer. Use PROACTIVELY when reviewing PRs,\n  checking implementations, or validating code before merging.\nmodel: sonnet\ntools: Read, Grep, Glob\n---\n\nYou are a senior code reviewer focused on correctness and maintainability.\n\nWhen reviewing code:\n- Flag bugs and logic errors, not just style issues\n- Suggest specific fixes with code, not vague improvements\n- Check for edge cases: null values, empty arrays, concurrent access\n- Note performance concerns only when they matter at scale\n- Verify error handling covers all failure modes\n- Check that new code has corresponding tests<\/code><\/pre>\n\n\n\n<p>The <code>tools<\/code> field restricts what the agent can do. A security auditor only needs <code>Read<\/code>, <code>Grep<\/code>, and <code>Glob<\/code> &#8211; it has no business writing files. The <code>model<\/code> field lets you use a cheaper, faster model for focused tasks. Haiku handles most read-only exploration well. Save Sonnet and Opus for work that needs deeper reasoning.<\/p>\n\n\n\n<p>Key agent frontmatter fields:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Field<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>name<\/code><\/td><td>Agent identifier<\/td><\/tr><tr><td><code>description<\/code><\/td><td>When Claude should delegate to this agent<\/td><\/tr><tr><td><code>model<\/code><\/td><td>haiku (fast\/cheap), sonnet (balanced), opus (complex tasks)<\/td><\/tr><tr><td><code>tools<\/code><\/td><td>Allowlist of tools the agent can use<\/td><\/tr><tr><td><code>disallowedTools<\/code><\/td><td>Denylist (removes from inherited tools)<\/td><\/tr><tr><td><code>maxTurns<\/code><\/td><td>Maximum agentic turns before stopping<\/td><\/tr><tr><td><code>memory<\/code><\/td><td>Persistent memory scope: user, project, or local<\/td><\/tr><tr><td><code>isolation: worktree<\/code><\/td><td>Run in an isolated git worktree<\/td><\/tr><tr><td><code>background: true<\/code><\/td><td>Run as a background task<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">settings.json: Permissions and Config<\/h2>\n\n\n\n<p>The <code>.claude\/settings.json<\/code> file controls what Claude is allowed to do. It defines which tools run automatically, which are blocked entirely, and which require confirmation.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"$schema\": \"https:\/\/json.schemastore.org\/claude-code-settings.json\",\n  \"permissions\": {\n    \"allow\": [\n      \"Bash(npm run *)\",\n      \"Bash(npx prisma *)\",\n      \"Bash(git status)\",\n      \"Bash(git diff *)\",\n      \"Bash(git log *)\",\n      \"Read\",\n      \"Write\",\n      \"Edit\",\n      \"Glob\",\n      \"Grep\"\n    ],\n    \"deny\": [\n      \"Bash(rm -rf *)\",\n      \"Bash(curl *)\",\n      \"Bash(wget *)\",\n      \"Read(.env)\",\n      \"Read(.env.*)\"\n    ]\n  },\n  \"env\": {\n    \"NODE_ENV\": \"development\"\n  }\n}<\/code><\/pre>\n\n\n\n<p>The <strong>allow<\/strong> list contains tools that run without asking for confirmation. The <strong>deny<\/strong> list contains tools blocked entirely. Anything not in either list requires confirmation before proceeding &#8211; that middle ground is intentional as a safety net.<\/p>\n\n\n\n<p>The <code>$schema<\/code> line enables autocomplete and inline validation in VS Code and Cursor. Always include it.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Settings Hierarchy<\/h3>\n\n\n\n<p>Settings merge from multiple scopes. Later scopes override earlier ones, except managed policy which cannot be overridden:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Merge order (last wins):\n\n1. Managed Policy     # Enforced by IT, cannot override\n2. ~\/.claude\/settings.json       # Your global defaults\n3. .claude\/settings.json         # Project team settings\n4. .claude\/settings.local.json   # Your local overrides (gitignored)<\/code><\/pre>\n\n\n\n<p>Arrays merge (allow\/deny lists combine from all scopes). Use <code>.claude\/settings.local.json<\/code> for permission changes you do not want committed to git.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Hooks: Event-Driven Automation<\/h2>\n\n\n\n<p>Hooks let you run code in response to Claude Code events &#8211; before a tool runs, after a session starts, when a permission is requested, and more. This is the feature most articles about the <code>.claude<\/code> directory miss entirely.<\/p>\n\n\n\n<p>Hooks are defined in <code>settings.json<\/code> and can trigger shell scripts, HTTP requests, model prompts, or subagents:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"hooks\": {\n    \"PreToolUse\": [\n      {\n        \"matcher\": \"Bash\",\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \".claude\/hooks\/validate-bash.sh\",\n            \"timeout\": 10\n          }\n        ]\n      }\n    ],\n    \"SessionStart\": [\n      {\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \".claude\/hooks\/setup-env.sh\"\n          }\n        ]\n      }\n    ]\n  }\n}<\/code><\/pre>\n\n\n\n<p>The <code>validate-bash.sh<\/code> hook runs before every Bash command. It receives the command as JSON on stdin and can block dangerous operations:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n# .claude\/hooks\/validate-bash.sh\nINPUT=$(cat)\nCOMMAND=$(echo \"$INPUT\" | jq -r '.tool_input.command \/\/ empty')\n\n# Block destructive commands\nif echo \"$COMMAND\" | grep -qE '(rm -rf \/|DROP DATABASE|truncate)'; then\n  echo '{\"decision\": \"block\", \"reason\": \"Destructive command blocked\"}'\n  exit 2\nfi\n\n# Block commands that leak secrets\nif echo \"$COMMAND\" | grep -qE '(cat.*\\.env|echo.*PASSWORD)'; then\n  echo '{\"decision\": \"block\", \"reason\": \"Command may expose secrets\"}'\n  exit 2\nfi\n\necho '{\"decision\": \"allow\"}'<\/code><\/pre>\n\n\n\n<p>Available hook events:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Event<\/th><th>When It Fires<\/th><\/tr><\/thead><tbody><tr><td><code>SessionStart<\/code><\/td><td>Session begins (setup env, load context)<\/td><\/tr><tr><td><code>SessionEnd<\/code><\/td><td>Session ends (cleanup, reporting)<\/td><\/tr><tr><td><code>PreToolUse<\/code><\/td><td>Before any tool executes (validate, block, modify)<\/td><\/tr><tr><td><code>PostToolUse<\/code><\/td><td>After a tool executes (logging, alerts)<\/td><\/tr><tr><td><code>UserPromptSubmit<\/code><\/td><td>When user sends a message<\/td><\/tr><tr><td><code>Stop<\/code><\/td><td>When Claude finishes responding<\/td><\/tr><tr><td><code>Notification<\/code><\/td><td>When a notification is sent<\/td><\/tr><tr><td><code>SubagentStart<\/code><\/td><td>When a subagent spawns<\/td><\/tr><tr><td><code>SubagentStop<\/code><\/td><td>When a subagent finishes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Hook types include <code>command<\/code> (shell script), <code>http<\/code> (webhook), <code>prompt<\/code> (model evaluation), and <code>agent<\/code> (subagent task). Exit code 0 means success, exit code 2 means block the action, and the hook&#8217;s stdout is parsed as JSON.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">MCP Servers: Extending Claude&#8217;s Tools<\/h2>\n\n\n\n<p>The Model Context Protocol (MCP) lets you give Claude access to external tools and data sources &#8211; databases, APIs, file systems, and more. Configure MCP servers in <code>.claude\/.mcp.json<\/code>:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>[\n  {\n    \"name\": \"filesystem\",\n    \"type\": \"stdio\",\n    \"command\": \"npx\",\n    \"args\": [\"@modelcontextprotocol\/server-filesystem\", \"\/path\/to\/allowed\/dir\"]\n  },\n  {\n    \"name\": \"postgres\",\n    \"type\": \"stdio\",\n    \"command\": \"npx\",\n    \"args\": [\"@modelcontextprotocol\/server-postgres\"],\n    \"env\": {\n      \"DATABASE_URL\": \"postgresql:\/\/user:pass@localhost:5432\/mydb\"\n    }\n  },\n  {\n    \"name\": \"github\",\n    \"type\": \"stdio\",\n    \"command\": \"npx\",\n    \"args\": [\"@modelcontextprotocol\/server-github\"],\n    \"env\": {\n      \"GITHUB_TOKEN\": \"$GITHUB_TOKEN\"\n    }\n  }\n]<\/code><\/pre>\n\n\n\n<p>MCP servers run as local processes. The <code>stdio<\/code> type launches a command and communicates over stdin\/stdout. Other types include <code>http<\/code> (REST endpoint), <code>sse<\/code> (server-sent events), and <code>ws<\/code> (WebSocket). You can also define MCP servers inline within agent configurations using the <code>mcpServers<\/code> field. MCP is part of a broader trend of <a href=\"https:\/\/computingforgeeks.com\/top-10-ai-tools-for-developers\/\" target=\"_blank\" rel=\"noreferrer noopener\">AI-powered developer tools<\/a> that extend what coding assistants can do beyond just reading and writing files.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The Memory System<\/h2>\n\n\n\n<p>Claude Code has a persistent memory system that stores notes across sessions. There are two types of memory:<\/p>\n\n\n\n<p><strong>Auto-memory<\/strong> lives in <code>~\/.claude\/projects\/&lt;project-hash&gt;\/memory\/<\/code>. Claude automatically saves useful observations as it works &#8211; commands it discovers, patterns it notices, architecture insights. You can browse and edit these with <code>\/memory<\/code>. The <code>MEMORY.md<\/code> file acts as an index, and individual memory files store specific topics.<\/p>\n\n\n\n<p><strong>Agent memory<\/strong> gives subagents their own persistent knowledge base. Agents configured with <code>memory: project<\/code> store memories in <code>.claude\/agent-memory\/&lt;agent-name&gt;\/<\/code> (shared with the team), while <code>memory: local<\/code> stores in <code>.claude\/agent-memory-local\/&lt;agent-name&gt;\/<\/code> (personal, gitignored).<\/p>\n\n\n\n<p>The memory system uses a specific file format with YAML frontmatter:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>---\nname: user-preferences\ndescription: How the user prefers code to be written\ntype: feedback\n---\n\nAlways use functional patterns over class-based.\nNever add trailing summaries after completing a task.\n\n**Why:** User explicitly corrected this behavior twice.\n**How to apply:** After finishing any code task, stop. Do not summarize.<\/code><\/pre>\n\n\n\n<p>Memory types include <code>user<\/code> (about the person), <code>feedback<\/code> (corrections and preferences), <code>project<\/code> (ongoing work context), and <code>reference<\/code> (pointers to external resources). Claude uses these to stay consistent across sessions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">When to Use What: Decision Guide<\/h2>\n\n\n\n<p>With six different configuration mechanisms, choosing the right one matters. Here is a practical decision guide:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>What are you trying to do?\n\u2502\n\u251c\u2500 Give Claude instructions about your project\n\u2502  \u251c\u2500 Under 200 lines total? \u2192 CLAUDE.md\n\u2502  \u251c\u2500 Over 200 lines? \u2192 Split into .claude\/rules\/ files\n\u2502  \u2514\u2500 Only for certain file types? \u2192 rules\/ with paths: frontmatter\n\u2502\n\u251c\u2500 Create a repeatable workflow you trigger manually\n\u2502  \u2514\u2500 .claude\/commands\/workflow-name.md\n\u2502\n\u251c\u2500 Create a workflow Claude triggers automatically\n\u2502  \u2514\u2500 .claude\/skills\/skill-name\/SKILL.md\n\u2502\n\u251c\u2500 Delegate to a specialist with its own context\n\u2502  \u2514\u2500 .claude\/agents\/specialist-name.md\n\u2502\n\u251c\u2500 Control what Claude can and cannot do\n\u2502  \u2514\u2500 .claude\/settings.json (permissions allow\/deny)\n\u2502\n\u251c\u2500 Run code when specific events happen\n\u2502  \u2514\u2500 Hooks in settings.json + .claude\/hooks\/ scripts\n\u2502\n\u251c\u2500 Give Claude access to external tools\/databases\n\u2502  \u2514\u2500 .claude\/.mcp.json\n\u2502\n\u2514\u2500 Remember things across sessions\n   \u2514\u2500 Memory system (~\/.claude\/projects\/...\/memory\/)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Getting Started: A Practical Progression<\/h2>\n\n\n\n<p>Do not try to set up everything at once. Here is a progression that works well:<\/p>\n\n\n\n<p><strong>Step 1:<\/strong> Run <code>\/init<\/code> inside Claude Code. It generates a starter CLAUDE.md by reading your project. Edit it down to the essentials &#8211; build commands, architecture, conventions, gotchas.<\/p>\n\n\n\n<p><strong>Step 2:<\/strong> Add <code>.claude\/settings.json<\/code> with allow\/deny rules appropriate for your stack. At minimum, allow your run commands and deny <code>.env<\/code> reads and destructive shell commands.<\/p>\n\n\n\n<p><strong>Step 3:<\/strong> Create one or two commands for the workflows you repeat most. Code review and issue fixing are good starting points.<\/p>\n\n\n\n<p><strong>Step 4:<\/strong> When CLAUDE.md gets crowded, start splitting instructions into <code>.claude\/rules\/<\/code> files. Scope them by file path where it makes sense.<\/p>\n\n\n\n<p><strong>Step 5:<\/strong> Add skills and agents when you have recurring complex workflows worth packaging. A deploy skill, a security audit agent, and a database explorer agent are common first additions.<\/p>\n\n\n\n<p>That covers 95% of projects. Hooks and MCP servers come in when you need event-driven automation or external tool integration.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Troubleshooting Common Issues<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">CLAUDE.md not loading or instructions being ignored<\/h3>\n\n\n\n<p>Check the file location. Claude Code looks for <code>CLAUDE.md<\/code> at the project root or inside <code>.claude\/CLAUDE.md<\/code>. If it is in a subdirectory without being at the root level, it will only lazy-load when Claude opens files in that directory. Also verify your CLAUDE.md is not too long &#8211; files over 200 lines cause adherence to drop.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Path-scoped rules not applying to specific files<\/h3>\n\n\n\n<p>The <code>paths:<\/code> field uses glob patterns. Common mistakes: using <code>src\/*.ts<\/code> when you mean <code>src\/**\/*.ts<\/code> (the double star matches nested directories), or forgetting the file extension. Test your glob pattern with <code>find src -name \"*.ts\"<\/code> and compare.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Custom commands not showing up<\/h3>\n\n\n\n<p>Commands must be in <code>.claude\/commands\/<\/code> (project) or <code>~\/.claude\/commands\/<\/code> (personal). The file must be markdown (<code>.md<\/code>) and the filename becomes the command name. Project commands appear as <code>\/project:name<\/code> and personal commands as <code>\/user:name<\/code>. Try restarting the Claude Code session after adding new commands.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Skills not auto-invoking<\/h3>\n\n\n\n<p>Auto-invocation depends on the <code>description<\/code> field in SKILL.md. If the description does not match what the user is asking, Claude will not trigger it. Write descriptions that include the exact phrases users say: &#8220;deploy&#8221;, &#8220;ship it&#8221;, &#8220;push to staging&#8221;. You can also set <code>disable-model-invocation: true<\/code> to make a skill manual-only.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Hook script not running or returning errors<\/h3>\n\n\n\n<p>Make sure the hook script is executable (<code>chmod +x .claude\/hooks\/script.sh<\/code>). Hooks receive JSON on stdin and must output JSON on stdout. Exit code 0 means success, exit code 2 means block the action. Any other exit code is treated as a non-blocking error. Test your hook script manually: <code>echo '{\"tool_name\":\"Bash\",\"tool_input\":{\"command\":\"ls\"}}' | .claude\/hooks\/validate-bash.sh<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusion<\/h2>\n\n\n\n<p>The <code>.claude<\/code> directory is a protocol for telling Claude who you are, what your project does, and what rules to follow. CLAUDE.md is the highest-leverage file &#8211; get that right first. Rules split your instructions as they grow. Commands automate your manual workflows. Skills handle context-aware automation. Agents delegate specialized work. Settings control permissions. Hooks react to events. And the memory system keeps Claude consistent across sessions. Start small with CLAUDE.md and settings.json, then add complexity as your project needs it.<\/p>\n\n\n","protected":false},"excerpt":{"rendered":"<p>Every Claude Code project has a .claude directory. Most people ignore it. That is a waste, because this one folder determines whether Claude remembers your coding standards, runs your workflows automatically, and stops asking you the same questions every session. This guide covers the full .claude directory structure: CLAUDE.md configuration, modular rules, custom slash commands, &#8230; <a title=\"The Complete .claude Directory Guide for Claude Code\" class=\"read-more\" href=\"https:\/\/computingforgeeks.com\/claude-code-dot-claude-directory-guide\/\" aria-label=\"Read more about The Complete .claude Directory Guide for Claude Code\">Read more<\/a><\/p>\n","protected":false},"author":3,"featured_media":163930,"comment_status":"open","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[39034,299],"tags":[],"class_list":["post-163917","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ai","category-how-to"],"_links":{"self":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/163917","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/comments?post=163917"}],"version-history":[{"count":3,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/163917\/revisions"}],"predecessor-version":[{"id":163951,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/posts\/163917\/revisions\/163951"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media\/163930"}],"wp:attachment":[{"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/media?parent=163917"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/categories?post=163917"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/computingforgeeks.com\/wp-json\/wp\/v2\/tags?post=163917"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}