Install command
Provided
Validates GraphQL schema files and checks for breaking changes when modified.
Open the source and read safety notes before installing.
Source-backed facts for citing this resource, derived directly from the registry — also available as plain text for AI assistants.
Decision playbook
Signals are present but mixed. Use the checklist below to confirm the source and operational safety for your environment.
0
78
—
No baseline selected
No major trust-signal divergence detected in the current selection.
Confirm ownership and provenance before trusting install instructions.
Source link availableRequired
Open the canonical repository and verify ownership.
Source provenance statusRequired
Marked as source-backed.
Metadata reviewed
Registry metadata indicates a reviewed listing.
Validate risk disclosures before installation or API wiring.
Safety notes presentRequired
Review the listed safety guidance before running commands.
Privacy notes presentRequired
Review data handling notes before connecting accounts or secrets.
Trust level risk gateRequired
Trust level does not block evaluation.
Check package metadata and artifact integrity signals.
Install payload available
Install or copy payload is available for review.
Package verification flag
No package verification flag provided.
Checksum metadata
No checksum provided for downloaded artifact.
Use compare context to validate trade-offs before adoption.
Compare tray has multiple entries
Add at least one more entry to compare trust differences.
Baseline comparison available
No baseline peer selected yet.
Diverging trust signals identified
No major trust-signal divergence found.
Setup at a glance
Copy-ready — paste the snippet to get started.
Install command
Provided
Config snippet
Provided
Copy snippet
Provided
Prerequisites
None
Platforms
1 listed
Difficulty
0/100
Adoption plan
Current risk score 16/100. Use staged verification before broader rollout.
Validate source and review signals before any execution.
Confirm source provenanceRequired
Source URL/provenance metadata is present.
Confirm metadata review state
Listing has review metadata.
Verify install payload
Install/config payload exists and can be inspected.
Confirm safety, privacy, and package integrity signals.
Review safety notesRequired
Safety notes are present.
Review privacy notesRequired
Privacy notes are present.
Verify package integrity metadata
No package verification/checksum metadata.
Adopt in controlled steps based on the selected plan.
Run in isolated sandbox firstRequired
Use a constrained sandbox and observe behavior across multiple tasks.
Roll out graduallyRequired
Roll out to a small cohort before wider usage.
Set monitoring and fallback
Define rollback path and monitor errors after adoption.
Evidence readiness
Required evidence gates are covered (5/6 signals complete).
Source repository/provenance is listed.
Required in this preset
Review metadata is present.
Required in this preset
Safety notes are present.
Required in this preset
Privacy notes are present.
Optional in this preset
Package integrity metadata is missing.
Optional in this preset
Install payload is available.
Required in this preset
Required evidence gates are covered for this preset.
Decision timeline
5/6 steps complete with no blocking gaps for this preset.
triage
Source/provenance metadata is available.
triage
Review metadata is available.
verify
Safety notes are available.
verify
Privacy notes are available.
verify
Package integrity metadata is missing.
rollout
Install payload is available.
No required blockers for this timeline preset.
Safety & privacy surface
1 safety and 1 privacy notes across 2 risk areas. Review closely: credentials & tokens, permissions & scopes.
#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a GraphQL schema file
if [[ "$FILE_PATH" == *.graphql ]] || [[ "$FILE_PATH" == *.gql ]] || [[ "$FILE_PATH" == *schema* ]]; then
echo "🔍 GraphQL Schema Validation for: $(basename "$FILE_PATH")" >&2
# Initialize validation counters
ERRORS=0
WARNINGS=0
VALIDATIONS=0
BREAKING_CHANGES=0
# Function to report validation results
report_validation() {
local level="$1"
local message="$2"
case "$level" in
"ERROR")
echo "❌ ERROR: $message" >&2
ERRORS=$((ERRORS + 1))
;;
"WARNING")
echo "⚠️ WARNING: $message" >&2
WARNINGS=$((WARNINGS + 1))
;;
"BREAKING")
echo "💥 BREAKING CHANGE: $message" >&2
BREAKING_CHANGES=$((BREAKING_CHANGES + 1))
;;
"PASS")
echo "✅ PASS: $message" >&2
VALIDATIONS=$((VALIDATIONS + 1))
;;
"INFO")
echo "ℹ️ INFO: $message" >&2
;;
esac
}
# Check if file exists and is readable
if [ ! -f "$FILE_PATH" ]; then
report_validation "ERROR" "Schema file not found: $FILE_PATH"
exit 1
fi
if [ ! -r "$FILE_PATH" ]; then
report_validation "ERROR" "Schema file is not readable: $FILE_PATH"
exit 1
fi
# Basic file info
FILE_SIZE=$(wc -c < "$FILE_PATH" 2>/dev/null || echo "0")
echo "📊 Schema file: $(basename "$FILE_PATH") ($(( FILE_SIZE / 1024 ))KB)" >&2
# 1. Basic GraphQL Syntax Validation
echo "📋 Checking GraphQL syntax..." >&2
# Check for basic GraphQL structure
if ! grep -q -E '(type|interface|enum|scalar|input|directive)' "$FILE_PATH" 2>/dev/null; then
report_validation "ERROR" "File doesn't appear to contain valid GraphQL schema definitions"
else
report_validation "PASS" "Basic GraphQL structure detected"
fi
# Check for common syntax errors
if grep -q ',$' "$FILE_PATH" 2>/dev/null; then
report_validation "WARNING" "Trailing commas detected - may cause parsing issues"
fi
# Check for proper type definitions
TYPE_COUNT=$(grep -c '^type ' "$FILE_PATH" 2>/dev/null || echo "0")
INTERFACE_COUNT=$(grep -c '^interface ' "$FILE_PATH" 2>/dev/null || echo "0")
ENUM_COUNT=$(grep -c '^enum ' "$FILE_PATH" 2>/dev/null || echo "0")
INPUT_COUNT=$(grep -c '^input ' "$FILE_PATH" 2>/dev/null || echo "0")
echo " 📊 Schema composition:" >&2
echo " Types: $TYPE_COUNT" >&2
echo " Interfaces: $INTERFACE_COUNT" >&2
echo " Enums: $ENUM_COUNT" >&2
echo " Inputs: $INPUT_COUNT" >&2
# 2. Advanced Validation with graphql-inspector (if available)
echo "🔍 Running advanced validation..." >&2
if command -v npx &> /dev/null; then
echo " Using graphql-inspector for comprehensive validation..." >&2
# Try to validate with graphql-inspector
if npx graphql-inspector validate "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "graphql-inspector validation successful"
else
# Check if graphql-inspector is available
if ! npx graphql-inspector --version &> /dev/null; then
echo " 📦 Installing graphql-inspector..." >&2
if npm install -g @graphql-inspector/cli 2>/dev/null; then
echo " ✅ graphql-inspector installed" >&2
if npx graphql-inspector validate "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "graphql-inspector validation successful (after install)"
else
report_validation "ERROR" "graphql-inspector validation failed"
fi
else
report_validation "WARNING" "Unable to install graphql-inspector - validation limited"
fi
else
report_validation "ERROR" "graphql-inspector validation failed"
fi
fi
else
report_validation "WARNING" "Node.js/npm not available - using basic validation only"
fi
# 3. Breaking Change Detection
echo "💥 Checking for breaking changes..." >&2
BACKUP_FILE="${FILE_PATH}.backup"
SCHEMA_BACKUP_DIR=".graphql_backups"
# Create backup directory if it doesn't exist
[ ! -d "$SCHEMA_BACKUP_DIR" ] && mkdir -p "$SCHEMA_BACKUP_DIR"
# Generate timestamped backup filename
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
TIMESTAMPED_BACKUP="$SCHEMA_BACKUP_DIR/$(basename "$FILE_PATH").${TIMESTAMP}.backup"
if [ -f "$BACKUP_FILE" ]; then
echo " 📋 Comparing with previous version..." >&2
# Try graphql-inspector diff if available
if command -v npx &> /dev/null && npx graphql-inspector --version &> /dev/null; then
DIFF_OUTPUT=$(npx graphql-inspector diff "$BACKUP_FILE" "$FILE_PATH" 2>&1)
DIFF_EXIT_CODE=$?
if [ $DIFF_EXIT_CODE -eq 0 ]; then
report_validation "PASS" "No breaking changes detected"
else
# Parse diff output for breaking changes
if echo "$DIFF_OUTPUT" | grep -q "BREAKING"; then
report_validation "BREAKING" "Breaking changes detected in schema"
echo "$DIFF_OUTPUT" | grep "BREAKING" | head -5 >&2
else
report_validation "WARNING" "Schema changes detected (non-breaking)"
fi
fi
else
# Basic diff comparison
if ! diff -q "$BACKUP_FILE" "$FILE_PATH" > /dev/null 2>&1; then
report_validation "WARNING" "Schema has changed (basic diff check)"
# Look for potentially breaking changes
if diff "$BACKUP_FILE" "$FILE_PATH" | grep -q '^<.*type\|^<.*field\|^<.*enum'; then
report_validation "BREAKING" "Potential breaking changes detected (type/field/enum removals)"
fi
else
report_validation "PASS" "No changes detected"
fi
fi
# Create timestamped backup of previous version
cp "$BACKUP_FILE" "$TIMESTAMPED_BACKUP"
echo " 📁 Previous version backed up to: $TIMESTAMPED_BACKUP" >&2
else
echo " ℹ️ No previous version found - first time validation" >&2
fi
# 4. Schema Quality Analysis
echo "📊 Analyzing schema quality..." >&2
# Check for Query, Mutation, Subscription types
if grep -q '^type Query' "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "Query type found"
else
report_validation "WARNING" "No Query type defined - schema may be incomplete"
fi
if grep -q '^type Mutation' "$FILE_PATH" 2>/dev/null; then
echo " ✅ Mutation type found" >&2
else
echo " ℹ️ No Mutation type (read-only API)" >&2
fi
if grep -q '^type Subscription' "$FILE_PATH" 2>/dev/null; then
echo " ✅ Subscription type found" >&2
else
echo " ℹ️ No Subscription type (no real-time features)" >&2
fi
# Check for proper field documentation
DOCUMENTED_FIELDS=$(grep -c '"""' "$FILE_PATH" 2>/dev/null || echo "0")
TOTAL_FIELDS=$(grep -c ':' "$FILE_PATH" 2>/dev/null || echo "1")
if [ "$DOCUMENTED_FIELDS" -gt 0 ]; then
DOCUMENTATION_RATIO=$((DOCUMENTED_FIELDS * 100 / TOTAL_FIELDS))
if [ "$DOCUMENTATION_RATIO" -gt 50 ]; then
report_validation "PASS" "Good documentation coverage (${DOCUMENTATION_RATIO}%)"
else
report_validation "WARNING" "Low documentation coverage (${DOCUMENTATION_RATIO}%)"
fi
else
report_validation "WARNING" "No field documentation found - consider adding descriptions"
fi
# 5. Federation Schema Checks (if applicable)
if grep -q '@key\|@external\|@provides\|@requires' "$FILE_PATH" 2>/dev/null; then
echo "🌐 Federation directives detected - checking federation compatibility..." >&2
if grep -q '@key' "$FILE_PATH" && grep -q 'extend type' "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "Federation schema structure looks valid"
else
report_validation "WARNING" "Federation directives found but schema structure may be incomplete"
fi
fi
# 6. Schema Complexity Analysis
echo "📈 Analyzing schema complexity..." >&2
NESTING_DEPTH=$(grep -o ' ' "$FILE_PATH" | wc -l 2>/dev/null || echo "0")
if [ "$NESTING_DEPTH" -gt 1000 ]; then
report_validation "WARNING" "High schema complexity detected - consider simplification"
else
echo " ✅ Schema complexity within acceptable range" >&2
fi
# Check for circular references (basic check)
if grep -E 'type.*:.*\[.*\]' "$FILE_PATH" | grep -q -E '(User.*User|Post.*Post|Comment.*Comment)' 2>/dev/null; then
report_validation "WARNING" "Potential circular references detected - review carefully"
fi
# 7. Security and Best Practices
echo "🔒 Security and best practices check..." >&2
# Check for potentially dangerous query patterns
if grep -q 'allUsers\|allPosts\|everything' "$FILE_PATH" 2>/dev/null; then
report_validation "WARNING" "Potentially dangerous 'all' queries detected - ensure proper pagination"
fi
# Check for proper input validation types
if [ "$INPUT_COUNT" -gt 0 ]; then
echo " ✅ Input types defined for mutations" >&2
elif grep -q '^type Mutation' "$FILE_PATH" 2>/dev/null; then
report_validation "WARNING" "Mutations found but no input types - consider using input types"
fi
# Update backup for next comparison
cp "$FILE_PATH" "$BACKUP_FILE"
echo " 💾 Current version backed up for future comparisons" >&2
# 8. Generate Validation Summary
echo "" >&2
echo "📋 GraphQL Schema Validation Summary:" >&2
echo "===================================" >&2
echo " 📄 Schema: $(basename "$FILE_PATH")" >&2
echo " 📏 Size: $(( FILE_SIZE / 1024 ))KB" >&2
echo " 📊 Types: $TYPE_COUNT, Interfaces: $INTERFACE_COUNT, Enums: $ENUM_COUNT" >&2
echo " ✅ Validations Passed: $VALIDATIONS" >&2
echo " ⚠️ Warnings: $WARNINGS" >&2
echo " ❌ Errors: $ERRORS" >&2
echo " 💥 Breaking Changes: $BREAKING_CHANGES" >&2
if [ "$ERRORS" -eq 0 ] && [ "$BREAKING_CHANGES" -eq 0 ]; then
if [ "$WARNINGS" -eq 0 ]; then
echo " 🎉 Status: EXCELLENT - Schema is valid and well-formed" >&2
else
echo " ✅ Status: GOOD - Schema is valid with minor recommendations" >&2
fi
elif [ "$ERRORS" -eq 0 ]; then
echo " ⚠️ Status: BREAKING CHANGES - Review impact before deployment" >&2
else
echo " ❌ Status: ERRORS - Schema has critical issues that must be fixed" >&2
fi
echo "" >&2
echo "💡 GraphQL Schema Best Practices:" >&2
echo " • Use descriptive type and field names" >&2
echo " • Add documentation with triple quotes \"\"\"" >&2
echo " • Use input types for mutations" >&2
echo " • Implement proper pagination for collections" >&2
echo " • Version your schema changes carefully" >&2
echo " • Use enums for predefined values" >&2
# Clean up old backups (keep last 10)
if [ -d "$SCHEMA_BACKUP_DIR" ]; then
ls -t "$SCHEMA_BACKUP_DIR"/*.backup 2>/dev/null | tail -n +11 | xargs rm -f 2>/dev/null || true
fi
# Exit with error if there are critical issues
if [ "$ERRORS" -gt 0 ]; then
echo "⚠️ Schema validation completed with errors" >&2
exit 1
fi
else
# Not a GraphQL file, exit silently
exit 0
fi
exit 0{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/graphql-schema-validator.sh",
"matchers": [
"write",
"edit"
]
}
}
}.claude/settings.local.json~/.claude/settings.json.claude/settings.json{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/graphql-schema-validator.sh",
"matchers": ["write", "edit"]
}
}
}
#!/usr/bin/env bash
# Read the tool input from stdin
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name')
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
# Check if this is a GraphQL schema file
if [[ "$FILE_PATH" == *.graphql ]] || [[ "$FILE_PATH" == *.gql ]] || [[ "$FILE_PATH" == *schema* ]]; then
echo "🔍 GraphQL Schema Validation for: $(basename "$FILE_PATH")" >&2
# Initialize validation counters
ERRORS=0
WARNINGS=0
VALIDATIONS=0
BREAKING_CHANGES=0
# Function to report validation results
report_validation() {
local level="$1"
local message="$2"
case "$level" in
"ERROR")
echo "❌ ERROR: $message" >&2
ERRORS=$((ERRORS + 1))
;;
"WARNING")
echo "⚠️ WARNING: $message" >&2
WARNINGS=$((WARNINGS + 1))
;;
"BREAKING")
echo "💥 BREAKING CHANGE: $message" >&2
BREAKING_CHANGES=$((BREAKING_CHANGES + 1))
;;
"PASS")
echo "✅ PASS: $message" >&2
VALIDATIONS=$((VALIDATIONS + 1))
;;
"INFO")
echo "ℹ️ INFO: $message" >&2
;;
esac
}
# Check if file exists and is readable
if [ ! -f "$FILE_PATH" ]; then
report_validation "ERROR" "Schema file not found: $FILE_PATH"
exit 1
fi
if [ ! -r "$FILE_PATH" ]; then
report_validation "ERROR" "Schema file is not readable: $FILE_PATH"
exit 1
fi
# Basic file info
FILE_SIZE=$(wc -c < "$FILE_PATH" 2>/dev/null || echo "0")
echo "📊 Schema file: $(basename "$FILE_PATH") ($(( FILE_SIZE / 1024 ))KB)" >&2
# 1. Basic GraphQL Syntax Validation
echo "📋 Checking GraphQL syntax..." >&2
# Check for basic GraphQL structure
if ! grep -q -E '(type|interface|enum|scalar|input|directive)' "$FILE_PATH" 2>/dev/null; then
report_validation "ERROR" "File doesn't appear to contain valid GraphQL schema definitions"
else
report_validation "PASS" "Basic GraphQL structure detected"
fi
# Check for common syntax errors
if grep -q ',$' "$FILE_PATH" 2>/dev/null; then
report_validation "WARNING" "Trailing commas detected - may cause parsing issues"
fi
# Check for proper type definitions
TYPE_COUNT=$(grep -c '^type ' "$FILE_PATH" 2>/dev/null || echo "0")
INTERFACE_COUNT=$(grep -c '^interface ' "$FILE_PATH" 2>/dev/null || echo "0")
ENUM_COUNT=$(grep -c '^enum ' "$FILE_PATH" 2>/dev/null || echo "0")
INPUT_COUNT=$(grep -c '^input ' "$FILE_PATH" 2>/dev/null || echo "0")
echo " 📊 Schema composition:" >&2
echo " Types: $TYPE_COUNT" >&2
echo " Interfaces: $INTERFACE_COUNT" >&2
echo " Enums: $ENUM_COUNT" >&2
echo " Inputs: $INPUT_COUNT" >&2
# 2. Advanced Validation with graphql-inspector (if available)
echo "🔍 Running advanced validation..." >&2
if command -v npx &> /dev/null; then
echo " Using graphql-inspector for comprehensive validation..." >&2
# Try to validate with graphql-inspector
if npx graphql-inspector validate "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "graphql-inspector validation successful"
else
# Check if graphql-inspector is available
if ! npx graphql-inspector --version &> /dev/null; then
echo " 📦 Installing graphql-inspector..." >&2
if npm install -g @graphql-inspector/cli 2>/dev/null; then
echo " ✅ graphql-inspector installed" >&2
if npx graphql-inspector validate "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "graphql-inspector validation successful (after install)"
else
report_validation "ERROR" "graphql-inspector validation failed"
fi
else
report_validation "WARNING" "Unable to install graphql-inspector - validation limited"
fi
else
report_validation "ERROR" "graphql-inspector validation failed"
fi
fi
else
report_validation "WARNING" "Node.js/npm not available - using basic validation only"
fi
# 3. Breaking Change Detection
echo "💥 Checking for breaking changes..." >&2
BACKUP_FILE="${FILE_PATH}.backup"
SCHEMA_BACKUP_DIR=".graphql_backups"
# Create backup directory if it doesn't exist
[ ! -d "$SCHEMA_BACKUP_DIR" ] && mkdir -p "$SCHEMA_BACKUP_DIR"
# Generate timestamped backup filename
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
TIMESTAMPED_BACKUP="$SCHEMA_BACKUP_DIR/$(basename "$FILE_PATH").${TIMESTAMP}.backup"
if [ -f "$BACKUP_FILE" ]; then
echo " 📋 Comparing with previous version..." >&2
# Try graphql-inspector diff if available
if command -v npx &> /dev/null && npx graphql-inspector --version &> /dev/null; then
DIFF_OUTPUT=$(npx graphql-inspector diff "$BACKUP_FILE" "$FILE_PATH" 2>&1)
DIFF_EXIT_CODE=$?
if [ $DIFF_EXIT_CODE -eq 0 ]; then
report_validation "PASS" "No breaking changes detected"
else
# Parse diff output for breaking changes
if echo "$DIFF_OUTPUT" | grep -q "BREAKING"; then
report_validation "BREAKING" "Breaking changes detected in schema"
echo "$DIFF_OUTPUT" | grep "BREAKING" | head -5 >&2
else
report_validation "WARNING" "Schema changes detected (non-breaking)"
fi
fi
else
# Basic diff comparison
if ! diff -q "$BACKUP_FILE" "$FILE_PATH" > /dev/null 2>&1; then
report_validation "WARNING" "Schema has changed (basic diff check)"
# Look for potentially breaking changes
if diff "$BACKUP_FILE" "$FILE_PATH" | grep -q '^<.*type\|^<.*field\|^<.*enum'; then
report_validation "BREAKING" "Potential breaking changes detected (type/field/enum removals)"
fi
else
report_validation "PASS" "No changes detected"
fi
fi
# Create timestamped backup of previous version
cp "$BACKUP_FILE" "$TIMESTAMPED_BACKUP"
echo " 📁 Previous version backed up to: $TIMESTAMPED_BACKUP" >&2
else
echo " ℹ️ No previous version found - first time validation" >&2
fi
# 4. Schema Quality Analysis
echo "📊 Analyzing schema quality..." >&2
# Check for Query, Mutation, Subscription types
if grep -q '^type Query' "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "Query type found"
else
report_validation "WARNING" "No Query type defined - schema may be incomplete"
fi
if grep -q '^type Mutation' "$FILE_PATH" 2>/dev/null; then
echo " ✅ Mutation type found" >&2
else
echo " ℹ️ No Mutation type (read-only API)" >&2
fi
if grep -q '^type Subscription' "$FILE_PATH" 2>/dev/null; then
echo " ✅ Subscription type found" >&2
else
echo " ℹ️ No Subscription type (no real-time features)" >&2
fi
# Check for proper field documentation
DOCUMENTED_FIELDS=$(grep -c '"""' "$FILE_PATH" 2>/dev/null || echo "0")
TOTAL_FIELDS=$(grep -c ':' "$FILE_PATH" 2>/dev/null || echo "1")
if [ "$DOCUMENTED_FIELDS" -gt 0 ]; then
DOCUMENTATION_RATIO=$((DOCUMENTED_FIELDS * 100 / TOTAL_FIELDS))
if [ "$DOCUMENTATION_RATIO" -gt 50 ]; then
report_validation "PASS" "Good documentation coverage (${DOCUMENTATION_RATIO}%)"
else
report_validation "WARNING" "Low documentation coverage (${DOCUMENTATION_RATIO}%)"
fi
else
report_validation "WARNING" "No field documentation found - consider adding descriptions"
fi
# 5. Federation Schema Checks (if applicable)
if grep -q '@key\|@external\|@provides\|@requires' "$FILE_PATH" 2>/dev/null; then
echo "🌐 Federation directives detected - checking federation compatibility..." >&2
if grep -q '@key' "$FILE_PATH" && grep -q 'extend type' "$FILE_PATH" 2>/dev/null; then
report_validation "PASS" "Federation schema structure looks valid"
else
report_validation "WARNING" "Federation directives found but schema structure may be incomplete"
fi
fi
# 6. Schema Complexity Analysis
echo "📈 Analyzing schema complexity..." >&2
NESTING_DEPTH=$(grep -o ' ' "$FILE_PATH" | wc -l 2>/dev/null || echo "0")
if [ "$NESTING_DEPTH" -gt 1000 ]; then
report_validation "WARNING" "High schema complexity detected - consider simplification"
else
echo " ✅ Schema complexity within acceptable range" >&2
fi
# Check for circular references (basic check)
if grep -E 'type.*:.*\[.*\]' "$FILE_PATH" | grep -q -E '(User.*User|Post.*Post|Comment.*Comment)' 2>/dev/null; then
report_validation "WARNING" "Potential circular references detected - review carefully"
fi
# 7. Security and Best Practices
echo "🔒 Security and best practices check..." >&2
# Check for potentially dangerous query patterns
if grep -q 'allUsers\|allPosts\|everything' "$FILE_PATH" 2>/dev/null; then
report_validation "WARNING" "Potentially dangerous 'all' queries detected - ensure proper pagination"
fi
# Check for proper input validation types
if [ "$INPUT_COUNT" -gt 0 ]; then
echo " ✅ Input types defined for mutations" >&2
elif grep -q '^type Mutation' "$FILE_PATH" 2>/dev/null; then
report_validation "WARNING" "Mutations found but no input types - consider using input types"
fi
# Update backup for next comparison
cp "$FILE_PATH" "$BACKUP_FILE"
echo " 💾 Current version backed up for future comparisons" >&2
# 8. Generate Validation Summary
echo "" >&2
echo "📋 GraphQL Schema Validation Summary:" >&2
echo "===================================" >&2
echo " 📄 Schema: $(basename "$FILE_PATH")" >&2
echo " 📏 Size: $(( FILE_SIZE / 1024 ))KB" >&2
echo " 📊 Types: $TYPE_COUNT, Interfaces: $INTERFACE_COUNT, Enums: $ENUM_COUNT" >&2
echo " ✅ Validations Passed: $VALIDATIONS" >&2
echo " ⚠️ Warnings: $WARNINGS" >&2
echo " ❌ Errors: $ERRORS" >&2
echo " 💥 Breaking Changes: $BREAKING_CHANGES" >&2
if [ "$ERRORS" -eq 0 ] && [ "$BREAKING_CHANGES" -eq 0 ]; then
if [ "$WARNINGS" -eq 0 ]; then
echo " 🎉 Status: EXCELLENT - Schema is valid and well-formed" >&2
else
echo " ✅ Status: GOOD - Schema is valid with minor recommendations" >&2
fi
elif [ "$ERRORS" -eq 0 ]; then
echo " ⚠️ Status: BREAKING CHANGES - Review impact before deployment" >&2
else
echo " ❌ Status: ERRORS - Schema has critical issues that must be fixed" >&2
fi
echo "" >&2
echo "💡 GraphQL Schema Best Practices:" >&2
echo " • Use descriptive type and field names" >&2
echo " • Add documentation with triple quotes \"\"\"" >&2
echo " • Use input types for mutations" >&2
echo " • Implement proper pagination for collections" >&2
echo " • Version your schema changes carefully" >&2
echo " • Use enums for predefined values" >&2
# Clean up old backups (keep last 10)
if [ -d "$SCHEMA_BACKUP_DIR" ]; then
ls -t "$SCHEMA_BACKUP_DIR"/*.backup 2>/dev/null | tail -n +11 | xargs rm -f 2>/dev/null || true
fi
# Exit with error if there are critical issues
if [ "$ERRORS" -gt 0 ]; then
echo "⚠️ Schema validation completed with errors" >&2
exit 1
fi
else
# Not a GraphQL file, exit silently
exit 0
fi
exit 0
Complete hook script that performs GraphQL schema validation
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [ -z "$FILE_PATH" ]; then
exit 0
fi
if [[ "$FILE_PATH" == *.graphql ]] || [[ "$FILE_PATH" == *.gql ]]; then
echo "🔍 GraphQL Schema Validation for: $(basename "$FILE_PATH")" >&2
if command -v npx &> /dev/null; then
if npx graphql-inspector validate "$FILE_PATH" 2>/dev/null; then
echo "✅ graphql-inspector validation successful" >&2
else
echo "❌ graphql-inspector validation failed" >&2
exit 1
fi
else
if grep -q -E '(type|interface|enum|scalar|input|directive)' "$FILE_PATH" 2>/dev/null; then
echo "✅ Basic GraphQL structure detected" >&2
else
echo "❌ File doesn't appear to contain valid GraphQL schema" >&2
exit 1
fi
fi
fi
exit 0
Complete hook configuration for .claude/settings.json to enable schema validation
{
"hooks": {
"postToolUse": {
"script": "./.claude/hooks/graphql-schema-validator.sh",
"matchers": ["write", "edit"]
}
}
}
Enhanced hook script for breaking change detection with graphql-inspector
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
BACKUP_FILE="${FILE_PATH}.backup"
if [[ "$FILE_PATH" == *.graphql ]] || [[ "$FILE_PATH" == *.gql ]]; then
if [ -f "$BACKUP_FILE" ] && command -v npx &> /dev/null && npx graphql-inspector --version &> /dev/null; then
DIFF_OUTPUT=$(npx graphql-inspector diff "$BACKUP_FILE" "$FILE_PATH" 2>&1)
if echo "$DIFF_OUTPUT" | grep -q "BREAKING"; then
echo "💥 BREAKING CHANGE: Breaking changes detected in schema" >&2
echo "$DIFF_OUTPUT" | grep "BREAKING" | head -5 >&2
exit 1
else
echo "✅ No breaking changes detected" >&2
fi
fi
cp "$FILE_PATH" "$BACKUP_FILE"
fi
exit 0
Enhanced hook script for schema quality analysis and federation compatibility checking
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
if [[ "$FILE_PATH" == *.graphql ]] || [[ "$FILE_PATH" == *.gql ]]; then
TYPE_COUNT=$(grep -c '^type ' "$FILE_PATH" 2>/dev/null || echo "0")
INTERFACE_COUNT=$(grep -c '^interface ' "$FILE_PATH" 2>/dev/null || echo "0")
ENUM_COUNT=$(grep -c '^enum ' "$FILE_PATH" 2>/dev/null || echo "0")
INPUT_COUNT=$(grep -c '^input ' "$FILE_PATH" 2>/dev/null || echo "0")
echo "📊 Schema composition:" >&2
echo " Types: $TYPE_COUNT" >&2
echo " Interfaces: $INTERFACE_COUNT" >&2
echo " Enums: $ENUM_COUNT" >&2
echo " Inputs: $INPUT_COUNT" >&2
if grep -q '@key\|@external\|@provides\|@requires' "$FILE_PATH" 2>/dev/null; then
echo "🌐 Federation directives detected" >&2
if grep -q '@key' "$FILE_PATH" && grep -q 'extend type' "$FILE_PATH" 2>/dev/null; then
echo "✅ Federation schema structure looks valid" >&2
else
echo "⚠️ Federation directives found but schema structure may be incomplete" >&2
fi
fi
fi
exit 0
Enhanced hook script for automatic schema backup with timestamped backups and cleanup
#!/usr/bin/env bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path // ""')
SCHEMA_BACKUP_DIR=".graphql_backups"
if [[ "$FILE_PATH" == *.graphql ]] || [[ "$FILE_PATH" == *.gql ]]; then
[ ! -d "$SCHEMA_BACKUP_DIR" ] && mkdir -p "$SCHEMA_BACKUP_DIR"
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
TIMESTAMPED_BACKUP="$SCHEMA_BACKUP_DIR/$(basename "$FILE_PATH").${TIMESTAMP}.backup"
cp "$FILE_PATH" "$TIMESTAMPED_BACKUP"
echo "💾 Schema backed up to: $TIMESTAMPED_BACKUP" >&2
ls -t "$SCHEMA_BACKUP_DIR"/*.backup 2>/dev/null | tail -n +11 | xargs rm -f 2>/dev/null || true
echo "🧹 Old backups cleaned (keeping last 10)" >&2
fi
exit 0
Tighten matchers to specific paths: 'matchers': ['write:.*\.(graphql|gql)$', 'edit:.schema.']. Prevents false positives on files with 'schema' in non-GraphQL contexts. Verify file extension matching logic. Test with various file names containing 'schema'.
Pre-install globally: 'npm install -g @graphql-inspector/cli'. Hook's mid-execution installs timeout. Add installation check at project setup instead of runtime. Verify npm and Node.js are available. Check network connectivity for npm install.
Requires valid schemas. If backup corrupted, create fresh: 'cp schema.graphql schema.graphql.backup'. Verify parsing with 'npx graphql-inspector validate' before comparison. Ensure backup file is valid GraphQL schema. Check graphql-inspector version compatibility.
Cleanup misses timestamped backups in .graphql_backups/. Add: 'find .graphql_backups -name "*.backup" -type f | sort -r | tail -n +11 | xargs rm -f' to retention. Verify cleanup command executes correctly. Check file permissions for backup directory.
graphql-inspector is whitespace-sensitive. Run 'prettier --write */.graphql' before comparisons. Add normalization: format both schemas with GraphQL formatter before diff. Use graphql-inspector format command. Verify schema formatting consistency.
Verify federation directives are properly formatted. Check @key directive usage: '@key(fields: "id")'. Ensure extend type is used correctly for federation. Use graphql-inspector for federation-specific validation. Verify Apollo Federation version compatibility.
Complexity analysis uses basic heuristics. Adjust complexity thresholds in hook script. Consider using graphql-inspector for more accurate complexity analysis. Verify nesting depth calculation logic. Use schema-specific complexity rules.
graphql-inspector may require directive definitions. Add directive definitions to schema: 'directive @custom on FIELD_DEFINITION'. Verify custom directive syntax. Use graphql-inspector with --require-directives flag. Check directive definition format.
GraphQL Schema Validator - Hooks side by side with 3 alternatives on trust, install, platform support, and disclosed safety notes — all from reviewed registry metadata.
| Field | Validates GraphQL schema files and checks for breaking changes when modified. Open dossier | Validates JSON files against their schemas when modified to ensure data integrity. Open dossier | Validates AWS CloudFormation templates for syntax errors and best practices using cfn-lint v1.40.4+ and AWS CLI v2.27.54+. Open dossier | Validates environment variables, checks for required vars, and ensures proper configuration across environments. Open dossier |
|---|---|---|---|---|
| Next steps | ||||
| Trust | ||||
| Review status | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed | ReviewedMaintainer reviewed |
| Package trust | Package not verified | Package not verified | Package not verified | Package not verified |
| Source provenance | Source-backed | Source-backed | Source-backed | Source-backed |
| Submitter | — | — | — | — |
| Install risk | Review first | Review first | Review first | Review first |
| Notes | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ | Safety ✓ Privacy ✓ |
| Brand | — | — | — | |
| Category | hooks | hooks | hooks | hooks |
| Source | source-backed | source-backed | source-backed | source-backed |
| Author | JSONbored | JSONbored | JSONbored | JSONbored |
| Added | 2025-09-19 | 2025-09-19 | 2025-09-19 | 2025-09-16 |
| Platforms | Claude Code | Claude Code | Claude Code | Claude Code |
| Source repo | — | — | — | — |
| Safety notes | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. | ✓Runs automatically on its configured Claude Code hook event and executes shell logic that can read, modify, or delete files in your project (and may run builds, installs, or network calls); review the script and scope it to expected paths before enabling. |
| Privacy notes | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. | ✓Receives Claude Code hook input (session metadata, file paths, and tool output) and reads local project files; review what the script logs or forwards to external services and keep credentials out of its output. |
| Prerequisites | — none listed | — none listed | — none listed | — none listed |
| Install | | | | |
| Config | | | | |
| Citations | ||||
| Claim | Unclaimed | Unclaimed | Unclaimed | Unclaimed |
Source-backed guides for putting this to work.
Loading live community signals…
A short, calm digest of reviewed Claude resources. Unsubscribe any time.