Claude Code Setup and Its Key Components

Software development is being redefined.

In the first part of this series, we explored why Claude Code is different — its agentic intelligence, full-project awareness, and strategic pillars.

Now it’s time to go hands-on.

This guide walks you through setting up Claude Code and understanding its most powerful components — so you can start using it like a professional from day one.

The Mindset Shift

Claude Code isn’t just a tool you install and run.

It’s a system you configure, teach, and extend.

The more intentional you are about setup, the more leverage you unlock.

Think of it this way:

A developer who configures Claude Code well gets an AI that knows their codebase, follows their standards, respects their boundaries, and works autonomously.

A developer who skips this step gets a very expensive autocomplete.

Let’s make sure you’re in the first group.

Installation

Claude Code runs as a CLI tool. You’ll need Node.js installed (v18 or higher).

npm install -g @anthropic-ai/claude-code

Once installed, navigate to your project directory and run:

claude

That’s it. You’re in.

Now let’s build the foundation.

Understanding Context: Project vs. Global

Before diving into the components, you need to understand one foundational concept: Claude Code has two configuration layers.

Project Context

Everything inside your project’s .claude/ folder and root CLAUDE.md is project-level context.

  • Scoped to that specific project
  • Checked into version control — shared with your team
  • Overrides global settings where they conflict

Global Context

Everything inside ~/.claude/ (your home directory) is global context.

  • Applies to every project on your machine
  • Personal to you — not version controlled
  • Sets your personal defaults and preferences
Project Context Global Context
Location .claude/ + CLAUDE.md ~/.claude/
Scope One project All projects
Shared with team? Yes (via git) No (personal)
Use for Codebase rules, team standards Personal preferences, global commands

The rule of thumb: If it’s about the project → project context. If it’s about how you work → global context.

This distinction applies to every component that follows.

1. CLAUDE.md: Project and Global Memory

The single most impactful thing you can do as a beginner.

CLAUDE.md is a Markdown file that Claude Code reads automatically at startup — before it does anything else. Think of it as your AI onboarding document.

It exists at two levels:

  • Project: CLAUDE.md at your project root — architecture, team standards, project-specific rules
  • Global: ~/.claude/CLAUDE.md — your personal working style and preferences that apply everywhere

What to put in your project CLAUDE.md

# Project Overview
This is a Node.js REST API for an e-commerce platform.
Primary language: TypeScript. Framework: Express. Database: PostgreSQL.

# Architecture
- /src/routes — API route handlers
- /src/services — Business logic
- /src/models — Database models

# Coding Standards
- Use async/await (no callbacks)
- Write unit tests for all service functions
- Follow RESTful conventions

# What NOT to do
- Do not modify the /legacy folder
- Do not use console.log in production code
- Do not change DB schema without running migrations

What to put in your global ~/.claude/CLAUDE.md

# My Preferences
- I prefer concise explanations over verbose ones
- Always suggest tests when modifying logic
- Use British English spelling in all documentation

Why it matters

Claude Code has no memory between sessions by default.

Without CLAUDE.md, you repeat yourself every single time. With it, Claude always knows exactly what project it’s working on, how you like to code, and what lines not to cross.

Create this file on day one. Update it as your project evolves.

2. Settings & Permissions

Claude Code gives you fine-grained control over what it can and can’t do autonomously.

Where settings live

Level Location Purpose
Project .claude/settings.json Project-specific permissions, hooks, MCP servers
Global ~/.claude/settings.json Personal defaults across all projects

Project settings take precedence over global settings.

{
  "permissions": {
    "allow": [
      "Bash(npm run test)",
      "Bash(npm run lint)",
      "Read(**)",
      "Write(src/**)"
    ],
    "deny": [
      "Bash(rm -rf **)",
      "Write(.env)"
    ]
  }
}

Key permission types

Read — What files Claude can access. Write — What files Claude can modify. Bash — What terminal commands Claude can execute.

The golden rule

Start restrictive, then open up as you build trust.

