Settings.json Schema — Claude Cert Academy

Settings.json Schema

Claude Code reads settings from settings.json (project or global) at startup. All keys are optional. Unknown keys are ignored.

Annotated Full Schema

{
  // Model to use by default. Overridden by --model flag.
  "model": "claude-opus-4-8",

  // Permission controls
  "permissions": {
    // Mode: "default" (prompt per tool), "auto" (no prompts), or "plan" (plan only)
    "mode": "default",

    // Tools (or tool+pattern) to allow without prompting in default mode
    "allow": [
      "Read",
      "Bash(npm test)",
      "Bash(npm run *)"
    ],

    // Tools (or tool+pattern) to block in all modes
    "deny": [
      "Bash(rm -rf *)",
      "Bash(git push --force*)",
      "Write(migrations/**)"
    ]
  },

  // Hooks: shell scripts invoked at agent lifecycle events
  "hooks": [
    {
      "event": "PreToolUse",
      "matcher": { "tool_name": "Bash" },
      "command": "/usr/local/bin/bash-guard.sh"
    },
    {
      "event": "PostToolUse",
      "command": "/usr/local/bin/audit-logger.sh"
    }
  ],

  // MCP server configurations
  "mcp": {
    "servers": [
      {
        "name": "my-db",
        "transport": "stdio",
        "command": "/usr/local/bin/mcp-db",
        "args": ["--config", "/etc/mcp/db.json"],
        "env": { "DB_URL": "postgres://localhost/mydb" }
      }
    ]
  },

  // Environment variables injected into every Claude Code session
  "env": {
    "NODE_ENV": "development",
    "LOG_LEVEL": "debug"
  }
}

Key Fields Reference

settings.json vs. settings.local.json

Never put ANTHROPIC_API_KEY or other secrets in settings.json. It is committed to the repo and visible to all contributors. Use settings.local.json or your shell profile instead.

Server-Managed Settings

Example: Complete Team settings.json

{
  "model": "claude-sonnet-4-6",
  "permissions": {
    "mode": "default",
    "allow": [
      "Read",
      "Bash(npm test)",
      "Bash(npm run lint)",
      "Bash(npm run build)"
    ],
    "deny": [
      "Bash(git push --force*)",
      "Bash(DROP TABLE*)",
      "Write(migrations/**)"
    ]
  },
  "hooks": [
    {
      "event": "PreToolUse",
      "matcher": { "tool_name": "Write", "tool_input.file_path": "migrations/**" },
      "command": "/usr/local/bin/migration-guard.sh"
    },
    {
      "event": "Stop",
      "command": "/usr/local/bin/session-audit.sh"
    }
  ],
  "mcp": {
    "servers": [
      {
        "name": "internal-docs",
        "transport": "http",
        "url": "https://mcp.internal.example.com/v1",
        "headers": { "Authorization": "Bearer ${INTERNAL_MCP_TOKEN}" }
      }
    ]
  },
  "env": {
    "NODE_ENV": "development"
  }
}

Pair settings.json with a settings.local.json.example file committed to the repo. The example shows which env vars to set (with placeholder values) so teammates know what to configure locally without exposing real credentials.

Continue to Claude Cert Academy