CC-103: Configuration Blueprint
Listen instead
Overview: What You Will Learn
Configuration is how you turn Claude Code from a generic coding assistant into a purpose-built agent for your specific project, team, and workflow. This module covers every configuration surface available: the CLAUDE.md file hierarchy, the settings.json structure, permission management, environment variables, hooks, MCP server integration, model selection, and memory patterns.
By the end of this module, you will be able to build a complete configuration blueprint from scratch for any project -- one that encodes your conventions, protects your safety boundaries, and maximizes Claude Code's effectiveness from the first prompt of every session.
The CLAUDE.md File Hierarchy
CLAUDE.md files are the primary mechanism for injecting persistent instructions into Claude Code's system prompt. They form a layered hierarchy where more specific files augment and override more general ones.
Layer 1: Global User Configuration
# ~/.claude/CLAUDE.md
# Applies to EVERY project you open with Claude Code
## Core Preferences
- Use TypeScript strict mode. No `any` types.
- Prefer functional patterns over class-based.
- Always handle errors explicitly. No swallowed catches.
- Commit messages follow Conventional Commits format.
- Never use `console.log` in production code. Use structured logger.
## Testing Standards
- Write tests alongside implementation, not after.
- Minimum coverage: 80% lines, 70% branches.
- Use descriptive test names: "should [verb] when [condition]".
## Security Baseline
- Never hardcode secrets or credentials.
- Validate all user input with Zod schemas.
- Sanitize HTML output to prevent XSS.
- Use parameterized queries. Never concatenate SQL.
This file travels with you across every project. It is your personal engineering standards document that Claude Code reads at the start of every session.
Layer 2: Project Root Configuration
# ./CLAUDE.md (project root)
# Applies to this specific repository
## Project Context
- Stack: Next.js 16, React 19, Tailwind 4, Drizzle ORM, PostgreSQL 16
- Architecture: API routes in src/api/v1/, pages in src/app/
- Auth: JWT httpOnly cookies, 15-minute access tokens, 7-day refresh tokens
## Database Conventions
- Table names: camelCase (e.g., requirementSpecs)
- FK columns: always validate org ownership before INSERT/UPDATE
- Every UPDATE/DELETE WHERE clause includes organizationId (TOCTOU protection)
- Drizzle ORM 0.33 index syntax: (table) => ({...})
## API Patterns
- authenticateRequest(request) for auth checks
- requirePermission(authResult, 'resource.action') for RBAC
- handleApiError(error) in every catch block
- parsePagination(searchParams) for list endpoints
- Every query must have .limit() -- no unbounded queries
## Known Gotchas
- Drizzle gt(column, value) -- column is always the first argument
- Content-Type enforcement must skip no-body POSTs (refresh, logout)
- useSearchParams() requires a Suspense boundary
This is where you encode everything a new developer (human or AI) needs to know about this specific codebase. The gotchas section is especially valuable -- it prevents Claude Code from hitting the same pitfalls your team has already discovered.
Layer 3: Subdirectory Configuration
# ./src/api/CLAUDE.md
# Applies only when Claude Code is working in the API directory
## API Route Requirements
- Every route handler must have try/catch with handleApiError
- Every PATCH handler needs Zod validation -- never destructure raw body
- Every [id] route needs validateUuid(id) check
- Rate limiting required on: auth routes, export, import, scans
- Use boundedJsonb instead of raw z.record(z.unknown())
Subdirectory CLAUDE.md files let you add context-specific rules without cluttering the project-level file. They activate automatically when Claude Code works in that directory.
Load Order and Precedence
~/.claude/CLAUDE.md-- Global (loaded first, lowest precedence)./CLAUDE.md-- Project root (overrides global)./src/CLAUDE.md-- Subdirectory (overrides project for work in /src)./.claude/settings.json-- Project settings (permissions, model config)
When instructions conflict, the more specific file wins. If your global CLAUDE.md says "use Jest" but your project CLAUDE.md says "use Vitest," Claude Code uses Vitest for that project.
The settings.json Structure
While CLAUDE.md files contain natural language instructions, settings.json provides structured configuration that controls Claude Code's runtime behavior. There are two levels:
# User-level settings (applies globally)
~/.claude/settings.json
# Project-level settings (applies to this repo only)
./.claude/settings.json
Complete Settings Reference
{
"permissions": {
"allow": [
"Read",
"Edit",
"Glob",
"Grep",
"Bash(npm test*)",
"Bash(npm run build*)",
"Bash(npm run lint*)",
"Bash(git status)",
"Bash(git diff*)",
"Bash(git log*)",
"Bash(git branch*)",
"Bash(npx drizzle-kit*)"
],
"deny": [
"Bash(rm -rf*)",
"Bash(git push --force*)",
"Bash(git reset --hard*)",
"Bash(curl*)",
"Bash(wget*)",
"Bash(npm publish*)"
]
},
"model": "claude-sonnet-4-20250514",
"contextWindow": {
"compactThreshold": 80
}
}
Permission Configuration Deep Dive
The permission system is Claude Code's safety mechanism. It determines what the agent can do autonomously versus what requires your explicit approval.
Permission Categories
| Category | Allow Example | Risk Level |
|---|---|---|
| File Reading | Read | Low -- read-only operations |
| File Search | Glob, Grep | Low -- read-only search |
| File Editing | Edit, Write | Medium -- modifies files |
| Safe Commands | Bash(npm test*) | Medium -- executes code |
| Build Commands | Bash(npm run build*) | Medium -- executes code |
| Git Read | Bash(git log*) | Low -- read-only |
| Git Write | Bash(git commit*) | Medium -- creates commits |
| Network | Bash(curl*) | High -- external requests |
| Destructive | Bash(rm -rf*) | Critical -- data loss |
Pattern Matching Rules
Permission patterns use prefix matching with wildcards:
# Exact match
"Bash(npm test)" # Only "npm test", nothing else
# Wildcard suffix
"Bash(npm test*)" # "npm test", "npm test -- --coverage",
# "npm test -- --grep auth"
# Tool-level allow
"Read" # All Read operations, any file
# Specific denial
"Bash(git push --force*)" # Blocks force push but allows regular push
Environment Variables
Claude Code respects several environment variables that control its behavior without requiring settings files:
# API configuration
export ANTHROPIC_API_KEY="sk-ant-..."
# Model override
export CLAUDE_MODEL="claude-sonnet-4-20250514"
# Proxy configuration (for corporate networks)
export HTTPS_PROXY="http://proxy.internal:8080"
# Disable telemetry
export CLAUDE_CODE_DISABLE_TELEMETRY=1
Environment variables override settings.json values, which makes them useful for CI/CD environments where you need different configuration per pipeline without modifying project files.
Hooks Configuration
Hooks let you run custom logic at specific points in Claude Code's execution cycle. They are configured in settings.json and execute shell commands.
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"command": "echo 'Tool: Bash' >> /tmp/claude-audit.log"
}
],
"PostToolUse": [
{
"matcher": "Edit",
"command": "npm run lint --fix $(echo $CLAUDE_FILE_PATH)"
}
],
"PreCompact": [
{
"command": "echo 'Context compacting at $(date)' >> /tmp/claude-sessions.log"
}
]
}
}
Available Hook Points
- PreToolUse -- Fires before a tool is executed. Use for auditing, validation, or injection of additional context.
- PostToolUse -- Fires after a tool completes. Use for auto-formatting, linting, or logging results.
- PreCompact -- Fires before context compaction. Use for saving session state or triggering memory persistence.
- SessionStart -- Fires when a new session begins. Use for loading context, checking prerequisites, or initializing state.
Hooks are powerful but they run synchronously and can slow down the agent if they take too long. Keep hook commands fast -- under 2 seconds is the practical limit before the delay becomes noticeable.
MCP Server Setup
The Model Context Protocol (MCP) lets Claude Code connect to external tool servers that extend its capabilities beyond the built-in toolbelt. MCP servers can provide access to databases, APIs, specialized tools, or any service you want Claude Code to interact with.
Configuring MCP Servers
# In .claude/settings.json or ~/.claude/settings.json
{
"mcpServers": {
"memory": {
"command": "npx",
"args": ["-y", "@anthropic/claude-memory-mcp"],
"env": {
"MEMORY_STORE_PATH": "/path/to/memory/store"
}
},
"github": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-github"],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
}
},
"postgres": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${DATABASE_URL}"
}
}
}
}
Each MCP server runs as a subprocess and registers its tools with Claude Code at session start. The agent then has access to those tools alongside its built-in ones, and can use them in the same agentic loop.
MCP Security Considerations
- Environment variable references -- Use
${VAR_NAME}syntax to reference secrets from the environment rather than hardcoding them in settings files. - Permission scope -- MCP tools inherit the same permission model as built-in tools. You can allow or deny specific MCP tool calls in your permissions config.
- Network access -- MCP servers may make network requests. Audit each server's behavior before adding it to your configuration.
- Version pinning -- Use specific versions in your npx args rather than relying on
@latestto prevent unexpected behavior changes.
Model Selection
Claude Code supports multiple models, each with different capability and cost profiles:
| Model | Best For | Context Window |
|---|---|---|
claude-sonnet-4-20250514 | Day-to-day coding, fast iteration | 200K tokens |
claude-opus-4-20250514 | Complex architecture, difficult debugging | 200K tokens |
You can switch models mid-session using the /model slash command, or set a default in settings.json or via the CLAUDE_MODEL environment variable. A practical pattern is to use Sonnet for routine work and switch to Opus when tackling complex architectural decisions or difficult debugging sessions.
Memory Configuration Patterns
Memory extends Claude Code's effectiveness across sessions. While Claude Code itself does not persist conversation state between sessions, you can build memory systems using CLAUDE.md files and MCP servers.
Pattern 1: CLAUDE.md as Living Documentation
# End of each session, ask Claude Code:
"Update the project CLAUDE.md with any new patterns, gotchas,
or conventions we discovered during this session."
This turns your CLAUDE.md into a growing knowledge base that improves with every session. New sessions start with all accumulated knowledge.
Pattern 2: MCP Memory Server
# Configure a memory MCP server for persistent recall
{
"mcpServers": {
"memory": {
"command": "npx",
"args": ["-y", "@anthropic/claude-memory-mcp"],
"env": {
"MEMORY_STORE_PATH": "~/.claude/memory"
}
}
}
}
A memory MCP server gives Claude Code the ability to store and recall information across sessions without modifying CLAUDE.md. This is useful for temporary context, session notes, and project state that does not belong in committed configuration files.
Pattern 3: Structured Project State
# In CLAUDE.md, maintain a structured state section:
## Current Sprint State
- Feature: OAuth2 integration
- Phase: 3 of 5 (token refresh implementation)
- Completed: provider abstraction, authorization flow, token storage
- Remaining: token refresh, session management
- Blockers: none
- Last session: 2026-03-22, implemented token storage with encryption
This pattern gives Claude Code immediate context on where you left off, what decisions were made, and what comes next -- without the agent needing to analyze git history or read through code to reconstruct the state.
Putting It All Together: A Complete Configuration Blueprint
Here is the complete file structure for a well-configured project:
project-root/
CLAUDE.md # Project context, conventions, gotchas
.claude/
settings.json # Permissions, model, hooks, MCP servers
src/
api/
CLAUDE.md # API-specific rules and patterns
app/
CLAUDE.md # Frontend-specific conventions
~/.claude/
CLAUDE.md # Global personal preferences
settings.json # Global permissions and defaults
Best Practices
- Start with a minimal CLAUDE.md and grow it. Do not try to document everything on day one. Add entries as you discover patterns and gotchas during real work.
- Keep permissions tight by default. Allow the tools you use frequently. Leave everything else at the approval-prompt level. Only deny things that are genuinely dangerous.
- Use environment variables for secrets. Never put API keys or credentials in settings.json or CLAUDE.md. Reference them via
${VAR_NAME}syntax. - Version control your configuration. Both CLAUDE.md and
.claude/settings.jsonshould be committed to git (excluding any files that might contain secrets). This gives your entire team consistent Claude Code behavior. - Audit your MCP servers. Every MCP server you add expands Claude Code's attack surface. Only add servers you trust and understand.
- Keep hooks fast. Slow hooks degrade the agent experience. If a hook takes more than 2 seconds, move the work to an async process.
- Document gotchas in real-time. When Claude Code hits a surprising behavior or makes a recurring mistake, add it to CLAUDE.md immediately. This is the highest-ROI configuration activity.
Official Documentation
For the complete settings reference, advanced configuration options, and MCP server documentation:
- Claude Code Settings -- Complete settings.json reference, permissions, and environment variables.
- Claude Code Overview -- Architecture context for understanding configuration impact.
- CLI Usage Reference -- Command-line flags that interact with configuration.