Allow Claude to run tests and linters. Restrict it from touching environment files or infrastructure configs until you’re confident.

This is the equivalent of onboarding a new developer — you don’t give them production access on day one.

3. Commands: Your Custom Shortcuts

Commands are pre-written Markdown instructions triggered with a / slash prefix inside Claude Code. They support YAML frontmatter for configuration and dynamic placeholders for arguments.

They exist at two levels:

Level Location Invoked as
Project .claude/commands/<name>.md /project:<name>
Personal ~/.claude/commands/<name>.md /<name>

Creating a project command

Create .claude/commands/fix-issue.md:

---
description: Fix a GitHub issue by number
argument-hint: [issue-number]
allowed-tools: Read, Grep, Glob, Bash(git *), Bash(gh *)
---

Fix GitHub issue #$ARGUMENTS following our coding standards.

## Context
- Issue details: !`gh issue view $ARGUMENTS`
- Current branch: !`git branch --show-current`

## Steps
1. Read the issue description above
2. Find the relevant code
3. Implement the fix
4. Write tests
5. Create a commit referencing issue #$ARGUMENTS

Type /project:fix-issue 42 — Claude receives the issue details inline and starts working.

Key features used above:

  • $ARGUMENTS — replaced with whatever you type after the command (42)
  • !`command` — runs the shell command before Claude sees the prompt, injecting live output
  • allowed-tools — grants Claude permission to use specific tools without asking
  • argument-hint — shows [issue-number] as autocomplete hint in the CLI

Creating a personal command

Create ~/.claude/commands/explain.md:

---
description: Explain selected code in plain English
allowed-tools: Read, Grep, Glob
---

Explain the selected code in plain English.
Focus on what it does, why it exists, and any non-obvious logic.
Keep it concise — one paragraph unless complexity requires more.

Now /explain is available in every project you work on.

Argument placeholders

Placeholder Description
$ARGUMENTS Everything typed after the command name
$ARGUMENTS[0], $0 First argument
$ARGUMENTS[1], $1 Second argument
!`command` Runs a shell command and injects its output

Example with positional arguments.claude/commands/compare.md:

---
description: Compare two files side by side
argument-hint: [file1] [file2]
---

Compare $0 and $1. Highlight meaningful differences and explain
what changed and why it might matter.

Usage: /project:compare src/old.ts src/new.ts

Commands turn Claude Code from a conversation into a workflow engine.


4. Hooks: Automate at Every Step

Hooks let you run automatic actions at specific lifecycle points — without you having to ask. They fire before or after Claude uses a tool, when a session starts, when Claude finishes a task, and more.

Hook structure

Hooks are configured in .claude/settings.json with three levels of nesting: eventmatcherhandler(s).

{
  "hooks": {
    "<EventName>": [
      {
        "matcher": "<regex pattern>",
        "hooks": [
          {
            "type": "command",
            "command": "your-shell-command",
            "timeout": 600
          }
        ]
      }
    ]
  }
}

Key hook events

Event When it fires Matcher filters on
PreToolUse Before a tool call executes Tool name (Bash, Edit|Write, mcp__.*)
PostToolUse After a tool call succeeds Tool name
Stop When Claude finishes responding
Notification When Claude sends a notification Notification type
SessionStart Session begins or resumes How started (startup, resume, compact)
UserPromptSubmit User submits a prompt

The matcher is a regexEdit|Write matches either tool, mcp__memory__.* matches all tools from the memory MCP server.

Example 1: Auto-format code after edits

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

Every time Claude edits or writes a file, Prettier auto-formats it. The hook receives the tool input as JSON on stdin — jq extracts the file path.

Example 2: Block destructive commands

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'COMMAND=$(jq -r .tool_input.command); if echo \"$COMMAND\" | grep -q \"rm -rf\"; then echo \"{\\\"hookSpecificOutput\\\":{\\\"hookEventName\\\":\\\"PreToolUse\\\",\\\"permissionDecision\\\":\\\"deny\\\",\\\"permissionDecisionReason\\\":\\\"Destructive command blocked by hook\\\"}}\" && exit 0; fi; exit 0'"
          }
        ]
      }
    ]
  }
}

