Claude
Skills
Sign in
โ† Back

claude-code-schema-validation

Included with Lifetime
$97 forever

Guide and workflow for Claude Code Schema Validation & Testing. Use when you need Claude Code Schema Validation & Testing.

AI Agents

What this skill does


# Claude Code Schema Validation & Testing

**Purpose**: Comprehensive guide for validating Claude Code settings.json and agent files using official and community tools.

## ๐ŸŽฏ Official JSON Schema Support (RESOLVED - Sept 2025)

As of **September 29, 2025**, Anthropic provides official JSON Schema validation for Claude Code settings.

### Official Schema URL
```
https://json.schemastore.org/claude-code-settings.json
```

**Source**: GitHub Issue #2783 - Closed as completed

## โœ… Using Official Schema Validation

### Step 1: Add Schema Reference to settings.json

Add the `$schema` field at the top of your settings.json:

```json
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "env": {
    "BASH_MAX_OUTPUT_LENGTH": "5000"
  },
  "permissions": {
    "allow": ["Bash(git:*)"]
  },
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "*",
        "hooks": [...]
      }
    ]
  }
}
```

### Step 2: Enable IDE Validation

Once the `$schema` field is added, your IDE will automatically:
- โœ… Validate settings structure
- โœ… Show errors for invalid fields
- โœ… Provide autocomplete for available options
- โœ… Display documentation on hover

**Supported IDEs**:
- VS Code
- IntelliJ IDEA
- WebStorm
- Any editor with JSON Schema support

## ๐Ÿงช Unit Testing Framework

### Option 1: Official Schema Validation (Recommended)

Use the official schema with standard JSON validation tools:

**Using Python (jsonschema)**:
```python
#!/usr/bin/env python3
"""Test Claude Code settings.json validation"""

import json
import requests
from jsonschema import validate, ValidationError

def test_settings_validation():
    """Validate settings.json against official schema"""

    # Fetch official schema
    schema_url = "https://json.schemastore.org/claude-code-settings.json"
    schema = requests.get(schema_url).json()

    # Load settings file
    with open('.claude/settings.json', 'r') as f:
        settings = json.load(f)

    # Validate
    try:
        validate(instance=settings, schema=schema)
        print("โœ… settings.json is valid")
        return True
    except ValidationError as e:
        print(f"โŒ Validation error: {e.message}")
        print(f"   Path: {' -> '.join(str(p) for p in e.path)}")
        return False

if __name__ == "__main__":
    success = test_settings_validation()
    exit(0 if success else 1)
```

**Using Node.js (ajv)**:
```javascript
#!/usr/bin/env node
const Ajv = require('ajv');
const fs = require('fs');
const https = require('https');

async function testSettingsValidation() {
  // Fetch official schema
  const schemaUrl = 'https://json.schemastore.org/claude-code-settings.json';
  const schema = await new Promise((resolve, reject) => {
    https.get(schemaUrl, (res) => {
      let data = '';
      res.on('data', chunk => data += chunk);
      res.on('end', () => resolve(JSON.parse(data)));
    }).on('error', reject);
  });

  // Load settings
  const settings = JSON.parse(fs.readFileSync('.claude/settings.json', 'utf8'));

  // Validate
  const ajv = new Ajv();
  const valid = ajv.validate(schema, settings);

  if (valid) {
    console.log('โœ… settings.json is valid');
    return true;
  } else {
    console.error('โŒ Validation errors:');
    ajv.errors.forEach(err => {
      console.error(`  - ${err.instancePath}: ${err.message}`);
    });
    return false;
  }
}

testSettingsValidation().then(success => process.exit(success ? 0 : 1));
```

### Option 2: Community Tools

**A. claude-code-settings-schema (npm)**

Generates local schema file for offline validation:

```bash
# Generate schema file
npx claude-code-settings-schema

# Your settings.json will reference local schema
{
  "$schema": "./claude-code-settings.schema.json",
  ...
}
```

**Benefits**:
- Offline validation
- IDE autocomplete and IntelliSense
- Based on official Anthropic documentation

