Certification
    August 25, 2026

    CCA Developer · M3 — Claude Code, MCP & Integration

    Permission modes, CLAUDE.md, hooks, subagents, skills and plugins, MCP server primitives, transport options, scope configuration, and enterprise authentication patterns.

    Share

    3.1 Claude Code — Permission Modes

    Claude Code operates in one of six permission modes. The mode controls what actions Claude can take without asking for your confirmation:

    Mode What Claude can do autonomously Typical use
    default Read files; asks before writing or running commands Day-to-day interactive use
    acceptEdits Read + write files; asks before running commands Sessions where you're comfortable with file edits
    plan No file writes or commands; produces a plan only Design sessions, review before committing
    auto Read, write, and run most commands Trusted automated tasks
    dontAsk Everything except bypassing safety Fully automated pipelines, CI with human oversight
    bypassPermissions Bypasses all permission checks CI/CD systems with full automation; no human in loop
    WARNING

    bypassPermissions should only be used in locked-down CI/CD environments where the task is fully defined and no external content can modify Claude's behaviour. Never use it interactively.

    Choosing a mode. The principle is least privilege: give Claude the minimum permissions it needs for the current task. Use plan mode first for unfamiliar tasks — review the plan, then switch to auto for execution.


    3.2 Configuration Hierarchy

    Claude Code has four configuration layers, applied in order (highest wins):

    Enterprise policy (locked)
      └── User global settings (~/.claude/settings.json)
           └── Project settings (.claude/settings.json)
                └── Local session overrides (--flag arguments)

    What belongs in each layer:

    • Enterprise policy: Enforced organisation-wide constraints — approved model IDs, blocked tool categories, compliance settings. Set by admin, cannot be overridden.
    • User global settings: Personal preferences — default model, preferred permission mode, API key location.
    • Project settings: Project-specific configuration — CLAUDE.md path, project-level MCP servers, hook configurations. Committed to the repo.
    • Local session overrides: One-off flags (--model, --permission-mode) that apply to the current terminal session only.

    3.3 CLAUDE.md — Durable Project Context

    CLAUDE.md is a Markdown file at the project root (or in .claude/) that provides persistent context read at every Claude Code session start. It is the authoritative source for:

    • Project architecture and conventions
    • Commands to run (build, test, lint)
    • Code style rules Claude must follow
    • Files or directories Claude should never modify
    • APIs and external services in use

    Structure for a CLAUDE.md:

    # CLAUDE.md
    
    ## Project
    E-commerce backend — Node.js + TypeScript + PostgreSQL. REST API, no GraphQL.
    
    ## Commands
    - Build: npm run build
    - Test: npm test (runs Vitest, must pass before any commit)
    - Lint: npm run lint (ESLint + Prettier — fix lint errors, never suppress)
    
    ## Architecture
    - src/routes/ — Express route handlers (thin; delegate to services)
    - src/services/ — Business logic (no direct DB calls; use repositories)
    - src/repositories/ — All database access (pg pool, never raw query strings)
    - src/lib/ — Shared utilities
    
    ## Conventions
    - All DB queries use parameterised queries — no string interpolation
    - Errors bubble up as AppError instances (src/lib/errors.ts)
    - Tests use integration test DB (TEST_DATABASE_URL env var)
    
    ## Do not modify
    - src/lib/auth.ts — auth logic, requires security review
    - migrations/ — migration files are append-only
    TIP

    A well-maintained CLAUDE.md removes the need to re-explain project conventions in every session. It is the most impactful single file for teams adopting Claude Code.


    3.4 Rules and Instruction Files

    Beyond CLAUDE.md, Claude Code supports scoped instruction files in a .claude/rules/ directory. These apply per-subdirectory or per-file-type:

    .claude/
      rules/
        frontend.md      # applies to src/components/**, src/pages/**
        api.md           # applies to api/**, src/routes/**
        security.md      # applies globally (sensitive patterns)

    This lets you give Claude different instructions for different parts of the codebase — e.g., strict security review rules for the authentication module, different style conventions for the frontend vs backend.


    3.5 Hooks

    Hooks are shell commands or scripts that Claude Code executes at defined lifecycle points. They give you programmatic control over Claude's actions:

    Hook type When it fires Common use
    PreToolUse Before Claude executes a tool Block dangerous commands, log actions, validate parameters
    PostToolUse After a tool completes Capture output, trigger downstream processes
    Notification When Claude emits a notification Send alerts to Slack/PagerDuty
    Stop When the session ends Cleanup, summary reports

    Example: Block rm -rf commands via PreToolUse hook.

    In .claude/settings.json:

    {
      "hooks": {
        "PreToolUse": [
          {
            "matcher": "Bash",
            "hooks": [
              {
                "type": "command",
                "command": "python .claude/hooks/check_dangerous_commands.py"
              }
            ]
          }
        ]
      }
    }

    The hook script receives the tool call details on stdin as JSON. If it exits with code 2, the tool call is blocked:

    import json, sys
    
    data = json.load(sys.stdin)
    command = data.get("tool_input", {}).get("command", "")
    
    dangerous = ["rm -rf", "DROP TABLE", "> /dev/sda"]
    if any(d in command for d in dangerous):
        print(f"BLOCKED: dangerous pattern detected in command")
        sys.exit(2)  # non-zero exit blocks the tool call
    
    sys.exit(0)  # allow
    NOTE

    Hooks run with the same permissions as the Claude Code process. A hook that makes an outbound network call, modifies files, or reads secrets is executing with full process permissions. Audit hook scripts carefully.


    3.6 Subagents

    Subagents are Claude Code instances spawned by a parent Claude Code session to handle parallel or delegated work. The parent orchestrates; subagents execute.

    Key security rule for subagents. Always run subagents in a sandboxed environment with least privilege. A subagent reading a file that contains attacker-controlled content could be manipulated through prompt injection embedded in that file. The sandbox limits the blast radius.

    # Spawning a subagent with restricted file access
    subagent = claude.spawn_agent(
        task="Analyse the security vulnerabilities in src/api/",
        permissions={
            "read": ["src/api/**"],
            "write": [],          # no writes
            "execute": []         # no command execution
        }
    )

    Trust hierarchy. Parent agent receives verified instructions from the user. Subagent receives instructions from the parent — these should be treated as trusted but still validated. Tool results returned to the subagent from external systems are untrusted.


    3.7 Skills and Plugins

    Skills are reusable instruction sets packaged as Markdown files that can be invoked by name in any Claude Code session. They define a specific workflow (e.g., "run a security review", "generate a PR description"):

    # .claude/skills/pr-review.md
    
    ## When invoked
    User wants a pull request description for their changes.
    
    ## Steps
    1. Run `git diff main` to see changed files
    2. Summarise the purpose of changes in ≤3 bullets
    3. List testing approach
    4. Write a PR body in the standard template (see .claude/templates/pr.md)

    Invoke with: /pr-review in the Claude Code session.

    Plugins are packaged tools with code — an MCP server bundled as an npm/pip package. Install a plugin to add tools (file analysis, code indexing, API connectors) to any Claude Code session without writing custom integration code.

    Skills Plugins
    Contains Markdown instructions Code (MCP server)
    Adds Workflow patterns New tool capabilities
    Distribution .claude/ directory or shared repo npm/pip package
    Example Code review checklist GitHub connector, database browser

    3.8 MCP — Model Context Protocol

    MCP is a standard protocol for exposing tools, data, and prompts to Claude. It separates the concern of "what tools exist" from "who is using them" — build one MCP server and any MCP client (Claude Code, Claude Desktop, your own agent) can use it.

    Three primitives.

    Primitive What it does Direction
    Tools Execute actions, return results Client calls → Server executes → returns result
    Resources Provide read-only data (files, docs, schemas) Client requests → Server returns content
    Prompts Parameterised prompt templates Client requests → Server returns prompt text

    Most MCP servers expose primarily tools. Resources are used for document stores and structured reference data. Prompts are used for reusable prompt patterns.

    Minimal MCP server example (TypeScript):

    import { Server } from "@modelcontextprotocol/sdk/server/index.js";
    import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
    
    const server = new Server({
      name: "my-tools",
      version: "1.0.0"
    });
    
    server.setRequestHandler("tools/list", async () => ({
      tools: [{
        name: "get_issue",
        description: "Retrieve a GitHub issue by number. Returns title, body, labels, and status.",
        inputSchema: {
          type: "object",
          properties: {
            issue_number: { type: "number", description: "The issue number" }
          },
          required: ["issue_number"]
        }
      }]
    }));
    
    server.setRequestHandler("tools/call", async (request) => {
      if (request.params.name === "get_issue") {
        const issue = await fetchGitHubIssue(request.params.arguments.issue_number);
        return { content: [{ type: "text", text: JSON.stringify(issue) }] };
      }
    });
    
    const transport = new StdioServerTransport();
    await server.connect(transport);

    3.9 MCP Transport Options

    Transport Description When to use
    stdio Server communicates over stdin/stdout Local tools, CLI integration, CI/CD, process-local servers
    HTTP (Streamable) Server exposes an HTTP endpoint with streaming Remote shared servers, multi-client deployments
    SSE (legacy) Server-sent events over HTTP Legacy compatibility only; prefer Streamable HTTP for new servers

    For local-only tools in CI, stdio is the right choice: simplest setup, no port conflicts, no authentication needed.

    For shared servers (e.g., a company-wide GitHub MCP server accessed by all developers), HTTP with authentication is required. The server handles the OAuth flow or API key validation; the client never sees the credentials.


    3.10 MCP Scope and Configuration

    MCP servers can be configured at three scopes:

    Scope Where configured Applies to
    User ~/.claude/mcp_servers.json All sessions for this user
    Project .claude/mcp_servers.json All users of this project (committed to repo)
    Server-managed Returned by server at connect time Dynamic configuration per session

    Project-scoped MCP configuration (committed to repo):

    {
      "mcpServers": {
        "github": {
          "command": "npx",
          "args": ["-y", "@github/mcp-server"],
          "env": {
            "GITHUB_PERSONAL_ACCESS_TOKEN": "${GITHUB_TOKEN}"
          }
        },
        "postgres": {
          "command": "uvx",
          "args": ["mcp-server-postgres", "${DATABASE_URL}"]
        }
      }
    }

    Environment variables use the ${VAR} syntax and are resolved from the current shell environment — secrets stay out of the committed config file.


    3.11 Enterprise Integration Patterns

    Authentication for protected APIs. The MCP server handles auth; Claude never receives the underlying credential:

    Claude Code → MCP server (holds OAuth token) → Protected internal API

    This is the correct pattern. Claude sees only the tool results, not the API credentials. The MCP server is responsible for refreshing tokens and handling auth failures.

    Code modernisation use case. One of the highest-ROI enterprise uses of Claude Code is modernising legacy codebases:

    1. Configure CLAUDE.md with target coding standards (e.g., "migrate Spring Boot 2.x to 3.x")
    2. Set up MCP server with read access to the codebase index
    3. Use plan mode first — review the migration plan before applying
    4. Run in auto mode per-module — humans review each module's diff before merging

    Code review with calibrated trust. AI-generated code should receive the same scrutiny as code from an unfamiliar contributor:

    • Read every changed line — don't approve based on "Claude wrote it"
    • Run the full test suite — AI code can pass type-checking but fail integration tests
    • Verify security-sensitive paths manually — injection, auth, data validation
    • Check for logic correctness on edge cases — AI code often handles happy paths well but misses boundary conditions
    NOTE

    Calibrated trust means neither blind trust nor blanket skepticism. Apply the same bar you'd apply to any code submitted by someone who is smart but unfamiliar with your specific system's requirements.


    M3 Checkpoint

    • bypassPermissions = CI/CD only — never interactive
    • CLAUDE.md is read at every session start — it's the highest-leverage file for team adoption
    • Hooks exit code 2 = block the tool call — exit 0 = allow
    • Subagents must run in sandboxes — attacker-controlled file content can inject instructions
    • MCP tools = actions; resources = read-only data; prompts = templates
    • stdio for local/CI; HTTP for shared remote servers
    • MCP server handles auth — Claude never sees the underlying credentials

    Ask about this article

    Get answers grounded in this post. AI-generated — based on this article, and may be imperfect.

    Free: CCA Foundations cheat-sheet (PDF)

    The domains, the 3 universal rules, core concepts, and exam-day shortcuts — one page. Enter your email and it's yours, plus my weekly AI-architecture notes.

    No spam. Unsubscribe any time.

    Scaled AI Weekly

    Enjoyed this? Get more like it every Monday.

    Real architecture decisions, LLMOps patterns that survive production, and engineering leadership advice — from 12+ years of building at enterprise scale. Free. No spam. Unsubscribe anytime.

    Join engineers building production AI systems

    Comments