- Detect the actual tech stack from lock files and config files (not assumptions)
- Read existing .claude/settings.local.json and .mcp.json to understand current state
- Include both read-only AND development commands appropriate for each detected tool
- Only include commands for tools actually detected in the project
- Never include absolute paths, user-specific paths, or destructive system commands
Generating settings without detection = wrong package manager commands, missing tools, security risks
This is not optional. Every recommendation requires stack verification.
Update Claude Settings
MANDATORY FIRST RESPONSE PROTOCOL
Before generating ANY settings, you MUST complete this checklist:
- ☐ List all files in the repository root (
ls -la)
- ☐ Detect config and lock files (package.json, pyproject.toml, go.mod, Cargo.toml, etc.)
- ☐ Read dependency files to identify frameworks and libraries
- ☐ Check for monorepo indicators (lerna.json, nx.json, turbo.json, pnpm-workspace.yaml)
- ☐ Check for service integrations (Sentry, Linear, etc.)
- ☐ Read existing .claude/settings.local.json (if it exists)
- ☐ Read existing .mcp.json (if it exists)
- ☐ Announce: "Detected [stack]: generating settings for [N] command categories and [M] WebFetch domains"
Generating settings WITHOUT completing this checklist = wrong permissions and missed tools.
Overview
Analyze a repository to generate recommended Claude Code settings.local.json permissions for read-only commands. Detects the tech stack, build tools, frameworks, services, and monorepo structure to produce accurate, project-specific recommendations.
What this skill does:
- Detects languages, package managers, frameworks, and build tools from config/lock files
- Detects service integrations (Sentry, Linear, etc.)
- Generates a complete
settings.local.json with both read-only AND development commands
- Includes framework-specific commands Claude needs (artisan, next, expo, manage.py, cargo, etc.)
- Suggests relevant WebFetch domains for framework documentation
- Suggests MCP server configurations when applicable
- Merges with existing settings if present
What this skill does NOT do:
- Install or configure any tools
- Modify code or project structure
- Include destructive system commands (rm -rf, format, etc.)
- Guess at tools not detected in the project
- Include user-specific or absolute paths
When to Use
- User says "audit settings", "setup permissions", "configure claude settings", "/update-claude-settings"
- User is setting up a new project with Claude Code
- User wants to review or update existing Claude Code permissions
- $ARGUMENTS provided as guidance (e.g.,
/update-claude-settings add docker commands)
Never generate settings proactively. Only when explicitly requested.
When NOT to Use
- Empty repository — no files to detect; ask user to describe their stack instead
- User wants to run commands — this skill generates permission config, it doesn't execute project commands
- User wants to modify code — this skill only produces settings.local.json and .mcp.json recommendations
- Settings are already comprehensive — if existing settings cover the detected stack, say so
Step 1: Detect Tech Stack
Gate: All languages, package managers, and build tools identified before proceeding to Step 2.
Run detection commands:
# List root directory contents
ls -la
# Find config and lock files (up to 2 levels deep)
find . -maxdepth 2 \( -name "*.toml" -o -name "*.json" -o -name "*.lock" -o -name "*.yaml" -o -name "*.yml" -o -name "Makefile" -o -name "Dockerfile" -o -name "*.tf" \) 2>/dev/null | head -50
Check for these indicator files:
| Category |
Files to Check |
| Python |
pyproject.toml, setup.py, requirements.txt, Pipfile, poetry.lock, uv.lock |
| Node.js |
package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb |
| Go |
go.mod, go.sum |
| Rust |
Cargo.toml, Cargo.lock |
| Ruby |
Gemfile, Gemfile.lock |
| Java/Kotlin |
pom.xml, build.gradle, build.gradle.kts |
| PHP |
composer.json, composer.lock |
| Swift/iOS |
Package.swift, *.xcodeproj, *.xcworkspace, Podfile |
| .NET |
*.csproj, *.sln, nuget.config |
| React Native |
app.json (with expo key), metro.config.js, react-native.config.js, eas.json |
| Build |
Makefile, Dockerfile, docker-compose.yml, docker-compose.yaml |
| Infra |
*.tf files, kubernetes/, helm/, pulumi/, serverless.yml |
| Monorepo |
lerna.json, nx.json, turbo.json, pnpm-workspace.yaml |
Step 2: Detect Frameworks and Services
Gate: All frameworks and service integrations identified before proceeding to Step 3.
Read dependency files to identify frameworks:
package.json → check dependencies and devDependencies
pyproject.toml → check [project.dependencies] or [tool.poetry.dependencies]
Gemfile → check gem names
Cargo.toml → check [dependencies]
composer.json → check require and require-dev
go.mod → check require block
Check for framework-specific indicators:
| Framework |
Detection |
| Next.js |
next in package.json deps, next.config.js/next.config.mjs/next.config.ts |
| React (Vite) |
vite + react in package.json deps, vite.config.ts/vite.config.js |
| Expo/React Native |
expo in package.json deps, app.json with expo key, eas.json |
| Express |
express in package.json deps |
| Laravel |
laravel/framework in composer.json require, artisan file in root |
| Magento |
magento/framework in composer.json require, bin/magento |
| Django |
django in Python deps |
| FastAPI |
fastapi in Python deps |
| Tailwind CSS |
tailwindcss in package.json deps, tailwind.config.js/tailwind.config.ts |
Check for service integrations:
| Service |
Detection |
| Sentry |
sentry-sdk in deps, @sentry/* packages, .sentryclirc, sentry.properties |
| Linear |
Linear config files, .linear/ directory |
| Datadog |
dd-trace in deps, datadog.yaml |
| AWS |
aws-cdk in deps, samconfig.toml, serverless.yml |
| Vercel |
vercel.json, @vercel/* packages |
| Supabase |
supabase/ directory, @supabase/* packages |
| Firebase |
firebase.json, @firebase/* or firebase-admin in deps |
Check for @ulpi tools:
| Tool |
Detection |
| browse |
command -v browse succeeds, or @ulpi/browse in global packages, or .claude/skills/browse/SKILL.md exists |
| codemap |
command -v codemap succeeds, or @ulpi/codemap in global packages, or .codemapignore exists |
Step 3: Check Existing Settings
Gate: Current settings state understood before proceeding to Step 4.
Read existing configuration files:
# Check existing Claude Code settings (both files — settings.json is project-level, settings.local.json is user-local)
cat .claude/settings.json 2>/dev/null || echo "No project settings"
cat .claude/settings.local.json 2>/dev/null || echo "No local settings"
# Check existing MCP config
cat .mcp.json 2>/dev/null || echo "No existing .mcp.json"
Note: .claude/settings.json is committed to git (shared with team). .claude/settings.local.json is gitignored (user-specific). Skills installed via skills.sh write to settings.json. Write permissions to settings.local.json by default, but if the user asks for shared settings, use settings.json.
If existing settings are found:
- Note which commands are already allowed
- Note which commands are denied
- Identify gaps (detected tools not in settings)
- Identify stale entries (settings for tools no longer in the project)
Step 4: Build Recommendations
Gate: Complete recommendation generated before proceeding to Step 5.
Build the allow list by combining baseline commands with stack-specific commands.
Baseline Commands (Always Include)
These read-only commands are safe and useful for any project:
[
"Bash(ls:*)",
"Bash(pwd:*)",
"Bash(find:*)",
"Bash(file:*)",
"Bash(stat:*)",
"Bash(wc:*)",
"Bash(head:*)",
"Bash(tail:*)",
"Bash(cat:*)",
"Bash(tree:*)",
"Bash(git status:*)",
"Bash(git log:*)",
"Bash(git diff:*)",
"Bash(git show:*)",
"Bash(git branch:*)",
"Bash(git remote:*)",
"Bash(git tag:*)",
"Bash(git stash list:*)",
"Bash(git rev-parse:*)",
"Bash(gh pr view:*)",
"Bash(gh pr list:*)",
"Bash(gh pr checks:*)",
"Bash(gh pr diff:*)",
"Bash(gh issue view:*)",
"Bash(gh issue list:*)",
"Bash(gh run view:*)",
"Bash(gh run list:*)",
"Bash(gh run logs:*)",
"Bash(gh repo view:*)",
"Bash(gh api:*)"
]
Stack-Specific Commands
Only include commands for tools actually detected in the project. Each section is split into read-only (safe to auto-allow) and development (needed for Claude to work effectively with the framework) commands.
Python
| If Detected |
Read-Only Commands |
Development Commands |
| Any Python |
python --version, python3 --version |
python, python3 |
poetry.lock |
poetry show, poetry env info |
poetry install, poetry add, poetry remove, poetry run, poetry lock |
uv.lock |
uv pip list, uv tree |
uv pip install, uv add, uv remove, uv run, uv sync, uv lock |
Pipfile.lock |
pipenv graph |
pipenv install, pipenv run |
requirements.txt (no other lock) |
pip list, pip show, pip freeze |
pip install |
| pytest detected |
— |
pytest, python -m pytest |
| mypy/pyright detected |
— |
mypy, pyright |
| ruff detected |
— |
ruff check, ruff format |
Python frameworks:
| If Detected |
Development Commands |
| Django |
python manage.py, django-admin (e.g., manage.py runserver, manage.py migrate, manage.py makemigrations, manage.py test, manage.py shell, manage.py createsuperuser) |
| FastAPI |
uvicorn, fastapi (e.g., uvicorn main:app, fastapi dev) |
| Flask |
flask run, flask shell |
| Celery |
celery -A, celery worker, celery beat |
| Alembic |
alembic upgrade, alembic downgrade, alembic revision, alembic history |
Node.js
| If Detected |
Read-Only Commands |
Development Commands |
| Any Node.js |
node --version |
node |
pnpm-lock.yaml |
pnpm list, pnpm why |
pnpm install, pnpm add, pnpm remove, pnpm run, pnpm exec, pnpm dlx, pnpm test |
yarn.lock |
yarn list, yarn info, yarn why |
yarn install, yarn add, yarn remove, yarn run, yarn dlx, yarn test |
bun.lockb |
bun --version |
bun install, bun add, bun remove, bun run, bun test, bunx |
package-lock.json |
npm list, npm view, npm outdated |
npm install, npm run, npm test, npm exec, npx |
TypeScript (tsconfig.json) |
tsc --version |
tsc, tsc --noEmit, npx tsc |
| ESLint detected |
— |
eslint, npx eslint |
| Prettier detected |
— |
prettier, npx prettier |
| Vitest detected |
— |
vitest, npx vitest |
| Jest detected |
— |
jest, npx jest |
Node.js frameworks:
| If Detected |
Development Commands |
| Next.js |
npx next build, npx next dev, npx next start, npx next lint, npx next info |
| Expo/React Native |
npx expo start, npx expo prebuild, npx expo install, npx expo config, npx expo lint, eas build, eas update, eas submit, npx eas --version |
| Vite |
npx vite, npx vite build, npx vite preview |
| Express |
(uses node and package manager run commands — no additional CLI) |
| Tailwind CSS |
npx tailwindcss, npx tailwindcss --watch |
| Storybook |
npx storybook dev, npx storybook build |
| Prisma |
npx prisma generate, npx prisma migrate, npx prisma db push, npx prisma db pull, npx prisma studio, npx prisma format |
| Drizzle |
npx drizzle-kit generate, npx drizzle-kit migrate, npx drizzle-kit push, npx drizzle-kit studio |
PHP
| If Detected |
Read-Only Commands |
Development Commands |
composer.json |
php --version, composer show, composer info |
php, composer install, composer require, composer remove, composer update, composer dump-autoload |
| PHPUnit detected |
— |
phpunit, ./vendor/bin/phpunit |
| PHPStan detected |
— |
phpstan, ./vendor/bin/phpstan |
PHP frameworks:
| If Detected |
Development Commands |
| Laravel |
php artisan (e.g., artisan migrate, artisan make:model, artisan make:controller, artisan make:migration, artisan route:list, artisan config:show, artisan test, artisan tinker, artisan queue:work, artisan schedule:run, artisan db:seed, artisan cache:clear, artisan key:generate, artisan serve) |
| Magento |
php bin/magento (e.g., bin/magento setup:upgrade, bin/magento cache:flush, bin/magento module:status, bin/magento indexer:reindex, bin/magento setup:di:compile) |
| Symfony |
php bin/console (e.g., bin/console doctrine:migrations:migrate, bin/console make:entity, bin/console cache:clear) |
Go
| If Detected |
Read-Only Commands |
Development Commands |
go.mod |
go version, go list, go mod graph, go env |
go build, go run, go test, go vet, go fmt, go mod tidy, go mod download, go generate, go get |
| golangci-lint detected |
— |
golangci-lint run |
Rust
| If Detected |
Read-Only Commands |
Development Commands |
Cargo.toml |
rustc --version, cargo --version, cargo tree, cargo metadata |
cargo build, cargo run, cargo test, cargo check, cargo clippy, cargo fmt, cargo add, cargo remove |
Ruby
| If Detected |
Read-Only Commands |
Development Commands |
Gemfile |
ruby --version, bundle list, bundle show |
bundle install, bundle exec, bundle add |
Ruby frameworks:
| If Detected |
Development Commands |
| Rails |
rails (e.g., rails server, rails console, rails generate, rails db:migrate, rails db:seed, rails test, rails routes) |
| RSpec detected |
rspec, bundle exec rspec |
Java/Kotlin
| If Detected |
Read-Only Commands |
Development Commands |
pom.xml |
java --version, mvn --version, mvn dependency:tree |
mvn compile, mvn test, mvn package, mvn clean, mvn install |
build.gradle / build.gradle.kts |
java --version, gradle --version, gradle dependencies |
gradle build, gradle test, gradle clean, gradle run, ./gradlew |
.NET
| If Detected |
Read-Only Commands |
Development Commands |
*.csproj / *.sln |
dotnet --version, dotnet list package |
dotnet build, dotnet run, dotnet test, dotnet add package, dotnet remove package, dotnet ef |
Build Tools & Infrastructure
| If Detected |
Read-Only Commands |
Development Commands |
Dockerfile |
docker --version, docker ps, docker images |
docker build, docker run, docker exec, docker logs, docker stop, docker rm |
docker-compose.yml |
docker-compose ps, docker-compose config |
docker-compose up, docker-compose down, docker-compose build, docker-compose logs, docker-compose exec |
*.tf files |
terraform --version, terraform providers, terraform state list |
terraform plan, terraform apply, terraform init, terraform validate |
Makefile |
make --version, make -n |
make |
serverless.yml |
serverless --version |
serverless deploy, serverless invoke, serverless logs |
AWS CDK (aws-cdk in deps) |
cdk --version |
cdk synth, cdk diff, cdk deploy, cdk destroy |
@ulpi Tools
| If Detected |
Commands to Allow |
| browse |
Bash(browse:*), Bash(browse goto:*), Bash(browse text:*), Bash(browse snapshot:*), Bash(browse click:*), Bash(browse fill:*), Bash(browse screenshot:*), and all other browse subcommands (see browse SKILL.md for full list) |
| codemap |
Bash(codemap:*), Bash(codemap search:*), Bash(codemap symbols:*), Bash(codemap deps:*), Bash(codemap dependents:*), Bash(codemap rank:*), Bash(codemap cycles:*), Bash(codemap summary:*), Bash(codemap index:*), Bash(codemap status:*), Bash(codemap coupling:*), Bash(codemap graph-stats:*) |
Package Manager Exclusion Rules
Only include the package manager actually used by the project:
| If Detected |
Include |
Do NOT Include |
pnpm-lock.yaml |
pnpm commands |
npm, yarn, bun |
yarn.lock |
yarn commands |
npm, pnpm, bun |
bun.lockb |
bun commands |
npm, yarn, pnpm |
package-lock.json |
npm commands |
yarn, pnpm, bun |
poetry.lock |
poetry commands |
pip (unless also has requirements.txt) |
uv.lock |
uv commands |
pip, poetry |
Pipfile.lock |
pipenv commands |
pip, poetry |
If multiple lock files exist, include only the commands for each detected manager.
WebFetch Domains
Add documentation domains for detected frameworks:
| If Detected |
Add Domains |
| Django |
docs.djangoproject.com |
| Flask |
flask.palletsprojects.com |
| FastAPI |
fastapi.tiangolo.com |
| React |
react.dev |
| Next.js |
nextjs.org |
| Expo/React Native |
docs.expo.dev, reactnative.dev |
| Vite |
vite.dev |
| Tailwind CSS |
tailwindcss.com |
| Vue |
vuejs.org |
| Angular |
angular.dev |
| Svelte |
svelte.dev |
| Express |
expressjs.com |
| Rails |
guides.rubyonrails.org, api.rubyonrails.org |
| Laravel |
laravel.com |
| Magento |
developer.adobe.com |
| Go |
pkg.go.dev |
| Rust |
docs.rs, doc.rust-lang.org |
| Docker |
docs.docker.com |
| Kubernetes |
kubernetes.io |
| Terraform |
registry.terraform.io |
| AWS CDK |
docs.aws.amazon.com |
| Firebase |
firebase.google.com |
Always include general-purpose domains:
[
"WebFetch(domain:docs.github.com)",
"WebFetch(domain:cli.github.com)"
]
MCP Tool Permissions (Always Include)
The codemap and memory MCP servers are core infrastructure for this project. Always allow ALL tools from both servers — do not cherry-pick individual tools.
[
"mcp__codemap__search_code",
"mcp__codemap__search_symbols",
"mcp__codemap__get_file_summary",
"mcp__codemap__get_index_stats",
"mcp__codemap__reindex",
"mcp__codemap__get_dependencies",
"mcp__codemap__get_dependents",
"mcp__codemap__get_file_rank",
"mcp__codemap__find_cycles",
"mcp__codemap__get_coupling_metrics",
"mcp__codemap__get_depgraph_stats",
"mcp__codemap__rebuild_depgraph",
"mcp__memory__search_memory",
"mcp__memory__save_memory",
"mcp__memory__get_timeline",
"mcp__memory__get_session_context",
"mcp__memory__forget",
"mcp__memory__memory_stats"
]
Why: These tools are read-only or low-risk (search, index, stats). Requiring per-tool approval creates friction during every session. All agents (main + subagents) need these tools to search the codebase and access project memory effectively.
MCP Server Suggestions
MCP servers are configured in .mcp.json (not settings.local.json). Only suggest MCP servers for detected services.
# Check existing MCP config
cat .mcp.json 2>/dev/null || echo "No existing .mcp.json"
Sentry MCP (if Sentry SDK detected)
{
"mcpServers": {
"sentry": {
"type": "http",
"url": "https://mcp.sentry.dev/mcp/{org-slug}/{project-slug}"
}
}
}
Linear MCP (if Linear usage detected)
{
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "@linear/mcp-server"],
"env": {
"LINEAR_API_KEY": "${LINEAR_API_KEY}"
}
}
}
}
Note: Never suggest GitHub MCP. Always use gh CLI commands for GitHub operations.
Step 5: Present Recommendations
Gate: User has reviewed the recommendations before proceeding to Step 6.
Present findings in this structure:
Output Format
## Detected Tech Stack
| Category | Found |
|----------|-------|
| Languages | [detected languages] |
| Package Manager | [detected manager] |
| Frameworks | [detected frameworks] |
| Services | [detected services] |
| Build Tools | [detected tools] |
| Monorepo | [yes/no, tool name] |
## Recommended .claude/settings.local.json
{complete JSON with grouped, commented permissions}
## Recommended .mcp.json (if applicable)
{MCP server config for detected services}
## Changes from Current Settings (if existing settings found)
| Change | Description |
|--------|------------|
| Added | [new commands for detected tools] |
| Removed | [stale commands for tools no longer detected] |
| Unchanged | [commands that remain the same] |
Use AskUserQuestion to confirm before writing any files:
- "Apply these settings?" with options to apply all, apply selectively, or just view
Step 6: Apply Settings
Gate: User approved the recommendations before writing files.
If the user approves:
- Write
.claude/settings.local.json with the recommended permissions
- Write
.mcp.json with MCP server suggestions (if applicable)
- If merging with existing settings, preserve user customizations (deny list, custom commands)
If existing settings exist, show a clear diff of what will change before writing.
Step 7: Verify Applied Settings
Gate: Settings files are valid JSON and contain expected content.
After writing:
- Verify
.claude/settings.local.json is valid JSON:
python3 -c "import json; json.load(open('.claude/settings.local.json'))" 2>&1 || echo "Invalid JSON"
- Verify
.mcp.json is valid JSON (if written):
python3 -c "import json; json.load(open('.mcp.json'))" 2>&1 || echo "Invalid JSON"
- Confirm all detected tools have corresponding commands in the settings
- Confirm no write/modify commands were included
Safety Rules
| Rule |
Reason |
| Never include destructive system commands |
No rm -rf, format, fdisk, or system-level destructive operations |
| Never include absolute paths |
Paths are user-specific and non-portable |
| Never include custom scripts |
Project scripts may have side effects; only standard tool commands |
| Never guess at tools |
Only include commands for tools detected via config/lock files |
| Never include wrong package manager |
If project uses pnpm, don't include npm/yarn commands |
| Always include development commands |
Claude needs build, test, run, install commands to work effectively |
| Always read existing settings first |
Preserve user customizations and deny lists |
| Always verify JSON validity |
Invalid settings.local.json breaks Claude Code |
| Always get user approval before writing |
User must review recommendations before files are modified |
| Never suggest GitHub MCP |
Use gh CLI commands for GitHub operations instead |
Quick Reference: Package Manager Detection
Lock file exists?
├── pnpm-lock.yaml → pnpm (exclude npm, yarn, bun)
├── yarn.lock → yarn (exclude npm, pnpm, bun)
├── bun.lockb → bun (exclude npm, yarn, pnpm)
├── package-lock.json → npm (exclude yarn, pnpm, bun)
├── poetry.lock → poetry (exclude pip unless requirements.txt also exists)
├── uv.lock → uv (exclude pip, poetry)
├── Pipfile.lock → pipenv (exclude pip, poetry)
├── Cargo.lock → cargo
├── Gemfile.lock → bundler
├── go.sum → go
└── composer.lock → composer
Step 8: Verification (MANDATORY)
After completing settings generation, verify the full workflow:
Check 1: Stack Detection Accuracy
Check 2: Command Safety
Check 3: Package Manager Correctness
Check 4: Settings Validity
Check 5: Completeness
Gate: Do NOT mark settings generation complete until all 5 checks pass.
Quality Checklist (Must Score 8/10)
Score yourself honestly before marking settings generation complete:
Stack Detection (0-2 points)
- 0 points: Assumed tech stack without reading config files
- 1 point: Detected some tools but missed others
- 2 points: Detected all languages, package managers, frameworks, services, and build tools from config/lock files
Command Accuracy (0-2 points)
- 0 points: Included commands for undetected tools or missed framework-specific commands
- 1 point: Mostly correct but included wrong package manager or missed development commands
- 2 points: Every command matches a detected tool, includes both read-only and development commands, correct package manager only
Existing Settings Handling (0-2 points)
- 0 points: Overwrote existing settings without reading them
- 1 point: Read existing settings but didn't preserve customizations
- 2 points: Read existing settings, preserved deny list and custom commands, showed clear diff
Output Quality (0-2 points)
- 0 points: Dumped raw JSON without explanation
- 1 point: Provided settings but missing summary table or grouping
- 2 points: Complete output: summary table, grouped/commented JSON, merge instructions if applicable
Verification (0-2 points)
- 0 points: Didn't verify JSON validity or command correctness
- 1 point: Verified JSON but didn't check for write commands or wrong package managers
- 2 points: Verified JSON validity, read-only compliance, package manager correctness, and completeness
Minimum passing score: 8/10
Common Rationalizations (All Wrong)
These are excuses. Don't fall for them:
- "Most projects use npm" → STILL detect the actual package manager from lock files
- "These extra commands might be useful" → STILL only include commands for detected tools
- "Any dev command is fine to include" → STILL verify each command is appropriate for the detected framework
- "The user can fix it later" → Get it right NOW; wrong settings cause permission friction
- "There's no existing settings.local.json" → STILL check; the user may have customizations elsewhere
- "I'll just include all package managers" → STILL exclude package managers not detected in the project
- "Absolute paths work on this machine" → STILL use only portable command names
- "This MCP server would be helpful" → STILL only suggest MCP servers for detected services
Failure Modes
Failure Mode 1: Wrong Package Manager
Symptom: Settings include npm commands but the project uses pnpm (or similar mismatch)
Fix: Always check lock files first. The lock file determines the package manager, not assumptions.
Failure Mode 2: Destructive Commands Included
Symptom: Settings allow rm -rf, system-level destructive operations, or commands that could cause data loss
Fix: Review every command for safety. Development commands (install, build, test, run) are fine; system-level destructive commands are not.
Failure Mode 3: Absolute Paths
Symptom: Settings include /Users/name/bin/tool or /home/user/.local/bin/script
Fix: Never include absolute paths. Only use bare command names that resolve via PATH.
Failure Mode 4: Stale Settings
Symptom: Settings include commands for tools removed from the project
Fix: Always detect the current stack before generating. Cross-reference existing settings against detected tools.
Failure Mode 5: Invalid JSON
Symptom: Claude Code fails to load settings because of JSON syntax errors
Fix: Always validate JSON after writing. Use python3 -c "import json; json.load(open(...))" to verify.
Quick Workflow Summary
STEP 1: DETECT TECH STACK
├── List root directory
├── Find config and lock files
├── Identify languages and package managers
└── Gate: All tools identified
STEP 2: DETECT FRAMEWORKS AND SERVICES
├── Read dependency files
├── Check for service integrations
└── Gate: All frameworks and services identified
STEP 3: CHECK EXISTING SETTINGS
├── Read .claude/settings.local.json
├── Read .mcp.json
├── Note gaps and stale entries
└── Gate: Current state understood
STEP 4: BUILD RECOMMENDATIONS
├── Start with baseline commands
├── Add stack-specific commands
├── Add WebFetch domains
├── Add MCP suggestions
├── Enforce package manager exclusion rules
└── Gate: Complete recommendation generated
STEP 5: PRESENT RECOMMENDATIONS
├── Show detected stack summary
├── Show recommended settings.local.json
├── Show changes from current (if applicable)
├── Get user approval
└── Gate: User reviewed
STEP 6: APPLY SETTINGS
├── Write .claude/settings.local.json
├── Write .mcp.json (if applicable)
├── Preserve existing customizations
└── Gate: User approved and files written
STEP 7: VERIFY SETTINGS
├── Validate JSON
├── Confirm read-only compliance
├── Confirm package manager correctness
└── Gate: Settings verified
STEP 8: VERIFICATION (MANDATORY)
├── Check 1: Stack detection accuracy
├── Check 2: Read-only compliance
├── Check 3: Package manager correctness
├── Check 4: Settings validity
├── Check 5: Completeness
└── Gate: All 5 checks pass
Completion Announcement
When settings generation is complete, announce:
Settings generation complete.
**Quality Score: X/10**
- Stack Detection: X/2
- Command Accuracy: X/2
- Existing Settings Handling: X/2
- Output Quality: X/2
- Verification: X/2
**Detected Stack:**
- Languages: [list]
- Package Manager: [name]
- Frameworks: [list]
- Services: [list]
- Build Tools: [list]
**Settings:**
- Commands allowed: [count]
- WebFetch domains: [count]
- MCP servers suggested: [count]
- Existing settings: [merged / new / unchanged]
**Verification:**
- JSON valid: ✅
- No destructive commands: ✅
- Correct package manager: ✅
- All tools covered (read-only + development): ✅
**Next steps:**
[Review settings in .claude/settings.local.json, restart Claude Code to apply]
Integration with Other Skills
The update-claude-settings skill integrates with:
start — Run update-claude-settings when setting up a new project
update-claude-md-after-install — After installing framework agents, update settings to match
commit — After generating settings, commit the changes
Workflow Chain:
New project setup
│
▼
update-claude-settings skill (this skill)
│
▼
commit skill (commit settings files)
│
▼
Begin development with correct permissions
1---2name: update-claude-settings-33description: Detect tech stack, generate Claude Code settings.local.json permissions and MCP server suggestions. Analyzes lock files, config files, frameworks, services, and monorepo structure. Invoke via /update-claude-settings or when user says "audit settings", "setup permissions", "configure claude settings".4---56<EXTREMELY-IMPORTANT>7Before generating ANY settings recommendations, you **ABSOLUTELY MUST**:891. Detect the actual tech stack from lock files and config files (not assumptions)102. Read existing .claude/settings.local.json and .mcp.json to understand current state113. Include both read-only AND development commands appropriate for each detected tool124. Only include commands for tools actually detected in the project135. Never include absolute paths, user-specific paths, or destructive system commands1415**Generating settings without detection = wrong package manager commands, missing tools, security risks**1617This is not optional. Every recommendation requires stack verification.18</EXTREMELY-IMPORTANT>1920# Update Claude Settings2122## MANDATORY FIRST RESPONSE PROTOCOL2324Before generating ANY settings, you **MUST** complete this checklist:25261. ☐ List all files in the repository root (`ls -la`)272. ☐ Detect config and lock files (package.json, pyproject.toml, go.mod, Cargo.toml, etc.)283. ☐ Read dependency files to identify frameworks and libraries294. ☐ Check for monorepo indicators (lerna.json, nx.json, turbo.json, pnpm-workspace.yaml)305. ☐ Check for service integrations (Sentry, Linear, etc.)316. ☐ Read existing .claude/settings.local.json (if it exists)327. ☐ Read existing .mcp.json (if it exists)338. ☐ Announce: "Detected [stack]: generating settings for [N] command categories and [M] WebFetch domains"3435**Generating settings WITHOUT completing this checklist = wrong permissions and missed tools.**3637## Overview3839Analyze a repository to generate recommended Claude Code `settings.local.json` permissions for read-only commands. Detects the tech stack, build tools, frameworks, services, and monorepo structure to produce accurate, project-specific recommendations.4041**What this skill does:**42- Detects languages, package managers, frameworks, and build tools from config/lock files43- Detects service integrations (Sentry, Linear, etc.)44- Generates a complete `settings.local.json` with both read-only AND development commands45- Includes framework-specific commands Claude needs (artisan, next, expo, manage.py, cargo, etc.)46- Suggests relevant WebFetch domains for framework documentation47- Suggests MCP server configurations when applicable48- Merges with existing settings if present4950**What this skill does NOT do:**51- Install or configure any tools52- Modify code or project structure53- Include destructive system commands (rm -rf, format, etc.)54- Guess at tools not detected in the project55- Include user-specific or absolute paths5657## When to Use5859- User says "audit settings", "setup permissions", "configure claude settings", "/update-claude-settings"60- User is setting up a new project with Claude Code61- User wants to review or update existing Claude Code permissions62- $ARGUMENTS provided as guidance (e.g., `/update-claude-settings add docker commands`)6364**Never generate settings proactively.** Only when explicitly requested.6566## When NOT to Use6768- **Empty repository** — no files to detect; ask user to describe their stack instead69- **User wants to run commands** — this skill generates permission config, it doesn't execute project commands70- **User wants to modify code** — this skill only produces settings.local.json and .mcp.json recommendations71- **Settings are already comprehensive** — if existing settings cover the detected stack, say so7273## Step 1: Detect Tech Stack7475**Gate: All languages, package managers, and build tools identified before proceeding to Step 2.**7677Run detection commands:7879```bash80# List root directory contents81ls -la8283# Find config and lock files (up to 2 levels deep)84find . -maxdepth 2 \( -name "*.toml" -o -name "*.json" -o -name "*.lock" -o -name "*.yaml" -o -name "*.yml" -o -name "Makefile" -o -name "Dockerfile" -o -name "*.tf" \) 2>/dev/null | head -5085```8687Check for these indicator files:8889| Category | Files to Check |90|----------|---------------|91| **Python** | `pyproject.toml`, `setup.py`, `requirements.txt`, `Pipfile`, `poetry.lock`, `uv.lock` |92| **Node.js** | `package.json`, `package-lock.json`, `yarn.lock`, `pnpm-lock.yaml`, `bun.lockb` |93| **Go** | `go.mod`, `go.sum` |94| **Rust** | `Cargo.toml`, `Cargo.lock` |95| **Ruby** | `Gemfile`, `Gemfile.lock` |96| **Java/Kotlin** | `pom.xml`, `build.gradle`, `build.gradle.kts` |97| **PHP** | `composer.json`, `composer.lock` |98| **Swift/iOS** | `Package.swift`, `*.xcodeproj`, `*.xcworkspace`, `Podfile` |99| **.NET** | `*.csproj`, `*.sln`, `nuget.config` |100| **React Native** | `app.json` (with `expo` key), `metro.config.js`, `react-native.config.js`, `eas.json` |101| **Build** | `Makefile`, `Dockerfile`, `docker-compose.yml`, `docker-compose.yaml` |102| **Infra** | `*.tf` files, `kubernetes/`, `helm/`, `pulumi/`, `serverless.yml` |103| **Monorepo** | `lerna.json`, `nx.json`, `turbo.json`, `pnpm-workspace.yaml` |104105## Step 2: Detect Frameworks and Services106107**Gate: All frameworks and service integrations identified before proceeding to Step 3.**108109Read dependency files to identify frameworks:110111- `package.json` → check `dependencies` and `devDependencies`112- `pyproject.toml` → check `[project.dependencies]` or `[tool.poetry.dependencies]`113- `Gemfile` → check gem names114- `Cargo.toml` → check `[dependencies]`115- `composer.json` → check `require` and `require-dev`116- `go.mod` → check `require` block117118Check for framework-specific indicators:119120| Framework | Detection |121|-----------|-----------|122| **Next.js** | `next` in package.json deps, `next.config.js`/`next.config.mjs`/`next.config.ts` |123| **React (Vite)** | `vite` + `react` in package.json deps, `vite.config.ts`/`vite.config.js` |124| **Expo/React Native** | `expo` in package.json deps, `app.json` with `expo` key, `eas.json` |125| **Express** | `express` in package.json deps |126| **Laravel** | `laravel/framework` in composer.json require, `artisan` file in root |127| **Magento** | `magento/framework` in composer.json require, `bin/magento` |128| **Django** | `django` in Python deps |129| **FastAPI** | `fastapi` in Python deps |130| **Tailwind CSS** | `tailwindcss` in package.json deps, `tailwind.config.js`/`tailwind.config.ts` |131132Check for service integrations:133134| Service | Detection |135|---------|-----------|136| **Sentry** | `sentry-sdk` in deps, `@sentry/*` packages, `.sentryclirc`, `sentry.properties` |137| **Linear** | Linear config files, `.linear/` directory |138| **Datadog** | `dd-trace` in deps, `datadog.yaml` |139| **AWS** | `aws-cdk` in deps, `samconfig.toml`, `serverless.yml` |140| **Vercel** | `vercel.json`, `@vercel/*` packages |141| **Supabase** | `supabase/` directory, `@supabase/*` packages |142| **Firebase** | `firebase.json`, `@firebase/*` or `firebase-admin` in deps |143144Check for @ulpi tools:145146| Tool | Detection |147|------|-----------|148| **browse** | `command -v browse` succeeds, or `@ulpi/browse` in global packages, or `.claude/skills/browse/SKILL.md` exists |149| **codemap** | `command -v codemap` succeeds, or `@ulpi/codemap` in global packages, or `.codemapignore` exists |150151## Step 3: Check Existing Settings152153**Gate: Current settings state understood before proceeding to Step 4.**154155Read existing configuration files:156157```bash158# Check existing Claude Code settings (both files — settings.json is project-level, settings.local.json is user-local)159cat .claude/settings.json 2>/dev/null || echo "No project settings"160cat .claude/settings.local.json 2>/dev/null || echo "No local settings"161162# Check existing MCP config163cat .mcp.json 2>/dev/null || echo "No existing .mcp.json"164```165166**Note:** `.claude/settings.json` is committed to git (shared with team). `.claude/settings.local.json` is gitignored (user-specific). Skills installed via `skills.sh` write to `settings.json`. Write permissions to `settings.local.json` by default, but if the user asks for shared settings, use `settings.json`.167168If existing settings are found:1691. Note which commands are already allowed1702. Note which commands are denied1713. Identify gaps (detected tools not in settings)1724. Identify stale entries (settings for tools no longer in the project)173174## Step 4: Build Recommendations175176**Gate: Complete recommendation generated before proceeding to Step 5.**177178Build the allow list by combining baseline commands with stack-specific commands.179180### Baseline Commands (Always Include)181182These read-only commands are safe and useful for any project:183184```json185[186 "Bash(ls:*)",187 "Bash(pwd:*)",188 "Bash(find:*)",189 "Bash(file:*)",190 "Bash(stat:*)",191 "Bash(wc:*)",192 "Bash(head:*)",193 "Bash(tail:*)",194 "Bash(cat:*)",195 "Bash(tree:*)",196 "Bash(git status:*)",197 "Bash(git log:*)",198 "Bash(git diff:*)",199 "Bash(git show:*)",200 "Bash(git branch:*)",201 "Bash(git remote:*)",202 "Bash(git tag:*)",203 "Bash(git stash list:*)",204 "Bash(git rev-parse:*)",205 "Bash(gh pr view:*)",206 "Bash(gh pr list:*)",207 "Bash(gh pr checks:*)",208 "Bash(gh pr diff:*)",209 "Bash(gh issue view:*)",210 "Bash(gh issue list:*)",211 "Bash(gh run view:*)",212 "Bash(gh run list:*)",213 "Bash(gh run logs:*)",214 "Bash(gh repo view:*)",215 "Bash(gh api:*)"216]217```218219### Stack-Specific Commands220221Only include commands for tools actually detected in the project. Each section is split into **read-only** (safe to auto-allow) and **development** (needed for Claude to work effectively with the framework) commands.222223#### Python224225| If Detected | Read-Only Commands | Development Commands |226|-------------|-------------------|---------------------|227| Any Python | `python --version`, `python3 --version` | `python`, `python3` |228| `poetry.lock` | `poetry show`, `poetry env info` | `poetry install`, `poetry add`, `poetry remove`, `poetry run`, `poetry lock` |229| `uv.lock` | `uv pip list`, `uv tree` | `uv pip install`, `uv add`, `uv remove`, `uv run`, `uv sync`, `uv lock` |230| `Pipfile.lock` | `pipenv graph` | `pipenv install`, `pipenv run` |231| `requirements.txt` (no other lock) | `pip list`, `pip show`, `pip freeze` | `pip install` |232| pytest detected | — | `pytest`, `python -m pytest` |233| mypy/pyright detected | — | `mypy`, `pyright` |234| ruff detected | — | `ruff check`, `ruff format` |235236**Python frameworks:**237238| If Detected | Development Commands |239|-------------|---------------------|240| **Django** | `python manage.py`, `django-admin` (e.g., `manage.py runserver`, `manage.py migrate`, `manage.py makemigrations`, `manage.py test`, `manage.py shell`, `manage.py createsuperuser`) |241| **FastAPI** | `uvicorn`, `fastapi` (e.g., `uvicorn main:app`, `fastapi dev`) |242| **Flask** | `flask run`, `flask shell` |243| **Celery** | `celery -A`, `celery worker`, `celery beat` |244| **Alembic** | `alembic upgrade`, `alembic downgrade`, `alembic revision`, `alembic history` |245246#### Node.js247248| If Detected | Read-Only Commands | Development Commands |249|-------------|-------------------|---------------------|250| Any Node.js | `node --version` | `node` |251| `pnpm-lock.yaml` | `pnpm list`, `pnpm why` | `pnpm install`, `pnpm add`, `pnpm remove`, `pnpm run`, `pnpm exec`, `pnpm dlx`, `pnpm test` |252| `yarn.lock` | `yarn list`, `yarn info`, `yarn why` | `yarn install`, `yarn add`, `yarn remove`, `yarn run`, `yarn dlx`, `yarn test` |253| `bun.lockb` | `bun --version` | `bun install`, `bun add`, `bun remove`, `bun run`, `bun test`, `bunx` |254| `package-lock.json` | `npm list`, `npm view`, `npm outdated` | `npm install`, `npm run`, `npm test`, `npm exec`, `npx` |255| TypeScript (`tsconfig.json`) | `tsc --version` | `tsc`, `tsc --noEmit`, `npx tsc` |256| ESLint detected | — | `eslint`, `npx eslint` |257| Prettier detected | — | `prettier`, `npx prettier` |258| Vitest detected | — | `vitest`, `npx vitest` |259| Jest detected | — | `jest`, `npx jest` |260261**Node.js frameworks:**262263| If Detected | Development Commands |264|-------------|---------------------|265| **Next.js** | `npx next build`, `npx next dev`, `npx next start`, `npx next lint`, `npx next info` |266| **Expo/React Native** | `npx expo start`, `npx expo prebuild`, `npx expo install`, `npx expo config`, `npx expo lint`, `eas build`, `eas update`, `eas submit`, `npx eas --version` |267| **Vite** | `npx vite`, `npx vite build`, `npx vite preview` |268| **Express** | (uses `node` and package manager `run` commands — no additional CLI) |269| **Tailwind CSS** | `npx tailwindcss`, `npx tailwindcss --watch` |270| **Storybook** | `npx storybook dev`, `npx storybook build` |271| **Prisma** | `npx prisma generate`, `npx prisma migrate`, `npx prisma db push`, `npx prisma db pull`, `npx prisma studio`, `npx prisma format` |272| **Drizzle** | `npx drizzle-kit generate`, `npx drizzle-kit migrate`, `npx drizzle-kit push`, `npx drizzle-kit studio` |273274#### PHP275276| If Detected | Read-Only Commands | Development Commands |277|-------------|-------------------|---------------------|278| `composer.json` | `php --version`, `composer show`, `composer info` | `php`, `composer install`, `composer require`, `composer remove`, `composer update`, `composer dump-autoload` |279| PHPUnit detected | — | `phpunit`, `./vendor/bin/phpunit` |280| PHPStan detected | — | `phpstan`, `./vendor/bin/phpstan` |281282**PHP frameworks:**283284| If Detected | Development Commands |285|-------------|---------------------|286| **Laravel** | `php artisan` (e.g., `artisan migrate`, `artisan make:model`, `artisan make:controller`, `artisan make:migration`, `artisan route:list`, `artisan config:show`, `artisan test`, `artisan tinker`, `artisan queue:work`, `artisan schedule:run`, `artisan db:seed`, `artisan cache:clear`, `artisan key:generate`, `artisan serve`) |287| **Magento** | `php bin/magento` (e.g., `bin/magento setup:upgrade`, `bin/magento cache:flush`, `bin/magento module:status`, `bin/magento indexer:reindex`, `bin/magento setup:di:compile`) |288| **Symfony** | `php bin/console` (e.g., `bin/console doctrine:migrations:migrate`, `bin/console make:entity`, `bin/console cache:clear`) |289290#### Go291292| If Detected | Read-Only Commands | Development Commands |293|-------------|-------------------|---------------------|294| `go.mod` | `go version`, `go list`, `go mod graph`, `go env` | `go build`, `go run`, `go test`, `go vet`, `go fmt`, `go mod tidy`, `go mod download`, `go generate`, `go get` |295| golangci-lint detected | — | `golangci-lint run` |296297#### Rust298299| If Detected | Read-Only Commands | Development Commands |300|-------------|-------------------|---------------------|301| `Cargo.toml` | `rustc --version`, `cargo --version`, `cargo tree`, `cargo metadata` | `cargo build`, `cargo run`, `cargo test`, `cargo check`, `cargo clippy`, `cargo fmt`, `cargo add`, `cargo remove` |302303#### Ruby304305| If Detected | Read-Only Commands | Development Commands |306|-------------|-------------------|---------------------|307| `Gemfile` | `ruby --version`, `bundle list`, `bundle show` | `bundle install`, `bundle exec`, `bundle add` |308309**Ruby frameworks:**310311| If Detected | Development Commands |312|-------------|---------------------|313| **Rails** | `rails` (e.g., `rails server`, `rails console`, `rails generate`, `rails db:migrate`, `rails db:seed`, `rails test`, `rails routes`) |314| RSpec detected | `rspec`, `bundle exec rspec` |315316#### Java/Kotlin317318| If Detected | Read-Only Commands | Development Commands |319|-------------|-------------------|---------------------|320| `pom.xml` | `java --version`, `mvn --version`, `mvn dependency:tree` | `mvn compile`, `mvn test`, `mvn package`, `mvn clean`, `mvn install` |321| `build.gradle` / `build.gradle.kts` | `java --version`, `gradle --version`, `gradle dependencies` | `gradle build`, `gradle test`, `gradle clean`, `gradle run`, `./gradlew` |322323#### .NET324325| If Detected | Read-Only Commands | Development Commands |326|-------------|-------------------|---------------------|327| `*.csproj` / `*.sln` | `dotnet --version`, `dotnet list package` | `dotnet build`, `dotnet run`, `dotnet test`, `dotnet add package`, `dotnet remove package`, `dotnet ef` |328329#### Build Tools & Infrastructure330331| If Detected | Read-Only Commands | Development Commands |332|-------------|-------------------|---------------------|333| `Dockerfile` | `docker --version`, `docker ps`, `docker images` | `docker build`, `docker run`, `docker exec`, `docker logs`, `docker stop`, `docker rm` |334| `docker-compose.yml` | `docker-compose ps`, `docker-compose config` | `docker-compose up`, `docker-compose down`, `docker-compose build`, `docker-compose logs`, `docker-compose exec` |335| `*.tf` files | `terraform --version`, `terraform providers`, `terraform state list` | `terraform plan`, `terraform apply`, `terraform init`, `terraform validate` |336| `Makefile` | `make --version`, `make -n` | `make` |337| `serverless.yml` | `serverless --version` | `serverless deploy`, `serverless invoke`, `serverless logs` |338| AWS CDK (`aws-cdk` in deps) | `cdk --version` | `cdk synth`, `cdk diff`, `cdk deploy`, `cdk destroy` |339340#### @ulpi Tools341342| If Detected | Commands to Allow |343|-------------|-------------------|344| **browse** | `Bash(browse:*)`, `Bash(browse goto:*)`, `Bash(browse text:*)`, `Bash(browse snapshot:*)`, `Bash(browse click:*)`, `Bash(browse fill:*)`, `Bash(browse screenshot:*)`, and all other browse subcommands (see browse SKILL.md for full list) |345| **codemap** | `Bash(codemap:*)`, `Bash(codemap search:*)`, `Bash(codemap symbols:*)`, `Bash(codemap deps:*)`, `Bash(codemap dependents:*)`, `Bash(codemap rank:*)`, `Bash(codemap cycles:*)`, `Bash(codemap summary:*)`, `Bash(codemap index:*)`, `Bash(codemap status:*)`, `Bash(codemap coupling:*)`, `Bash(codemap graph-stats:*)` |346347### Package Manager Exclusion Rules348349Only include the package manager actually used by the project:350351| If Detected | Include | Do NOT Include |352|-------------|---------|---------------|353| `pnpm-lock.yaml` | pnpm commands | npm, yarn, bun |354| `yarn.lock` | yarn commands | npm, pnpm, bun |355| `bun.lockb` | bun commands | npm, yarn, pnpm |356| `package-lock.json` | npm commands | yarn, pnpm, bun |357| `poetry.lock` | poetry commands | pip (unless also has requirements.txt) |358| `uv.lock` | uv commands | pip, poetry |359| `Pipfile.lock` | pipenv commands | pip, poetry |360361If multiple lock files exist, include only the commands for each detected manager.362363### WebFetch Domains364365Add documentation domains for detected frameworks:366367| If Detected | Add Domains |368|-------------|------------|369| **Django** | `docs.djangoproject.com` |370| **Flask** | `flask.palletsprojects.com` |371| **FastAPI** | `fastapi.tiangolo.com` |372| **React** | `react.dev` |373| **Next.js** | `nextjs.org` |374| **Expo/React Native** | `docs.expo.dev`, `reactnative.dev` |375| **Vite** | `vite.dev` |376| **Tailwind CSS** | `tailwindcss.com` |377| **Vue** | `vuejs.org` |378| **Angular** | `angular.dev` |379| **Svelte** | `svelte.dev` |380| **Express** | `expressjs.com` |381| **Rails** | `guides.rubyonrails.org`, `api.rubyonrails.org` |382| **Laravel** | `laravel.com` |383| **Magento** | `developer.adobe.com` |384| **Go** | `pkg.go.dev` |385| **Rust** | `docs.rs`, `doc.rust-lang.org` |386| **Docker** | `docs.docker.com` |387| **Kubernetes** | `kubernetes.io` |388| **Terraform** | `registry.terraform.io` |389| **AWS CDK** | `docs.aws.amazon.com` |390| **Firebase** | `firebase.google.com` |391392Always include general-purpose domains:393394```json395[396 "WebFetch(domain:docs.github.com)",397 "WebFetch(domain:cli.github.com)"398]399```400401### MCP Tool Permissions (Always Include)402403The codemap and memory MCP servers are core infrastructure for this project. **Always allow ALL tools from both servers** — do not cherry-pick individual tools.404405```json406[407 "mcp__codemap__search_code",408 "mcp__codemap__search_symbols",409 "mcp__codemap__get_file_summary",410 "mcp__codemap__get_index_stats",411 "mcp__codemap__reindex",412 "mcp__codemap__get_dependencies",413 "mcp__codemap__get_dependents",414 "mcp__codemap__get_file_rank",415 "mcp__codemap__find_cycles",416 "mcp__codemap__get_coupling_metrics",417 "mcp__codemap__get_depgraph_stats",418 "mcp__codemap__rebuild_depgraph",419 "mcp__memory__search_memory",420 "mcp__memory__save_memory",421 "mcp__memory__get_timeline",422 "mcp__memory__get_session_context",423 "mcp__memory__forget",424 "mcp__memory__memory_stats"425]426```427428**Why:** These tools are read-only or low-risk (search, index, stats). Requiring per-tool approval creates friction during every session. All agents (main + subagents) need these tools to search the codebase and access project memory effectively.429430### MCP Server Suggestions431432MCP servers are configured in `.mcp.json` (not `settings.local.json`). Only suggest MCP servers for detected services.433434```bash435# Check existing MCP config436cat .mcp.json 2>/dev/null || echo "No existing .mcp.json"437```438439#### Sentry MCP (if Sentry SDK detected)440441```json442{443 "mcpServers": {444 "sentry": {445 "type": "http",446 "url": "https://mcp.sentry.dev/mcp/{org-slug}/{project-slug}"447 }448 }449}450```451452#### Linear MCP (if Linear usage detected)453454```json455{456 "mcpServers": {457 "linear": {458 "command": "npx",459 "args": ["-y", "@linear/mcp-server"],460 "env": {461 "LINEAR_API_KEY": "${LINEAR_API_KEY}"462 }463 }464 }465}466```467468**Note:** Never suggest GitHub MCP. Always use `gh` CLI commands for GitHub operations.469470## Step 5: Present Recommendations471472**Gate: User has reviewed the recommendations before proceeding to Step 6.**473474Present findings in this structure:475476### Output Format477478```479## Detected Tech Stack480481| Category | Found |482|----------|-------|483| Languages | [detected languages] |484| Package Manager | [detected manager] |485| Frameworks | [detected frameworks] |486| Services | [detected services] |487| Build Tools | [detected tools] |488| Monorepo | [yes/no, tool name] |489490## Recommended .claude/settings.local.json491492{complete JSON with grouped, commented permissions}493494## Recommended .mcp.json (if applicable)495496{MCP server config for detected services}497498## Changes from Current Settings (if existing settings found)499500| Change | Description |501|--------|------------|502| Added | [new commands for detected tools] |503| Removed | [stale commands for tools no longer detected] |504| Unchanged | [commands that remain the same] |505```506507Use AskUserQuestion to confirm before writing any files:508- "Apply these settings?" with options to apply all, apply selectively, or just view509510## Step 6: Apply Settings511512**Gate: User approved the recommendations before writing files.**513514If the user approves:5155161. Write `.claude/settings.local.json` with the recommended permissions5172. Write `.mcp.json` with MCP server suggestions (if applicable)5183. If merging with existing settings, preserve user customizations (deny list, custom commands)519520If existing settings exist, show a clear diff of what will change before writing.521522## Step 7: Verify Applied Settings523524**Gate: Settings files are valid JSON and contain expected content.**525526After writing:5275281. Verify `.claude/settings.local.json` is valid JSON:529530```bash531python3 -c "import json; json.load(open('.claude/settings.local.json'))" 2>&1 || echo "Invalid JSON"532```5335342. Verify `.mcp.json` is valid JSON (if written):535536```bash537python3 -c "import json; json.load(open('.mcp.json'))" 2>&1 || echo "Invalid JSON"538```5395403. Confirm all detected tools have corresponding commands in the settings5414. Confirm no write/modify commands were included542543---544545## Safety Rules546547| Rule | Reason |548|------|--------|549| Never include destructive system commands | No `rm -rf`, `format`, `fdisk`, or system-level destructive operations |550| Never include absolute paths | Paths are user-specific and non-portable |551| Never include custom scripts | Project scripts may have side effects; only standard tool commands |552| Never guess at tools | Only include commands for tools detected via config/lock files |553| Never include wrong package manager | If project uses pnpm, don't include npm/yarn commands |554| Always include development commands | Claude needs build, test, run, install commands to work effectively |555| Always read existing settings first | Preserve user customizations and deny lists |556| Always verify JSON validity | Invalid settings.local.json breaks Claude Code |557| Always get user approval before writing | User must review recommendations before files are modified |558| Never suggest GitHub MCP | Use `gh` CLI commands for GitHub operations instead |559560---561562## Quick Reference: Package Manager Detection563564```565Lock file exists?566├── pnpm-lock.yaml → pnpm (exclude npm, yarn, bun)567├── yarn.lock → yarn (exclude npm, pnpm, bun)568├── bun.lockb → bun (exclude npm, yarn, pnpm)569├── package-lock.json → npm (exclude yarn, pnpm, bun)570├── poetry.lock → poetry (exclude pip unless requirements.txt also exists)571├── uv.lock → uv (exclude pip, poetry)572├── Pipfile.lock → pipenv (exclude pip, poetry)573├── Cargo.lock → cargo574├── Gemfile.lock → bundler575├── go.sum → go576└── composer.lock → composer577```578579---580581## Step 8: Verification (MANDATORY)582583After completing settings generation, verify the full workflow:584585### Check 1: Stack Detection Accuracy586- [ ] Every language detected has corresponding commands in settings587- [ ] No commands included for undetected tools588589### Check 2: Command Safety590- [ ] No destructive system commands included (rm -rf, format, fdisk, etc.)591- [ ] No absolute paths or user-specific paths included592- [ ] Development commands are appropriate for detected frameworks593594### Check 3: Package Manager Correctness595- [ ] Only the detected package manager's commands are included596- [ ] No competing package manager commands present597598### Check 4: Settings Validity599- [ ] `.claude/settings.local.json` is valid JSON (if written)600- [ ] `.mcp.json` is valid JSON (if written)601602### Check 5: Completeness603- [ ] WebFetch domains included for detected frameworks604- [ ] MCP suggestions provided for detected services605- [ ] Existing settings preserved where applicable606607**Gate:** Do NOT mark settings generation complete until all 5 checks pass.608609---610611## Quality Checklist (Must Score 8/10)612613Score yourself honestly before marking settings generation complete:614615### Stack Detection (0-2 points)616- **0 points:** Assumed tech stack without reading config files617- **1 point:** Detected some tools but missed others618- **2 points:** Detected all languages, package managers, frameworks, services, and build tools from config/lock files619620### Command Accuracy (0-2 points)621- **0 points:** Included commands for undetected tools or missed framework-specific commands622- **1 point:** Mostly correct but included wrong package manager or missed development commands623- **2 points:** Every command matches a detected tool, includes both read-only and development commands, correct package manager only624625### Existing Settings Handling (0-2 points)626- **0 points:** Overwrote existing settings without reading them627- **1 point:** Read existing settings but didn't preserve customizations628- **2 points:** Read existing settings, preserved deny list and custom commands, showed clear diff629630### Output Quality (0-2 points)631- **0 points:** Dumped raw JSON without explanation632- **1 point:** Provided settings but missing summary table or grouping633- **2 points:** Complete output: summary table, grouped/commented JSON, merge instructions if applicable634635### Verification (0-2 points)636- **0 points:** Didn't verify JSON validity or command correctness637- **1 point:** Verified JSON but didn't check for write commands or wrong package managers638- **2 points:** Verified JSON validity, read-only compliance, package manager correctness, and completeness639640**Minimum passing score: 8/10**641642---643644## Common Rationalizations (All Wrong)645646These are excuses. Don't fall for them:647648- **"Most projects use npm"** → STILL detect the actual package manager from lock files649- **"These extra commands might be useful"** → STILL only include commands for detected tools650- **"Any dev command is fine to include"** → STILL verify each command is appropriate for the detected framework651- **"The user can fix it later"** → Get it right NOW; wrong settings cause permission friction652- **"There's no existing settings.local.json"** → STILL check; the user may have customizations elsewhere653- **"I'll just include all package managers"** → STILL exclude package managers not detected in the project654- **"Absolute paths work on this machine"** → STILL use only portable command names655- **"This MCP server would be helpful"** → STILL only suggest MCP servers for detected services656657---658659## Failure Modes660661### Failure Mode 1: Wrong Package Manager662663**Symptom:** Settings include npm commands but the project uses pnpm (or similar mismatch)664**Fix:** Always check lock files first. The lock file determines the package manager, not assumptions.665666### Failure Mode 2: Destructive Commands Included667668**Symptom:** Settings allow `rm -rf`, system-level destructive operations, or commands that could cause data loss669**Fix:** Review every command for safety. Development commands (install, build, test, run) are fine; system-level destructive commands are not.670671### Failure Mode 3: Absolute Paths672673**Symptom:** Settings include `/Users/name/bin/tool` or `/home/user/.local/bin/script`674**Fix:** Never include absolute paths. Only use bare command names that resolve via PATH.675676### Failure Mode 4: Stale Settings677678**Symptom:** Settings include commands for tools removed from the project679**Fix:** Always detect the current stack before generating. Cross-reference existing settings against detected tools.680681### Failure Mode 5: Invalid JSON682683**Symptom:** Claude Code fails to load settings because of JSON syntax errors684**Fix:** Always validate JSON after writing. Use `python3 -c "import json; json.load(open(...))"` to verify.685686---687688## Quick Workflow Summary689690```691STEP 1: DETECT TECH STACK692├── List root directory693├── Find config and lock files694├── Identify languages and package managers695└── Gate: All tools identified696697STEP 2: DETECT FRAMEWORKS AND SERVICES698├── Read dependency files699├── Check for service integrations700└── Gate: All frameworks and services identified701702STEP 3: CHECK EXISTING SETTINGS703├── Read .claude/settings.local.json704├── Read .mcp.json705├── Note gaps and stale entries706└── Gate: Current state understood707708STEP 4: BUILD RECOMMENDATIONS709├── Start with baseline commands710├── Add stack-specific commands711├── Add WebFetch domains712├── Add MCP suggestions713├── Enforce package manager exclusion rules714└── Gate: Complete recommendation generated715716STEP 5: PRESENT RECOMMENDATIONS717├── Show detected stack summary718├── Show recommended settings.local.json719├── Show changes from current (if applicable)720├── Get user approval721└── Gate: User reviewed722723STEP 6: APPLY SETTINGS724├── Write .claude/settings.local.json725├── Write .mcp.json (if applicable)726├── Preserve existing customizations727└── Gate: User approved and files written728729STEP 7: VERIFY SETTINGS730├── Validate JSON731├── Confirm read-only compliance732├── Confirm package manager correctness733└── Gate: Settings verified734735STEP 8: VERIFICATION (MANDATORY)736├── Check 1: Stack detection accuracy737├── Check 2: Read-only compliance738├── Check 3: Package manager correctness739├── Check 4: Settings validity740├── Check 5: Completeness741└── Gate: All 5 checks pass742```743744---745746## Completion Announcement747748When settings generation is complete, announce:749750```751Settings generation complete.752753**Quality Score: X/10**754- Stack Detection: X/2755- Command Accuracy: X/2756- Existing Settings Handling: X/2757- Output Quality: X/2758- Verification: X/2759760**Detected Stack:**761- Languages: [list]762- Package Manager: [name]763- Frameworks: [list]764- Services: [list]765- Build Tools: [list]766767**Settings:**768- Commands allowed: [count]769- WebFetch domains: [count]770- MCP servers suggested: [count]771- Existing settings: [merged / new / unchanged]772773**Verification:**774- JSON valid: ✅775- No destructive commands: ✅776- Correct package manager: ✅777- All tools covered (read-only + development): ✅778779**Next steps:**780[Review settings in .claude/settings.local.json, restart Claude Code to apply]781```782783---784785## Integration with Other Skills786787The `update-claude-settings` skill integrates with:788789- **`start`** — Run `update-claude-settings` when setting up a new project790- **`update-claude-md-after-install`** — After installing framework agents, update settings to match791- **`commit`** — After generating settings, commit the changes792793**Workflow Chain:**794795```796New project setup797 │798 ▼799update-claude-settings skill (this skill)800 │801 ▼802commit skill (commit settings files)803 │804 ▼805Begin development with correct permissions806```