Exit code 0 with a permissionDecision: "deny" in the output blocks the action. Exit code 2 also blocks the action (stderr is fed back to Claude).

Example 3: Log all Bash commands

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.command' >> ~/.claude/command-log.txt"
          }
        ]
      }
    ]
  }
}

Example 4: Re-inject context after compaction

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "compact",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Reminder: use Bun, not npm. Run bun test before committing.'"
          }
        ]
      }
    ]
  }
}

When the context window compacts, this hook re-injects key reminders so Claude doesn’t forget.

Three hook handler types

Type What it does
command Runs a shell command. Input JSON on stdin.
prompt Sends a prompt to a fast LLM (Haiku) to evaluate the action.
agent Spawns a subagent to verify the action (e.g., run tests before stopping).

Agent hook example — run tests before Claude stops:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "Run the test suite and verify all tests pass. $ARGUMENTS",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

Hooks turn Claude Code into a self-disciplined development partner.

5. Skills: The Evolution of Commands

Skills are the next generation of slash commands — reusable instruction sets that live in their own directories, carry supporting resources, and can be invoked by you or by Claude automatically.

Skills vs Commands

Slash commands have been merged into the skills system. Your existing .claude/commands/ files still work, but skills are the recommended path forward.

Feature Old Slash Commands Skills
Location .claude/commands/name.md .claude/skills/name/SKILL.md
Supporting files No — single Markdown file only Yes — scripts, templates, examples, reference docs
Invoked by you Yes, with /command-name Yes, with /skill-name
Auto-invoked by Claude No Yes — Claude reads the description and activates it when relevant
YAML frontmatter Supported (after merge) Yes — name, description, allowed-tools, model, subagent context
Subagent / fork context No Yes

A command says “do this task.” A skill says “whenever you do this type of work, here is the complete standard to follow — and here are the resources to do it right.”

Where skills live

Each skill is a directory inside .claude/skills/, containing a required SKILL.md and optional supporting files. Claude Code auto-discovers them — no need to reference them in CLAUDE.md.

Scope Location
Project .claude/skills/<skill-name>/SKILL.md
Personal ~/.claude/skills/<skill-name>/SKILL.md

Skill directory structure

.claude/skills/
├── testing/
│   ├── SKILL.md              ← Main instructions (required)
│   ├── template.test.ts      ← Test file template
│   └── examples/
│       └── sample.test.ts    ← Example output for Claude to follow
├── api-design/
│   ├── SKILL.md              ← API design standards
│   ├── response-schema.json  ← JSON schema for response envelope
│   └── reference.md          ← Detailed endpoint documentation
└── migrate-component/
    ├── SKILL.md              ← Migration instructions
    └── scripts/
        └── validate.sh       ← Validation script Claude can run

The key advantage: supporting files stay in the skill folder, so Claude can access templates, examples, scripts, and reference docs — all scoped to that specific skill.

SKILL.md format

Every SKILL.md has two parts: YAML frontmatter for configuration and Markdown content with instructions.

---
name: testing
description: Generates unit tests following our Jest + TypeScript standards
allowed-tools: Bash(npm run test), Write(src/**/*.test.ts)
---

## Framework
Jest with TypeScript. All test files end in `.test.ts`.

## Structure
- Group tests with `describe` blocks by function name
- Use `it` statements that read like English sentences
- One assertion per test where possible

## Coverage expectations
- All service functions need unit tests
- All API routes need integration tests
- Edge cases: null inputs, empty arrays, error states

## Mocking
- Use jest.mock() for all external dependencies
- Never hit the real database in unit tests

## Naming
Test files live alongside source: `userService.ts` → `userService.test.ts`

## Resources
- For the test template, see [template.test.ts](template.test.ts)
- For example output, see [examples/sample.test.ts](examples/sample.test.ts)

Key frontmatter fields