**B. claude-json-validator (Python CLI)**

Standalone validator for settings files:

```bash
# Clone repository
git clone https://github.com/trial123Zel/claude-json-validator
cd claude-json-validator

# Setup
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate
pip install -r requirements.txt

# Validate
python claude-json-validator.py ~/.claude/settings.json
python claude-json-validator.py .claude/settings.json --verbose
python claude-json-validator.py settings.json --strict
```

**Exit Codes**:
- `0`: Valid (warnings allowed unless `--strict`)
- `1`: Errors found

## ๐Ÿ”ง Pre-Commit Hook Integration

### Method 1: Using Official Schema (Python)

**File**: `.claude/hooks/validate_settings.py`

```python
#!/usr/bin/env python3
"""Pre-commit hook to validate settings.json"""

import json
import sys
from pathlib import Path

try:
    import requests
    from jsonschema import validate, ValidationError
except ImportError:
    print("โš ๏ธ  jsonschema not installed, skipping validation")
    print("   Install with: pip install jsonschema requests")
    sys.exit(0)

def validate_settings():
    """Validate all settings.json files in the project"""

    schema_url = "https://json.schemastore.org/claude-code-settings.json"

    # Find settings files
    settings_files = [
        Path.home() / '.claude' / 'settings.json',
        Path('.claude') / 'settings.json',
    ]

    errors = []

    for settings_file in settings_files:
        if not settings_file.exists():
            continue

        print(f"๐Ÿ” Validating {settings_file}...")

        try:
            # Load schema
            schema = requests.get(schema_url, timeout=5).json()

            # Load settings
            with open(settings_file, 'r') as f:
                settings = json.load(f)

            # Validate
            validate(instance=settings, schema=schema)
            print(f"   โœ… Valid")

        except ValidationError as e:
            print(f"   โŒ Validation error: {e.message}")
            print(f"      Path: {' -> '.join(str(p) for p in e.path)}")
            errors.append((settings_file, e))
        except json.JSONDecodeError as e:
            print(f"   โŒ Invalid JSON: {e}")
            errors.append((settings_file, e))
        except Exception as e:
            print(f"   โš ๏ธ  Error validating: {e}")

    if errors:
        print(f"\nโŒ Found {len(errors)} validation error(s)")
        return False

    print(f"\nโœ… All settings files valid")
    return True

if __name__ == "__main__":
    success = validate_settings()
    sys.exit(0 if success else 1)
```

**Register in .claude/settings.json**:

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'if [[ \"$CLAUDE_TOOL_INPUT\" == *\"settings.json\"* ]]; then python3 .claude/hooks/validate_settings.py; fi'",
            "description": "Validate settings.json before writing"
          }
        ]
      }
    ]
  }
}
```

### Method 2: Using /doctor Command

The simplest validation method:

```bash
# Run validation
/doctor
```

**Advantages**:
- Built into Claude Code
- No external dependencies
- Validates settings, agents, hooks
- Fast and reliable

**Pre-commit hook**:

```bash
#!/bin/bash
# .claude/hooks/pre_commit_validation.sh

echo "๐Ÿ” Running Claude Code validation..."

# Run /doctor (requires claude CLI)
if command -v claude >/dev/null 2>&1; then
    claude /doctor --quiet || {
        echo "โŒ /doctor validation failed"
        exit 1
    }
    echo "โœ… /doctor validation passed"
else
    echo "โš ๏ธ  claude CLI not found, skipping /doctor validation"
fi

exit 0
```

## ๐Ÿงช Agent Frontmatter Validation

### Validation Script for Agent Files

**File**: `.claude/hooks/validate_agents.py`

```python
#!/usr/bin/env python3
"""Validate Claude Code agent frontmatter"""

import re
import sys
from pathlib import Path

def validate_agent_frontmatter(agent_file):
    """Validate agent file frontmatter"""

    with open(agent_file, 'r') as f:
        content = f.read()

    # Check for frontmatter
    if 

Related in AI Agents