
TL;DR
The Short Answer
Claude Code is configured with plain files in your repo: CLAUDE.md for instructions, .claude/agents/ for subagents, .claude/skills/ for skills and slash commands, .claude/settings.json for permissions and hooks, and .mcp.json for MCP servers. The templates below are minimal starting points with only documented fields, checked against Anthropic's Claude Code docs on November 5, 2026. Replace the commands and paths with your own.
| Where it lives | What it does | |
|---|---|---|
| CLAUDE.md | ./CLAUDE.md or ./.claude/CLAUDE.md (all projects: ~/.claude/CLAUDE.md) | Instructions Claude reads at the start of every session |
| CLAUDE.local.md | ./CLAUDE.local.md, added to .gitignore | Your personal notes for one project |
| Rules | .claude/rules/*.md | Instructions that load only for files matching a paths: filter |
| Subagent | .claude/agents/<name>.md (all projects: ~/.claude/agents/) | A helper with its own prompt, tools, and context window |
| Skill | .claude/skills/<name>/SKILL.md (all projects: ~/.claude/skills/) | A procedure or reference Claude loads on demand, also runnable as /name |
| Command file | .claude/commands/<name>.md (all projects: ~/.claude/commands/) | The older one-file format for a /name command |
| Settings | .claude/settings.json (team), .claude/settings.local.json (you), ~/.claude/settings.json (all projects) | Permissions, hooks, environment variables, and other options |
| Hook script | .claude/hooks/<name>.sh, registered in a settings file | A script Claude Code runs at a fixed point, every time |
| MCP servers | .mcp.json at the project root (team), ~/.claude.json (just you) | Connects external tools such as a browser or GitHub |
CLAUDE.md Template (Short)
When to use it: a personal project or a small repo. Start here, then add a line each time you correct Claude on the same thing twice.
CLAUDE.md is guidance Claude reads every session, not enforced configuration. Anthropic's advice is to keep it to what Claude can't work out from the code: the exact commands to check work, places where the code is misleading, and decisions that live outside the repo. Leave out your folder layout and generic advice like "write clean code". /init generates a first draft from your codebase if you'd rather edit than write.
# Commands
- Dev server: npm run dev
- Test one file: npx vitest run path/to/file.test.ts
- Typecheck: npx tsc --noEmit
- Lint: npm run lint
# Rules
- Call the API through src/lib/api.ts, never fetch() directly
- Components are function components with named exports
# Gotchas
- Tests need a local Postgres: docker compose up -d dbCLAUDE.md Template (Full, for a Team Repo)
When to use it: a shared repository where several people (and Claude) need the same ground rules. Commit it as ./CLAUDE.md or ./.claude/CLAUDE.md.
The docs recommend staying under 200 lines per file, and this one is about 35. A few notes on what's in it:
@docs/api-conventions.mdimports another file. Imports keep things organized but still load every session, so they don't save context.- A rule that only matters in one folder belongs in
.claude/rules/<topic>.mdwithpaths:frontmatter, so it loads only when Claude touches matching files. - A multi-step procedure, like writing a migration, belongs in a skill (template below), not here.
- Your personal preferences go in
CLAUDE.local.md, added to.gitignore. - Run
/context allin a session to confirm the file loaded.
# Project
Invoicing app for small agencies. Next.js app router, Postgres via Drizzle, deployed on Vercel.
# Commands
- Install: npm ci
- Dev: npm run dev (http://localhost:3000)
- Test one file: npx vitest run path/to/file.test.ts
- All tests: npm test
- Typecheck: npx tsc --noEmit
- Lint and fix: npm run lint -- --fix
# Checking your work
- Run the typecheck and the tests for the files you changed before saying you're done
- For UI changes, start the dev server and check the page
# Conventions
- Server code lives in src/server/. Never import it from a client component
- Validate request input with the zod schemas in src/server/schemas/
- Store money as integer cents, never floats
- Log with src/server/log.ts, not console.log
# Gotchas
- src/legacy/ is still in production. Don't copy its patterns into new code
- Integration tests need DATABASE_URL, see .env.example
- Files in db/migrations/ are generated. Never edit them by hand
# Workflow
- Use plan mode for any change under src/server/billing/
- Commit messages: imperative mood, under 72 characters
- Don't push or open pull requests unless asked
# More
- API design rules: @docs/api-conventions.mdSubagent Template
When to use it: a task that produces a lot of output you don't want in your main conversation, like running tests or searching a large codebase. The subagent works in its own context window and hands back a summary.
Save it in .claude/agents/ for the project or ~/.claude/agents/ for all your projects. Only name and description are required. Claude decides when to delegate based on the description, and the docs suggest adding "use proactively" if you want it used without being asked. You can also name it in your prompt or @-mention it.
toolslimits what it can do. This one has no Edit or Write, so it can't change files. Omit the field to inherit all tools.modeltakessonnet,opus,haiku,fable, a full model ID, orinherit. A cheaper model suits a narrow job like this.- Other documented fields include
disallowedTools,permissionMode,maxTurns,skills,memory,effort, andisolation: worktree. Field names are camelCase and must match exactly: Claude Code silently ignores a field it doesn't recognize.
---
name: test-runner
description: Runs tests and reports failures with the likely cause. Use proactively after code changes, or when the user asks to run tests.
tools: Read, Grep, Glob, Bash
model: haiku
---
You run tests and report results. You never edit files.
1. Run the narrowest test command that covers the change. The test commands are in CLAUDE.md.
2. If a test fails, read the failing test and the code it exercises.
3. Report the command you ran, the pass and fail counts, and for each failure:
the test name, the error message, and the most likely cause in one or two lines.
Keep the report under 30 lines. Don't paste full logs.Skill Template (SKILL.md)
When to use it: a procedure or a piece of team knowledge that only matters for some tasks. Until it's needed, only the description sits in context, so a skill costs far less than the same text in CLAUDE.md.
A skill is a folder with a SKILL.md file: .claude/skills/<name>/SKILL.md for the project, ~/.claude/skills/<name>/SKILL.md for you. Claude loads it when a request matches the description, and you can run it yourself as /db-migrations. All fields are optional, but write a description with the words people actually use, because that's what Claude matches against.
allowed-toolspre-approves tools for the turn the skill runs. It doesn't block other tools.- Supporting files like
reference.mdsit next toSKILL.mdand load only when Claude follows the link. The docs suggest keepingSKILL.mdunder 500 lines. - Add
disable-model-invocation: truefor anything with side effects, like a deploy, so only you can start it. Adduser-invocable: falsefor background knowledge only Claude should load. - Skill field names are lowercase with hyphens (
allowed-tools, notallowedTools). The cheat sheet has a manual-only release skill as a second example.
---
name: db-migrations
description: Creates and reviews database migrations for this repo. Use when the user asks to add or change a table, column, or index, or to write or check a migration.
allowed-tools: Bash(npm run db:generate *)
---
# Database migrations
1. Change the schema in src/server/db/schema.ts first. Migrations are generated from it.
2. Run `npm run db:generate -- --name <short_name>`, with a snake_case name.
3. Read the generated SQL in db/migrations/. Don't edit it. If it's wrong, fix the schema and generate again.
4. If the SQL drops or renames a column or table, stop and ask before going further.
5. Run `npm test -- db` and report the result.
For naming rules, backfill patterns, and past examples, read [reference.md](reference.md).Custom Slash Command Template
When to use it: a prompt you type over and over and always want to start yourself, like committing.
Custom commands were merged into skills. A file at .claude/commands/commit.md still works and creates /commit, and it accepts the same frontmatter as a skill except name and paths. The docs recommend a skill folder (.claude/skills/commit/SKILL.md) for new work because it can hold supporting files, but the content is identical either way. If both exist with the same name, the skill wins.
disable-model-invocation: truemeans Claude can't run it on its own.argument-hintshows in autocomplete.$ARGUMENTSis replaced with whatever you type after/commit.$0,$1and so on pick out single arguments.- A line starting with
!followed by a command in backticks runs that command before Claude sees the prompt and inserts its output, so Claude starts with the real diff. If one of these commands fails, the whole command is cancelled.
---
description: Commit the current changes with a clear message
argument-hint: "[extra instructions]"
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *)
---
## Current state
- Branch: !`git branch --show-current`
- Status: !`git status --short`
- Diff: !`git diff HEAD`
## Task
Commit the changes above. Extra instructions: $ARGUMENTS
- Stage only files that belong to this change. List anything you left unstaged.
- If the changes cover unrelated work, make one commit per topic.
- Message: imperative summary under 72 characters, plus a short body if the reason isn't obvious.
- Never use --no-verify. If a pre-commit hook fails, fix the cause and commit again.
- Don't push.settings.json Permissions Template
When to use it: you want routine commands to run without a prompt and some things blocked outright, the same way for everyone on the team.
Save it as .claude/settings.json and commit it. For rules that are just yours, use .claude/settings.local.json (choosing "Yes, and don't ask again" in a prompt saves there) or ~/.claude/settings.json for all projects. Settings files are strict JSON, so no comments or trailing commas.
- Rules are checked in the order deny, then ask, then allow, and the first match wins. An allow rule can't carve an exception out of a deny rule.
Bash(npm test *)matchesnpm testand anything after it. Put the*after the subcommand, not before it.denyrules hold in every permission mode, including auto andbypassPermissions. AReaddeny also blockscat .env, but not a script that opens the file, so turn on the sandbox (/sandbox) when it really matters.- Read-only commands like
ls,grep, andgit diffalready run without a prompt, so they don't need allow rules. - A teammate's Claude Code applies this file's
allowrules only after they accept the folder's trust dialog.denyandaskrules apply right away. defaultMode(for example"acceptEdits"or"plan") sets the starting permission mode.autoandbypassPermissionsdon't take effect from project or local settings, so set those in~/.claude/settings.json.
The $schema line gives you autocomplete and validation in editors that support JSON schema.
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint *)",
"Bash(npm test *)",
"Bash(npx vitest run *)",
"Bash(npx tsc --noEmit)",
"WebFetch(domain:nextjs.org)"
],
"ask": [
"Bash(git push *)"
],
"deny": [
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)",
"Bash(curl *)"
]
}
}Hooks Template: Typecheck Before Finishing, Block Protected Files
When to use it: a rule with zero exceptions. CLAUDE.md works most of the time. A hook is run by Claude Code itself, so it fires every time.
This template sets up two hooks. Put the hooks block in the same .claude/settings.json as your permissions, as a sibling of permissions.
Stopruns when Claude tries to finish its turn. If the typecheck fails,exit 2blocks the stop and the compiler errors (redirected to stderr) go back to Claude, which keeps working untiltscpasses. If the hook blocks eight stops in a row with no tool call in between, Claude Code lets the turn end anyway.PreToolUsewith the matcherEdit|Writeruns before every file edit and calls the script in the next section. Exit code 2 blocks the edit, and the script's message tells Claude why.
Check what's registered with /hooks. A few other examples worth knowing: a PostToolUse hook that runs your formatter after every edit (in the cheat sheet), a Notification hook in ~/.claude/settings.json that pings your desktop when Claude needs input, and a SessionStart hook with the matcher compact that re-adds key context after compaction.
{
"hooks": {
"Stop": [
{
"hooks": [
{ "type": "command", "command": "npx tsc --noEmit 1>&2 || exit 2" }
]
}
],
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh" }
]
}
]
}
}Hook Script Template: Protect Files From Edits
When to use it: files Claude should never edit directly: secrets, lockfiles, generated migrations. This is adapted from the docs' protect-files example.
The hook receives the tool call as JSON on stdin, so the script reads tool_input.file_path with jq (install it if you don't have it). Make the script executable with chmod +x .claude/hooks/protect-files.sh, then ask Claude to add a comment to .env to see it blocked.
A permission deny rule like Edit(./db/migrations/**) can do the same job with no script. The script is worth it when you want a custom message back to Claude or logic that a rule can't express.
#!/bin/bash
# Blocks Edit and Write calls on protected paths (PreToolUse hook)
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# Normalize Windows backslashes so the patterns below match
FILE_PATH="${FILE_PATH//\\//}"
PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/" "db/migrations/")
for pattern in "${PROTECTED_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
exit 2
fi
done
exit 0MCP Config Template (.mcp.json)
When to use it: your team should share the same external tools. .mcp.json at the project root is the project-scope MCP file, meant to be committed. Servers that are only for you go in ~/.claude.json, which claude mcp add writes to by default.
- An
httpserver needs aurl. Astdioserver needs acommandandargs, and can take anenvobject. ${VAR}and${VAR:-default}expand from each person's environment, so tokens stay out of git. Use a variable name of your own: Claude Code deliberately reads some credential variables, such asANTHROPIC_API_KEYandNPM_TOKEN, as empty in a remote server'surlandheaders.- The first time an interactive session sees a server from
.mcp.json, Claude Code asks you to approve it, so a cloned repo can't start processes on your machine without your consent. - Each connected server adds tool definitions to context. Turn off the ones you aren't using with
/mcp.
The Playwright server gives Claude a browser and needs no account. The GitHub server takes a fine-grained personal access token. To build a server of your own, see how to build an MCP server.
{
"mcpServers": {
"playwright": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@playwright/mcp@latest"]
},
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_MCP_PAT}"
}
}
}
}How to Check That a Template Loaded
Most of these files fail quietly. A misspelled frontmatter field is ignored without an error, and a YAML mistake in a skill loads the body with no settings. Check each one after you add it:
- CLAUDE.md and rules:
/context alllists them under Memory files. - Settings:
/statusshows which settings files loaded./permissionslists every rule and the file it came from. - Hooks:
/hookslists them grouped by event. - Skills and commands:
/skillslists them, or type/and look for the name. - Subagents: type
@and look for the name, or ask "what subagents are available?". - MCP servers:
/mcpin a session, orclaude mcp listfrom your shell. - Anything else: run
claude --debugand read the debug log, which shows YAML parse errors and names subagent fields Claude Code doesn't recognize./doctor prompt-auditreviews your instruction files for outdated or conflicting content.
Where to Go Next
- Need the commands and shortcuts that go with these files? The Claude Code cheat sheet covers them, plus a manual-only release skill and a formatter hook.
- Want something to build with your new setup? 10 Claude Code projects has starter prompts, including one where Claude writes a skill and a subagent for you.
- New to Claude Code? Start with the Claude Code tutorial.
FAQ
- Where do Claude Code template files go?
- Project files go in the repository: CLAUDE.md at the root, subagents in .claude/agents/, skills in .claude/skills/<name>/SKILL.md, settings and hooks in .claude/settings.json, and MCP servers in .mcp.json. For files that apply to all your projects, use the same names under ~/.claude/, except MCP servers, which go in ~/.claude.json.
- Is there an official CLAUDE.md template?
- There is no single required format. Running /init generates a starting CLAUDE.md from your codebase, and Anthropic's best-practices page shows a short example with Commands, Conventions, and Gotchas sections. The docs recommend keeping each file under 200 lines and only including what Claude can't work out from the code.
- Should I write a skill or a custom slash command?
- Both create a /name command. A file in .claude/commands/ is the older format and still works. A skill in .claude/skills/<name>/SKILL.md takes the same frontmatter plus name and paths, can include supporting files, and wins if both share a name, so the docs recommend skills for new work.
- Why does Claude Code ignore a field in my subagent or skill?
- Claude Code silently ignores frontmatter fields it doesn't recognize. Subagent fields are camelCase, such as disallowedTools and maxTurns. Skill fields use hyphens, such as allowed-tools and disable-model-invocation. Run claude --debug and check the debug log, which names unrecognized subagent fields and shows YAML parse errors.
- Does Claude Code read AGENTS.md?
- Yes. Recent versions read AGENTS.md as project instructions when there is no CLAUDE.md or CLAUDE.local.md in the working directory or above it. If you have both, Claude reads only CLAUDE.md unless you change the Project instructions setting in /config. To share one file across tools, put @AGENTS.md at the top of your CLAUDE.md.
- Is it safe to commit .claude/settings.json and .mcp.json?
- Yes, that is what they are for, as long as they hold no secrets. Reference tokens with ${VAR} in .mcp.json instead. Teammates are protected too: allow rules in a project settings file apply only after they accept the folder trust dialog, and Claude Code asks before using a server from .mcp.json for the first time.