Field Purpose
name Display name and /slash-command name. Defaults to directory name.
description What the skill does. Claude uses this to decide when to activate it automatically.
allowed-tools Tools Claude can use without asking permission when this skill is active.
disable-model-invocation Set to true to prevent Claude from auto-invoking this skill.
user-invocable Set to false to hide from the / menu (Claude-only skill).
context Set to fork to run in a subagent context.

How skills get activated

Skills are activated in two ways:

1. You invoke it — type /testing and Claude executes the skill with its full instructions and supporting files.

2. Claude invokes it automatically — Claude sees the skill’s description in context. When your conversation matches (e.g., you ask Claude to write tests), it loads and applies the skill on its own.

No need to reference skills in CLAUDE.md. They are auto-discovered from .claude/skills/.

Example: An API design skill

Create .claude/skills/api-design/SKILL.md:

---
name: api-design
description: Enforces API design standards for all route handlers
---

## Routing conventions
- Use plural nouns for resource endpoints: /users, /orders
- Nest related resources: /users/:id/orders
- Keep nesting to two levels maximum

## Response structure
Always return the envelope defined in [response-schema.json](response-schema.json)

## Error handling
- 400 for validation errors — include field-level details
- 401 for unauthenticated requests
- 403 for unauthorized (authenticated but no permission)
- 404 for missing resources — never expose internals
- 500 for unexpected failures — log internally, return generic message

## Versioning
All routes are prefixed with /api/v1/

Supporting file .claude/skills/api-design/response-schema.json:

{
  "data": {},
  "error": null,
  "meta": { "timestamp": "", "version": "" }
}

Now when you ask Claude to create an API endpoint — or type /api-design — it applies these standards and references the schema file automatically.

Build skills for the areas where you want the most consistency: testing, API design, error handling, component migrations.

6. Subagents: Parallel Specialist AI Workers

Subagents are where Claude Code starts to feel like a team of developers, not a single assistant.

A subagent is an isolated AI instance that handles a specific task — in its own context window, in parallel with other tasks. Each subagent gets its own tools, permissions, and optionally its own model.

Built-in subagents

Subagent Purpose Tools
Explore Fast codebase search and file discovery Read-only (no Write/Edit)
Plan Research during plan mode Read-only (no Write/Edit)
general-purpose Complex multi-step operations All tools

Claude automatically delegates to the right subagent type. Ask it to “search the codebase for deprecated API calls” and it routes to Explore. Ask it to “refactor the auth module” and it uses general-purpose.

Custom subagents

You can define your own specialized agents as Markdown files:

Scope Location
Project .claude/agents/<name>.md
Personal ~/.claude/agents/<name>.md

Example.claude/agents/code-reviewer.md:

---
name: code-reviewer
description: Expert code review specialist. Use proactively after writing or modifying code.
tools: Read, Grep, Glob, Bash(git diff *)
model: inherit
---

You are a senior code reviewer ensuring high standards of quality and security.

When invoked:
1. Run `git diff` to see recent changes
2. Focus on modified files
3. Begin review immediately

Review checklist:
- Code is clear and readable
- No duplicated code
- Proper error handling
- No exposed secrets or API keys
- Good test coverage

Provide feedback organized by priority:
- **Critical** — must fix before merge
- **Warning** — should fix
- **Suggestion** — consider improving

Now Claude proactively invokes this agent after code changes, or you can ask: “Use the code-reviewer subagent to review my changes.”

Key subagent configuration fields

Field Description
name Unique identifier (lowercase, hyphens)
description When Claude should delegate to this subagent
tools Tools the subagent can use (inherits all if omitted)
model sonnet, opus, haiku, or inherit
maxTurns Maximum agentic turns before stopping
skills Skills to preload into the subagent’s context
memory Persistent memory scope: user, project, or local
isolation Set to worktree to run in a temporary git worktree

How subagents work

  • Each subagent runs in its own context window — the main conversation only sees summarized results
  • Up to 10 concurrent subagents can run at once
  • Subagents cannot spawn other subagents (no infinite nesting)
  • Press Ctrl+B to background a running subagent while you continue working

