dotclaude-config
Claude Code Configuration
Work with Claude Code configuration at any level - global (~/.claude/) or project (.claude/).
First: Determine Context
Before making changes, identify where you're working and what already exists:
# Where are we?
pwd
# In a project repo or in ~/.claude itself?
[[ "$(pwd)" == "$HOME/.claude"* ]] && echo "GLOBAL" || echo "PROJECT"
# What config exists at each level?
ls -la ~/.claude/settings.json ~/.claude.json 2>/dev/null
ls -la .claude/settings.json .mcp.json 2>/dev/null
Context determines approach:
| Context | You're configuring... | Primary concern |
|---|---|---|
Global (~/.claude) |
Personal defaults for all projects | Reusable patterns |
Project (.claude/) |
Project-specific behavior | Avoid duplicating global |
Working in Project Context
When configuring a project's .claude/ directory, always follow this workflow:
1. Audit Global Config First
Before adding anything to project config, examine what's already defined globally:
# Check global settings
cat ~/.claude/settings.json 2>/dev/null | jq .
# Check global MCP servers
cat ~/.claude.json 2>/dev/null | jq .mcpServers
# List global agents, commands, skills
ls ~/.claude/agents/ ~/.claude/commands/ ~/.claude/skills/ 2>/dev/null
2. Apply the Reuse Principle
Only add to project config what is:
- Unique to this project (project-specific MCP servers, custom workflows)
- Overriding global behavior intentionally (stricter permissions, different model)
- Sharable with the team via version control
Do NOT duplicate:
- Permissions already in global config
- MCP servers you use across all projects
- Personal agents/skills that aren't project-specific
3. Explain Your Reasoning
When making recommendations, always explain WHY:
**Recommendation:** Add this permission to `.claude/settings.json`
**Reasoning:** This permission is project-specific because:
- It references paths unique to this project (`./src/api/**`)
- The global config doesn't cover this use case
- Team members will need this when they clone the repo
**Not adding to global because:** This pattern only makes sense for this project's structure.
Placement Decision Guide
Use this to decide where configuration belongs:
| Configuration | Global (~/.claude) |
Project (.claude/) |
|---|---|---|
| Permissions | Personal security rules (deny secrets, keys) | Project-specific paths, team-agreed rules |
| Hooks | Personal workflows (formatters, linters) | Project build/test hooks, CI-related |
| StatusLine | Personal preference | Never (statusline is personal) |
| Model | Personal default | Team agreement on model for project |
| MCP Servers | Personal tools (perplexity, notion) | Project-specific APIs, databases |
| Agents | Personal productivity agents | Project-specific workflows |
| Skills | General-purpose skills | Project/domain-specific skills |
| Commands | Personal shortcuts | Project-specific operations |
| CLAUDE.md | Personal preferences, style | Project context, architecture, conventions |
Configuration Hierarchy
Settings merge from general to specific (later overrides earlier):
- Global:
~/.claude/settings.json- applies to all projects - Project:
.claude/settings.json- project-specific, git-committed - Local:
.claude/settings.local.json- per-machine, gitignored
For MCP servers:
- Global:
~/.claude.json(mcpServers key) - Project:
.mcp.json(mcpServers key)
For instructions:
- Global:
~/.claude/CLAUDE.md - Project:
CLAUDE.mdor.claude/CLAUDE.md
Configuration Inventory
Scan projects for Claude Code configuration status and identify overlap:
bun ~/.claude/skills/dotclaude-config/scripts/inventory.ts # scan ~/code/
bun ~/.claude/skills/dotclaude-config/scripts/inventory.ts ~/work # custom path
Reports: configured vs unconfigured projects, skill counts, package managers, and flags project skills that shadow global skills (candidates for removal or promotion to global).
Using Built-in Subagents
claude-code-guide
Query official Claude Code documentation:
Task(subagent_type="claude-code-guide", prompt="How do hooks work in settings.json?")
When to use: Latest features, undocumented behavior, syntax verification.
Explore
Examine actual configuration across levels:
Task(subagent_type="Explore", prompt="Compare global and project permissions")
Task(subagent_type="Explore", prompt="What MCP servers are configured at each level?")
When to use: Understanding current state, finding conflicts, debugging.
Quick Reference
Permissions
"permissions": {
"allow": ["Bash(git status)", "Read(./src/**)"],
"deny": ["Read(.env)", "Read(**/*.key)"],
"ask": ["Bash(git push:*)"]
}
Hooks
"hooks": {
"PostToolUse": [{"matcher": "Write|Edit", "hooks": [{"type": "command", "command": "..."}]}]
}
Model
"model": "opus" // or "sonnet", "haiku"
CLAUDE.md Configuration
For authoring and organizing CLAUDE.md files — placement, @path imports, rules files, size management — see references/claude-md-patterns.md.
Key rules:
- Keep CLAUDE.md concise (<500 lines); use
@pathimports for detail - Use
.claude/rules/*.mdfor modular, auto-loaded instructions - Put personal preferences in
~/.claude/CLAUDE.md, project context in project CLAUDE.md
Working in ~/.claude Itself
When the current directory IS ~/.claude:
- Everything is global — changes affect all Claude Code sessions
- Treat it as a public repo — never commit secrets
Worktree Setup (Recommended)
If ~/.claude is a git repo with a development clone elsewhere, it should be a worktree — not an independent clone. Check:
# File = worktree (good), Directory = standalone clone (migrate)
[ -f ~/.claude/.git ] && echo "WORKTREE" || echo "STANDALONE — see development-workflow.md"
When ~/.claude is a worktree:
- Development happens in the dev repo (on
main), never directly here - A SessionStart hook auto-syncs merged PRs — no manual maintenance
git statusdetects untracked/unignored files (gitignore covers ~30k ephemeral files)
To set up or migrate, see references/development-workflow.md.
Detailed Documentation
- settings.json schema: See references/settings-json.md
- MCP configuration: See references/mcp-config.md
- Extensibility (agents/commands/skills): See references/extensibility.md
- CLAUDE.md patterns: See references/claude-md-patterns.md
- Hooks reference: See references/hooks-reference.md
- Hook patterns: See references/hook-patterns.md
- Permission templates: See references/permission-templates.md
- Project config checklist: See references/project-config-checklist.md
Example: Project Config Audit
When asked to configure a project, produce an audit like this:
## Configuration Audit
### Global Config (already have)
- **Permissions**: deny secrets/keys, allow git commands
- **MCP**: perplexity-mcp (personal)
- **Hooks**: PostToolUse formatter, Stop session-title
- **Model**: opus
### Project Needs
- Custom permission for `./packages/**` paths
- MCP server for project's Supabase instance
- Agent for project's deployment workflow
### Recommendations
1. **Add to `.claude/settings.json`:**
```json
{"permissions": {"allow": ["Read(./packages/**)"]}}
Reasoning: Project-specific path not in global config
-
Add to
.mcp.json:{"mcpServers": {"supabase": {...}}}Reasoning: Project database, needs team access via git
-
Skip adding:
- General git permissions (already global)
- Perplexity MCP (personal, not project-specific)
- Formatter hooks (already in global PostToolUse)
## Common Tasks
### Add a project-specific permission
First check global: `cat ~/.claude/settings.json | jq .permissions`
If not covered, add to `.claude/settings.json`:
```json
"permissions": {"allow": ["Bash(npm run build:*)"]}
Add a project MCP server
Add to .mcp.json (not ~/.claude.json) so team gets it:
{"mcpServers": {"project-db": {"command": "...", "env": {"DB_URL": "${PROJECT_DB_URL}"}}}}
Create a project-specific agent
Create .claude/agents/deploy.md for project workflows.
Keep personal agents in ~/.claude/agents/.
Override global settings
Project settings merge with (and can override) global:
// .claude/settings.json - stricter for this project
{"permissions": {"deny": ["Write(./contracts/**)"]}}