Skills can also spawn subagents

Use context: fork in a skill’s frontmatter to run it as an isolated subagent:

---
name: pr-summary
description: Summarize changes in a pull request
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---

## Pull request context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`

## Your task
Summarize this pull request. Highlight breaking changes and areas needing review.

Type /pr-summary — it spawns an Explore subagent with the PR data pre-injected, analyzes it in isolation, and returns a summary to your main conversation.

7. MCP Setup: Connecting Claude to Your World

MCP — the Model Context Protocol — transforms Claude Code from a coding assistant into a workflow orchestrator.

It allows Claude to connect to external tools, services, and APIs — and take real-world actions.

What MCP unlocks

  • Query a live database
  • Create a GitHub issue
  • Post to Slack
  • Interact with your CI/CD pipeline
  • Browse internal documentation

Configuring MCP

MCP servers are configured in .claude/settings.json:

{
  "mcpServers": {
    "github": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-github"],
      "env": {
        "GITHUB_PERSONAL_ACCESS_TOKEN": "your_token_here"
      }
    },
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": {
        "POSTGRES_CONNECTION_STRING": "postgresql://localhost/mydb"
      }
    }
  }
}

Available MCP servers

  • GitHub — Manage repos, issues, PRs
  • PostgreSQL — Query databases directly
  • Slack — Send messages and read channels
  • File System — Extended file operations
  • Brave Search — Real-time web search

Beginner advice

Start with one MCP server that solves a real pain point.

If you constantly switch between your terminal and GitHub to create issues — connect the GitHub MCP server. Let Claude Code do it for you, in context, without breaking your flow.

Putting It All Together

Project structure

my-project/
├── CLAUDE.md                        ← Project context & standards
└── .claude/
    ├── settings.json                ← Permissions, hooks, MCP servers
    ├── commands/
    │   ├── review-pr.md             ← Legacy command (still works)
    │   └── document.md              ← Legacy command (still works)
    └── skills/
        ├── testing/
        │   ├── SKILL.md             ← Testing skill
        │   ├── template.test.ts     ← Test template
        │   └── examples/
        │       └── sample.test.ts   ← Example output
        └── api-design/
            ├── SKILL.md             ← API design skill
            └── response-schema.json ← Supporting resource

Global structure (your machine)

~/.claude/
├── CLAUDE.md                        ← Your personal preferences
├── settings.json                    ← Global defaults
├── commands/
│   ├── explain.md                   ← Legacy command (still works)
│   └── summarize.md                 ← Legacy command (still works)
└── skills/
    └── explain-code/
        └── SKILL.md                 ← Personal skill, available everywhere

With this setup, every Claude Code session starts with full project context, enforces your standards automatically, executes your workflows on demand, and can reach out to external tools when needed.

Your First Week Checklist

Getting started doesn’t have to be overwhelming. Take it step by step.

Day 1: Create your CLAUDE.md with project overview, architecture, and key rules.

Day 2: Configure basic permissions — allow reads and writes to your source folder, allow test and lint commands.

Day 3: Create two or three slash commands for your most repeated tasks.

Day 4: Add one or two PostToolUse hooks — start with auto-linting.

Day 5: Write your first skill file for the area where you want the most consistency.

Week 2: Set up one MCP server that connects to a tool you use daily.

Week 3 onwards: Explore subagents for parallelizing complex, multi-part tasks.

Conclusion: Configuration Is the Leverage

Installing Claude Code takes five minutes.

Configuring it well is what separates developers who get 10% productivity gains from those who get 10x leverage.

The components covered in this guide — CLAUDE.md, Settings, Commands, Hooks, Skills, Subagents, and MCP — are not advanced features reserved for power users.

They are the foundation.

Master them now, and you’ll build a development environment that works with you — not just for you.

This is Part 2 of a series on Claude Code. Read Part 1: Getting Started with Claude Code — A Strategic Guide for Developers to understand the strategic landscape before going hands-on.

Leave a comment


Purnananda Behera